Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 8 Oct 2007 21:09:11 -0400 (EDT)
From:      Daniel Eischen <deischen@freebsd.org>
To:        Jeff Roberson <jroberson@chesapeake.net>
Cc:        arch@freebsd.org
Subject:   Re: Abolishing sleeps in issignal()
Message-ID:  <Pine.GSO.4.64.0710082056090.1871@sea.ntplx.net>
In-Reply-To: <20071008142928.Y912@10.0.0.1>
References:  <20071008142928.Y912@10.0.0.1>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, 8 Oct 2007, Jeff Roberson wrote:

> During the work on thread lock I observed that there is a significant amount 
> of locking involved in our signal paths right now.  And these locks also show 
> up contended in many workloads.  Furthermore, requiring a DEF mutex 
> complicates sleep queues by forcing them to drop the spinlock to check for 
> signals and then check for races.
>
> The current issignal() code will actually msleep in the case of a stopevent() 
> requested by the debugger.  This is fine for signals that would normally 
> abort the sleep anyway, but SIGSTOP actually leaves the thread on the sleep 
> queue and tries to resume the sleep after the stop has cleared.  So SIGSTOP 
> combined with a stopevent() actually breaks because the stopevent() removes 
> the thread from the sleep queue.  I'm not certain what the failure mode is 
> currently, but I'm certain that it's wrong.
>
> What I'd like to do is stop sleeping in issignal() all together.  For regular 
> restartable syscalls this would mean failing back out to ast() where we'd 
> then handle the signals including SIGSTOP.  After SIGCONT we'd then restart 
> the syscall.  For non-restartable syscalls we could have a special issignal 
> variant that is called when msleep/cv_timedwait_sig return interrupted that 
> would check for SIGSTOP/debugger events and sleep within a loop retrying the 
> operation.  This would preserve the behavior of debugging events and SIGSTOP 
> not aborting non-restartable syscalls as they do now.
>
> Once we have moved the location of the sleeps it will be possible to check 
> for signals using a spinlock without dropping the sleep queue lock in 
> sleepq_catch_signals().
>
> What I'd like from readers on arch@ is for you to consider if there are other 
> cases than non-restartable syscalls that will break if msleep/sleepqs return 
> EINTR from SIGSTOP and debug events.  Also, is there an authoritative list of 
> non-restartable syscalls anywhere?  It's just those involving timevals right? 
> nanosleep/poll/select/kqueue.. others?

I would consult the POSIX spec; it may be of some value to you. 
Generally, any syscall that can block should be able to restart
the syscall without the application handling EINTR.  On the flip
side, any syscall that can be guaranteed to complete in a short
time should not return EINTR, but should delay signal delivery
until after syscall completion.  Some functions are guaranteed
by POSIX to not return EINTR (e.g., getpid & getuid).

See:

   http://www.opengroup.org/onlinepubs/000095399/xrat/xsh_chap02.html#tag_03_02_04

I don't know if that link will work...

-- 
DE



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