mac80211_hwsim: add workqueue to wait for deferred radio deletion on mod unload
When closing multiple wmediumd instances with many radios and try to unload the mac80211_hwsim module, it may happen that the work items live longer than the module. To wait especially for this deletion work items, add a work queue, otherwise flush_scheduled_work would be necessary. Signed-off-by: Benjamin Beichler <benjamin.beichler@uni-rostock.de> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
7a94b8c2ee
commit
b71d856ab5
@ -489,6 +489,7 @@ static const struct ieee80211_iface_combination hwsim_if_comb_p2p_dev[] = {
|
|||||||
|
|
||||||
static spinlock_t hwsim_radio_lock;
|
static spinlock_t hwsim_radio_lock;
|
||||||
static LIST_HEAD(hwsim_radios);
|
static LIST_HEAD(hwsim_radios);
|
||||||
|
static struct workqueue_struct *hwsim_wq;
|
||||||
static int hwsim_radio_idx;
|
static int hwsim_radio_idx;
|
||||||
|
|
||||||
static struct platform_driver mac80211_hwsim_driver = {
|
static struct platform_driver mac80211_hwsim_driver = {
|
||||||
@ -3342,7 +3343,7 @@ static void remove_user_radios(u32 portid)
|
|||||||
if (entry->destroy_on_close && entry->portid == portid) {
|
if (entry->destroy_on_close && entry->portid == portid) {
|
||||||
list_del(&entry->list);
|
list_del(&entry->list);
|
||||||
INIT_WORK(&entry->destroy_work, destroy_radio);
|
INIT_WORK(&entry->destroy_work, destroy_radio);
|
||||||
schedule_work(&entry->destroy_work);
|
queue_work(hwsim_wq, &entry->destroy_work);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spin_unlock_bh(&hwsim_radio_lock);
|
spin_unlock_bh(&hwsim_radio_lock);
|
||||||
@ -3417,7 +3418,7 @@ static void __net_exit hwsim_exit_net(struct net *net)
|
|||||||
|
|
||||||
list_del(&data->list);
|
list_del(&data->list);
|
||||||
INIT_WORK(&data->destroy_work, destroy_radio);
|
INIT_WORK(&data->destroy_work, destroy_radio);
|
||||||
schedule_work(&data->destroy_work);
|
queue_work(hwsim_wq, &data->destroy_work);
|
||||||
}
|
}
|
||||||
spin_unlock_bh(&hwsim_radio_lock);
|
spin_unlock_bh(&hwsim_radio_lock);
|
||||||
}
|
}
|
||||||
@ -3449,6 +3450,10 @@ static int __init init_mac80211_hwsim(void)
|
|||||||
|
|
||||||
spin_lock_init(&hwsim_radio_lock);
|
spin_lock_init(&hwsim_radio_lock);
|
||||||
|
|
||||||
|
hwsim_wq = alloc_workqueue("hwsim_wq",WQ_MEM_RECLAIM,0);
|
||||||
|
if (!hwsim_wq)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
err = register_pernet_device(&hwsim_net_ops);
|
err = register_pernet_device(&hwsim_net_ops);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
@ -3587,8 +3592,11 @@ static void __exit exit_mac80211_hwsim(void)
|
|||||||
hwsim_exit_netlink();
|
hwsim_exit_netlink();
|
||||||
|
|
||||||
mac80211_hwsim_free();
|
mac80211_hwsim_free();
|
||||||
|
flush_workqueue(hwsim_wq);
|
||||||
|
|
||||||
unregister_netdev(hwsim_mon);
|
unregister_netdev(hwsim_mon);
|
||||||
platform_driver_unregister(&mac80211_hwsim_driver);
|
platform_driver_unregister(&mac80211_hwsim_driver);
|
||||||
unregister_pernet_device(&hwsim_net_ops);
|
unregister_pernet_device(&hwsim_net_ops);
|
||||||
|
destroy_workqueue(hwsim_wq);
|
||||||
}
|
}
|
||||||
module_exit(exit_mac80211_hwsim);
|
module_exit(exit_mac80211_hwsim);
|
||||||
|
Loading…
Reference in New Issue
Block a user