Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp403852pxb; Sat, 6 Mar 2021 03:45:58 -0800 (PST) X-Google-Smtp-Source: ABdhPJwjAKPtz1sIZaq1p7aRSy1tCFvNOerytm7hTbXEL5HvJwtAm53j8O7ZqQU4kZayEwJz/ET5 X-Received: by 2002:a05:6402:30a5:: with SMTP id df5mr13930849edb.24.1615031157855; Sat, 06 Mar 2021 03:45:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1615031157; cv=none; d=google.com; s=arc-20160816; b=nwEnB9x1oRmx027tQ3CWagPtrh6izqYxtNevV4MQOwVY+tfH5+FuveIOtEBC/v5y0G tg4wOa9wPiMPfagZLRLbOpy9E3rZwy6pdgNm1Vs1ReATGvbT1XtuL6VZotTIcF6IfKHw /QvIh3ZhX9tIhAB2z+TpuVHw2hJFQTN8lOe0wL+IjNsqGlGpLocq7l89pLP0RclDuEZG 0z9TLeoAUxzsvFcGEFgyEcNYaYDUTtRG+VEd+9+FFcAp0uE9pneq1Kl8ZEln5vQn5qdx WPrUqSfzoulDuRxnHA9vFgkeaXpieUMqRl4nCMDjJ2ny6r0bk9z0XcL9Jhl9NuOailL5 6ZQQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:robot-unsubscribe :robot-id:message-id:mime-version:references:in-reply-to:cc:subject :to:reply-to:sender:from:dkim-signature:dkim-signature:date; bh=JeaEYVhu+77EDVCDVK7k5q00t0U7QsQXoyYLwl8BYcA=; b=OnSFg7Q7oAgXk98tMnc3qgOzsP2zt90T6tEmT4lV1WFvNKlViqOiviy4NJZnXJ6Yxr wN9WNdvGmVQr3HgRiEOA1vkZpRafJommV/E3Jc3Kv9afVVTvcQl6wv0895CWtZ0RomHc jEf4SQyW/woZAixDaLpICqURBuipCzsUFPaCGR99pZ9JZi6I0BAMc3RBMf85GEFooJsQ GGP0nl5beEQtSUISX9FkWJ9qDc45BOGkQ9WExNcu2aTqwaJGqDfkKkgCu1jqt3CKyWFc x8wYoUQoYw0oXzvb7q2GkCqKNc2knSu6m2XoLIe0nZBo+ff3fQ9yMee4znnSCSf8Pwx3 x1Tg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b="4smvSPa/"; dkim=neutral (no key) header.i=@linutronix.de; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id kk8si3203345ejc.404.2021.03.06.03.45.35; Sat, 06 Mar 2021 03:45:57 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b="4smvSPa/"; dkim=neutral (no key) header.i=@linutronix.de; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231435AbhCFLnL (ORCPT + 99 others); Sat, 6 Mar 2021 06:43:11 -0500 Received: from Galois.linutronix.de ([193.142.43.55]:34280 "EHLO galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230426AbhCFLm1 (ORCPT ); Sat, 6 Mar 2021 06:42:27 -0500 Date: Sat, 06 Mar 2021 11:42:26 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1615030946; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=JeaEYVhu+77EDVCDVK7k5q00t0U7QsQXoyYLwl8BYcA=; b=4smvSPa/hqX2rKdyCapcCtfpuo+pub4Rcb0XbgQs4ufEnz0YdAujULaRMTVpjFHAqwMa0H 73tumFNbl6aAmLldFxf7zTgd3Nu1vTHQagRoe7cTvRwMgWknbrtvl2AEpz/i/ndeC05vwC mLhcH4gwO/mwJhFW0YCqPAHvnrWko+LRXBLg4PfQz/xqm8iKQtAbP+RSb2EuUuBieP1y91 aVdffRHEHi2zQDw0dtv0iYPVS7XaRKYnYYJ25bzJYgD3Uwhh9GFz2hfuAdT9pTDn4ClVA7 fq1Gea5oseqLDEMgdvzj+yAUaqhgZfrDUqmEiousKYR+7xWLFTOmBbPSuJRONg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1615030946; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=JeaEYVhu+77EDVCDVK7k5q00t0U7QsQXoyYLwl8BYcA=; b=R+EPeQfrGtfs6nG9wQ0JGzhLIETjXreJykGxGAouYomwYfB7xaV5EFmcL+Cqg/Odjcbbp4 Pvx2oAFXW/y7EtCw== From: "tip-bot2 for Peter Zijlstra" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: sched/core] sched: Fix migration_cpu_stop() requeueing Cc: stable@kernel.org, "Peter Zijlstra (Intel)" , Ingo Molnar , Valentin Schneider , x86@kernel.org, linux-kernel@vger.kernel.org In-Reply-To: <20210224131355.357743989@infradead.org> References: <20210224131355.357743989@infradead.org> MIME-Version: 1.0 Message-ID: <161503094617.398.15367885573032267808.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The following commit has been merged into the sched/core branch of tip: Commit-ID: 8a6edb5257e2a84720fe78cb179eca58ba76126f Gitweb: https://git.kernel.org/tip/8a6edb5257e2a84720fe78cb179eca58ba76126f Author: Peter Zijlstra AuthorDate: Sat, 13 Feb 2021 13:10:35 +01:00 Committer: Ingo Molnar CommitterDate: Sat, 06 Mar 2021 12:40:20 +01:00 sched: Fix migration_cpu_stop() requeueing When affine_move_task(p) is called on a running task @p, which is not otherwise already changing affinity, we'll first set p->migration_pending and then do: stop_one_cpu(cpu_of_rq(rq), migration_cpu_stop, &arg); This then gets us to migration_cpu_stop() running on the CPU that was previously running our victim task @p. If we find that our task is no longer on that runqueue (this can happen because of a concurrent migration due to load-balance etc.), then we'll end up at the: } else if (dest_cpu < 1 || pending) { branch. Which we'll take because we set pending earlier. Here we first check if the task @p has already satisfied the affinity constraints, if so we bail early [A]. Otherwise we'll reissue migration_cpu_stop() onto the CPU that is now hosting our task @p: stop_one_cpu_nowait(cpu_of(rq), migration_cpu_stop, &pending->arg, &pending->stop_work); Except, we've never initialized pending->arg, which will be all 0s. This then results in running migration_cpu_stop() on the next CPU with arg->p == NULL, which gives the by now obvious result of fireworks. The cure is to change affine_move_task() to always use pending->arg, furthermore we can use the exact same pattern as the SCA_MIGRATE_ENABLE case, since we'll block on the pending->done completion anyway, no point in adding yet another completion in stop_one_cpu(). This then gives a clear distinction between the two migration_cpu_stop() use cases: - sched_exec() / migrate_task_to() : arg->pending == NULL - affine_move_task() : arg->pending != NULL; And we can have it ignore p->migration_pending when !arg->pending. Any stop work from sched_exec() / migrate_task_to() is in addition to stop works from affine_move_task(), which will be sufficient to issue the completion. Fixes: 6d337eab041d ("sched: Fix migrate_disable() vs set_cpus_allowed_ptr()") Cc: stable@kernel.org Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Ingo Molnar Reviewed-by: Valentin Schneider Link: https://lkml.kernel.org/r/20210224131355.357743989@infradead.org --- kernel/sched/core.c | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index ca2bb62..79ddba5 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -1922,6 +1922,24 @@ static int migration_cpu_stop(void *data) rq_lock(rq, &rf); pending = p->migration_pending; + if (pending && !arg->pending) { + /* + * This happens from sched_exec() and migrate_task_to(), + * neither of them care about pending and just want a task to + * maybe move about. + * + * Even if there is a pending, we can ignore it, since + * affine_move_task() will have it's own stop_work's in flight + * which will manage the completion. + * + * Notably, pending doesn't need to match arg->pending. This can + * happen when tripple concurrent affine_move_task() first sets + * pending, then clears pending and eventually sets another + * pending. + */ + pending = NULL; + } + /* * If task_rq(p) != rq, it cannot be migrated here, because we're * holding rq->lock, if p->on_rq == 0 it cannot get enqueued because @@ -2194,10 +2212,6 @@ static int affine_move_task(struct rq *rq, struct task_struct *p, struct rq_flag int dest_cpu, unsigned int flags) { struct set_affinity_pending my_pending = { }, *pending = NULL; - struct migration_arg arg = { - .task = p, - .dest_cpu = dest_cpu, - }; bool complete = false; /* Can the task run on the task's current CPU? If so, we're done */ @@ -2235,6 +2249,12 @@ static int affine_move_task(struct rq *rq, struct task_struct *p, struct rq_flag /* Install the request */ refcount_set(&my_pending.refs, 1); init_completion(&my_pending.done); + my_pending.arg = (struct migration_arg) { + .task = p, + .dest_cpu = -1, /* any */ + .pending = &my_pending, + }; + p->migration_pending = &my_pending; } else { pending = p->migration_pending; @@ -2265,12 +2285,6 @@ static int affine_move_task(struct rq *rq, struct task_struct *p, struct rq_flag p->migration_flags &= ~MDF_PUSH; task_rq_unlock(rq, p, rf); - pending->arg = (struct migration_arg) { - .task = p, - .dest_cpu = -1, - .pending = pending, - }; - stop_one_cpu_nowait(cpu_of(rq), migration_cpu_stop, &pending->arg, &pending->stop_work); @@ -2283,8 +2297,11 @@ static int affine_move_task(struct rq *rq, struct task_struct *p, struct rq_flag * is_migration_disabled(p) checks to the stopper, which will * run on the same CPU as said p. */ + refcount_inc(&pending->refs); /* pending->{arg,stop_work} */ task_rq_unlock(rq, p, rf); - stop_one_cpu(cpu_of(rq), migration_cpu_stop, &arg); + + stop_one_cpu_nowait(cpu_of(rq), migration_cpu_stop, + &pending->arg, &pending->stop_work); } else {