Hello Hiilf,
On 3/7/2025 11:38 AM, Hillf Danton wrote:
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
Reader seeing a pipe full should wake up a writer allowing 118768 to
wakeup again and fill the pipe. Am I missing something?
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
--
Thanks and Regards,
Prateek