Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Thomas Graf and committed by
David S. Miller
3d54b82f e41a33e6

+37 -47
+3 -4
include/net/pkt_sched.h
··· 13 13 14 14 extern rwlock_t qdisc_tree_lock; 15 15 16 - #define QDISC_ALIGN 32 17 - #define QDISC_ALIGN_CONST (QDISC_ALIGN - 1) 16 + #define QDISC_ALIGNTO 32 17 + #define QDISC_ALIGN(len) (((len) + QDISC_ALIGNTO-1) & ~(QDISC_ALIGNTO-1)) 18 18 19 19 static inline void *qdisc_priv(struct Qdisc *q) 20 20 { 21 - return (char *)q + ((sizeof(struct Qdisc) + QDISC_ALIGN_CONST) 22 - & ~QDISC_ALIGN_CONST); 21 + return (char *) q + QDISC_ALIGN(sizeof(struct Qdisc)); 23 22 } 24 23 25 24 /*
+1
include/net/sch_generic.h
··· 173 173 extern void dev_deactivate(struct net_device *dev); 174 174 extern void qdisc_reset(struct Qdisc *qdisc); 175 175 extern void qdisc_destroy(struct Qdisc *qdisc); 176 + extern struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops); 176 177 extern struct Qdisc *qdisc_create_dflt(struct net_device *dev, 177 178 struct Qdisc_ops *ops); 178 179
+9 -32
net/sched/sch_api.c
··· 399 399 { 400 400 int err; 401 401 struct rtattr *kind = tca[TCA_KIND-1]; 402 - void *p = NULL; 403 402 struct Qdisc *sch; 404 403 struct Qdisc_ops *ops; 405 - int size; 406 404 407 405 ops = qdisc_lookup_ops(kind); 408 406 #ifdef CONFIG_KMOD ··· 435 437 if (ops == NULL) 436 438 goto err_out; 437 439 438 - /* ensure that the Qdisc and the private data are 32-byte aligned */ 439 - size = ((sizeof(*sch) + QDISC_ALIGN_CONST) & ~QDISC_ALIGN_CONST); 440 - size += ops->priv_size + QDISC_ALIGN_CONST; 441 - 442 - p = kmalloc(size, GFP_KERNEL); 443 - err = -ENOBUFS; 444 - if (!p) 440 + sch = qdisc_alloc(dev, ops); 441 + if (IS_ERR(sch)) { 442 + err = PTR_ERR(sch); 445 443 goto err_out2; 446 - memset(p, 0, size); 447 - sch = (struct Qdisc *)(((unsigned long)p + QDISC_ALIGN_CONST) 448 - & ~QDISC_ALIGN_CONST); 449 - sch->padded = (char *)sch - (char *)p; 444 + } 450 445 451 - INIT_LIST_HEAD(&sch->list); 452 - skb_queue_head_init(&sch->q); 453 - 454 - if (handle == TC_H_INGRESS) 446 + if (handle == TC_H_INGRESS) { 455 447 sch->flags |= TCQ_F_INGRESS; 456 - 457 - sch->ops = ops; 458 - sch->enqueue = ops->enqueue; 459 - sch->dequeue = ops->dequeue; 460 - sch->dev = dev; 461 - dev_hold(dev); 462 - atomic_set(&sch->refcnt, 1); 463 - sch->stats_lock = &dev->queue_lock; 464 - if (handle == 0) { 448 + handle = TC_H_MAKE(TC_H_INGRESS, 0); 449 + } else if (handle == 0) { 465 450 handle = qdisc_alloc_handle(dev); 466 451 err = -ENOMEM; 467 452 if (handle == 0) 468 453 goto err_out3; 469 454 } 470 455 471 - if (handle == TC_H_INGRESS) 472 - sch->handle =TC_H_MAKE(TC_H_INGRESS, 0); 473 - else 474 - sch->handle = handle; 456 + sch->handle = handle; 475 457 476 458 if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS-1])) == 0) { 477 459 qdisc_lock_tree(dev); ··· 467 489 } 468 490 err_out3: 469 491 dev_put(dev); 492 + kfree((char *) sch - sch->padded); 470 493 err_out2: 471 494 module_put(ops->owner); 472 495 err_out: 473 496 *errp = err; 474 - if (p) 475 - kfree(p); 476 497 return NULL; 477 498 } 478 499
+24 -11
net/sched/sch_generic.c
··· 395 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 400 void *p; 401 401 struct Qdisc *sch; 402 - int size; 402 + unsigned int size; 403 + int err = -ENOBUFS; 403 404 404 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 += ops->priv_size + QDISC_ALIGN_CONST; 406 + size = QDISC_ALIGN(sizeof(*sch)); 407 + size += ops->priv_size + (QDISC_ALIGNTO - 1); 407 408 408 409 p = kmalloc(size, GFP_KERNEL); 409 410 if (!p) 410 - return NULL; 411 + goto errout; 411 412 memset(p, 0, size); 412 - 413 - sch = (struct Qdisc *)(((unsigned long)p + QDISC_ALIGN_CONST) 414 - & ~QDISC_ALIGN_CONST); 415 - sch->padded = (char *)sch - (char *)p; 413 + sch = (struct Qdisc *) QDISC_ALIGN((unsigned long) p); 414 + sch->padded = (char *) sch - (char *) p; 416 415 417 416 INIT_LIST_HEAD(&sch->list); 418 417 skb_queue_head_init(&sch->q); ··· 422 423 dev_hold(dev); 423 424 sch->stats_lock = &dev->queue_lock; 424 425 atomic_set(&sch->refcnt, 1); 426 + 427 + return sch; 428 + errout: 429 + return ERR_PTR(-err); 430 + } 431 + 432 + struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops) 433 + { 434 + struct Qdisc *sch; 435 + 436 + sch = qdisc_alloc(dev, ops); 437 + if (IS_ERR(sch)) 438 + goto errout; 439 + 425 440 if (!ops->init || ops->init(sch, NULL) == 0) 426 441 return sch; 427 442 428 - dev_put(dev); 429 - kfree(p); 443 + errout: 430 444 return NULL; 431 445 } 432 446 ··· 603 591 EXPORT_SYMBOL(noop_qdisc); 604 592 EXPORT_SYMBOL(noop_qdisc_ops); 605 593 EXPORT_SYMBOL(qdisc_create_dflt); 594 + EXPORT_SYMBOL(qdisc_alloc); 606 595 EXPORT_SYMBOL(qdisc_destroy); 607 596 EXPORT_SYMBOL(qdisc_reset); 608 597 EXPORT_SYMBOL(qdisc_restart);