Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 01 Sep 2008 01:31:17 +0000 (UTC)
From:      Tor Egge <Tor.Egge@cvsup.no.freebsd.org>
To:        Benjamin.Close@clearchain.com
Cc:        attilio@freebsd.org, kevinxlinuz@163.com, freebsd-current@freebsd.org, kib@freebsd.org
Subject:   Re: [BUG] I think sleepqueue need to be protected in sleepq_broadcast
Message-ID:  <20080901.013117.74700691.Tor.Egge@cvsup.no.freebsd.org>
In-Reply-To: <48B6BC81.5060300@clearchain.com>
References:  <200808230003.44081.jhb@freebsd.org> <3bbf2fe10808230233u195f3530wf4e3b6e007b638d9@mail.gmail.com> <48B6BC81.5060300@clearchain.com>

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

sleepq_resume_thread() contains an ownership handover of sq if the resumed
thread is the last one blocked on the wait channel.  After the handover, sq is
no longer protected by the sleep queue chain lock and should no longer be
accessed by sleepq_broadcast().

Normally, when sleepq_broadcast() incorrectly accesses sq after the handover,
it will find the sq->sq_blocked queue to be empty, and the code appears to
work.

If the last correctly woken thread manages to go to sleep again very quickly on
another wait channel, sleepq_broadcast() might incorrectly determine that the
sq->sq_blocked queue isn't empty, and start doing the wrong thing.

A similar (but probably much more difficult to trigger) issue is present with
regards to thread_lock() and turnstiles.

The caller of thread_lock() might have performed sufficient locking to ensure
that the thread to be locked doesn't go away, but any turnstile spin lock
pointed to by td->td_lock isn't protected.  Making turnstiles type stable
(setting UMA_ZONE_NOFREE flag for turnstile_zone) should fix that issue.

- Tor Egge



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