On Thu, 6 Mar 2025 10:30:21 +0100 Oleg Nesterov <oleg@xxxxxxxxxx> > On 03/06, Hillf Danton wrote: > > On Wed, 5 Mar 2025 12:44:34 +0100 Oleg Nesterov <oleg@xxxxxxxxxx> > > > On 03/05, Hillf Danton wrote: > > > > See the loop in ___wait_event(), > > > > > > > > for (;;) { > > > > prepare_to_wait_event(); > > > > > > > > // flip > > > > if (condition) > > > > break; > > > > > > > > schedule(); > > > > } > > > > > > > > After wakeup, waiter will sleep again if condition flips false on the waker > > > > side before waiter checks condition, even if condition is atomic, no? > > > > > > Yes, but in this case pipe_full() == true is correct, this writer can > > > safely sleep. > > > > > No, because no reader is woken up before sleep to make pipe not full. > > Why the reader should be woken before this writer sleeps? Why the reader > should be woken at all in this case (when pipe is full again) ? > "to make pipe not full" failed to prevent you asking questions like this one. > We certainly can't understand each other. > > Could your picture the exact scenario/sequence which can hang? > If you think the scenario in commit 3d252160b818 [1] is correct, check the following one. step-00 pipe->head = 36 pipe->tail = 36 after 3d252160b818 step-01 task-118762 writer pipe->head++; wakes up task-118740 and task-118768 step-02 task-118768 writer makes pipe full; sleeps without waking up any reader as pipe was not empty after step-01 step-03 task-118766 new reader makes pipe empty sleeps step-04 task-118740 reader sleeps as pipe is empty [ Tasks 118740 and 118768 can then indefinitely wait on each other. ] [1] https://web.git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/fs/pipe.c?id=3d252160b818045f3a152b13756f6f37ca34639d