diff options
| -rw-r--r-- | include/net/pkt_sched.h | 7 | ||||
| -rw-r--r-- | include/net/sch_generic.h | 1 | ||||
| -rw-r--r-- | net/sched/sch_api.c | 41 | ||||
| -rw-r--r-- | net/sched/sch_generic.c | 35 |
4 files changed, 37 insertions, 47 deletions
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index 2f494a20d512..6492e7363d84 100644 --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h | |||
| @@ -13,13 +13,12 @@ struct qdisc_walker | |||
| 13 | 13 | ||
| 14 | extern rwlock_t qdisc_tree_lock; | 14 | extern rwlock_t qdisc_tree_lock; |
| 15 | 15 | ||
| 16 | #define QDISC_ALIGN 32 | 16 | #define QDISC_ALIGNTO 32 |
| 17 | #define QDISC_ALIGN_CONST (QDISC_ALIGN - 1) | 17 | #define QDISC_ALIGN(len) (((len) + QDISC_ALIGNTO-1) & ~(QDISC_ALIGNTO-1)) |
| 18 | 18 | ||
| 19 | static inline void *qdisc_priv(struct Qdisc *q) | 19 | static inline void *qdisc_priv(struct Qdisc *q) |
| 20 | { | 20 | { |
| 21 | return (char *)q + ((sizeof(struct Qdisc) + QDISC_ALIGN_CONST) | 21 | return (char *) q + QDISC_ALIGN(sizeof(struct Qdisc)); |
| 22 | & ~QDISC_ALIGN_CONST); | ||
| 23 | } | 22 | } |
| 24 | 23 | ||
| 25 | /* | 24 | /* |
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index c76d34e62ff6..7b6ec9986715 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h | |||
| @@ -173,6 +173,7 @@ extern void dev_activate(struct net_device *dev); | |||
| 173 | extern void dev_deactivate(struct net_device *dev); | 173 | extern void dev_deactivate(struct net_device *dev); |
| 174 | extern void qdisc_reset(struct Qdisc *qdisc); | 174 | extern void qdisc_reset(struct Qdisc *qdisc); |
| 175 | extern void qdisc_destroy(struct Qdisc *qdisc); | 175 | extern void qdisc_destroy(struct Qdisc *qdisc); |
| 176 | extern struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops); | ||
| 176 | extern struct Qdisc *qdisc_create_dflt(struct net_device *dev, | 177 | extern struct Qdisc *qdisc_create_dflt(struct net_device *dev, |
| 177 | struct Qdisc_ops *ops); | 178 | struct Qdisc_ops *ops); |
| 178 | 179 | ||
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 05e6e0a799da..1ef482ba6b36 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
| @@ -399,10 +399,8 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp) | |||
| 399 | { | 399 | { |
| 400 | int err; | 400 | int err; |
| 401 | struct rtattr *kind = tca[TCA_KIND-1]; | 401 | struct rtattr *kind = tca[TCA_KIND-1]; |
| 402 | void *p = NULL; | ||
| 403 | struct Qdisc *sch; | 402 | struct Qdisc *sch; |
| 404 | struct Qdisc_ops *ops; | 403 | struct Qdisc_ops *ops; |
| 405 | int size; | ||
| 406 | 404 | ||
| 407 | ops = qdisc_lookup_ops(kind); | 405 | ops = qdisc_lookup_ops(kind); |
| 408 | #ifdef CONFIG_KMOD | 406 | #ifdef CONFIG_KMOD |
| @@ -437,43 +435,23 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp) | |||
| 437 | if (ops == NULL) | 435 | if (ops == NULL) |
| 438 | goto err_out; | 436 | goto err_out; |
| 439 | 437 | ||
| 440 | /* ensure that the Qdisc and the private data are 32-byte aligned */ | 438 | sch = qdisc_alloc(dev, ops); |
| 441 | size = ((sizeof(*sch) + QDISC_ALIGN_CONST) & ~QDISC_ALIGN_CONST); | 439 | if (IS_ERR(sch)) { |
| 442 | size += ops->priv_size + QDISC_ALIGN_CONST; | 440 | err = PTR_ERR(sch); |
| 443 | |||
| 444 | p = kmalloc(size, GFP_KERNEL); | ||
| 445 | err = -ENOBUFS; | ||
| 446 | if (!p) | ||
| 447 | goto err_out2; | 441 | goto err_out2; |
| 448 | memset(p, 0, size); | 442 | } |
| 449 | sch = (struct Qdisc *)(((unsigned long)p + QDISC_ALIGN_CONST) | ||
| 450 | & ~QDISC_ALIGN_CONST); | ||
| 451 | sch->padded = (char *)sch - (char *)p; | ||
| 452 | |||
| 453 | INIT_LIST_HEAD(&sch->list); | ||
| 454 | skb_queue_head_init(&sch->q); | ||
| 455 | 443 | ||
| 456 | if (handle == TC_H_INGRESS) | 444 | if (handle == TC_H_INGRESS) { |
| 457 | sch->flags |= TCQ_F_INGRESS; | 445 | sch->flags |= TCQ_F_INGRESS; |
| 458 | 446 | handle = TC_H_MAKE(TC_H_INGRESS, 0); | |
| 459 | sch->ops = ops; | 447 | } else if (handle == 0) { |
| 460 | sch->enqueue = ops->enqueue; | ||
| 461 | sch->dequeue = ops->dequeue; | ||
| 462 | sch->dev = dev; | ||
| 463 | dev_hold(dev); | ||
| 464 | atomic_set(&sch->refcnt, 1); | ||
| 465 | sch->stats_lock = &dev->queue_lock; | ||
| 466 | if (handle == 0) { | ||
| 467 | handle = qdisc_alloc_handle(dev); | 448 | handle = qdisc_alloc_handle(dev); |
| 468 | err = -ENOMEM; | 449 | err = -ENOMEM; |
| 469 | if (handle == 0) | 450 | if (handle == 0) |
| 470 | goto err_out3; | 451 | goto err_out3; |
| 471 | } | 452 | } |
| 472 | 453 | ||
| 473 | if (handle == TC_H_INGRESS) | 454 | sch->handle = handle; |
| 474 | sch->handle =TC_H_MAKE(TC_H_INGRESS, 0); | ||
| 475 | else | ||
| 476 | sch->handle = handle; | ||
| 477 | 455 | ||
| 478 | if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS-1])) == 0) { | 456 | if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS-1])) == 0) { |
| 479 | qdisc_lock_tree(dev); | 457 | qdisc_lock_tree(dev); |
| @@ -489,12 +467,11 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp) | |||
| 489 | } | 467 | } |
| 490 | err_out3: | 468 | err_out3: |
| 491 | dev_put(dev); | 469 | dev_put(dev); |
| 470 | kfree((char *) sch - sch->padded); | ||
| 492 | err_out2: | 471 | err_out2: |
| 493 | module_put(ops->owner); | 472 | module_put(ops->owner); |
| 494 | err_out: | 473 | err_out: |
| 495 | *errp = err; | 474 | *errp = err; |
| 496 | if (p) | ||
| 497 | kfree(p); | ||
| 498 | return NULL; | 475 | return NULL; |
| 499 | } | 476 | } |
| 500 | 477 | ||
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); |
