Now that I look at this more ... > +static void cfg80211_wiphy_work(struct work_struct *work) > +{ > + struct cfg80211_registered_device *rdev; > + > + rdev = container_of(work, struct cfg80211_registered_device, wiphy_work); > + > + spin_lock_irq(&rdev->wiphy_work_lock); > + while (!list_empty(&rdev->wiphy_work_list)) { > + struct wiphy_work *wk; > + > + wk = list_first_entry(&rdev->wiphy_work_list, > + struct wiphy_work, entry); > + list_del_init(&wk->entry); > + spin_unlock_irq(&rdev->wiphy_work_lock); > + > + mutex_lock(&rdev->wiphy.mtx); If I just change the locking here to take the wiphy.mtx before looking at the list, which basically doesn't matter, then I don't even need workqueue_pause() and all, nor do I even need a separate workqueue, just schedule_work() will be good enough ... Just needs a _bit_ more work when cancelling and here we should reschedule the work if the list isn't empty after the first round, but overall that ends up far simpler. So I think I'll drop the workqueue pause/resume the next time around, FWIW. johannes