On Sun, Sep 30, 2018 at 09:04:11AM +1000, NeilBrown wrote: > On Sat, Sep 29 2018, Al Viro wrote: > > Rationale in e2f23b606b94 (md: avoid oops on unload if some > > process is in poll or select) is very odd. Waitqueue code _does_ > > provide a way to remove all listeners from a waitqueue - it's simply > > wake_up_all(). Once the wakeup callback has been executed (and it > > runs in context of wake_up_all() caller), we don't *care* if md.o > > is still there - all waiters are gone from the queue and the callback > > (pollwake() and friends) doesn't reinsert them. > > I don't think wake_up_all() does remove anything from the queue. > It simply wakes up the various processes that are waiting. > They remain on the queue until they call remove_wait_queue(), which > could be delayed arbitrarily. > If it was delayed until after the module was unloaded and > "md_event_waiters" no longer existed, the unlink attempt would cause an > invalid memory access. init_wait_entry() initialises wq_entry->func to autoremove_wake_function which calls list_del_init() when it's called from __wake_up_common(). If we look at the AIO path, it sets ->func to aio_poll_wake() which also calls list_del_init(). So I think Al is right, but I haven't looked at _every_ code path.