epoll_ctl can avoid EINTR entirely
Upstreaming the non-LX portion of OS-5521 from SmartOS:
epoll_ctl() is not expected to be interruptable, the wait for write access to its devpoll resource can be a little tricky. This was especially troublesome for the LX emulation, which could not rely on signal delivery and later retry (via SA_RESTART or the native libc logic). As it turns out, the constrains of epoll, where a maximum of two entries will be processed by
dpwrite() (a remove and an add to implement
EPOLL_CTL_MOD) means a firm upper bound on the wait time, meaning a signal-ignorant wait would be completely acceptable (for epoll-flavored handles).
This has been in production on SmartOS since 2016.
Updated by Patrick Mooney over 3 years ago
I added an illumos-specific test to the epoll suite to verify the
/dev/poll write limit imposed as part of this patch.
On a system without the change, writes larger than two descriptors can proceed:
test_illumos 0 TFAIL: 48 != -1 test_illumos 1 TFAIL: 0 != 22 test_illumos 2 TFAIL: -1 != 0 test_illumos 3 TPASS
With the patch (limited to two-descriptor writes for the sake of
EPOLL_CTL_MOD), the test is clean:
test_illumos 0 TPASS test_illumos 1 TPASS test_illumos 2 TPASS test_illumos 3 TPASS
The other signal-related portion of this test is difficult to exercise. Hitting that race was a rare occurrence for even heavy epoll users. (The one notable exception was a proprietary Haskell app) That said, this fix has been in SmartOS and OmniOS for years without issue.
Updated by Electric Monk over 3 years ago
- Status changed from In Progress to Closed
- % Done changed from 0 to 100
commit 3c2d4f391c2bc4b3b4126c0757329835c80781ed Author: Patrick Mooney <email@example.com> Date: 2020-07-06T15:33:58.000Z 12907 epoll_ctl can avoid EINTR entirely Reviewed by: Ryan Zezeski <firstname.lastname@example.org> Reviewed by: Jerry Jelinek <email@example.com> Approved by: Robert Mustacchi <firstname.lastname@example.org>