diff options
| -rw-r--r-- | net/mac80211/iface.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index ae2eb148a028..d6d1f1df9119 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
| @@ -418,20 +418,24 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local) | |||
| 418 | return ret; | 418 | return ret; |
| 419 | } | 419 | } |
| 420 | 420 | ||
| 421 | mutex_lock(&local->iflist_mtx); | ||
| 422 | rcu_assign_pointer(local->monitor_sdata, sdata); | ||
| 423 | mutex_unlock(&local->iflist_mtx); | ||
| 424 | |||
| 421 | mutex_lock(&local->mtx); | 425 | mutex_lock(&local->mtx); |
| 422 | ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef, | 426 | ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef, |
| 423 | IEEE80211_CHANCTX_EXCLUSIVE); | 427 | IEEE80211_CHANCTX_EXCLUSIVE); |
| 424 | mutex_unlock(&local->mtx); | 428 | mutex_unlock(&local->mtx); |
| 425 | if (ret) { | 429 | if (ret) { |
| 430 | mutex_lock(&local->iflist_mtx); | ||
| 431 | rcu_assign_pointer(local->monitor_sdata, NULL); | ||
| 432 | mutex_unlock(&local->iflist_mtx); | ||
| 433 | synchronize_net(); | ||
| 426 | drv_remove_interface(local, sdata); | 434 | drv_remove_interface(local, sdata); |
| 427 | kfree(sdata); | 435 | kfree(sdata); |
| 428 | return ret; | 436 | return ret; |
| 429 | } | 437 | } |
| 430 | 438 | ||
| 431 | mutex_lock(&local->iflist_mtx); | ||
| 432 | rcu_assign_pointer(local->monitor_sdata, sdata); | ||
| 433 | mutex_unlock(&local->iflist_mtx); | ||
| 434 | |||
| 435 | return 0; | 439 | return 0; |
| 436 | } | 440 | } |
| 437 | 441 | ||
