diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2011-12-15 17:09:45 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-12-16 15:40:33 -0500 |
commit | 869aa41044b04964e27822124b88f799e46f01b9 (patch) | |
tree | 740c289a40c1ffc9ec23d9369cdb9389b1edb8ca /net/sched | |
parent | c607b2ed84929e143d9fb5653c4b5d0109147cde (diff) |
sch_gred: prefer GFP_KERNEL allocations
In control path, its better to use GFP_KERNEL allocations where
possible.
Before taking qdisc spinlock, we preallocate memory just in case we'll
need it in gred_change_vq()
This is a followup to commit 3f1e6d3fd37b (sch_gred: should not use
GFP_KERNEL while holding a spinlock)
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched')
-rw-r--r-- | net/sched/sch_gred.c | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c index 1b5e63126cb3..53204de71c39 100644 --- a/net/sched/sch_gred.c +++ b/net/sched/sch_gred.c | |||
@@ -380,18 +380,19 @@ static inline int gred_change_table_def(struct Qdisc *sch, struct nlattr *dps) | |||
380 | 380 | ||
381 | static inline int gred_change_vq(struct Qdisc *sch, int dp, | 381 | static inline int gred_change_vq(struct Qdisc *sch, int dp, |
382 | struct tc_gred_qopt *ctl, int prio, | 382 | struct tc_gred_qopt *ctl, int prio, |
383 | u8 *stab, u32 max_P) | 383 | u8 *stab, u32 max_P, |
384 | struct gred_sched_data **prealloc) | ||
384 | { | 385 | { |
385 | struct gred_sched *table = qdisc_priv(sch); | 386 | struct gred_sched *table = qdisc_priv(sch); |
386 | struct gred_sched_data *q; | 387 | struct gred_sched_data *q = table->tab[dp]; |
387 | 388 | ||
388 | if (table->tab[dp] == NULL) { | 389 | if (!q) { |
389 | table->tab[dp] = kzalloc(sizeof(*q), GFP_ATOMIC); | 390 | table->tab[dp] = q = *prealloc; |
390 | if (table->tab[dp] == NULL) | 391 | *prealloc = NULL; |
392 | if (!q) | ||
391 | return -ENOMEM; | 393 | return -ENOMEM; |
392 | } | 394 | } |
393 | 395 | ||
394 | q = table->tab[dp]; | ||
395 | q->DP = dp; | 396 | q->DP = dp; |
396 | q->prio = prio; | 397 | q->prio = prio; |
397 | q->limit = ctl->limit; | 398 | q->limit = ctl->limit; |
@@ -421,6 +422,7 @@ static int gred_change(struct Qdisc *sch, struct nlattr *opt) | |||
421 | int err, prio = GRED_DEF_PRIO; | 422 | int err, prio = GRED_DEF_PRIO; |
422 | u8 *stab; | 423 | u8 *stab; |
423 | u32 max_P; | 424 | u32 max_P; |
425 | struct gred_sched_data *prealloc; | ||
424 | 426 | ||
425 | if (opt == NULL) | 427 | if (opt == NULL) |
426 | return -EINVAL; | 428 | return -EINVAL; |
@@ -460,9 +462,10 @@ static int gred_change(struct Qdisc *sch, struct nlattr *opt) | |||
460 | prio = ctl->prio; | 462 | prio = ctl->prio; |
461 | } | 463 | } |
462 | 464 | ||
465 | prealloc = kzalloc(sizeof(*prealloc), GFP_KERNEL); | ||
463 | sch_tree_lock(sch); | 466 | sch_tree_lock(sch); |
464 | 467 | ||
465 | err = gred_change_vq(sch, ctl->DP, ctl, prio, stab, max_P); | 468 | err = gred_change_vq(sch, ctl->DP, ctl, prio, stab, max_P, &prealloc); |
466 | if (err < 0) | 469 | if (err < 0) |
467 | goto errout_locked; | 470 | goto errout_locked; |
468 | 471 | ||
@@ -476,6 +479,7 @@ static int gred_change(struct Qdisc *sch, struct nlattr *opt) | |||
476 | 479 | ||
477 | errout_locked: | 480 | errout_locked: |
478 | sch_tree_unlock(sch); | 481 | sch_tree_unlock(sch); |
482 | kfree(prealloc); | ||
479 | errout: | 483 | errout: |
480 | return err; | 484 | return err; |
481 | } | 485 | } |