Re: Clarification required about select vs wake_up race condition

From: Dmitry Adamushko
Date: Wed Mar 14 2007 - 13:08:30 EST


On 12/03/07, Ravinandan Arakali (rarakali) <rarakali@xxxxxxxxx> wrote:
Hi,
I am facing following problem and was wondering if somebody could help
me out.
Our char driver(pretty much like all other char drivers) does a
poll_wait()
and returns status depending on whether data is available to be read.
Even though some data is available to be read(verified using one of our
internal
commands), the select() never wakes up, inspite of any no. of messages
sent.

To understand this, I was looking at the code of select vs
wake_up_interruptible().
I feel I am misunderstanding some part of the kernel code but will be
glad if
somebody can point it out.

My understanding:
The do_select() sets the state of task to TASK_INTERRUPTIBLE and calls
the driver's
poll entry point. In our poll(), let's say immediately after we
determine that there's
nothing to be read, some data arrives causing a wake_up_interruptible()
on another CPU.
The wake up happens in the context of process sending the data. Since
the receiving
process was already added to the list of listeners, from looking at the
code of
try_to_wake_up(), it looks like it can set the state of the receiving
process to
TASK_RUNNING(I don't see any lock preventing this). After this happens,
the receiving
process goes to sleep (because of schedule_timeout called by do_select)
but
state is still set to TASK_RUNNING.

No, it's not going to sleep then.

The effect of schedule() being called with current->state ==
TASK_RUNNING is a re-scheduling to another task with a higher prio (if
any) or just getting back (iow, the task doesn't lose a cpu). For both
cases, the task is on the runqueue.

/ Look how/when deactivate_task() is called in schedule() /

Maybe there is a race in your code between (1) how you check "data is
available" in poll and (2) a part that sets this fact (data is
available)...


--
Best regards,
Dmitry Adamushko
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/