Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 02 Sep 2007 23:23:38 -0400
From:      Joe Marcus Clarke <marcus@FreeBSD.org>
To:        Bruce Evans <brde@optusnet.com.au>
Cc:        Jilles Tjoelker <jilles@stack.nl>, freebsd-arch@FreeBSD.org
Subject:   Re: Understanding interrupted system calls
Message-ID:  <1188789818.97969.9.camel@shumai.marcuscom.com>
In-Reply-To: <20070902131910.H46281@delplex.bde.org>
References:  <1188600721.1255.11.camel@shumai.marcuscom.com> <20070901112600.GA33832@stack.nl> <1188660782.41727.5.camel@shumai.marcuscom.com> <20070901224025.GA97796@stack.nl> <20070902131910.H46281@delplex.bde.org>

next in thread | previous in thread | raw e-mail | index | archive | help

--=-e9iPozRu55oGEQ3WZ39A
Content-Type: text/plain
Content-Transfer-Encoding: quoted-printable

On Sun, 2007-09-02 at 14:17 +1000, Bruce Evans wrote:
> On Sun, 2 Sep 2007, Jilles Tjoelker wrote:
>=20
> > 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 t=
o
> >> 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.
>=20
> 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.

>=20
> > Some system calls, e.g. connect(), read/write/etc that have already
> > committed some data and under BSD also select/poll/kqueue do not restar=
t
> > and always return EINTR or partial success.  In the kernel code, this
> > appears as changing ERESTART to EINTR.
>=20
> This translation happens at a high level, but the translation of ps_sigin=
tr
> happens at the [*]sleep() level.  So ps_sigintr has a significant affect
> at a low level, but only (?) to select between ERESTART and EINTR.
>=20
> >From Jilles' previous reply:
>=20
> >>> The problem seems to be the following code in
> >>> src/sys/dev/syscons/syscons.c, in case VT_WAITACTIVE in scioctl():
> >>>=20
> >>> 	while ((error=3Dtsleep(&scp->smode, PZERO|PCATCH,
> >>> 			     "waitvt", 0)) =3D=3D ERESTART) ;
> >>>=20
> >>> 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 userl=
and
> >>> and back).  With EINTR, the signal handler would return to directly
> >>> after the system call instruction.
> >>>=20
> >>> The fixed version would then be
> >>>=20
> >>> 	error =3D tsleep(&scp->smode, PZERO|PCATCH, "waitvt", 0);
>=20
> I think this is right.  The kernel should never loop on ERESTART like thi=
s.
> 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

--=20
Joe Marcus Clarke
FreeBSD GNOME Team      ::      gnome@FreeBSD.org
FreeNode / #freebsd-gnome
http://www.FreeBSD.org/gnome

--=-e9iPozRu55oGEQ3WZ39A
Content-Type: application/pgp-signature; name=signature.asc
Content-Description: This is a digitally signed message part

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (FreeBSD)

iD8DBQBG2346b2iPiv4Uz4cRAsJwAKCJacuQMP+LUCxYbiWQed5EV6gJAQCfaTFP
cONVTPYttoSv1A3bhmrPGtY=
=d8MY
-----END PGP SIGNATURE-----

--=-e9iPozRu55oGEQ3WZ39A--




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1188789818.97969.9.camel>