On Sun, Apr 28, 2019 at 8:58 AM Waiman Long <longman@xxxxxxxxxx> wrote: > > + > + /* 2nd pass */ > + list_for_each_entry(waiter, &wlist, list) { This is not safe, as far as I can tell. As this loop walks the list, you do that smp_store_release(&waiter->task, NULL); and that very action means that the "waiter" is now released, and you cannot possibly use it. HOWEVER. "list_for_each_entry()" will load "waiter->next" to go forward in the list. So you absolutely *have* to use "list_for_each_entry_safe()" in this loop, I think. You should treat that "smp_store_release()" as if you deleted the list entry, because you cannot trust it after you've done it, because the sleeper may have gone its own merry ways and released the on-stack 'waiter' allocation. It's the *first* loop that you could play games with, because you hold the lock, and the list is stable during that loop. So the *first* loop could just walk the list, and then do one list splitting operation instead of doing that "list_move_tail()" thing for each entry. But as long as you do "list_move_tail()" in the first loop, you'll obviously have to use list_for_each_entry_safe() there too, since right now you change that list as you walk it. I'm just saying that you *could* optimize that first phase to just walk it and then perhaps split it with list_cut_before() when you find the first entry that isn't going to be woken up. Linus