From: Tim Wright <timw@splhi.com>
To: Daniel Phillips <phillips@innominate.de>
Cc: Tim Wright <timw@splhi.com>, linux-kernel@vger.kernel.org
Subject: Re: [RFC] Semaphores used for daemon wakeup
Date: Tue, 19 Dec 2000 08:07:59 -0800 [thread overview]
Message-ID: <20001219080759.A24812@scutter.internal.splhi.com> (raw)
In-Reply-To: <0012171922570J.00623@gimli> <20001218193405.A24041@scutter.internal.splhi.com> <3A3F5E74.3F1988AB@innominate.de>
In-Reply-To: <3A3F5E74.3F1988AB@innominate.de>; from phillips@innominate.de on Tue, Dec 19, 2000 at 02:11:16PM +0100
Hi Daniel,
On Tue, Dec 19, 2000 at 02:11:16PM +0100, Daniel Phillips wrote:
[...]
> I'm curious, is my method of avoiding the deadlock race the same as
> yours? My solution is to keep a count of tasks that 'intend' to take
> the down():
>
> atomic_inc(&bdflush_waiters);
> up(&bdflush_request);
> down(&bdflush_waiter);
>
> so that bdflush will issue the correct number of up's even if the waiter
> has not yet gone to sleep. IOW, is your approach in DYNIX the same only
> in spirit, or in detail?
>
> --
> Daniel
OK,
this is not how we generally would achieve the goal, although the approach
looks valid. We have a number of primitives available that are not currently
used in Linux (unless I'm losing my eyesight :-)
We use p_sema, and v_sema for down and up respectively (this was done many
years ago, and the names are in deference to Edsger Dijkstra.
For normal semaphores (as opposed to read/writer or other variants), we have
sema_t sema;
init_sema(&sema, 1); /* initialize semaphore & set initial count */
p_sema(&sema, PZERO); /* "grab" semaphore and set process priority */
/* priority < PZERO == sleep uninterruptibly */
v_sema(&sema); /* release semaphore (i.e. increment count) */
cp_sema(&sema); /* Attempt to grab semaphore iff free else EBUSY */
vall_sema(&sema); /* Wake up all sleepers on this semaphore */
blocked_sema(&sema); /* boolean: any sleepers ? */
p_sema_v_lock(&sema, priority, &lock); /* atomically release the lock AND */
/* go to sleep on the semaphore */
Simple spinlock primitives are similar (e.g. p_lock ...), but the last
primitive above is the key to avoiding many races. The classic coding style
in DYNIX/ptx (this for buffer allocation) is then:
dmabuf_init(...);
{
...
init_sema(&dmabuf_wait, 0);
init_lock(&dmabuf_mutex);
...
}
dmabuf_alloc(...)
{
spl_t saved_spl;
...
while (1) {
saved_spl = p_lock(&dmabuf_mutex, SPLSWP);
attempt to grab a free buffer;
if (success){
v_lock(&dmabuf_mutex, saved_spl);
return;
} else {
p_sema_v_lock(&dmabuf_wait, PSWP+1, &dmabuf_mutex);
}
}
}
dmabuf_free(...)
{
spl_t saved_spl;
...
saved_spl = p_lock(&dmabuf_mutex, SPLHI);
free up buffer;
if (blocked_sema(&dmabuf_wait)) {
vall_sema(&dmabuf_wait);
}
v_lock(&dmabuf_mutex, s);
}
As you can see, the spinlocks ensure no races, and the key is the atomicity
of p_sema_v_lock(). No-one can race in and sleep on dmabuf_wait, because
they have to hold dmabuf_mutex to do so. Exactly the same mechanism would
work for the bdflush problem.
One can argue the relative merits of the different approaches. I suspect that
the above code is less bus-intensive relative to the atomic inc/dec/count ops,
but I may be wrong.
Regards,
Tim
--
Tim Wright - timw@splhi.com or timw@aracnet.com or twright@us.ibm.com
"Nobody ever said I was charming, they said "Rimmer, you're a git!"" RD VI
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/
next prev parent reply other threads:[~2000-12-19 16:38 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2000-12-17 12:06 [RFC] Semaphores used for daemon wakeup Daniel Phillips
2000-12-19 0:14 ` Nigel Gamble
2000-12-19 3:34 ` Tim Wright
2000-12-19 13:11 ` Daniel Phillips
2000-12-19 16:07 ` Tim Wright [this message]
2000-12-20 1:34 ` Daniel Phillips
2000-12-21 16:28 ` Tim Wright
2000-12-19 9:01 ` Daniel Phillips
[not found] <3A42380B.6E9291D1@sgi.com>
2000-12-21 19:30 ` Paul Cassella
2000-12-21 22:19 ` Tim Wright
2000-12-22 1:12 ` Daniel Phillips
2000-12-22 1:50 ` Daniel Phillips
2000-12-22 4:26 ` Paul Cassella
2000-12-22 11:46 ` Daniel Phillips
2000-12-22 15:33 ` Tim Wright
2000-12-22 17:25 ` Daniel Phillips
2000-12-22 17:32 ` Brian Pomerantz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20001219080759.A24812@scutter.internal.splhi.com \
--to=timw@splhi.com \
--cc=linux-kernel@vger.kernel.org \
--cc=phillips@innominate.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.