From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932362AbcBWVzw (ORCPT ); Tue, 23 Feb 2016 16:55:52 -0500 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:41665 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755578AbcBWVo4 (ORCPT ); Tue, 23 Feb 2016 16:44:56 -0500 Content-Type: text/plain; charset="UTF-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 From: Ben Hutchings To: linux-kernel@vger.kernel.org, stable@vger.kernel.org CC: akpm@linux-foundation.org, "Byungchul Park" , "Mike Galbraith" , "Peter Zijlstra" , "Willy Tarreau" Date: Tue, 23 Feb 2016 21:42:03 +0000 Message-ID: X-Mailer: LinuxStableQueue (scripts by bwh) Subject: [PATCH 3.2 67/67] sched: fix __sched_setscheduler() vs load balancing race In-Reply-To: X-SA-Exim-Connect-IP: 92.40.248.141 X-SA-Exim-Mail-From: ben@decadent.org.uk X-SA-Exim-Scanned: No (on shadbolt.decadent.org.uk); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.2.78-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Mike Galbraith __sched_setscheduler() may release rq->lock in pull_rt_task() as a task is being changed rt -> fair class. load balancing may sneak in, move the task behind __sched_setscheduler()'s back, which explodes in switched_to_fair() when the passed but no longer valid rq is used. Tell can_migrate_task() to say no if ->pi_lock is held. @stable: Kernels that predate SCHED_DEADLINE can use this simple (and tested) check in lieu of backport of the full 18 patch mainline treatment. Signed-off-by: Mike Galbraith [bwh: Backported to 3.2: - Adjust numbering in the comment - Adjust filename] Signed-off-by: Ben Hutchings Cc: Byungchul Park Cc: Peter Zijlstra Cc: Willy Tarreau --- kernel/sched/fair.c | 9 +++++++++ 1 file changed, 9 insertions(+) --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -2791,6 +2791,7 @@ int can_migrate_task(struct task_struct * 1) running (obviously), or * 2) cannot be migrated to this CPU due to cpus_allowed, or * 3) are cache-hot on their current CPU. + * 4) p->pi_lock is held. */ if (!cpumask_test_cpu(this_cpu, tsk_cpus_allowed(p))) { schedstat_inc(p, se.statistics.nr_failed_migrations_affine); @@ -2804,6 +2805,14 @@ int can_migrate_task(struct task_struct } /* + * rt -> fair class change may be in progress. If we sneak in should + * double_lock_balance() release rq->lock, and move the task, we will + * cause switched_to_fair() to meet a passed but no longer valid rq. + */ + if (raw_spin_is_locked(&p->pi_lock)) + return 0; + + /* * Aggressive migration if: * 1) task is cache cold, or * 2) too many balance attempts have failed.