Commit 0b5d404e authored by Jarek Poplawski's avatar Jarek Poplawski Committed by David S. Miller

pkt_sched: Fix lockdep warning on est_tree_lock in gen_estimator

This patch fixes a lockdep warning:

[  516.287584] =========================================================
[  516.288386] [ INFO: possible irq lock inversion dependency detected ]
[  516.288386] 2.6.35b #7
[  516.288386] ---------------------------------------------------------
[  516.288386] swapper/0 just changed the state of lock:
[  516.288386]  (&qdisc_tx_lock){+.-...}, at: [<c12eacda>] est_timer+0x62/0x1b4
[  516.288386] but this lock took another, SOFTIRQ-unsafe lock in the past:
[  516.288386]  (est_tree_lock){+.+...}
[  516.288386] 
[  516.288386] and interrupts could create inverse lock ordering between them.
...

So, est_tree_lock needs BH protection because it's taken by
qdisc_tx_lock, which is used both in BH and process contexts.
(Full warning with this patch at netdev, 02 Sep 2010.)

Fixes commit: ae638c47
("pkt_sched: gen_estimator: add a new lock")
Signed-off-by: default avatarJarek Poplawski <jarkao2@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7bcbf81a
...@@ -232,7 +232,7 @@ int gen_new_estimator(struct gnet_stats_basic_packed *bstats, ...@@ -232,7 +232,7 @@ int gen_new_estimator(struct gnet_stats_basic_packed *bstats,
est->last_packets = bstats->packets; est->last_packets = bstats->packets;
est->avpps = rate_est->pps<<10; est->avpps = rate_est->pps<<10;
spin_lock(&est_tree_lock); spin_lock_bh(&est_tree_lock);
if (!elist[idx].timer.function) { if (!elist[idx].timer.function) {
INIT_LIST_HEAD(&elist[idx].list); INIT_LIST_HEAD(&elist[idx].list);
setup_timer(&elist[idx].timer, est_timer, idx); setup_timer(&elist[idx].timer, est_timer, idx);
...@@ -243,7 +243,7 @@ int gen_new_estimator(struct gnet_stats_basic_packed *bstats, ...@@ -243,7 +243,7 @@ int gen_new_estimator(struct gnet_stats_basic_packed *bstats,
list_add_rcu(&est->list, &elist[idx].list); list_add_rcu(&est->list, &elist[idx].list);
gen_add_node(est); gen_add_node(est);
spin_unlock(&est_tree_lock); spin_unlock_bh(&est_tree_lock);
return 0; return 0;
} }
...@@ -270,7 +270,7 @@ void gen_kill_estimator(struct gnet_stats_basic_packed *bstats, ...@@ -270,7 +270,7 @@ void gen_kill_estimator(struct gnet_stats_basic_packed *bstats,
{ {
struct gen_estimator *e; struct gen_estimator *e;
spin_lock(&est_tree_lock); spin_lock_bh(&est_tree_lock);
while ((e = gen_find_node(bstats, rate_est))) { while ((e = gen_find_node(bstats, rate_est))) {
rb_erase(&e->node, &est_root); rb_erase(&e->node, &est_root);
...@@ -281,7 +281,7 @@ void gen_kill_estimator(struct gnet_stats_basic_packed *bstats, ...@@ -281,7 +281,7 @@ void gen_kill_estimator(struct gnet_stats_basic_packed *bstats,
list_del_rcu(&e->list); list_del_rcu(&e->list);
call_rcu(&e->e_rcu, __gen_kill_estimator); call_rcu(&e->e_rcu, __gen_kill_estimator);
} }
spin_unlock(&est_tree_lock); spin_unlock_bh(&est_tree_lock);
} }
EXPORT_SYMBOL(gen_kill_estimator); EXPORT_SYMBOL(gen_kill_estimator);
...@@ -320,9 +320,9 @@ bool gen_estimator_active(const struct gnet_stats_basic_packed *bstats, ...@@ -320,9 +320,9 @@ bool gen_estimator_active(const struct gnet_stats_basic_packed *bstats,
ASSERT_RTNL(); ASSERT_RTNL();
spin_lock(&est_tree_lock); spin_lock_bh(&est_tree_lock);
res = gen_find_node(bstats, rate_est) != NULL; res = gen_find_node(bstats, rate_est) != NULL;
spin_unlock(&est_tree_lock); spin_unlock_bh(&est_tree_lock);
return res; return res;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment