netem: dont call vfree() under spinlock and BH disabled
commit 6373a9a286
(netem: use vmalloc for distribution table) added a
regression, since vfree() is called while holding a spinlock and BH
being disabled.
Fix this by doing the pointers swap in critical section, and freeing
after spinlock release.
Also add __GFP_NOWARN to the kmalloc() try, since we fallback to
vmalloc().
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Acked-by: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
5f0a6e2d50
commit
bb52c7acf8
|
@ -488,7 +488,7 @@ static int get_dist_table(struct Qdisc *sch, const struct nlattr *attr)
|
|||
return -EINVAL;
|
||||
|
||||
s = sizeof(struct disttable) + n * sizeof(s16);
|
||||
d = kmalloc(s, GFP_KERNEL);
|
||||
d = kmalloc(s, GFP_KERNEL | __GFP_NOWARN);
|
||||
if (!d)
|
||||
d = vmalloc(s);
|
||||
if (!d)
|
||||
|
@ -501,9 +501,10 @@ static int get_dist_table(struct Qdisc *sch, const struct nlattr *attr)
|
|||
root_lock = qdisc_root_sleeping_lock(sch);
|
||||
|
||||
spin_lock_bh(root_lock);
|
||||
dist_free(q->delay_dist);
|
||||
q->delay_dist = d;
|
||||
swap(q->delay_dist, d);
|
||||
spin_unlock_bh(root_lock);
|
||||
|
||||
dist_free(d);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue