diff options
author | Andrew Evans <aevans@nicira.com> | 2011-05-18 11:30:07 -0700 |
---|---|---|
committer | Andrew Evans <aevans@nicira.com> | 2011-05-18 11:30:07 -0700 |
commit | 76abe283baa043bae84163873b0c7c498bfb260a (patch) | |
tree | 58fee6ca32534584c988caba03e0041b8a916c6e /datapath/table.c | |
parent | f9c71a155bb27a981865407d5a3d78ecd9ca24af (diff) |
datapath: Hash and compare only the part of sw_flow_key actually used.
Currently the whole flow key struct is hashed on every packet received from the
network or userspace. The whole struct is also compared byte-for-byte when
doing flow table lookups. This consumes a fair percentage of CPU time, and most
of the time part of the structure is unused (e.g. the IPv6 fields when handling
IPv4 traffic; the IPv4 fields when handling Ethernet frames).
This commit reorders the fields in the flow key struct to put the least
commonly used elements at the end and changes the hash and comparison functions
to look only at the part that contains data.
Signed-off-by: Andrew Evans <aevans@nicira.com>
Acked-by: Jesse Gross <jesse@nicira.com>
Diffstat (limited to 'datapath/table.c')
-rw-r--r-- | datapath/table.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/datapath/table.c b/datapath/table.c index 47fa0169..725845de 100644 --- a/datapath/table.c +++ b/datapath/table.c @@ -178,14 +178,14 @@ static struct tbl_bucket __rcu **find_bucket(struct tbl *table, u32 hash) return &table->buckets[l1][l2]; } -static int search_bucket(const struct tbl_bucket *bucket, void *target, u32 hash, - int (*cmp)(const struct tbl_node *, void *)) +static int search_bucket(const struct tbl_bucket *bucket, void *target, int len, u32 hash, + int (*cmp)(const struct tbl_node *, void *, int len)) { int i; for (i = 0; i < bucket->n_objs; i++) { struct tbl_node *obj = bucket->objs[i]; - if (obj->hash == hash && likely(cmp(obj, target))) + if (obj->hash == hash && likely(cmp(obj, target, len))) return i; } @@ -197,6 +197,8 @@ static int search_bucket(const struct tbl_bucket *bucket, void *target, u32 hash * @table: hash table to search * @target: identifier for the object that is being searched for, will be * provided as an argument to @cmp when making comparisions + * @len: length of @target in bytes, will be provided as an argument to @cmp + * when making comparisons * @hash: hash of @target * @cmp: comparision function to match objects with the given hash, returns * nonzero if the objects match, zero otherwise @@ -204,8 +206,8 @@ static int search_bucket(const struct tbl_bucket *bucket, void *target, u32 hash * Searches @table for an object identified by @target. Returns the tbl_node * contained in the object if successful, otherwise %NULL. */ -struct tbl_node *tbl_lookup(struct tbl *table, void *target, u32 hash, - int (*cmp)(const struct tbl_node *, void *)) +struct tbl_node *tbl_lookup(struct tbl *table, void *target, int len, u32 hash, + int (*cmp)(const struct tbl_node *, void *, int)) { struct tbl_bucket __rcu **bucketp = find_bucket(table, hash); struct tbl_bucket *bucket = get_bucket(*bucketp); @@ -214,7 +216,7 @@ struct tbl_node *tbl_lookup(struct tbl *table, void *target, u32 hash, if (!bucket) return NULL; - index = search_bucket(bucket, target, hash, cmp); + index = search_bucket(bucket, target, len, hash, cmp); if (index < 0) return NULL; |