Page MenuHomeFreeBSD

Fix pipe_poll() after r349546.
ClosedPublic

Authored by markj on Aug 20 2019, 1:24 AM.
Tags
None
Referenced Files
Unknown Object (File)
Dec 22 2023, 11:12 PM
Unknown Object (File)
Dec 20 2023, 10:43 PM
Unknown Object (File)
Sep 11 2023, 4:56 AM
Unknown Object (File)
Aug 31 2023, 6:35 PM
Unknown Object (File)
Aug 28 2023, 2:32 AM
Unknown Object (File)
Aug 28 2023, 2:31 AM
Unknown Object (File)
Aug 28 2023, 2:31 AM
Unknown Object (File)
Aug 27 2023, 2:31 PM
Subscribers

Details

Summary

Recall from r349546 that PIPE_DIRECTW is a semaphore used to provide
mutual exclusion for the pipe_map fields (note that it is unrelated to
the global pipe_map). These fields hold an array of pages mapped in to
the writer until the reader drains them. PIPE_DIRECTW provides mutual
exclusion among multiple writers; prior to r349546, a reader would clear
PIPE_DIRECTW after draining the data, but this was incorrect because the
writer is responsible for doing run-down of the pipe_map fields.

r349546 changes things so that the writer clears PIPE_DIRECTW after the
reader drains data and wakes the writer up. However, this broke
pipe_poll() since it returned POLLIN if PIPE_DIRECTW is set. If
pipe_poll() executes after a reader has drained all data and before the
writer clears PIPE_DIRECTW, it would return POLLIN even though no data
is present.

Fix this by replacing most checks for PIPE_DIRECTW with tests for
pipe_map.cnt != 0. We still test PIPE_DIRECTW in filt_pipewrite() and
pipe_poll(POLLOUT) since a writer may block whenever PIPE_DIRECTW is
set.

Test Plan

I tested using a python script from mav that exposes the race. I will ask
Peter to test.

Diff Detail

Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 25970
Build 24526: arc lint + arc unit