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.