aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2011-12-15 17:09:45 -0500
committerDavid S. Miller <davem@davemloft.net>2011-12-16 15:40:33 -0500
commit869aa41044b04964e27822124b88f799e46f01b9 (patch)
tree740c289a40c1ffc9ec23d9369cdb9389b1edb8ca /net/sched
parentc607b2ed84929e143d9fb5653c4b5d0109147cde (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.c18
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
381static inline int gred_change_vq(struct Qdisc *sch, int dp, 381static 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
477errout_locked: 480errout_locked:
478 sch_tree_unlock(sch); 481 sch_tree_unlock(sch);
482 kfree(prealloc);
479errout: 483errout:
480 return err; 484 return err;
481} 485}