Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3d54b82f authored by Thomas Graf's avatar Thomas Graf Committed by David S. Miller
Browse files

[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: default avatarThomas Graf <tgraf@suug.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e41a33e6
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -13,13 +13,12 @@ struct qdisc_walker

extern rwlock_t qdisc_tree_lock;

#define	QDISC_ALIGN		32
#define	QDISC_ALIGN_CONST	(QDISC_ALIGN - 1)
#define QDISC_ALIGNTO		32
#define QDISC_ALIGN(len)	(((len) + QDISC_ALIGNTO-1) & ~(QDISC_ALIGNTO-1))

static inline void *qdisc_priv(struct Qdisc *q)
{
	return (char *)q + ((sizeof(struct Qdisc) + QDISC_ALIGN_CONST)
			      & ~QDISC_ALIGN_CONST);
	return (char *) q + QDISC_ALIGN(sizeof(struct Qdisc));
}

/* 
+1 −0
Original line number Diff line number Diff line
@@ -173,6 +173,7 @@ extern void dev_activate(struct net_device *dev);
extern void dev_deactivate(struct net_device *dev);
extern void qdisc_reset(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,
				       struct Qdisc_ops *ops);

+9 −32
Original line number Diff line number Diff line
@@ -399,10 +399,8 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp)
{
	int err;
	struct rtattr *kind = tca[TCA_KIND-1];
	void *p = NULL;
	struct Qdisc *sch;
	struct Qdisc_ops *ops;
	int size;

	ops = qdisc_lookup_ops(kind);
#ifdef CONFIG_KMOD
@@ -437,42 +435,22 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp)
	if (ops == NULL)
		goto err_out;

	/* ensure that the Qdisc and the private data are 32-byte aligned */
	size = ((sizeof(*sch) + QDISC_ALIGN_CONST) & ~QDISC_ALIGN_CONST);
	size += ops->priv_size + QDISC_ALIGN_CONST;

	p = kmalloc(size, GFP_KERNEL);
	err = -ENOBUFS;
	if (!p)
	sch = qdisc_alloc(dev, ops);
	if (IS_ERR(sch)) {
		err = PTR_ERR(sch);
		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);
	skb_queue_head_init(&sch->q);
	}

	if (handle == TC_H_INGRESS)
	if (handle == TC_H_INGRESS) {
		sch->flags |= TCQ_F_INGRESS;

	sch->ops = ops;
	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 = TC_H_MAKE(TC_H_INGRESS, 0);
	} else if (handle == 0) {
		handle = qdisc_alloc_handle(dev);
		err = -ENOMEM;
		if (handle == 0)
			goto err_out3;
	}

	if (handle == TC_H_INGRESS)
                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) {
@@ -489,12 +467,11 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp)
	}
err_out3:
	dev_put(dev);
	kfree((char *) sch - sch->padded);
err_out2:
	module_put(ops->owner);
err_out:
	*errp = err;
	if (p)
		kfree(p);
	return NULL;
}

+24 −11
Original line number Diff line number Diff line
@@ -395,23 +395,22 @@ static struct Qdisc_ops pfifo_fast_ops = {
	.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;
	struct Qdisc *sch;
	int size;
	unsigned int size;
	int err = -ENOBUFS;

	/* ensure that the Qdisc and the private data are 32-byte aligned */
	size = ((sizeof(*sch) + QDISC_ALIGN_CONST) & ~QDISC_ALIGN_CONST);
	size += ops->priv_size + QDISC_ALIGN_CONST;
	size = QDISC_ALIGN(sizeof(*sch));
	size += ops->priv_size + (QDISC_ALIGNTO - 1);

	p = kmalloc(size, GFP_KERNEL);
	if (!p)
		return NULL;
		goto errout;
	memset(p, 0, size);

	sch = (struct Qdisc *)(((unsigned long)p + QDISC_ALIGN_CONST) 
			       & ~QDISC_ALIGN_CONST);
	sch = (struct Qdisc *) QDISC_ALIGN((unsigned long) p);
	sch->padded = (char *) sch - (char *) p;

	INIT_LIST_HEAD(&sch->list);
@@ -423,11 +422,24 @@ struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops)
	dev_hold(dev);
	sch->stats_lock = &dev->queue_lock;
	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)
		return sch;

	dev_put(dev);
	kfree(p);
errout:
	return NULL;
}

@@ -591,6 +603,7 @@ EXPORT_SYMBOL(__netdev_watchdog_up);
EXPORT_SYMBOL(noop_qdisc);
EXPORT_SYMBOL(noop_qdisc_ops);
EXPORT_SYMBOL(qdisc_create_dflt);
EXPORT_SYMBOL(qdisc_alloc);
EXPORT_SYMBOL(qdisc_destroy);
EXPORT_SYMBOL(qdisc_reset);
EXPORT_SYMBOL(qdisc_restart);