diff options
Diffstat (limited to 'net/sched/sch_generic.c')
-rw-r--r-- | net/sched/sch_generic.c | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 7683b34dc6a9..73e218e646ac 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
@@ -395,24 +395,23 @@ static struct Qdisc_ops pfifo_fast_ops = { | |||
395 | .owner = THIS_MODULE, | 395 | .owner = THIS_MODULE, |
396 | }; | 396 | }; |
397 | 397 | ||
398 | struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops) | 398 | struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops) |
399 | { | 399 | { |
400 | void *p; | 400 | void *p; |
401 | struct Qdisc *sch; | 401 | struct Qdisc *sch; |
402 | int size; | 402 | unsigned int size; |
403 | int err = -ENOBUFS; | ||
403 | 404 | ||
404 | /* ensure that the Qdisc and the private data are 32-byte aligned */ | 405 | /* ensure that the Qdisc and the private data are 32-byte aligned */ |
405 | size = ((sizeof(*sch) + QDISC_ALIGN_CONST) & ~QDISC_ALIGN_CONST); | 406 | size = QDISC_ALIGN(sizeof(*sch)); |
406 | size += ops->priv_size + QDISC_ALIGN_CONST; | 407 | size += ops->priv_size + (QDISC_ALIGNTO - 1); |
407 | 408 | ||
408 | p = kmalloc(size, GFP_KERNEL); | 409 | p = kmalloc(size, GFP_KERNEL); |
409 | if (!p) | 410 | if (!p) |
410 | return NULL; | 411 | goto errout; |
411 | memset(p, 0, size); | 412 | memset(p, 0, size); |
412 | 413 | sch = (struct Qdisc *) QDISC_ALIGN((unsigned long) p); | |
413 | sch = (struct Qdisc *)(((unsigned long)p + QDISC_ALIGN_CONST) | 414 | sch->padded = (char *) sch - (char *) p; |
414 | & ~QDISC_ALIGN_CONST); | ||
415 | sch->padded = (char *)sch - (char *)p; | ||
416 | 415 | ||
417 | INIT_LIST_HEAD(&sch->list); | 416 | INIT_LIST_HEAD(&sch->list); |
418 | skb_queue_head_init(&sch->q); | 417 | skb_queue_head_init(&sch->q); |
@@ -423,11 +422,24 @@ struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops) | |||
423 | dev_hold(dev); | 422 | dev_hold(dev); |
424 | sch->stats_lock = &dev->queue_lock; | 423 | sch->stats_lock = &dev->queue_lock; |
425 | atomic_set(&sch->refcnt, 1); | 424 | atomic_set(&sch->refcnt, 1); |
425 | |||
426 | return sch; | ||
427 | errout: | ||
428 | return ERR_PTR(-err); | ||
429 | } | ||
430 | |||
431 | struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops) | ||
432 | { | ||
433 | struct Qdisc *sch; | ||
434 | |||
435 | sch = qdisc_alloc(dev, ops); | ||
436 | if (IS_ERR(sch)) | ||
437 | goto errout; | ||
438 | |||
426 | if (!ops->init || ops->init(sch, NULL) == 0) | 439 | if (!ops->init || ops->init(sch, NULL) == 0) |
427 | return sch; | 440 | return sch; |
428 | 441 | ||
429 | dev_put(dev); | 442 | errout: |
430 | kfree(p); | ||
431 | return NULL; | 443 | return NULL; |
432 | } | 444 | } |
433 | 445 | ||
@@ -591,6 +603,7 @@ EXPORT_SYMBOL(__netdev_watchdog_up); | |||
591 | EXPORT_SYMBOL(noop_qdisc); | 603 | EXPORT_SYMBOL(noop_qdisc); |
592 | EXPORT_SYMBOL(noop_qdisc_ops); | 604 | EXPORT_SYMBOL(noop_qdisc_ops); |
593 | EXPORT_SYMBOL(qdisc_create_dflt); | 605 | EXPORT_SYMBOL(qdisc_create_dflt); |
606 | EXPORT_SYMBOL(qdisc_alloc); | ||
594 | EXPORT_SYMBOL(qdisc_destroy); | 607 | EXPORT_SYMBOL(qdisc_destroy); |
595 | EXPORT_SYMBOL(qdisc_reset); | 608 | EXPORT_SYMBOL(qdisc_reset); |
596 | EXPORT_SYMBOL(qdisc_restart); | 609 | EXPORT_SYMBOL(qdisc_restart); |