3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-11-26 10:39:23 +01:00

wiphy: make wiphy work queue reentrancy safe

Now both the do_work and destroy callback can safely insert new
work items without causing problems.
This commit is contained in:
James Prestwood 2021-11-22 12:44:25 -08:00 committed by Denis Kenzior
parent 44faa81a06
commit aed383b037

View File

@ -118,6 +118,7 @@ struct wiphy {
char regdom_country[2]; char regdom_country[2];
/* Work queue for this radio */ /* Work queue for this radio */
struct l_queue *work; struct l_queue *work;
bool work_in_callback;
bool support_scheduled_scan:1; bool support_scheduled_scan:1;
bool support_rekey_offload:1; bool support_rekey_offload:1;
@ -1924,14 +1925,19 @@ static void wiphy_radio_work_next(struct wiphy *wiphy)
work->priority = INT_MIN; work->priority = INT_MIN;
l_debug("Starting work item %u", work->id); l_debug("Starting work item %u", work->id);
wiphy->work_in_callback = true;
done = work->ops->do_work(work); done = work->ops->do_work(work);
wiphy->work_in_callback = false;
if (done) { if (done) {
work->id = 0; work->id = 0;
l_queue_remove(wiphy->work, work); l_queue_remove(wiphy->work, work);
wiphy->work_in_callback = true;
destroy_work(work); destroy_work(work);
wiphy->work_in_callback = false;
wiphy_radio_work_next(wiphy); wiphy_radio_work_next(wiphy);
} }
@ -1961,7 +1967,7 @@ uint32_t wiphy_radio_work_insert(struct wiphy *wiphy,
l_queue_insert(wiphy->work, item, insert_by_priority, NULL); l_queue_insert(wiphy->work, item, insert_by_priority, NULL);
if (l_queue_length(wiphy->work) == 1) if (l_queue_length(wiphy->work) == 1 && !wiphy->work_in_callback)
wiphy_radio_work_next(wiphy); wiphy_radio_work_next(wiphy);
return item->id; return item->id;
@ -1999,7 +2005,9 @@ void wiphy_radio_work_done(struct wiphy *wiphy, uint32_t id)
item->id = 0; item->id = 0;
wiphy->work_in_callback = true;
destroy_work(item); destroy_work(item);
wiphy->work_in_callback = false;
if (next) if (next)
wiphy_radio_work_next(wiphy); wiphy_radio_work_next(wiphy);