net sched actions: Convert to use idr_alloc_u32
Use the new helper. Also untangle the error path, and in so doing noticed that estimator generator failure would lead to us leaking an ID. Fix that bug. Signed-off-by: Matthew Wilcox <mawilcox@microsoft.com>
This commit is contained in:
parent
e096f6a762
commit
339913a8be
@ -274,7 +274,6 @@ int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est,
|
|||||||
struct tcf_idrinfo *idrinfo = tn->idrinfo;
|
struct tcf_idrinfo *idrinfo = tn->idrinfo;
|
||||||
struct idr *idr = &idrinfo->action_idr;
|
struct idr *idr = &idrinfo->action_idr;
|
||||||
int err = -ENOMEM;
|
int err = -ENOMEM;
|
||||||
unsigned long idr_index;
|
|
||||||
|
|
||||||
if (unlikely(!p))
|
if (unlikely(!p))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -284,45 +283,28 @@ int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est,
|
|||||||
|
|
||||||
if (cpustats) {
|
if (cpustats) {
|
||||||
p->cpu_bstats = netdev_alloc_pcpu_stats(struct gnet_stats_basic_cpu);
|
p->cpu_bstats = netdev_alloc_pcpu_stats(struct gnet_stats_basic_cpu);
|
||||||
if (!p->cpu_bstats) {
|
if (!p->cpu_bstats)
|
||||||
err1:
|
|
||||||
kfree(p);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
p->cpu_qstats = alloc_percpu(struct gnet_stats_queue);
|
|
||||||
if (!p->cpu_qstats) {
|
|
||||||
err2:
|
|
||||||
free_percpu(p->cpu_bstats);
|
|
||||||
goto err1;
|
goto err1;
|
||||||
}
|
p->cpu_qstats = alloc_percpu(struct gnet_stats_queue);
|
||||||
|
if (!p->cpu_qstats)
|
||||||
|
goto err2;
|
||||||
}
|
}
|
||||||
spin_lock_init(&p->tcfa_lock);
|
spin_lock_init(&p->tcfa_lock);
|
||||||
|
idr_preload(GFP_KERNEL);
|
||||||
|
spin_lock_bh(&idrinfo->lock);
|
||||||
/* user doesn't specify an index */
|
/* user doesn't specify an index */
|
||||||
if (!index) {
|
if (!index) {
|
||||||
idr_preload(GFP_KERNEL);
|
index = 1;
|
||||||
spin_lock_bh(&idrinfo->lock);
|
err = idr_alloc_u32(idr, NULL, &index, UINT_MAX, GFP_ATOMIC);
|
||||||
err = idr_alloc_ext(idr, NULL, &idr_index, 1, 0,
|
|
||||||
GFP_ATOMIC);
|
|
||||||
spin_unlock_bh(&idrinfo->lock);
|
|
||||||
idr_preload_end();
|
|
||||||
if (err) {
|
|
||||||
err3:
|
|
||||||
free_percpu(p->cpu_qstats);
|
|
||||||
goto err2;
|
|
||||||
}
|
|
||||||
p->tcfa_index = idr_index;
|
|
||||||
} else {
|
} else {
|
||||||
idr_preload(GFP_KERNEL);
|
err = idr_alloc_u32(idr, NULL, &index, index, GFP_ATOMIC);
|
||||||
spin_lock_bh(&idrinfo->lock);
|
|
||||||
err = idr_alloc_ext(idr, NULL, NULL, index, index + 1,
|
|
||||||
GFP_ATOMIC);
|
|
||||||
spin_unlock_bh(&idrinfo->lock);
|
|
||||||
idr_preload_end();
|
|
||||||
if (err)
|
|
||||||
goto err3;
|
|
||||||
p->tcfa_index = index;
|
|
||||||
}
|
}
|
||||||
|
spin_unlock_bh(&idrinfo->lock);
|
||||||
|
idr_preload_end();
|
||||||
|
if (err)
|
||||||
|
goto err3;
|
||||||
|
|
||||||
|
p->tcfa_index = index;
|
||||||
p->tcfa_tm.install = jiffies;
|
p->tcfa_tm.install = jiffies;
|
||||||
p->tcfa_tm.lastuse = jiffies;
|
p->tcfa_tm.lastuse = jiffies;
|
||||||
p->tcfa_tm.firstuse = 0;
|
p->tcfa_tm.firstuse = 0;
|
||||||
@ -330,9 +312,8 @@ err3:
|
|||||||
err = gen_new_estimator(&p->tcfa_bstats, p->cpu_bstats,
|
err = gen_new_estimator(&p->tcfa_bstats, p->cpu_bstats,
|
||||||
&p->tcfa_rate_est,
|
&p->tcfa_rate_est,
|
||||||
&p->tcfa_lock, NULL, est);
|
&p->tcfa_lock, NULL, est);
|
||||||
if (err) {
|
if (err)
|
||||||
goto err3;
|
goto err4;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p->idrinfo = idrinfo;
|
p->idrinfo = idrinfo;
|
||||||
@ -340,6 +321,15 @@ err3:
|
|||||||
INIT_LIST_HEAD(&p->list);
|
INIT_LIST_HEAD(&p->list);
|
||||||
*a = p;
|
*a = p;
|
||||||
return 0;
|
return 0;
|
||||||
|
err4:
|
||||||
|
idr_remove(idr, index);
|
||||||
|
err3:
|
||||||
|
free_percpu(p->cpu_qstats);
|
||||||
|
err2:
|
||||||
|
free_percpu(p->cpu_bstats);
|
||||||
|
err1:
|
||||||
|
kfree(p);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(tcf_idr_create);
|
EXPORT_SYMBOL(tcf_idr_create);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user