From 9303e010522c7feaff6d6b4ce06b39f89c8b3318 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 18 Aug 2008 22:32:10 -0700 Subject: [PATCH] --- yaml --- r: 108847 b: refs/heads/master c: deb3abf15fb92a608fba630da2e8719862731714 h: refs/heads/master i: 108845: e7688ed47135c64d06c3eb373c7f8e2664dc0dc7 108843: 783e1148b8162deec1064cafaf2f8b1d2d5d23f8 108839: c29f4b8e49e0a5586cbbda54006e4fa841ade0e5 108831: fcc2fef67b978ebe965b4d4b21a345630f883e3b v: v3 --- [refs] | 2 +- trunk/net/core/gen_estimator.c | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/[refs] b/[refs] index c7fe6d4b263a..bfee953eda2e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: e5befbd9525d92bb074b70192eb2c69aae65fc60 +refs/heads/master: deb3abf15fb92a608fba630da2e8719862731714 diff --git a/trunk/net/core/gen_estimator.c b/trunk/net/core/gen_estimator.c index a89f32fa94f6..57abe8266be1 100644 --- a/trunk/net/core/gen_estimator.c +++ b/trunk/net/core/gen_estimator.c @@ -99,7 +99,7 @@ struct gen_estimator_head static struct gen_estimator_head elist[EST_MAX_INTERVAL+1]; -/* Protects against NULL dereference and RCU write-side */ +/* Protects against NULL dereference */ static DEFINE_RWLOCK(est_lock); static void est_timer(unsigned long arg) @@ -185,7 +185,6 @@ int gen_new_estimator(struct gnet_stats_basic *bstats, est->last_packets = bstats->packets; est->avpps = rate_est->pps<<10; - write_lock_bh(&est_lock); if (!elist[idx].timer.function) { INIT_LIST_HEAD(&elist[idx].list); setup_timer(&elist[idx].timer, est_timer, idx); @@ -195,7 +194,6 @@ int gen_new_estimator(struct gnet_stats_basic *bstats, mod_timer(&elist[idx].timer, jiffies + ((HZ/4) << idx)); list_add_rcu(&est->list, &elist[idx].list); - write_unlock_bh(&est_lock); return 0; } @@ -214,6 +212,7 @@ static void __gen_kill_estimator(struct rcu_head *head) * Removes the rate estimator specified by &bstats and &rate_est * and deletes the timer. * + * NOTE: Called under rtnl_mutex */ void gen_kill_estimator(struct gnet_stats_basic *bstats, struct gnet_stats_rate_est *rate_est) @@ -227,17 +226,17 @@ void gen_kill_estimator(struct gnet_stats_basic *bstats, if (!elist[idx].timer.function) continue; - write_lock_bh(&est_lock); list_for_each_entry_safe(e, n, &elist[idx].list, list) { if (e->rate_est != rate_est || e->bstats != bstats) continue; + write_lock_bh(&est_lock); e->bstats = NULL; + write_unlock_bh(&est_lock); list_del_rcu(&e->list); call_rcu(&e->e_rcu, __gen_kill_estimator); } - write_unlock_bh(&est_lock); } }