public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Robert Love <rml@tech9.net>
To: "Perez-Gonzalez, Inaky" <inaky.perez-gonzalez@intel.com>
Cc: torvalds@transmeta.org, linux-kernel@vger.kernel.org
Subject: RE: [PATCH 2.5.52] Use __set_current_state() instead of current-> state = (take 1)
Date: 18 Dec 2002 20:03:13 -0500	[thread overview]
Message-ID: <1040259792.6857.93.camel@phantasy> (raw)
In-Reply-To: <A46BBDB345A7D5118EC90002A5072C7806CACA2A@orsmsx116.jf.intel.com>

On Wed, 2002-12-18 at 19:46, Perez-Gonzalez, Inaky wrote:

> > Some of these should probably be set_current_state().  I 
> > realize the current code is equivalent to __set_current_state()
> > but it might as well be done right.
> 
> Agreed; however, I also don't want to introduce unnecessary
> bloat, so I need to understand first what cases need it - it
> is kind of hard for me. Care to let me know some gotchas?

set_current_state() includes a write barrier to ensure the setting of
the state is flushed before any further instructions.  This is to
provide a memory barrier for weak-ordering processors that can and will
rearrange the writes.

Not all processors like those made by your employer are strongly-ordered
:)

Anyhow, the problem is when the setting of the state is set to
TASK_INTERRUPTIBLE or TASK_UNINTERRUPTIBLE.  In those cases, it may be
possible for the state to actually be flushed to memory AFTER the wake
up event has occurred.

So you have code like this:

	__set_current_state(TASK_INTERRUPTIBLE);
	add_waitqueue(...);

but the processor ends up storing the current->state write after the
task is added to the waitqueue.  In between those events, the wake up
event occurs and the task is woken up.  Then the write to current->state
is flushed.  So you end up with:

	add_waitqueue(...);
	interrupt or whatever occurs and wakes up the wait queue
	task is now woken up and running
	current->state = TASK_INTERRUPTIBLE /* BOOM! */

the task is marked sleeping now, but its wait event has already occurred
-- its in for a long sleep...

So to ensure the write is flushed then and there, and that the processor
(or compile, but we do not really worry about it because the call to
add_waitqueue will act as a compiler barrier, for example) does not move
the write to after the potential wake up, we use the write barrier.

In short, set_current_state() uses a memory barrier to ensure the state
setting occurs before any potential wake up activity, eliminating a
potential race and process deadlock.

It sounds complicated but its pretty simple... my explanation was
probably way too long - better than any I have seen here before on why
we have these things, at least.  Hope it helps.

If in doubt, just make all of them set_current_state().  That is the
standard API, and its at least safe.

	Robert Love


  reply	other threads:[~2002-12-19  0:55 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-12-19  0:46 [PATCH 2.5.52] Use __set_current_state() instead of current-> state = (take 1) Perez-Gonzalez, Inaky
2002-12-19  1:03 ` Robert Love [this message]
  -- strict thread matches above, loose matches on Subject: below --
2002-12-19 19:04 Perez-Gonzalez, Inaky
2002-12-20  3:08 ` Alan Cox
2002-12-20 19:36   ` Oliver Xymoron
2002-12-19  2:40 Perez-Gonzalez, Inaky
2002-12-19  3:19 ` Robert Love
2002-12-19  1:53 Perez-Gonzalez, Inaky
2002-12-19  2:04 ` Robert Love
2002-12-18 23:56 [PATCH 2.5.52] Use __set_current_state() instead of current->state " Inaky Perez-Gonzalez
2002-12-19  0:11 ` Robert Love

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=1040259792.6857.93.camel@phantasy \
    --to=rml@tech9.net \
    --cc=inaky.perez-gonzalez@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@transmeta.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox