summaryrefslogtreecommitdiffstats
path: root/net/sched/act_api.c
diff options
context:
space:
mode:
authorTakashi Iwai2010-08-18 15:17:30 +0200
committerTakashi Iwai2010-08-18 15:17:30 +0200
commit6ab561c8aab2e4af535f09adbc6253f958536848 (patch)
tree37846adb4ea106485720d113e252d71d615c23ed /net/sched/act_api.c
parentALSA: usb: USB3 SuperSpeed sound support (diff)
parentALSA: ISA: Remove snd-sgalaxy (diff)
downloadkernel-qcow2-linux-6ab561c8aab2e4af535f09adbc6253f958536848.tar.gz
kernel-qcow2-linux-6ab561c8aab2e4af535f09adbc6253f958536848.tar.xz
kernel-qcow2-linux-6ab561c8aab2e4af535f09adbc6253f958536848.zip
Merge branch 'topic/isa' into topic/misc
Diffstat (limited to 'net/sched/act_api.c')
-rw-r--r--net/sched/act_api.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 972378f47f3c..23b25f89e7e0 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -26,6 +26,11 @@
#include <net/act_api.h>
#include <net/netlink.h>
+static void tcf_common_free_rcu(struct rcu_head *head)
+{
+ kfree(container_of(head, struct tcf_common, tcfc_rcu));
+}
+
void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo)
{
unsigned int h = tcf_hash(p->tcfc_index, hinfo->hmask);
@@ -38,7 +43,11 @@ void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo)
write_unlock_bh(hinfo->lock);
gen_kill_estimator(&p->tcfc_bstats,
&p->tcfc_rate_est);
- kfree(p);
+ /*
+ * gen_estimator est_timer() might access p->tcfc_lock
+ * or bstats, wait a RCU grace period before freeing p
+ */
+ call_rcu(&p->tcfc_rcu, tcf_common_free_rcu);
return;
}
}