diff options
author | Patrick McHardy <kaber@trash.net> | 2010-06-15 17:31:06 +0200 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2010-06-15 17:31:06 +0200 |
commit | f9181f4ffc71d7b7dd1906c9a11d51d6659220ae (patch) | |
tree | 194f22e8216a1b9ee2c0dd019142202d73a7dc87 /net/core/gen_estimator.c | |
parent | 0902b469bd25065aa0688c3cee6f11744c817e7c (diff) | |
parent | 1ab6c163dee279559e3a62d774af7e4c4c9b4c67 (diff) | |
download | kernel_samsung_espresso10-f9181f4ffc71d7b7dd1906c9a11d51d6659220ae.zip kernel_samsung_espresso10-f9181f4ffc71d7b7dd1906c9a11d51d6659220ae.tar.gz kernel_samsung_espresso10-f9181f4ffc71d7b7dd1906c9a11d51d6659220ae.tar.bz2 |
Merge branch 'master' of /repos/git/net-next-2.6
Conflicts:
include/net/netfilter/xt_rateest.h
net/bridge/br_netfilter.c
net/netfilter/nf_conntrack_core.c
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/core/gen_estimator.c')
-rw-r--r-- | net/core/gen_estimator.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c index cf8e703..9fbe7f7 100644 --- a/net/core/gen_estimator.c +++ b/net/core/gen_estimator.c @@ -107,6 +107,7 @@ static DEFINE_RWLOCK(est_lock); /* Protects against soft lockup during large deletion */ static struct rb_root est_root = RB_ROOT; +static DEFINE_SPINLOCK(est_tree_lock); static void est_timer(unsigned long arg) { @@ -201,7 +202,6 @@ struct gen_estimator *gen_find_node(const struct gnet_stats_basic_packed *bstats * * Returns 0 on success or a negative error code. * - * NOTE: Called under rtnl_mutex */ int gen_new_estimator(struct gnet_stats_basic_packed *bstats, struct gnet_stats_rate_est *rate_est, @@ -232,6 +232,7 @@ int gen_new_estimator(struct gnet_stats_basic_packed *bstats, est->last_packets = bstats->packets; est->avpps = rate_est->pps<<10; + spin_lock(&est_tree_lock); if (!elist[idx].timer.function) { INIT_LIST_HEAD(&elist[idx].list); setup_timer(&elist[idx].timer, est_timer, idx); @@ -242,6 +243,7 @@ int gen_new_estimator(struct gnet_stats_basic_packed *bstats, list_add_rcu(&est->list, &elist[idx].list); gen_add_node(est); + spin_unlock(&est_tree_lock); return 0; } @@ -261,13 +263,14 @@ static void __gen_kill_estimator(struct rcu_head *head) * * Removes the rate estimator specified by &bstats and &rate_est. * - * NOTE: Called under rtnl_mutex + * Note : Caller should respect an RCU grace period before freeing stats_lock */ void gen_kill_estimator(struct gnet_stats_basic_packed *bstats, struct gnet_stats_rate_est *rate_est) { struct gen_estimator *e; + spin_lock(&est_tree_lock); while ((e = gen_find_node(bstats, rate_est))) { rb_erase(&e->node, &est_root); @@ -278,6 +281,7 @@ void gen_kill_estimator(struct gnet_stats_basic_packed *bstats, list_del_rcu(&e->list); call_rcu(&e->e_rcu, __gen_kill_estimator); } + spin_unlock(&est_tree_lock); } EXPORT_SYMBOL(gen_kill_estimator); @@ -312,8 +316,14 @@ EXPORT_SYMBOL(gen_replace_estimator); bool gen_estimator_active(const struct gnet_stats_basic_packed *bstats, const struct gnet_stats_rate_est *rate_est) { + bool res; + ASSERT_RTNL(); - return gen_find_node(bstats, rate_est) != NULL; + spin_lock(&est_tree_lock); + res = gen_find_node(bstats, rate_est) != NULL; + spin_unlock(&est_tree_lock); + + return res; } EXPORT_SYMBOL(gen_estimator_active); |