diff options
author | Jarek Poplawski <jarkao2@gmail.com> | 2008-08-11 21:11:06 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-08-11 21:11:06 -0400 |
commit | 1cfa26661a85549063e369e2b40275eeaa7b923c (patch) | |
tree | c2d10164ad6b46cd9ac4123a7b2e7b4e2e6ac745 /net/sched | |
parent | 0a37c10ed460872d41259659f7f589edebdc42b7 (diff) |
pkt_sched: Add BH protection for qdisc_stab_lock.
Since qdisc_stab_lock is used in qdisc_put_stab(), which is called in
BH context from __qdisc_destroy() RCU callback, softirq safe locking
is needed.
Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched')
-rw-r--r-- | net/sched/sch_api.c | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index bbf149dd7818..c25465e5607a 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
@@ -331,7 +331,7 @@ static struct qdisc_size_table *qdisc_get_stab(struct nlattr *opt) | |||
331 | if (!s || tsize != s->tsize || (!tab && tsize > 0)) | 331 | if (!s || tsize != s->tsize || (!tab && tsize > 0)) |
332 | return ERR_PTR(-EINVAL); | 332 | return ERR_PTR(-EINVAL); |
333 | 333 | ||
334 | spin_lock(&qdisc_stab_lock); | 334 | spin_lock_bh(&qdisc_stab_lock); |
335 | 335 | ||
336 | list_for_each_entry(stab, &qdisc_stab_list, list) { | 336 | list_for_each_entry(stab, &qdisc_stab_list, list) { |
337 | if (memcmp(&stab->szopts, s, sizeof(*s))) | 337 | if (memcmp(&stab->szopts, s, sizeof(*s))) |
@@ -339,11 +339,11 @@ static struct qdisc_size_table *qdisc_get_stab(struct nlattr *opt) | |||
339 | if (tsize > 0 && memcmp(stab->data, tab, tsize * sizeof(u16))) | 339 | if (tsize > 0 && memcmp(stab->data, tab, tsize * sizeof(u16))) |
340 | continue; | 340 | continue; |
341 | stab->refcnt++; | 341 | stab->refcnt++; |
342 | spin_unlock(&qdisc_stab_lock); | 342 | spin_unlock_bh(&qdisc_stab_lock); |
343 | return stab; | 343 | return stab; |
344 | } | 344 | } |
345 | 345 | ||
346 | spin_unlock(&qdisc_stab_lock); | 346 | spin_unlock_bh(&qdisc_stab_lock); |
347 | 347 | ||
348 | stab = kmalloc(sizeof(*stab) + tsize * sizeof(u16), GFP_KERNEL); | 348 | stab = kmalloc(sizeof(*stab) + tsize * sizeof(u16), GFP_KERNEL); |
349 | if (!stab) | 349 | if (!stab) |
@@ -354,9 +354,9 @@ static struct qdisc_size_table *qdisc_get_stab(struct nlattr *opt) | |||
354 | if (tsize > 0) | 354 | if (tsize > 0) |
355 | memcpy(stab->data, tab, tsize * sizeof(u16)); | 355 | memcpy(stab->data, tab, tsize * sizeof(u16)); |
356 | 356 | ||
357 | spin_lock(&qdisc_stab_lock); | 357 | spin_lock_bh(&qdisc_stab_lock); |
358 | list_add_tail(&stab->list, &qdisc_stab_list); | 358 | list_add_tail(&stab->list, &qdisc_stab_list); |
359 | spin_unlock(&qdisc_stab_lock); | 359 | spin_unlock_bh(&qdisc_stab_lock); |
360 | 360 | ||
361 | return stab; | 361 | return stab; |
362 | } | 362 | } |
@@ -366,14 +366,14 @@ void qdisc_put_stab(struct qdisc_size_table *tab) | |||
366 | if (!tab) | 366 | if (!tab) |
367 | return; | 367 | return; |
368 | 368 | ||
369 | spin_lock(&qdisc_stab_lock); | 369 | spin_lock_bh(&qdisc_stab_lock); |
370 | 370 | ||
371 | if (--tab->refcnt == 0) { | 371 | if (--tab->refcnt == 0) { |
372 | list_del(&tab->list); | 372 | list_del(&tab->list); |
373 | kfree(tab); | 373 | kfree(tab); |
374 | } | 374 | } |
375 | 375 | ||
376 | spin_unlock(&qdisc_stab_lock); | 376 | spin_unlock_bh(&qdisc_stab_lock); |
377 | } | 377 | } |
378 | EXPORT_SYMBOL(qdisc_put_stab); | 378 | EXPORT_SYMBOL(qdisc_put_stab); |
379 | 379 | ||