Messages in this thread | | | Date | Fri, 6 Mar 2015 22:07:03 +0000 (UTC) | From | Mathieu Desnoyers <> | Subject | Re: Possible lock-less list race in scheduler_ipi() |
| |
----- Original Message ----- > From: "Steven Rostedt" <rostedt@goodmis.org> > To: "Mathieu Desnoyers" <mathieu.desnoyers@efficios.com> > Cc: "Linus Torvalds" <torvalds@linux-foundation.org>, "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>, "Huang Ying" > <ying.huang@intel.com>, "Lai Jiangshan" <laijs@cn.fujitsu.com>, "Lai Jiangshan" <eag0628@gmail.com>, "Peter > Zijlstra" <peterz@infradead.org>, "LKML" <linux-kernel@vger.kernel.org>, "Ingo Molnar" <mingo@kernel.org> > Sent: Friday, March 6, 2015 3:39:25 PM > Subject: Re: Possible lock-less list race in scheduler_ipi() > > On Fri, 6 Mar 2015 15:38:21 -0500 > Steven Rostedt <rostedt@goodmis.org> wrote: > > > On Fri, 6 Mar 2015 19:39:44 +0000 (UTC) > > Mathieu Desnoyers <mathieu.desnoyers@efficios.com> wrote: > > > > ask concurrently with the llist iteration within sched_ttwu_pending(). > > > > > > AFAIU, ttwu_queue_remote() is called from ttwu_queue() without holding > > > the rq lock. So I'm wondering what prevents corruption of the wake_list > > > in this situation. > > > > I guess if it is on the wake_list, then the task's state is already > > RUNNING. Any other task can switch a task's state to RUNNING but only > > the task itself can switch it back to something else. If the task is on > > the wake_list, it's state is already RUNNING, but it has not run yet. > > That means any other wakeup will jump to the "goto out" and skip over > > the ttwu_queue() call. > > If my assumption is indeed the case, then these types of subtleties > really need comments in the code.
My understanding is that try_to_wake_up, by calling ttwu_queue(), is responsible for enqueuing the task into the wake_list. Inspection of try_to_wake_up() seems to show that the state of the task is set to TASK_WAKING by try_to_wake_up.
Then when dequeuing the task from the llist, ttwu_do_wakeup sets the task state to TASK_RUNNING.
Both TASK_WAKING and TASK_RUNNING mean that the try_to_wake_up check for if (!(p->state & state)), which is typically done against TASK_NORMAL, will skip the following ttwu_queue() for that task until it is set to TASK_INTERRUPTIBLE or TASK_UNINTERRUPTIBLE again.
So there should not be any double-enqueue AFAIU.
Thanks,
Mathieu
-- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com
| |