|
@@ -57,20 +57,21 @@ static u16 range_n_bytes(const struct sw_flow_key_range *range)
|
|
|
}
|
|
|
|
|
|
void ovs_flow_mask_key(struct sw_flow_key *dst, const struct sw_flow_key *src,
|
|
|
- const struct sw_flow_mask *mask)
|
|
|
+ bool full, const struct sw_flow_mask *mask)
|
|
|
{
|
|
|
- const long *m = (const long *)((const u8 *)&mask->key +
|
|
|
- mask->range.start);
|
|
|
- const long *s = (const long *)((const u8 *)src +
|
|
|
- mask->range.start);
|
|
|
- long *d = (long *)((u8 *)dst + mask->range.start);
|
|
|
+ int start = full ? 0 : mask->range.start;
|
|
|
+ int len = full ? sizeof *dst : range_n_bytes(&mask->range);
|
|
|
+ const long *m = (const long *)((const u8 *)&mask->key + start);
|
|
|
+ const long *s = (const long *)((const u8 *)src + start);
|
|
|
+ long *d = (long *)((u8 *)dst + start);
|
|
|
int i;
|
|
|
|
|
|
- /* The memory outside of the 'mask->range' are not set since
|
|
|
- * further operations on 'dst' only uses contents within
|
|
|
- * 'mask->range'.
|
|
|
+ /* If 'full' is true then all of 'dst' is fully initialized. Otherwise,
|
|
|
+ * if 'full' is false the memory outside of the 'mask->range' is left
|
|
|
+ * uninitialized. This can be used as an optimization when further
|
|
|
+ * operations on 'dst' only use contents within 'mask->range'.
|
|
|
*/
|
|
|
- for (i = 0; i < range_n_bytes(&mask->range); i += sizeof(long))
|
|
|
+ for (i = 0; i < len; i += sizeof(long))
|
|
|
*d++ = *s++ & *m++;
|
|
|
}
|
|
|
|
|
@@ -475,7 +476,7 @@ static struct sw_flow *masked_flow_lookup(struct table_instance *ti,
|
|
|
u32 hash;
|
|
|
struct sw_flow_key masked_key;
|
|
|
|
|
|
- ovs_flow_mask_key(&masked_key, unmasked, mask);
|
|
|
+ ovs_flow_mask_key(&masked_key, unmasked, false, mask);
|
|
|
hash = flow_hash(&masked_key, &mask->range);
|
|
|
head = find_bucket(ti, hash);
|
|
|
hlist_for_each_entry_rcu(flow, head, flow_table.node[ti->node_ver]) {
|