aboutsummaryrefslogtreecommitdiff
path: root/datapath/table.c
diff options
context:
space:
mode:
authorAndrew Evans <aevans@nicira.com>2011-05-18 11:30:07 -0700
committerAndrew Evans <aevans@nicira.com>2011-05-18 11:30:07 -0700
commit76abe283baa043bae84163873b0c7c498bfb260a (patch)
tree58fee6ca32534584c988caba03e0041b8a916c6e /datapath/table.c
parentf9c71a155bb27a981865407d5a3d78ecd9ca24af (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.c14
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;