aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/sch_generic.c
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2010-04-20 16:02:01 +0200
committerPatrick McHardy <kaber@trash.net>2010-04-20 16:02:01 +0200
commit62910554656cdcd6b6f84a5154c4155aae4ca231 (patch)
treedcf14004f6fd2ef7154362ff948bfeba0f3ea92d /net/sched/sch_generic.c
parent22265a5c3c103cf8c50be62e6c90d045eb649e6d (diff)
parentab9304717f7624c41927f442e6b6d418b2d8b3e4 (diff)
downloadkernel_samsung_aries-62910554656cdcd6b6f84a5154c4155aae4ca231.zip
kernel_samsung_aries-62910554656cdcd6b6f84a5154c4155aae4ca231.tar.gz
kernel_samsung_aries-62910554656cdcd6b6f84a5154c4155aae4ca231.tar.bz2
Merge branch 'master' of /repos/git/net-next-2.6
Conflicts: Documentation/feature-removal-schedule.txt net/ipv6/netfilter/ip6t_REJECT.c net/netfilter/xt_limit.c Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/sched/sch_generic.c')
-rw-r--r--net/sched/sch_generic.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 5173c1e..aeddabf 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -24,6 +24,7 @@
#include <linux/init.h>
#include <linux/rcupdate.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <net/pkt_sched.h>
/* Main transmission queue. */
@@ -528,7 +529,7 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
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 64-byte aligned */
size = QDISC_ALIGN(sizeof(*sch));
size += ops->priv_size + (QDISC_ALIGNTO - 1);
@@ -590,6 +591,13 @@ void qdisc_reset(struct Qdisc *qdisc)
}
EXPORT_SYMBOL(qdisc_reset);
+static void qdisc_rcu_free(struct rcu_head *head)
+{
+ struct Qdisc *qdisc = container_of(head, struct Qdisc, rcu_head);
+
+ kfree((char *) qdisc - qdisc->padded);
+}
+
void qdisc_destroy(struct Qdisc *qdisc)
{
const struct Qdisc_ops *ops = qdisc->ops;
@@ -613,7 +621,11 @@ void qdisc_destroy(struct Qdisc *qdisc)
dev_put(qdisc_dev(qdisc));
kfree_skb(qdisc->gso_skb);
- kfree((char *) qdisc - qdisc->padded);
+ /*
+ * gen_estimator est_timer() might access qdisc->q.lock,
+ * wait a RCU grace period before freeing qdisc.
+ */
+ call_rcu(&qdisc->rcu_head, qdisc_rcu_free);
}
EXPORT_SYMBOL(qdisc_destroy);