Understanding interrupted system calls

Joe Marcus Clarke marcus at FreeBSD.org
Sun Sep 2 20:23:46 PDT 2007


On Sun, 2007-09-02 at 14:17 +1000, Bruce Evans wrote:
> On Sun, 2 Sep 2007, Jilles Tjoelker wrote:
> 
> > On Sat, Sep 01, 2007 at 11:33:02AM -0400, Joe Marcus Clarke wrote:
> >> However, I'm curious as to my other point in this thread.  Why should
> >> one need to re-register the default signal handlers to get a syscall to
> >> return EINTR?  Or should ERESTART be caught and turned into EINTR then
> >> return to the caller (as in kern_connect())?
> >
> > It is intended that most blocking system calls are not interrupted by
> > signals.  This saves the programmer some checks on EINTR.
> 
> Yes, I think this is just the historical default for BSD.  Not
> restarting syscalls is very unusual in BSD, and this was implemented
> by defaulting ps_sigintr to all unset (?).  Before sigaction(2) existed,
> signal(3) was probably signal(2), and most programs used only signal()
> and got the default.  siginterrupt(3) was more probably siginterrupt(2),
> and the few programs that understand this stuff and want to change the
> default had to use it to get EINTR.  Now with sigaction(2), the default
> doesn't apply to userland, since setting up a signal catcher requires
> using sigaction(2) which sets the ps_sigintr bit to the inverse of the
> SA_RESTART bit in the sigaction data.  However, the default might still
> affect operation in the kernel for programs that never call sigaction().
> I think it shouldn't have any effect except to return to near the
> syscall entry point to decide what to do.  Lower levels should see
> ERESTART and return to near the syscall entry point.  Similarly if
> sigaction() is used to change the default.

Thanks, Bruce and Jilles for the explanation.  It is much clearer now.

> 
> > Some system calls, e.g. connect(), read/write/etc that have already
> > committed some data and under BSD also select/poll/kqueue do not restart
> > and always return EINTR or partial success.  In the kernel code, this
> > appears as changing ERESTART to EINTR.
> 
> This translation happens at a high level, but the translation of ps_sigintr
> happens at the [*]sleep() level.  So ps_sigintr has a significant affect
> at a low level, but only (?) to select between ERESTART and EINTR.
> 
> >From Jilles' previous reply:
> 
> >>> The problem seems to be the following code in
> >>> src/sys/dev/syscons/syscons.c, in case VT_WAITACTIVE in scioctl():
> >>> 
> >>> 	while ((error=tsleep(&scp->smode, PZERO|PCATCH,
> >>> 			     "waitvt", 0)) == ERESTART) ;
> >>> 
> >>> If a signal is caught and system call restart is enabled for that
> >>> signal, this makes it spin in a tight loop, waiting in vain for the
> >>> signal to go away.  The idea of ERESTART is that the syscall function
> >>> returns it and then the signal handler is entered.  If and when the
> >>> signal handler returns, it will return to the system call instruction,
> >>> restarting it (perhaps this is optimized to avoid the switch to userland
> >>> and back).  With EINTR, the signal handler would return to directly
> >>> after the system call instruction.
> >>> 
> >>> The fixed version would then be
> >>> 
> >>> 	error = tsleep(&scp->smode, PZERO|PCATCH, "waitvt", 0);
> 
> I think this is right.  The kernel should never loop on ERESTART like this.
> Please fix the remaining style bug in it (missing spaces around binary
> operator).

I think these patches do what you and Jilles suggested.  As Jilles said,
the pcvt patch only applies to -STABLE as this driver was removed in
-CURRENT.  Thanks again, guys, for helping me out with this.

http://www.marcuscom.com/downloads/syscons.c.diff
http://www.marcuscom.com/downloads/pcvt_ext.c.diff

Joe

-- 
Joe Marcus Clarke
FreeBSD GNOME Team      ::      gnome at FreeBSD.org
FreeNode / #freebsd-gnome
http://www.FreeBSD.org/gnome
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 187 bytes
Desc: This is a digitally signed message part
Url : http://lists.freebsd.org/pipermail/freebsd-arch/attachments/20070903/9a3ef44c/attachment.pgp


More information about the freebsd-arch mailing list