Messages in this thread | | | From | Linus Torvalds <> | Date | Tue, 24 Nov 2020 12:34:33 -0800 | Subject | Re: kernel BUG at fs/ext4/inode.c:LINE! |
| |
On Tue, Nov 24, 2020 at 12:16 PM Matthew Wilcox <willy@infradead.org> wrote: > > So my s/if/while/ suggestion is wrong and we need to do something to > prevent spurious wakeups. Unless we bury the spurious wakeup logic > inside wait_on_page_writeback() ...
We can certainly make the "if()" in that loop be a "while()'.
That's basically what the old code did - simply by virtue of the wakeup not happening if the writeback bit was set in wake_page_function():
if (test_bit(key->bit_nr, &key->page->flags)) return -1;
of course, the race was still there - because the writeback bit might be clear at that point, but another CPU would reallocate and dirty it, and then autoremove_wake_function() would happen anyway.
But back in the bad old days, the wait_on_page_bit_common() code would then double-check in a loop, so it would catch that case, re-insert itself on the wait queue, and try again. Except for the DROP case, which isn't used by writeback.
Anyway, making that "if()" be a "while()" in wait_on_page_writeback() would basically re-introduce that old behavior. I don't really care, because it was the lock bit that really mattered, the writeback bit is not really all that interesting (except from a "let's fix this bug" angle)
I'm not 100% sure I like the fragility of this writeback thing.
Anyway, I'm certainly happy with either model, whether it be an added while() in wait_on_page_writeback(), or it be the page reference count in end_page_writeback().
Strong opinions?
Linus
| |