]> Pileus Git - ~andy/linux/blobdiff - net/netfilter/xt_RATEEST.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
[~andy/linux] / net / netfilter / xt_RATEEST.c
index 69c01e10f8afe00ebcdefd1becdec4875fa84a06..de079abd5bc873ae270abdfaa8d9c28af7df11ba 100644 (file)
@@ -60,13 +60,22 @@ struct xt_rateest *xt_rateest_lookup(const char *name)
 }
 EXPORT_SYMBOL_GPL(xt_rateest_lookup);
 
+static void xt_rateest_free_rcu(struct rcu_head *head)
+{
+       kfree(container_of(head, struct xt_rateest, rcu));
+}
+
 void xt_rateest_put(struct xt_rateest *est)
 {
        mutex_lock(&xt_rateest_mutex);
        if (--est->refcnt == 0) {
                hlist_del(&est->list);
                gen_kill_estimator(&est->bstats, &est->rstats);
-               kfree(est);
+               /*
+                * gen_estimator est_timer() might access est->lock or bstats,
+                * wait a RCU grace period before freeing 'est'
+                */
+               call_rcu(&est->rcu, xt_rateest_free_rcu);
        }
        mutex_unlock(&xt_rateest_mutex);
 }
@@ -179,6 +188,7 @@ static int __init xt_rateest_tg_init(void)
 static void __exit xt_rateest_tg_fini(void)
 {
        xt_unregister_target(&xt_rateest_tg_reg);
+       rcu_barrier(); /* Wait for completion of call_rcu()'s (xt_rateest_free_rcu) */
 }