diff options
author | John W. Linville <linville@tuxdriver.com> | 2010-07-27 11:59:19 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-07-27 11:59:19 -0400 |
commit | 800f65bba8d2030b3fef62850e203f9f176625a8 (patch) | |
tree | 6507c4fe7a0826c253b4afb29375ab306a0fd9c8 /net/core/gen_estimator.c | |
parent | 06b3cda0c12986f5bba578b918b188d731c4e191 (diff) | |
parent | b3190df628617c7a4f188a9465aeabe1f5761933 (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.c | 16 |
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 */ |
109 | static struct rb_root est_root = RB_ROOT; | 109 | static struct rb_root est_root = RB_ROOT; |
110 | static DEFINE_SPINLOCK(est_tree_lock); | ||
110 | 111 | ||
111 | static void est_timer(unsigned long arg) | 112 | static 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 | */ |
206 | int gen_new_estimator(struct gnet_stats_basic_packed *bstats, | 206 | int 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 | */ |
266 | void gen_kill_estimator(struct gnet_stats_basic_packed *bstats, | 268 | void 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 | } |
282 | EXPORT_SYMBOL(gen_kill_estimator); | 286 | EXPORT_SYMBOL(gen_kill_estimator); |
283 | 287 | ||
@@ -312,8 +316,14 @@ EXPORT_SYMBOL(gen_replace_estimator); | |||
312 | bool gen_estimator_active(const struct gnet_stats_basic_packed *bstats, | 316 | bool 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 | } |
319 | EXPORT_SYMBOL(gen_estimator_active); | 329 | EXPORT_SYMBOL(gen_estimator_active); |