datapath: update exact match lookup hash value to avoid hash collision
authorAndy Zhou <azhou@nicira.com>
Tue, 3 Feb 2015 21:57:55 +0000 (13:57 -0800)
committerAndy Zhou <azhou@nicira.com>
Tue, 3 Feb 2015 23:14:41 +0000 (15:14 -0800)
Currently, the exact match cache lookup uses 'skb->hash' as an index.
In most cases, this value will be the same for pre and post
recirculation lookup, threshing the exact match cache. This patch
avoid this hash collision by using the rehashed value, by mixing in
in the 'recirc_id', as the lookup index.

Signed-off-by: Andy Zhou <azhou@nicira.com>
Acked-by: Pravin B Shelar <pshelar@nicira.com>
datapath/flow_table.c

index 10bf830..1f6fb70 100644 (file)
@@ -574,7 +574,7 @@ struct sw_flow *ovs_flow_tbl_lookup_stats(struct flow_table *tbl,
        struct table_instance *ti = rcu_dereference(tbl->ti);
        struct mask_cache_entry *entries, *ce;
        struct sw_flow *flow;
-       u32 hash = skb_hash;
+       u32 hash;
        int seg;
 
        *n_mask_hit = 0;
@@ -584,7 +584,14 @@ struct sw_flow *ovs_flow_tbl_lookup_stats(struct flow_table *tbl,
                return flow_lookup(tbl, ti, ma, key, n_mask_hit, &mask_index);
        }
 
+       /* Pre and post recirulation flows usually have the same skb_hash
+        * value. To avoid hash collisions, rehash the 'skb_hash' with
+        * 'recirc_id'.  */
+       if (key->recirc_id)
+               skb_hash = jhash_1word(skb_hash, key->recirc_id);
+
        ce = NULL;
+       hash = skb_hash;
        entries = this_cpu_ptr(tbl->mask_cache);
 
        /* Find the cache entry 'ce' to operate on. */