diff options
author | Thomas Graf <tgraf@suug.ch> | 2005-07-05 17:15:09 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2005-07-05 17:15:09 -0400 |
commit | 3d54b82fdf0ca79608f61448fb8ab92676487645 (patch) | |
tree | 441e7a997eca58d2d7d2d06c387667ba82937d58 | |
parent | e41a33e6ec20a0a6ac762629149e36cab5d4213f (diff) |
[PKT_SCHED]: Cleanup qdisc creation and alignment macros
Adds qdisc_alloc() to share code between qdisc_create()
and qdisc_create_dflt(). Hides the qdisc alignment behind
macros and makes use of them.
Signed-off-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
-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); |