diff options
| author | Anton Altaparmakov <aia21@cantab.net> | 2005-07-13 18:09:23 -0400 |
|---|---|---|
| committer | Anton Altaparmakov <aia21@cantab.net> | 2005-07-13 18:09:23 -0400 |
| commit | c514720716c7b109ff980f8b3cb93f9af872c91c (patch) | |
| tree | 490a9578995705de69712893a190b67651bddc56 /net/sched/sch_api.c | |
| parent | 07929dcb963786512c760dd3ecd148d89295e7e5 (diff) | |
| parent | 1e279dd855d15b72364b4103f872d67d8592647e (diff) | |
Automatic merge with /usr/src/ntfs-2.6.git.
Diffstat (limited to 'net/sched/sch_api.c')
| -rw-r--r-- | net/sched/sch_api.c | 63 |
1 files changed, 26 insertions, 37 deletions
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 05e6e0a799da..b9a069af4a02 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,64 +435,55 @@ 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) { |
| 457 | #ifdef CONFIG_NET_ESTIMATOR | ||
| 458 | if (tca[TCA_RATE-1]) { | ||
| 459 | err = gen_new_estimator(&sch->bstats, &sch->rate_est, | ||
| 460 | sch->stats_lock, | ||
| 461 | tca[TCA_RATE-1]); | ||
| 462 | if (err) { | ||
| 463 | /* | ||
| 464 | * Any broken qdiscs that would require | ||
| 465 | * a ops->reset() here? The qdisc was never | ||
| 466 | * in action so it shouldn't be necessary. | ||
| 467 | */ | ||
| 468 | if (ops->destroy) | ||
| 469 | ops->destroy(sch); | ||
| 470 | goto err_out3; | ||
| 471 | } | ||
| 472 | } | ||
| 473 | #endif | ||
| 479 | qdisc_lock_tree(dev); | 474 | qdisc_lock_tree(dev); |
| 480 | list_add_tail(&sch->list, &dev->qdisc_list); | 475 | list_add_tail(&sch->list, &dev->qdisc_list); |
| 481 | qdisc_unlock_tree(dev); | 476 | qdisc_unlock_tree(dev); |
| 482 | 477 | ||
| 483 | #ifdef CONFIG_NET_ESTIMATOR | ||
| 484 | if (tca[TCA_RATE-1]) | ||
| 485 | gen_new_estimator(&sch->bstats, &sch->rate_est, | ||
| 486 | sch->stats_lock, tca[TCA_RATE-1]); | ||
| 487 | #endif | ||
| 488 | return sch; | 478 | return sch; |
| 489 | } | 479 | } |
| 490 | err_out3: | 480 | err_out3: |
| 491 | dev_put(dev); | 481 | dev_put(dev); |
| 482 | kfree((char *) sch - sch->padded); | ||
| 492 | err_out2: | 483 | err_out2: |
| 493 | module_put(ops->owner); | 484 | module_put(ops->owner); |
| 494 | err_out: | 485 | err_out: |
| 495 | *errp = err; | 486 | *errp = err; |
| 496 | if (p) | ||
| 497 | kfree(p); | ||
| 498 | return NULL; | 487 | return NULL; |
| 499 | } | 488 | } |
| 500 | 489 | ||
