aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mesh.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-09-10 18:01:50 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-09-15 16:48:20 -0400
commitb7413430d4d2a6168e68231d9f93763047b6d60c (patch)
tree18e85326ddb298500820252f2e510b58319b52d2 /net/mac80211/mesh.c
parent472dbc45dc1966284de72d7de15690c17ed2cf33 (diff)
mac80211: fix work race
When we stop an interface, the work on it may still be pending or running. We do cancel the timer, but we do not currently protect against the work struct. The race is very unlikely to hit -- it'll happen only when the driver is using mac80211's workqueue to run long-running tasks and the sta/mesh works are delayed for quite a bit. This patch fixes it by cancelling the work explicitly. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/mesh.c')
-rw-r--r--net/mac80211/mesh.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 9e47725cc592..a0141f5ff184 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -449,6 +449,15 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
449{ 449{
450 del_timer_sync(&sdata->u.mesh.housekeeping_timer); 450 del_timer_sync(&sdata->u.mesh.housekeeping_timer);
451 /* 451 /*
452 * If the timer fired while we waited for it, it will have
453 * requeued the work. Now the work will be running again
454 * but will not rearm the timer again because it checks
455 * whether the interface is running, which, at this point,
456 * it no longer is.
457 */
458 cancel_work_sync(&sdata->u.mesh.work);
459
460 /*
452 * When we get here, the interface is marked down. 461 * When we get here, the interface is marked down.
453 * Call synchronize_rcu() to wait for the RX path 462 * Call synchronize_rcu() to wait for the RX path
454 * should it be using the interface and enqueuing 463 * should it be using the interface and enqueuing