Page MenuHomeFreeBSD

Make some linux syscalls non-restartable.
Needs ReviewPublic

Authored by trasz on Jul 18 2020, 12:05 PM.
Tags
None
Referenced Files
Unknown Object (File)
Dec 20 2023, 8:31 AM
Unknown Object (File)
Oct 30 2023, 2:32 AM
Unknown Object (File)
Nov 27 2022, 9:15 AM
Subscribers

Details

Reviewers
kib
Group Reviewers
Linux Emulation
Summary

Some Linux syscalls - sigtimedwait(2), ppoll(2) and the like - should
not be restarted, even if the current signal mask specifies SA_RESTART.
See https://man7.org/linux/man-pages/man7/signal.7.html for details.

Because this has potential to break things, there's a new chicken flag,
compat.linux.ignore_erestart.

This should include poll(2), but it's a bit more involved and I'm not sure
if our poll(2) can actually return ERESTART?

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 32398
Build 29879: arc lint + arc unit

Event Timeline

sys/compat/linux/linux_misc.c
535

select(2) never returns ERESTART.

2202

Same for pselect(2).

2266

poll(2) never returns ERESTART.

sys/compat/linux/linux_signal.c
435

Why this conversion is needed for rt_sigtimedwait() ? Can you describe the semantic of the syscall ?

sys/compat/linux/linux_misc.c
2202

Perfect. The regular select(2) never does it too, right?

sys/compat/linux/linux_signal.c
435

From what I understand it's pretty much the same as our sigtimedwait(2), it just never returns ERESTART, even if interrupted by a signal registered with SA_RESTART. There are some regression tests that verify it.

sys/compat/linux/linux_signal.c
435

And this is the right behaviour, if timeout is specified, we should never return ERESTART. Otherwise the calling thread would sleep too much. This is same as for other syscalls that take timeout (select/pselect/poll/kqueue).

If timeout was not specified, we do not translate ERESTART to EINTR for sigtimedwait().

So I tend to think that your patch is not valid at all.

sys/compat/linux/linux_signal.c
435

I agree it's the right behaviour - for FreeBSD. It's not the behaviour of sigtimedwait() in Linux, though. And it's actually documented:

       The following interfaces are never restarted after being interrupted
       by a signal handler, regardless of the use of SA_RESTART; they always
       fail with the error EINTR when interrupted by a signal handler:

[..]

       * Interfaces used to wait for signals: pause(2), sigsuspend(2),
         sigtimedwait(2), and sigwaitinfo(2).
sys/compat/linux/linux_signal.c
435

Can you provide the minimal example that demonstrates the difference in behavior between Linux and FreeBSD ? For sigtimedwait(2).