All of lore.kernel.org
 help / color / mirror / Atom feed
From: zhouchengming <zhouchengming1@huawei.com>
To: Zhou Chengming <zhouchengming1@huawei.com>,
	<linux-kernel@vger.kernel.org>, <mingo@redhat.com>,
	<peterz@infradead.org>, <rostedt@goodmis.org>
Cc: <huawei.libin@huawei.com>
Subject: Re: [PATCH] sched/rt.c: pick and check task if double_lock_balance() unlock the rq
Date: Mon, 25 Sep 2017 19:53:13 +0800	[thread overview]
Message-ID: <59C8EE29.4070904@huawei.com> (raw)
In-Reply-To: <1505112709-102019-1-git-send-email-zhouchengming1@huawei.com>

ping...
Or it isn't a real problem ?

Thanks.

On 2017/9/11 14:51, Zhou Chengming wrote:
> push_rt_task() pick the first pushable task and find an eligible
> lowest_rq, then double_lock_balance(rq, lowest_rq). So if
> double_lock_balance() unlock the rq (when double_lock_balance() return 1),
> we have to check if this task is still on the rq.
>
> The problem is that the check conditions are not sufficient:
>
> if (unlikely(task_rq(task) != rq ||
> 	     !cpumask_test_cpu(lowest_rq->cpu,&task->cpus_allowed) ||
> 	     task_running(rq, task) ||
> 	     !rt_task(task) ||
> 	     !task_on_rq_queued(task))) {
>
> cpu2				cpu1			cpu0
> push_rt_task(rq1)
>    pick task_A on rq1
>    find rq0
>      double_lock_balance(rq1, rq0)
>        unlock(rq1)
> 				rq1 __schedule
> 				  pick task_A run
> 				task_A sleep (dequeued)
>        lock(rq0)
>        lock(rq1)
>      do_above_check(task_A)
>        task_rq(task_A) == rq1
>        cpus_allowed unchanged
>        task_running == false
>        rt_task(task_A) == true
> 							try_to_wake_up(task_A)
> 							  select_cpu = cpu3
> 							  enqueue(rq3, task_A)
> 							  task_A->on_rq = 1
>        task_on_rq_queued(task_A)
>      above_check passed, return rq0
>      ...
>      migrate task_A from rq1 to rq0
>
> So we can't rely on these checks of task_A to make sure the task_A is
> still on the rq1, even though we hold the rq1->lock. This patch will
> repick the first pushable task to be sure the task is still on the rq.
>
> Signed-off-by: Zhou Chengming<zhouchengming1@huawei.com>
> ---
>   kernel/sched/rt.c | 49 +++++++++++++++++++++++--------------------------
>   1 file changed, 23 insertions(+), 26 deletions(-)
>
> diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
> index 45caf93..787b721 100644
> --- a/kernel/sched/rt.c
> +++ b/kernel/sched/rt.c
> @@ -1703,6 +1703,26 @@ static int find_lowest_rq(struct task_struct *task)
>   	return -1;
>   }
>
> +static struct task_struct *pick_next_pushable_task(struct rq *rq)
> +{
> +	struct task_struct *p;
> +
> +	if (!has_pushable_tasks(rq))
> +		return NULL;
> +
> +	p = plist_first_entry(&rq->rt.pushable_tasks,
> +			      struct task_struct, pushable_tasks);
> +
> +	BUG_ON(rq->cpu != task_cpu(p));
> +	BUG_ON(task_current(rq, p));
> +	BUG_ON(p->nr_cpus_allowed<= 1);
> +
> +	BUG_ON(!task_on_rq_queued(p));
> +	BUG_ON(!rt_task(p));
> +
> +	return p;
> +}
> +
>   /* Will lock the rq it finds */
>   static struct rq *find_lock_lowest_rq(struct task_struct *task, struct rq *rq)
>   {
> @@ -1734,13 +1754,10 @@ static struct rq *find_lock_lowest_rq(struct task_struct *task, struct rq *rq)
>   			 * We had to unlock the run queue. In
>   			 * the mean time, task could have
>   			 * migrated already or had its affinity changed.
> -			 * Also make sure that it wasn't scheduled on its rq.
>   			 */
> -			if (unlikely(task_rq(task) != rq ||
> -				     !cpumask_test_cpu(lowest_rq->cpu,&task->cpus_allowed) ||
> -				     task_running(rq, task) ||
> -				     !rt_task(task) ||
> -				     !task_on_rq_queued(task))) {
> +			struct task_struct *next_task = pick_next_pushable_task(rq);
> +			if (unlikely(next_task != task ||
> +				     !cpumask_test_cpu(lowest_rq->cpu,&task->cpus_allowed))) {
>
>   				double_unlock_balance(rq, lowest_rq);
>   				lowest_rq = NULL;
> @@ -1760,26 +1777,6 @@ static struct rq *find_lock_lowest_rq(struct task_struct *task, struct rq *rq)
>   	return lowest_rq;
>   }
>
> -static struct task_struct *pick_next_pushable_task(struct rq *rq)
> -{
> -	struct task_struct *p;
> -
> -	if (!has_pushable_tasks(rq))
> -		return NULL;
> -
> -	p = plist_first_entry(&rq->rt.pushable_tasks,
> -			      struct task_struct, pushable_tasks);
> -
> -	BUG_ON(rq->cpu != task_cpu(p));
> -	BUG_ON(task_current(rq, p));
> -	BUG_ON(p->nr_cpus_allowed<= 1);
> -
> -	BUG_ON(!task_on_rq_queued(p));
> -	BUG_ON(!rt_task(p));
> -
> -	return p;
> -}
> -
>   /*
>    * If the current CPU has more than one RT task, see if the non
>    * running task can migrate over to a CPU that is running a task

  parent reply	other threads:[~2017-09-25 11:54 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-09-11  6:51 [PATCH] sched/rt.c: pick and check task if double_lock_balance() unlock the rq Zhou Chengming
2017-09-12  2:11 ` zhouchengming
2017-09-25 11:53 ` zhouchengming [this message]
2017-09-25 19:40 ` Steven Rostedt
2017-09-26  1:23   ` zhouchengming
2017-09-26  3:18     ` Steven Rostedt
2017-10-07  3:30       ` zhouchengming
2018-04-10 22:05 ` Steven Rostedt
2018-04-11 10:26   ` Peter Zijlstra
2018-04-12  8:54     ` Libin (Huawei)

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=59C8EE29.4070904@huawei.com \
    --to=zhouchengming1@huawei.com \
    --cc=huawei.libin@huawei.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.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 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.