diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 08dd521a51a5..7afcea3447c1 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -40,9 +40,8 @@ struct ieee802154_local { int open_count; /* As in mac80211 slaves list is modified: - * 1) under the RTNL - * 2) protected by slaves_mtx; - * 3) in an RCU manner + * 1) under the RTNL; + * 2) protected by iflist_mtx. * * So atomic readers can use any of this protection methods. */ @@ -101,6 +100,7 @@ enum { enum ieee802154_sdata_state_bits { SDATA_STATE_RUNNING, + SDATA_STATE_REMOVED, }; /* Slave interface definition. diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index c0e2da5072be..700c80e94bb2 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -669,7 +669,7 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name, goto err; mutex_lock(&local->iflist_mtx); - list_add_tail_rcu(&sdata->list, &local->interfaces); + list_add_tail(&sdata->list, &local->interfaces); mutex_unlock(&local->iflist_mtx); return ndev; @@ -683,11 +683,13 @@ void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata) { ASSERT_RTNL(); + if (test_and_set_bit(SDATA_STATE_REMOVED, &sdata->state)) + return; + mutex_lock(&sdata->local->iflist_mtx); - list_del_rcu(&sdata->list); + list_del(&sdata->list); mutex_unlock(&sdata->local->iflist_mtx); - synchronize_rcu(); unregister_netdevice(sdata->dev); } @@ -697,6 +699,8 @@ void ieee802154_remove_interfaces(struct ieee802154_local *local) mutex_lock(&local->iflist_mtx); list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) { + if (test_and_set_bit(SDATA_STATE_REMOVED, &sdata->state)) + continue; list_del(&sdata->list); unregister_netdevice(sdata->dev);