Print this page
8634 epoll fails to wake on certain edge-triggered conditions
8635 epoll should not emit POLLNVAL
8636 recursive epoll should emit EPOLLRDNORM
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Toomas Soome <tsoome@me.com>
Reviewed by: Igor Kozhukhov <igor@dilos.org>
*** 38,47 ****
--- 38,48 ----
* "Header: bpf.c,v 1.67 96/09/26 22:00:52 leres Exp ";
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2017 Joyent, Inc.
*/
/*
* The BPF implements the following access controls for zones attempting
* to read and write data. Writing of data requires that the net_rawaccess
*** 1394,1417 ****
mutex_exit(&d->bd_lock);
return (0);
}
! /*
! * Support for poll() system call
! *
! * Return true iff the specific operation will not block indefinitely - with
! * the assumption that it is safe to positively acknowledge a request for the
! * ability to write to the BPF device.
! * Otherwise, return false but make a note that a selnotify() must be done.
! */
int
bpfchpoll(dev_t dev, short events, int anyyet, short *reventsp,
struct pollhead **phpp)
{
struct bpf_d *d = bpf_dev_get(getminor(dev));
if (events & (POLLIN | POLLRDNORM)) {
/*
* An imitation of the FIONREAD ioctl code.
*/
mutex_enter(&d->bd_lock);
--- 1395,1419 ----
mutex_exit(&d->bd_lock);
return (0);
}
! /* ARGSUSED */
int
bpfchpoll(dev_t dev, short events, int anyyet, short *reventsp,
struct pollhead **phpp)
{
struct bpf_d *d = bpf_dev_get(getminor(dev));
+ /*
+ * Until this driver is modified to issue proper pollwakeup() calls on
+ * its pollhead, edge-triggered polling is not allowed.
+ */
+ if (events & POLLET) {
+ return (EPERM);
+ }
+
if (events & (POLLIN | POLLRDNORM)) {
/*
* An imitation of the FIONREAD ioctl code.
*/
mutex_enter(&d->bd_lock);
*** 1418,1430 ****
if (d->bd_hlen != 0 ||
((d->bd_immediate || d->bd_state == BPF_TIMED_OUT) &&
d->bd_slen != 0)) {
*reventsp |= events & (POLLIN | POLLRDNORM);
} else {
*reventsp = 0;
- if (!anyyet)
- *phpp = &d->bd_poll;
/* Start the read timeout if necessary */
if (d->bd_rtout > 0 && d->bd_state == BPF_IDLE) {
bpf_clear_timeout(d);
/*
* Only allow the timeout to be set once.
--- 1420,1436 ----
if (d->bd_hlen != 0 ||
((d->bd_immediate || d->bd_state == BPF_TIMED_OUT) &&
d->bd_slen != 0)) {
*reventsp |= events & (POLLIN | POLLRDNORM);
} else {
+ /*
+ * Until the bpf driver has been updated to include
+ * adequate pollwakeup() logic, no pollhead will be
+ * emitted here, preventing the resource from being
+ * cached by poll()/devpoll/epoll.
+ */
*reventsp = 0;
/* Start the read timeout if necessary */
if (d->bd_rtout > 0 && d->bd_state == BPF_IDLE) {
bpf_clear_timeout(d);
/*
* Only allow the timeout to be set once.