NetBSD Problem Report #46248
From www@NetBSD.org Fri Mar 23 01:08:19 2012
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [149.20.53.66])
by www.NetBSD.org (Postfix) with ESMTP id BF54D63E3EB
for <gnats-bugs@gnats.NetBSD.org>; Fri, 23 Mar 2012 01:08:19 +0000 (UTC)
Message-Id: <20120323010818.E7A0863B946@www.NetBSD.org>
Date: Fri, 23 Mar 2012 01:08:18 +0000 (UTC)
From: gnrp@komkon2.de
Reply-To: gnrp@komkon2.de
To: gnats-bugs@NetBSD.org
Subject: kevent won't return when kqueue is being closed
X-Send-Pr-Version: www-1.0
>Number: 46248
>Category: kern
>Synopsis: kevent won't return when kqueue is being closed
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: jdolecek
>State: closed
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Mar 23 01:10:01 +0000 2012
>Closed-Date: Sun May 02 19:16:52 +0000 2021
>Last-Modified: Sun May 02 19:20:01 +0000 2021
>Originator: Julian Fagir
>Release: 6.0_BETA
>Organization:
>Environment:
NetBSD eselhitler 6.0_BETA NetBSD 6.0_BETA (ESELHITLER) #15: Fri Mar 16 12:21:49 CET 2012 gnrp@eselhitler:/home/ssd/netbsd-6.0/sys/arch/amd64/compile/obj/ESELHITLER amd64
NetBSD devrandom 6.0_BETA NetBSD 6.0_BETA (GENERIC) sparc64
>Description:
Apparently, FreeBSD and NetBSD handle kqueue'ing differently when the kqueue underneath a kevent(2) call is closed.
On FreeBSD, closing the kqueue just succeeds and kevent returns, or whatever, at least the close(2) call succeeds.
On NetBSD, the close won't return. If you have a pending kevent without timeout (i.e. last field set to NULL), you won't be able to shut that call down (at least not by this way).
>How-To-Repeat:
Save the attached program to `test.c`, and then compile and run with
`cc -lpthread test.c; time ./a.out`.
On NetBSD, this won't return until you stop it manually.
On FreeBSD, this will return after one second.
===test.c:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#include <pthread.h>
static void *
closekq(void *kq)
{
sleep(1);
close(*(int *) kq);
exit(0);
}
int
main(int argc, char *argv[])
{
int kq, event;
struct kevent kq_events;
pthread_t thr;
if ((kq = kqueue()) == -1)
err(1, "kqueue");
if (pthread_create(&thr, NULL, closekq, &kq))
err(1, "pthread_create");
event = kevent(kq, NULL, 0, &kq_events, 1, NULL);
if (event == -1)
err(1, "kevent");
return 0;
}
>Fix:
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: kern-bug-people->jdolecek
Responsible-Changed-By: jdolecek@NetBSD.org
Responsible-Changed-When: Sun, 24 Jan 2021 12:56:42 +0000
Responsible-Changed-Why:
Might look into this one, looks like useful to fix.
State-Changed-From-To: open->closed
State-Changed-By: jdolecek@NetBSD.org
State-Changed-When: Sun, 02 May 2021 19:16:52 +0000
State-Changed-Why:
Problem fixed.
It's unclear to me how FreeBSD managed to work - I was not able to find
any place in FreeBSD kernel which would wakeup the blocked kevent(2) call
when the descriptor is closed. Nevetheless, your test program now works
on NetBSD.
From: "Jaromir Dolecek" <jdolecek@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/46248 CVS commit: src/sys
Date: Sun, 2 May 2021 19:13:43 +0000
Module Name: src
Committed By: jdolecek
Date: Sun May 2 19:13:43 UTC 2021
Modified Files:
src/sys/kern: kern_event.c
src/sys/sys: eventvar.h
Log Message:
implement fo_restart hook for kqueue descriptors, so that close(2)
on the descriptor won't block indefinitely if other thread is currently
blocked on the same kqueue in kevent(2)
done similarily to pipes and sockets, i.e. using flag on the potentially
shared kqueue structure hooked off file_t - this is somewhat suboptimal
if the application dup(2)ped the descriptor, but this should be rare
enough to not really matter
usually this causes the kevent(2) to end up returning EBADF since
on the syscall restart the descriptor is not there anymore; if
dup(2)ped the kevent(2) call can continue successfully if the closed
kqueue descriptor was other than the one used for the kevent(2)
call
PR kern/46248 by Julian Fagir
To generate a diff of this commit:
cvs rdiff -u -r1.117 -r1.118 src/sys/kern/kern_event.c
cvs rdiff -u -r1.8 -r1.9 src/sys/sys/eventvar.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.46 2020/01/03 16:35:01 leot Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2020
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.