diff options
Diffstat (limited to 'net/sched')
| -rw-r--r-- | net/sched/cls_u32.c | 24 | 
1 files changed, 14 insertions, 10 deletions
| diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index cf5649292ee0..4d27300c287c 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -386,14 +386,19 @@ static int u32_init(struct tcf_proto *tp)  	return 0;  } -static int u32_destroy_key(struct tc_u_knode *n, bool free_pf) +static void __u32_destroy_key(struct tc_u_knode *n)  {  	struct tc_u_hnode *ht = rtnl_dereference(n->ht_down);  	tcf_exts_destroy(&n->exts); -	tcf_exts_put_net(&n->exts);  	if (ht && --ht->refcnt == 0)  		kfree(ht); +	kfree(n); +} + +static void u32_destroy_key(struct tc_u_knode *n, bool free_pf) +{ +	tcf_exts_put_net(&n->exts);  #ifdef CONFIG_CLS_U32_PERF  	if (free_pf)  		free_percpu(n->pf); @@ -402,8 +407,7 @@ static int u32_destroy_key(struct tc_u_knode *n, bool free_pf)  	if (free_pf)  		free_percpu(n->pcpu_success);  #endif -	kfree(n); -	return 0; +	__u32_destroy_key(n);  }  /* u32_delete_key_rcu should be called when free'ing a copied @@ -811,10 +815,6 @@ static struct tc_u_knode *u32_init_knode(struct net *net, struct tcf_proto *tp,  	new->flags = n->flags;  	RCU_INIT_POINTER(new->ht_down, ht); -	/* bump reference count as long as we hold pointer to structure */ -	if (ht) -		ht->refcnt++; -  #ifdef CONFIG_CLS_U32_PERF  	/* Statistics may be incremented by readers during update  	 * so we must keep them in tact. When the node is later destroyed @@ -836,6 +836,10 @@ static struct tc_u_knode *u32_init_knode(struct net *net, struct tcf_proto *tp,  		return NULL;  	} +	/* bump reference count as long as we hold pointer to structure */ +	if (ht) +		ht->refcnt++; +  	return new;  } @@ -900,13 +904,13 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,  				    extack);  		if (err) { -			u32_destroy_key(new, false); +			__u32_destroy_key(new);  			return err;  		}  		err = u32_replace_hw_knode(tp, new, flags, extack);  		if (err) { -			u32_destroy_key(new, false); +			__u32_destroy_key(new);  			return err;  		} | 
