NetBSD Problem Report #57369

From www@netbsd.org  Wed Apr 19 11:04:09 2023
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))
	(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
	by mollari.NetBSD.org (Postfix) with ESMTPS id 30AC81A9239
	for <gnats-bugs@gnats.NetBSD.org>; Wed, 19 Apr 2023 11:04:09 +0000 (UTC)
Message-Id: <20230419110407.9A9191A923A@mollari.NetBSD.org>
Date: Wed, 19 Apr 2023 11:04:07 +0000 (UTC)
From: yamt9999@gmail.com
Reply-To: yamt9999@gmail.com
To: gnats-bugs@NetBSD.org
Subject: unexpected poll timeout on pipe
X-Send-Pr-Version: www-1.0

>Number:         57369
>Category:       kern
>Synopsis:       unexpected poll timeout on pipe
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Apr 19 11:05:02 +0000 2023
>Last-Modified:  Thu Apr 20 06:50:01 +0000 2023
>Originator:     YAMAMOTO Takashi
>Release:        NetBSD 9.3
>Organization:
>Environment:
NetBSD ushi 9.3 NetBSD 9.3 (GENERIC) #0: Thu Aug  4 15:30:37 UTC 2022  mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/amd64/compile/GENERIC amd64
>Description:
please see the following test code.
(it's available on github as well: https://github.com/yamt/garbage/blob/master/c/poll/test.c)
it succeeds on macOS and ubuntu.
but on netbsd, poll times out. (returns 0)
its 9.3 GENERIC kernel + older userland if it matters.

#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int
main()
{
        int pipefds[2];
        int ret;
        ret = pipe(pipefds);
        if (ret != 0) {
                printf("pipe failed\n");
                exit(1);
        }
        pid_t p = fork();
        if (p == -1) {
                printf("fork failed\n");
                exit(1);
        }
        if (p == 0) {
                /* sleep to ensure the parent starts poll before we exit */
                sleep(1);
                _Exit(0);
        }
        ret = close(pipefds[0]); /* read side */
        if (ret != 0) {
                printf("close failed unexpectdly\n");
                exit(1);
        }
        struct pollfd pfd;
        memset(&pfd, 0, sizeof(pfd));
        pfd.fd = pipefds[1]; /* write side */
        pfd.events = POLLHUP;
        ret = poll(&pfd, 1, 3000);
        if (ret != 1) {
                printf("poll returned unexpectd value %d\n", ret);
                exit(1);
        }
        printf("success\n");
        exit(0);
}

>How-To-Repeat:
see above
>Fix:

>Audit-Trail:
From: mlelstv@serpens.de (Michael van Elst)
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: kern/57369: unexpected poll timeout on pipe
Date: Thu, 20 Apr 2023 06:22:36 -0000 (UTC)

 yamt9999@gmail.com writes:

 >please see the following test code.
 >(it's available on github as well: https://github.com/yamt/garbage/blob/master/c/poll/test.c)
 >it succeeds on macOS and ubuntu.
 >but on netbsd, poll times out. (returns 0)
 >its 9.3 GENERIC kernel + older userland if it matters.


 This can be changed with:

 Index: sys/kern/sys_pipe.c
 ===================================================================
 RCS file: /cvsroot/src/sys/kern/sys_pipe.c,v
 retrieving revision 1.158
 diff -p -u -r1.158 sys_pipe.c
 --- sys/kern/sys_pipe.c 11 Oct 2021 01:07:36 -0000      1.158
 +++ sys/kern/sys_pipe.c 20 Apr 2023 06:20:45 -0000
 @@ -846,7 +846,7 @@ pipe_poll(file_t *fp, int events)
                 revents |= POLLHUP;

         if (revents == 0) {
 -               if (events & (POLLIN | POLLRDNORM))
 +               if (events & (POLLIN | POLLHUP | POLLRDNORM))
                         selrecord(curlwp, &rpipe->pipe_sel);

                 if (events & (POLLOUT | POLLWRNORM))


 But I don't see that this has ever worked. It also doesn't help (alone)
 for the opposite direction.


From: mlelstv@serpens.de (Michael van Elst)
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: kern/57369: unexpected poll timeout on pipe
Date: Thu, 20 Apr 2023 06:48:24 -0000 (UTC)

 mlelstv@serpens.de (Michael van Elst) writes:

 >The following reply was made to PR kern/57369; it has been noted by GNATS.

 >From: mlelstv@serpens.de (Michael van Elst)
 >To: gnats-bugs@netbsd.org
 >Cc: 
 >Subject: Re: kern/57369: unexpected poll timeout on pipe
 >Date: Thu, 20 Apr 2023 06:22:36 -0000 (UTC)

 > yamt9999@gmail.com writes:
 > 
 > >please see the following test code.
 > >(it's available on github as well: https://github.com/yamt/garbage/blob/master/c/poll/test.c)
 > >it succeeds on macOS and ubuntu.
 > >but on netbsd, poll times out. (returns 0)
 > >its 9.3 GENERIC kernel + older userland if it matters.
 > 
 > 
 > This can be changed with:
 > 
 > Index: sys/kern/sys_pipe.c
 > ===================================================================
 > RCS file: /cvsroot/src/sys/kern/sys_pipe.c,v
 > retrieving revision 1.158
 > diff -p -u -r1.158 sys_pipe.c
 > --- sys/kern/sys_pipe.c 11 Oct 2021 01:07:36 -0000      1.158
 > +++ sys/kern/sys_pipe.c 20 Apr 2023 06:20:45 -0000
 > @@ -846,7 +846,7 @@ pipe_poll(file_t *fp, int events)
 >                 revents |= POLLHUP;
 >  
 >         if (revents == 0) {
 > -               if (events & (POLLIN | POLLRDNORM))
 > +               if (events & (POLLIN | POLLHUP | POLLRDNORM))
 >                         selrecord(curlwp, &rpipe->pipe_sel);
 >  
 >                 if (events & (POLLOUT | POLLWRNORM))
 > 
 > 
 > But I don't see that this has ever worked. It also doesn't help (alone)
 > for the opposite direction.


 The write case is missed, because the EOF condition is set after
 notifying the peer.

 @@ -973,8 +973,8 @@ pipeclose(struct pipe *pipe)
          * Disconnect from peer.
          */
         if ((ppipe = pipe->pipe_peer) != NULL) {
 -               pipeselwakeup(ppipe, ppipe, POLL_HUP);
                 ppipe->pipe_state |= PIPE_EOF;
 +               pipeselwakeup(ppipe, ppipe, POLL_HUP);
                 cv_broadcast(&ppipe->pipe_rcv);
                 ppipe->pipe_peer = NULL;
         }

 A few lines earlier (waking openers of the closing
 side) seems to be the wrong order too.

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.47 2022/09/11 19:34:41 kim Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2023 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.