diff options
Diffstat (limited to 'net/openvswitch/flow_table.c')
| -rw-r--r-- | net/openvswitch/flow_table.c | 26 | 
1 files changed, 14 insertions, 12 deletions
diff --git a/net/openvswitch/flow_table.c b/net/openvswitch/flow_table.c index d22d8e948d0f..c7f74aab34b9 100644 --- a/net/openvswitch/flow_table.c +++ b/net/openvswitch/flow_table.c @@ -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++;  } @@ -92,7 +93,8 @@ struct sw_flow *ovs_flow_alloc(void)  	/* Initialize the default stat node. */  	stats = kmem_cache_alloc_node(flow_stats_cache, -				      GFP_KERNEL | __GFP_ZERO, 0); +				      GFP_KERNEL | __GFP_ZERO, +				      node_online(0) ? 0 : NUMA_NO_NODE);  	if (!stats)  		goto err; @@ -475,7 +477,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]) {  | 
