@@ -29,7 +29,9 @@ struct ieee802154_local {
/* ieee802154 phy */
struct wpan_phy *phy;
+ /* Open/close counter and lock */
int open_count;
+ struct mutex device_lock;
/* As in mac80211 slaves list is modified:
* 1) under the RTNL
@@ -315,11 +315,15 @@ static int mac802154_slave_close(struct net_device *dev)
ASSERT_RTNL();
+ mutex_lock(&local->device_lock);
+
netif_stop_queue(dev);
local->open_count--;
clear_bit(SDATA_STATE_RUNNING, &sdata->state);
+ mutex_unlock(&local->device_lock);
+
if (!local->open_count)
ieee802154_stop_device(local);
@@ -90,6 +90,7 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops)
INIT_LIST_HEAD(&local->interfaces);
mutex_init(&local->iflist_mtx);
+ mutex_init(&local->device_lock);
tasklet_setup(&local->tasklet, ieee802154_tasklet_handler);
@@ -143,14 +143,14 @@ int ieee802154_mlme_tx(struct ieee802154_local *local,
{
int ret;
- /* Avoid possible calls to ->ndo_stop() when we asynchronously perform
- * MLME transmissions.
+ /* Serialize possible calls to ->ndo_stop() when we asynchronously
+ * perform MLME transmissions.
*/
- rtnl_lock();
+ mutex_lock(&local->device_lock);
/* Ensure the device was not stopped, otherwise error out */
if (!local->open_count) {
- rtnl_unlock();
+ mutex_unlock(&local->device_lock);
return -ENETDOWN;
}
@@ -158,14 +158,14 @@ int ieee802154_mlme_tx(struct ieee802154_local *local,
* net interface expects this cannot happen.
*/
if (WARN_ON_ONCE(!netif_running(sdata->dev))) {
- rtnl_unlock();
+ mutex_unlock(&local->device_lock);
return -ENETDOWN;
}
ieee802154_tx(local, skb);
ret = ieee802154_sync_queue(local);
- rtnl_unlock();
+ mutex_unlock(&local->device_lock);
return ret;
}
The purpose of this device lock is to prevent the removal of the device while an asynchronous MLME operation happens. The RTNL works well for that but in a later series having the RTNL taken here will be problematic and will cause lockdep to warn us about a circular dependency. We don't really need the RTNL here, just a serialization over this operation. Replace the RTNL calls with this new lock. Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> --- net/mac802154/ieee802154_i.h | 2 ++ net/mac802154/iface.c | 4 ++++ net/mac802154/main.c | 1 + net/mac802154/tx.c | 12 ++++++------ 4 files changed, 13 insertions(+), 6 deletions(-)