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)
Wed, Jan 29, 5:43 AM
Unknown Object (File)
Sat, Jan 11, 3:40 PM
Unknown Object (File)
Nov 27 2024, 8:59 PM
Unknown Object (File)
Nov 24 2024, 4:13 PM
Unknown Object (File)
Nov 19 2024, 2:48 PM
Unknown Object (File)
Nov 16 2024, 2:02 PM
Unknown Object (File)
Nov 11 2024, 4:32 PM
Unknown Object (File)
Nov 11 2024, 12:54 AM
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

Repository
rS FreeBSD src repository - subversion
Lint
Lint Not Applicable
Unit
Tests Not Applicable