Index: linux-2.6.8.1-ck8/net/sched/sch_api.c =================================================================== --- linux-2.6.8.1-ck8.orig/net/sched/sch_api.c 2004-08-15 14:08:20.000000000 +1000 +++ linux-2.6.8.1-ck8/net/sched/sch_api.c 2004-09-17 01:00:43.419133098 +1000 @@ -389,7 +389,8 @@ qdisc_create(struct net_device *dev, u32 { 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 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 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 err_out: *errp = err; - if (sch) - kfree(sch); + if (p) + kfree(p); return NULL; } Index: linux-2.6.8.1-ck8/net/sched/sch_cbq.c =================================================================== --- linux-2.6.8.1-ck8.orig/net/sched/sch_cbq.c 2004-08-15 14:08:20.000000000 +1000 +++ linux-2.6.8.1-ck8/net/sched/sch_cbq.c 2004-09-17 01:00:41.975366591 +1000 @@ -1746,15 +1746,18 @@ static void cbq_destroy_filters(struct c } } -static void cbq_destroy_class(struct cbq_class *cl) +static void cbq_destroy_class(struct Qdisc *sch, struct cbq_class *cl) { + struct cbq_sched_data *q = qdisc_priv(sch); + cbq_destroy_filters(cl); qdisc_destroy(cl->q); qdisc_put_rtab(cl->R_tab); #ifdef CONFIG_NET_ESTIMATOR qdisc_kill_estimator(&cl->stats); #endif - kfree(cl); + if (cl != &q->link) + kfree(cl); } static void @@ -1777,8 +1780,7 @@ cbq_destroy(struct Qdisc* sch) for (cl = q->classes[h]; cl; cl = next) { next = cl->next; - if (cl != &q->link) - cbq_destroy_class(cl); + cbq_destroy_class(sch, cl); } } @@ -1799,7 +1801,7 @@ static void cbq_put(struct Qdisc *sch, u spin_unlock_bh(&sch->dev->queue_lock); #endif - cbq_destroy_class(cl); + cbq_destroy_class(sch, cl); } } @@ -2035,7 +2037,7 @@ static int cbq_delete(struct Qdisc *sch, sch_tree_unlock(sch); if (--cl->refcnt == 0) - cbq_destroy_class(cl); + cbq_destroy_class(sch, cl); return 0; }