lkml.org 
[lkml]   [2010]   [Jan]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
SubjectRe: Lots of bugs with current->state = TASK_*INTERRUPTIBLE
From
Date
On Thu, 2010-01-21 at 11:47 +0100, Julia Lawall wrote:
> What about something like the following (drivers/macintosh/adb.c):
>
> add_wait_queue(&state->wait_queue, &wait);
> current->state = TASK_INTERRUPTIBLE;
>
> for (;;) {
> req = state->completed;
> if (req != NULL)
> state->completed = req->next;
> else if (atomic_read(&state->n_pending) == 0)
> ret = -EIO;
> if (req != NULL || ret != 0)
> break;
>
> if (file->f_flags & O_NONBLOCK) {
> ret = -EAGAIN;
> break;
> }
> if (signal_pending(current)) {
> ret = -ERESTARTSYS;
> break;
> }
> spin_unlock_irqrestore(&state->lock, flags);
> schedule();
> spin_lock_irqsave(&state->lock, flags);
> }
>
> current->state = TASK_RUNNING;
> remove_wait_queue(&state->wait_queue, &wait);
>
> There is a call to schedule eventually after the first current->state
> assignment, but it is not right after.

I looked at this code in a bit more detail. Seems that it does not need
the set_current_state(), because all activities between the state of the
task and the variables being checked (state->n_pending, et al) are under
the state->lock.

But there should be a comment stating that above the assignment of
current->state. Something like:

/*
* No need for the set_current_state() memory barrier since
* all checks between state and wakeups are done under the
* state->lock.
*/
current->state = TASK_INTERRUPTIBLE;


But I'd rather have the author of this code write that.

-- Steve






\
 
 \ /
  Last update: 2010-01-21 18:33    [W:0.068 / U:23.608 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site