diff options
| author | Ingo Molnar <[email protected]> | 2014-07-28 10:03:00 +0200 | 
|---|---|---|
| committer | Ingo Molnar <[email protected]> | 2014-07-28 10:03:00 +0200 | 
| commit | ca5bc6cd5de5b53eb8fd6fea39aa3fe2a1e8c3d9 (patch) | |
| tree | 75beaae2d4b6bc654eb28994dd5906d8dcf5ef46 /net/sched/cls_u32.c | |
| parent | c1221321b7c25b53204447cff9949a6d5a7ddddc (diff) | |
| parent | d8d28c8f00e84a72e8bee39a85835635417bee49 (diff) | |
Merge branch 'sched/urgent' into sched/core, to merge fixes before applying new changes
Signed-off-by: Ingo Molnar <[email protected]>
Diffstat (limited to 'net/sched/cls_u32.c')
| -rw-r--r-- | net/sched/cls_u32.c | 19 | 
1 files changed, 14 insertions, 5 deletions
| diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index c39b583ace32..70c0be8d0121 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -38,6 +38,7 @@  #include <linux/errno.h>  #include <linux/rtnetlink.h>  #include <linux/skbuff.h> +#include <linux/bitmap.h>  #include <net/netlink.h>  #include <net/act_api.h>  #include <net/pkt_cls.h> @@ -460,17 +461,25 @@ static int u32_delete(struct tcf_proto *tp, unsigned long arg)  	return 0;  } +#define NR_U32_NODE (1<<12)  static u32 gen_new_kid(struct tc_u_hnode *ht, u32 handle)  {  	struct tc_u_knode *n; -	unsigned int i = 0x7FF; +	unsigned long i; +	unsigned long *bitmap = kzalloc(BITS_TO_LONGS(NR_U32_NODE) * sizeof(unsigned long), +					GFP_KERNEL); +	if (!bitmap) +		return handle | 0xFFF;  	for (n = ht->ht[TC_U32_HASH(handle)]; n; n = n->next) -		if (i < TC_U32_NODE(n->handle)) -			i = TC_U32_NODE(n->handle); -	i++; +		set_bit(TC_U32_NODE(n->handle), bitmap); -	return handle | (i > 0xFFF ? 0xFFF : i); +	i = find_next_zero_bit(bitmap, NR_U32_NODE, 0x800); +	if (i >= NR_U32_NODE) +		i = find_next_zero_bit(bitmap, NR_U32_NODE, 1); + +	kfree(bitmap); +	return handle | (i >= NR_U32_NODE ? 0xFFF : i);  }  static const struct nla_policy u32_policy[TCA_U32_MAX + 1] = { |