summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2004-08-15 05:33:16 -0700
committerDavid S. Miller <davem@kernel.bkbits.net>2004-08-15 05:33:16 -0700
commit40964cc0e22a763b262eed365b86f7192c3612fe (patch)
treeece3949b73d9593659f8c90ee84da06f52e37aca
parent1c8641274f7c01434822dd4d79169cdc3170e045 (diff)
[PKT_SCHED]: cacheline-align qdisc data in qdisc_create()
Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@redhat.com>
-rw-r--r--net/sched/sch_api.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 1f9bf9d0834c..19ff1b9e3e01 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -389,7 +389,8 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp)
{
int err;
struct rtattr *kind = tca[TCA_KIND-1];
- struct Qdisc *sch = NULL;
+ void *p = NULL;
+ struct Qdisc *sch;
struct Qdisc_ops *ops;
int size;
@@ -407,12 +408,18 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp)
if (ops == NULL)
goto err_out;
- size = sizeof(*sch) + ops->priv_size;
+ /* 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;
- sch = kmalloc(size, GFP_KERNEL);
+ p = kmalloc(size, GFP_KERNEL);
err = -ENOBUFS;
- if (!sch)
+ if (!p)
goto err_out;
+ memset(p, 0, size);
+ sch = (struct Qdisc *)(((unsigned long)p + QDISC_ALIGN_CONST)
+ & ~QDISC_ALIGN_CONST);
+ sch->padded = (char *)sch - (char *)p;
/* Grrr... Resolve race condition with module unload */
@@ -420,8 +427,6 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp)
if (ops != qdisc_lookup_ops(kind))
goto err_out;
- memset(sch, 0, size);
-
INIT_LIST_HEAD(&sch->list);
skb_queue_head_init(&sch->q);
@@ -470,8 +475,8 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp)
err_out:
*errp = err;
- if (sch)
- kfree(sch);
+ if (p)
+ kfree(p);
return NULL;
}