qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] Re: [5578] Increase default IO timeout from 10ms to 5s


From: M. Warner Losh
Subject: Re: [Qemu-devel] Re: [5578] Increase default IO timeout from 10ms to 5s
Date: Wed, 05 Nov 2008 22:19:58 -0700 (MST)

In message: <address@hidden>
            Jamie Lokier <address@hidden> writes:
: M. Warner Losh wrote:
: > : > Which ones have a good kernel implementation of it?  FreeBSD's is
: > : > currently approximately:
: > : > 
: > : >         if (!mask)
: > : >                 _sigprocmask(mask, &oldmask);
: > : >         /* here */
: > : >         select();
: > : >         if (!mask)
: > : >                 _sigprocmask(oldmask, NULL);
: > : > 
: > : > I'm assuming that the problem is due to a signal arriving at /* here */.
: > : 
: > : If that's _kernel_ code and the kernel behaves like Linux, it's not a
: > : problem because signals don't affect the control flow until returning
: > : to userspace, meaning the select() will return EINTR.
: > 
: > It is currently user level code, and I'm looking at moving it into the
: > kernel, but I need to understand the race being talked about here.
: 
: Ugh, I had imagined FreeBSD would have got that right, since it's
: quite good in other areas.  I've added FreeBSD to my blacklist of
: broken pselect() implementations, thanks for the info.
: 
: Do you know if FreeBSD's pread() and pwrite() are also thread-unsafe
: userspace wrappers using lseek+read/write?  They are harder to avoid
: when you're looking at high performance code.

I haven't looked...

: > Why is it no good.  What is the race here?  Is it just the oldmask
: > thing and multiple callers to select, or is it something else?
: 
: It's racy with a single caller.  The race is: program's signal handler
: sets a flag like "alarm_happened = 1".  The program's main loop checks
: the flag before calling select().  If the signal is delivered before
: that check, the program doesn't call select() and handles the reason
: for the flag.  If the signal is delivered during select(), that
: returns EINTR and the program handles the reason for the flag.  But if
: the signal is delivered _between_ checking the flag and calling
: select(), the program gets stuck.
: 
: pselect() avoids that stuck state, by blocking the signal before the
: program checks the flag, and guaranteeing if the signal is delivered
: after that point, pselect() returns EINTR.  It's sort of analogous to
: pthread_cond_wait() needing a mutex.

OK.  that makes sense.

: > And if it is the oldmask thing, why wouldn't multiple callers of
: > pselect mess it up depending on what order they have.
: 
: Signal masks are per-thread anyway, multiple callers isn't an issue.

OK.  I have never had good things happen with signals and threads...

Warner




reply via email to

[Prev in Thread] Current Thread [Next in Thread]