[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>
This commit is contained in:
parent
e41a33e6ec
commit
3d54b82fdf
@ -13,13 +13,12 @@ struct qdisc_walker
|
|||||||
|
|
||||||
extern rwlock_t qdisc_tree_lock;
|
extern rwlock_t qdisc_tree_lock;
|
||||||
|
|
||||||
#define QDISC_ALIGN 32
|
#define QDISC_ALIGNTO 32
|
||||||
#define QDISC_ALIGN_CONST (QDISC_ALIGN - 1)
|
#define QDISC_ALIGN(len) (((len) + QDISC_ALIGNTO-1) & ~(QDISC_ALIGNTO-1))
|
||||||
|
|
||||||
static inline void *qdisc_priv(struct Qdisc *q)
|
static inline void *qdisc_priv(struct Qdisc *q)
|
||||||
{
|
{
|
||||||
return (char *)q + ((sizeof(struct Qdisc) + QDISC_ALIGN_CONST)
|
return (char *) q + QDISC_ALIGN(sizeof(struct Qdisc));
|
||||||
& ~QDISC_ALIGN_CONST);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -173,6 +173,7 @@ extern void dev_activate(struct net_device *dev);
|
|||||||
extern void dev_deactivate(struct net_device *dev);
|
extern void dev_deactivate(struct net_device *dev);
|
||||||
extern void qdisc_reset(struct Qdisc *qdisc);
|
extern void qdisc_reset(struct Qdisc *qdisc);
|
||||||
extern void qdisc_destroy(struct Qdisc *qdisc);
|
extern void qdisc_destroy(struct Qdisc *qdisc);
|
||||||
|
extern struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops);
|
||||||
extern struct Qdisc *qdisc_create_dflt(struct net_device *dev,
|
extern struct Qdisc *qdisc_create_dflt(struct net_device *dev,
|
||||||
struct Qdisc_ops *ops);
|
struct Qdisc_ops *ops);
|
||||||
|
|
||||||
|
@ -399,10 +399,8 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp)
|
|||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
struct rtattr *kind = tca[TCA_KIND-1];
|
struct rtattr *kind = tca[TCA_KIND-1];
|
||||||
void *p = NULL;
|
|
||||||
struct Qdisc *sch;
|
struct Qdisc *sch;
|
||||||
struct Qdisc_ops *ops;
|
struct Qdisc_ops *ops;
|
||||||
int size;
|
|
||||||
|
|
||||||
ops = qdisc_lookup_ops(kind);
|
ops = qdisc_lookup_ops(kind);
|
||||||
#ifdef CONFIG_KMOD
|
#ifdef CONFIG_KMOD
|
||||||
@ -437,43 +435,23 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp)
|
|||||||
if (ops == NULL)
|
if (ops == NULL)
|
||||||
goto err_out;
|
goto err_out;
|
||||||
|
|
||||||
/* ensure that the Qdisc and the private data are 32-byte aligned */
|
sch = qdisc_alloc(dev, ops);
|
||||||
size = ((sizeof(*sch) + QDISC_ALIGN_CONST) & ~QDISC_ALIGN_CONST);
|
if (IS_ERR(sch)) {
|
||||||
size += ops->priv_size + QDISC_ALIGN_CONST;
|
err = PTR_ERR(sch);
|
||||||
|
|
||||||
p = kmalloc(size, GFP_KERNEL);
|
|
||||||
err = -ENOBUFS;
|
|
||||||
if (!p)
|
|
||||||
goto err_out2;
|
goto err_out2;
|
||||||
memset(p, 0, size);
|
}
|
||||||
sch = (struct Qdisc *)(((unsigned long)p + QDISC_ALIGN_CONST)
|
|
||||||
& ~QDISC_ALIGN_CONST);
|
|
||||||
sch->padded = (char *)sch - (char *)p;
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&sch->list);
|
if (handle == TC_H_INGRESS) {
|
||||||
skb_queue_head_init(&sch->q);
|
|
||||||
|
|
||||||
if (handle == TC_H_INGRESS)
|
|
||||||
sch->flags |= TCQ_F_INGRESS;
|
sch->flags |= TCQ_F_INGRESS;
|
||||||
|
handle = TC_H_MAKE(TC_H_INGRESS, 0);
|
||||||
sch->ops = ops;
|
} else if (handle == 0) {
|
||||||
sch->enqueue = ops->enqueue;
|
|
||||||
sch->dequeue = ops->dequeue;
|
|
||||||
sch->dev = dev;
|
|
||||||
dev_hold(dev);
|
|
||||||
atomic_set(&sch->refcnt, 1);
|
|
||||||
sch->stats_lock = &dev->queue_lock;
|
|
||||||
if (handle == 0) {
|
|
||||||
handle = qdisc_alloc_handle(dev);
|
handle = qdisc_alloc_handle(dev);
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
if (handle == 0)
|
if (handle == 0)
|
||||||
goto err_out3;
|
goto err_out3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handle == TC_H_INGRESS)
|
sch->handle = handle;
|
||||||
sch->handle =TC_H_MAKE(TC_H_INGRESS, 0);
|
|
||||||
else
|
|
||||||
sch->handle = handle;
|
|
||||||
|
|
||||||
if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS-1])) == 0) {
|
if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS-1])) == 0) {
|
||||||
qdisc_lock_tree(dev);
|
qdisc_lock_tree(dev);
|
||||||
@ -489,12 +467,11 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp)
|
|||||||
}
|
}
|
||||||
err_out3:
|
err_out3:
|
||||||
dev_put(dev);
|
dev_put(dev);
|
||||||
|
kfree((char *) sch - sch->padded);
|
||||||
err_out2:
|
err_out2:
|
||||||
module_put(ops->owner);
|
module_put(ops->owner);
|
||||||
err_out:
|
err_out:
|
||||||
*errp = err;
|
*errp = err;
|
||||||
if (p)
|
|
||||||
kfree(p);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,24 +395,23 @@ static struct Qdisc_ops pfifo_fast_ops = {
|
|||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops)
|
struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops)
|
||||||
{
|
{
|
||||||
void *p;
|
void *p;
|
||||||
struct Qdisc *sch;
|
struct Qdisc *sch;
|
||||||
int size;
|
unsigned int size;
|
||||||
|
int err = -ENOBUFS;
|
||||||
|
|
||||||
/* ensure that the Qdisc and the private data are 32-byte aligned */
|
/* ensure that the Qdisc and the private data are 32-byte aligned */
|
||||||
size = ((sizeof(*sch) + QDISC_ALIGN_CONST) & ~QDISC_ALIGN_CONST);
|
size = QDISC_ALIGN(sizeof(*sch));
|
||||||
size += ops->priv_size + QDISC_ALIGN_CONST;
|
size += ops->priv_size + (QDISC_ALIGNTO - 1);
|
||||||
|
|
||||||
p = kmalloc(size, GFP_KERNEL);
|
p = kmalloc(size, GFP_KERNEL);
|
||||||
if (!p)
|
if (!p)
|
||||||
return NULL;
|
goto errout;
|
||||||
memset(p, 0, size);
|
memset(p, 0, size);
|
||||||
|
sch = (struct Qdisc *) QDISC_ALIGN((unsigned long) p);
|
||||||
sch = (struct Qdisc *)(((unsigned long)p + QDISC_ALIGN_CONST)
|
sch->padded = (char *) sch - (char *) p;
|
||||||
& ~QDISC_ALIGN_CONST);
|
|
||||||
sch->padded = (char *)sch - (char *)p;
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&sch->list);
|
INIT_LIST_HEAD(&sch->list);
|
||||||
skb_queue_head_init(&sch->q);
|
skb_queue_head_init(&sch->q);
|
||||||
@ -423,11 +422,24 @@ struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops)
|
|||||||
dev_hold(dev);
|
dev_hold(dev);
|
||||||
sch->stats_lock = &dev->queue_lock;
|
sch->stats_lock = &dev->queue_lock;
|
||||||
atomic_set(&sch->refcnt, 1);
|
atomic_set(&sch->refcnt, 1);
|
||||||
|
|
||||||
|
return sch;
|
||||||
|
errout:
|
||||||
|
return ERR_PTR(-err);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops)
|
||||||
|
{
|
||||||
|
struct Qdisc *sch;
|
||||||
|
|
||||||
|
sch = qdisc_alloc(dev, ops);
|
||||||
|
if (IS_ERR(sch))
|
||||||
|
goto errout;
|
||||||
|
|
||||||
if (!ops->init || ops->init(sch, NULL) == 0)
|
if (!ops->init || ops->init(sch, NULL) == 0)
|
||||||
return sch;
|
return sch;
|
||||||
|
|
||||||
dev_put(dev);
|
errout:
|
||||||
kfree(p);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -591,6 +603,7 @@ EXPORT_SYMBOL(__netdev_watchdog_up);
|
|||||||
EXPORT_SYMBOL(noop_qdisc);
|
EXPORT_SYMBOL(noop_qdisc);
|
||||||
EXPORT_SYMBOL(noop_qdisc_ops);
|
EXPORT_SYMBOL(noop_qdisc_ops);
|
||||||
EXPORT_SYMBOL(qdisc_create_dflt);
|
EXPORT_SYMBOL(qdisc_create_dflt);
|
||||||
|
EXPORT_SYMBOL(qdisc_alloc);
|
||||||
EXPORT_SYMBOL(qdisc_destroy);
|
EXPORT_SYMBOL(qdisc_destroy);
|
||||||
EXPORT_SYMBOL(qdisc_reset);
|
EXPORT_SYMBOL(qdisc_reset);
|
||||||
EXPORT_SYMBOL(qdisc_restart);
|
EXPORT_SYMBOL(qdisc_restart);
|
||||||
|
Loading…
Reference in New Issue
Block a user