svn commit: r238936 - in head/sys: fs/fifofs kern sys
Bruce Evans
brde at optusnet.com.au
Tue Jul 31 11:36:55 UTC 2012
On Tue, 31 Jul 2012, David Xu wrote:
> On 2012/7/31 15:22, Giovanni Trematerra wrote:
>> On Tue, Jul 31, 2012 at 7:48 AM, David Xu <davidxu at freebsd.org> wrote:
>>> Log:
>>> I am comparing current pipe code with the one in 8.3-STABLE r236165,
>>> I found 8.3 is a history BSD version using socket to implement FIFO
>>> pipe, it uses per-file seqcount to compare with writer generation
>>> stored in per-pipe object. The concept is after all writers are gone,
>>> the pipe enters next generation, all old readers have not closed the
>>> pipe should get the indication that the pipe is disconnected, result
>>> is they should get EPIPE, SIGPIPE or get POLLHUP in poll().
>>> But newcomer should not know that previous writters were gone, it
>>> should treat it as a fresh session.
Good commit message. Almost worth quoting in 3 followups :-). I wrote
most of the code and forgotten some details, and the above made them
clear.
>>> I am trying to bring back FIFO pipe to history behavior. It is still
>>> unclear that if single EOF flag can represent SBS_CANTSENDMORE and
>>> SBS_CANTRCVMORE which socket-based version is using, but I have run
>>> the poll regression test in tool directory, output is same as the one
>>> on 8.3-STABLE now.
Not very historic. Only FreeBSD-8 (maybe 9?) did that.
>>> I think the output "not ok 18 FIFO state 6b: poll result 0 expected 1.
>>> expected POLLHUP; got 0" might be bogus, because newcomer should not
>>> know that old writers were gone. I got the same behavior on Linux.
6b is intentionally different from Linux. I forget if it is to reduce
races with readers or just to simply the implementation and understanding
it. New readers simply joing old readers with a hangup set for all if
they manage to open the fifo (necessarily using O_NONBLOCK) after the
hangup but before the old readers go away. Since this seems to increase
races, I may remember it backwards
>>> Our implementation always return POLLIN for disconnected pipe even it
>>> should return POLLHUP, but I think it is not wise to remove POLLIN for
>>> compatible reason, this is our history behavior.
This is historical back to FreeBSD-3 (earlier versions didn't have
poll()). I think it is just a bug. POLLHUP was unimplemented for
most file types before FreeBSD-8, and setting POLLIN works around this
for most callers. I tried to get it fixed for at least fifos when I
fixed POLLHUP for some file types. No one uses fifos, so they are
safer to fix than sockets :-).
>> I'm sorry but I'm failing to understand the reason for this change.
>> Can you point me out a test that confirm that the change is needed.
>> The only thing I see is an increase in the memory footprint for the pipes.
>> There was a lot of discussions on this topic on -arch mailing list
Many poll regression tests fail.
>> http://lists.freebsd.org/pipermail/freebsd-arch/2012-January/012131.html
>> http://lists.freebsd.org/pipermail/freebsd-arch/2012-February/012314.html
There are also a lot of old PRs about this for poll() (not for your new
fifo implementation). I think the PRs are mentioned in these threads.
> The old code broke some history semantic of FIFO pipe, you can try the test
> tool /usr/src/tools/regression/poll/pipepoll, try it before and after my
> commit, also compare the result with 8.3-STABLE, without this commit,
> both sub-tests 6c and 6d failed.
>
> I think old code did not mimic original code correctly,
> in 8.3-STABLE code, seqcount is stored in each file, writer generation
> detection is based on each copy of seqcount, but your code stored single
> copy of seqcount in fifoinfo object which is store as vnode data, and
> made the writer generation flag global by setting PIPE_SAMEWGEN in pipe
> object and used this flag to determine if it should return POLLHUP/POLLIN
> or not, this is wrong, for example:
> when there is no writer but have old readers, new incoming reader will
> executes:
> line 174 and 175:
> fip->fi_seqcount = fip->fi_wgen - fip->fi_writers;
> FIFO_WPDWGEN(fip, fpipe);
>
> this causes fi_seqcount to be equal to fi_wgen because fi_writer is zero,
> and FIFO_WPDWGEN() turns on flag PIPE_SAMEWGEN.
> When PIPE_SAMEWGEN is on, pipe_poll() ignores EOF, this breaks old readers,
> it causes old reader to get nothing while it should get POLLHUP from poll().
>
> The new incoming reader should get nothing, so I think sub-tests 6b
> is wrong.
Luckily I have forgotten the details for fifos and never understood them
all for nameless pipes, so you get to fix it :-).
Bruce
More information about the svn-src-head
mailing list