aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/gen_estimator.c
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2010-07-27 11:59:19 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-07-27 11:59:19 -0400
commit800f65bba8d2030b3fef62850e203f9f176625a8 (patch)
tree6507c4fe7a0826c253b4afb29375ab306a0fd9c8 /net/core/gen_estimator.c
parent06b3cda0c12986f5bba578b918b188d731c4e191 (diff)
parentb3190df628617c7a4f188a9465aeabe1f5761933 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/holtmann/bluetooth-next-2.6
Conflicts: drivers/net/wireless/iwlwifi/iwl-commands.h
Diffstat (limited to 'net/core/gen_estimator.c')
-rw-r--r--net/core/gen_estimator.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c
index cf8e70392fe0..9fbe7f7429b0 100644
--- a/net/core/gen_estimator.c
+++ b/net/core/gen_estimator.c
@@ -107,6 +107,7 @@ static DEFINE_RWLOCK(est_lock);
107 107
108/* Protects against soft lockup during large deletion */ 108/* Protects against soft lockup during large deletion */
109static struct rb_root est_root = RB_ROOT; 109static struct rb_root est_root = RB_ROOT;
110static DEFINE_SPINLOCK(est_tree_lock);
110 111
111static void est_timer(unsigned long arg) 112static void est_timer(unsigned long arg)
112{ 113{
@@ -201,7 +202,6 @@ struct gen_estimator *gen_find_node(const struct gnet_stats_basic_packed *bstats
201 * 202 *
202 * Returns 0 on success or a negative error code. 203 * Returns 0 on success or a negative error code.
203 * 204 *
204 * NOTE: Called under rtnl_mutex
205 */ 205 */
206int gen_new_estimator(struct gnet_stats_basic_packed *bstats, 206int gen_new_estimator(struct gnet_stats_basic_packed *bstats,
207 struct gnet_stats_rate_est *rate_est, 207 struct gnet_stats_rate_est *rate_est,
@@ -232,6 +232,7 @@ int gen_new_estimator(struct gnet_stats_basic_packed *bstats,
232 est->last_packets = bstats->packets; 232 est->last_packets = bstats->packets;
233 est->avpps = rate_est->pps<<10; 233 est->avpps = rate_est->pps<<10;
234 234
235 spin_lock(&est_tree_lock);
235 if (!elist[idx].timer.function) { 236 if (!elist[idx].timer.function) {
236 INIT_LIST_HEAD(&elist[idx].list); 237 INIT_LIST_HEAD(&elist[idx].list);
237 setup_timer(&elist[idx].timer, est_timer, idx); 238 setup_timer(&elist[idx].timer, est_timer, idx);
@@ -242,6 +243,7 @@ int gen_new_estimator(struct gnet_stats_basic_packed *bstats,
242 243
243 list_add_rcu(&est->list, &elist[idx].list); 244 list_add_rcu(&est->list, &elist[idx].list);
244 gen_add_node(est); 245 gen_add_node(est);
246 spin_unlock(&est_tree_lock);
245 247
246 return 0; 248 return 0;
247} 249}
@@ -261,13 +263,14 @@ static void __gen_kill_estimator(struct rcu_head *head)
261 * 263 *
262 * Removes the rate estimator specified by &bstats and &rate_est. 264 * Removes the rate estimator specified by &bstats and &rate_est.
263 * 265 *
264 * NOTE: Called under rtnl_mutex 266 * Note : Caller should respect an RCU grace period before freeing stats_lock
265 */ 267 */
266void gen_kill_estimator(struct gnet_stats_basic_packed *bstats, 268void gen_kill_estimator(struct gnet_stats_basic_packed *bstats,
267 struct gnet_stats_rate_est *rate_est) 269 struct gnet_stats_rate_est *rate_est)
268{ 270{
269 struct gen_estimator *e; 271 struct gen_estimator *e;
270 272
273 spin_lock(&est_tree_lock);
271 while ((e = gen_find_node(bstats, rate_est))) { 274 while ((e = gen_find_node(bstats, rate_est))) {
272 rb_erase(&e->node, &est_root); 275 rb_erase(&e->node, &est_root);
273 276
@@ -278,6 +281,7 @@ void gen_kill_estimator(struct gnet_stats_basic_packed *bstats,
278 list_del_rcu(&e->list); 281 list_del_rcu(&e->list);
279 call_rcu(&e->e_rcu, __gen_kill_estimator); 282 call_rcu(&e->e_rcu, __gen_kill_estimator);
280 } 283 }
284 spin_unlock(&est_tree_lock);
281} 285}
282EXPORT_SYMBOL(gen_kill_estimator); 286EXPORT_SYMBOL(gen_kill_estimator);
283 287
@@ -312,8 +316,14 @@ EXPORT_SYMBOL(gen_replace_estimator);
312bool gen_estimator_active(const struct gnet_stats_basic_packed *bstats, 316bool gen_estimator_active(const struct gnet_stats_basic_packed *bstats,
313 const struct gnet_stats_rate_est *rate_est) 317 const struct gnet_stats_rate_est *rate_est)
314{ 318{
319 bool res;
320
315 ASSERT_RTNL(); 321 ASSERT_RTNL();
316 322
317 return gen_find_node(bstats, rate_est) != NULL; 323 spin_lock(&est_tree_lock);
324 res = gen_find_node(bstats, rate_est) != NULL;
325 spin_unlock(&est_tree_lock);
326
327 return res;
318} 328}
319EXPORT_SYMBOL(gen_estimator_active); 329EXPORT_SYMBOL(gen_estimator_active);