Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756098AbbDIU3S (ORCPT ); Thu, 9 Apr 2015 16:29:18 -0400 Received: from mail-am1on0083.outbound.protection.outlook.com ([157.56.112.83]:50365 "EHLO emea01-am1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1754214AbbDIU3R (ORCPT ); Thu, 9 Apr 2015 16:29:17 -0400 Authentication-Results: spf=fail (sender IP is 12.216.194.146) smtp.mailfrom=ezchip.com; infradead.org; dkim=none (message not signed) header.d=none; From: Chris Metcalf To: Thomas Gleixner CC: Chris Metcalf , Frederic Weisbecker , Don Zickus , , Peter Zijlstra Subject: [PATCH] smpboot: allow excluding cpus from the smpboot threads Date: Thu, 9 Apr 2015 16:29:01 -0400 Message-ID: <1428611341-27563-1-git-send-email-cmetcalf@ezchip.com> X-Mailer: git-send-email 2.1.2 In-Reply-To: References: X-EOPAttributedMessage: 0 X-Forefront-Antispam-Report: CIP:12.216.194.146;CTRY:US;IPV:NLI;EFV:NLI;BMV:1;SFV:NSPM;SFS:(10009020)(979002)(6009001)(339900001)(199003)(189002)(6806004)(50226001)(50466002)(229853001)(2950100001)(50986999)(19580405001)(106466001)(62966003)(86362001)(87936001)(92566002)(48376002)(76176999)(36756003)(46102003)(33646002)(106356001)(105606002)(85426001)(104016003)(47776003)(77156002)(42186005)(110136001)(19580395003)(9376004)(969003)(989001)(999001)(1009001)(1019001);DIR:OUT;SFP:1101;SCL:1;SRVR:VI1PR02MB0784;H:ld-1.internal.tilera.com;FPR:;SPF:Fail;MLV:ovrnspm;A:1;MX:1;PTR:InfoNoRecords;LANG:en; MIME-Version: 1.0 Content-Type: text/plain X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:VI1PR02MB0784; X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(5002010)(5005006);SRVR:VI1PR02MB0784;BCL:0;PCL:0;RULEID:;SRVR:VI1PR02MB0784; X-Forefront-PRVS: 0541031FF6 X-OriginatorOrg: ezchip.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 09 Apr 2015 20:29:11.3590 (UTC) X-MS-Exchange-CrossTenant-Id: 0fc16e0a-3cd3-4092-8b2f-0a42cff122c3 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=0fc16e0a-3cd3-4092-8b2f-0a42cff122c3;Ip=[12.216.194.146];Helo=[ld-1.internal.tilera.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR02MB0784 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4503 Lines: 122 This change allows some cores to be excluded from running the smp_hotplug_thread tasks. The motivating example for this is the watchdog threads, which by default we don't want to run on any enabled nohz_full cores. A new smp_hotplug_thread field is introduced, "valid_cpu", which is an optional pointer to a function that returns per-cpu whether or not the given smp_hotplug_thread should run on that core; the function is called when deciding whether to unpark the thread. If a change is made to which cpus are valid, the smpboot_repark_percpu_thread() function should be called and threads will be suitably parked and unparked. Signed-off-by: Chris Metcalf --- Thomas, how does this look? If this seems about right, I'll fold in your feedback and put out a patch set that includes the matching changes to the watchdog and, if Frederic will take it for the nohz queue to the timer tree, send it up that way. This is just compile-tested so far since I have to wrap up for the time being and head home. Final patch will actually be tested :-) I took Frederic's suggested patch from a 10,000 foot viewpoint and modified it to stick with the valid_cpu() callback approach. p.s. I think the smpboot_thread_schedule() declaration in linux/smpboot.h is dead; there doesn't seem to be a definition. include/linux/smpboot.h | 4 ++++ kernel/smpboot.c | 37 +++++++++++++++++++++++++++++++++---- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/include/linux/smpboot.h b/include/linux/smpboot.h index 13e929679550..7dedbf92420e 100644 --- a/include/linux/smpboot.h +++ b/include/linux/smpboot.h @@ -27,6 +27,8 @@ struct smpboot_thread_data; * @pre_unpark: Optional unpark function, called before the thread is * unparked (cpu online). This is not guaranteed to be * called on the target cpu of the thread. Careful! + * @valid_cpu: Optional function, called when unparking the threads, + * to limit the set of cpus on which threads are unparked. * @selfparking: Thread is not parked by the park function. * @thread_comm: The base name of the thread */ @@ -41,12 +43,14 @@ struct smp_hotplug_thread { void (*park)(unsigned int cpu); void (*unpark)(unsigned int cpu); void (*pre_unpark)(unsigned int cpu); + int (*valid_cpu)(unsigned int cpu); bool selfparking; const char *thread_comm; }; int smpboot_register_percpu_thread(struct smp_hotplug_thread *plug_thread); void smpboot_unregister_percpu_thread(struct smp_hotplug_thread *plug_thread); +void smpboot_repark_percpu_thread(struct smp_hotplug_thread *plug_thread); int smpboot_thread_schedule(void); #endif diff --git a/kernel/smpboot.c b/kernel/smpboot.c index 40190f28db35..c7dd768a4599 100644 --- a/kernel/smpboot.c +++ b/kernel/smpboot.c @@ -218,11 +218,13 @@ int smpboot_create_threads(unsigned int cpu) static void smpboot_unpark_thread(struct smp_hotplug_thread *ht, unsigned int cpu) { - struct task_struct *tsk = *per_cpu_ptr(ht->store, cpu); + if (!ht->valid_cpu || ht->valid_cpu(cpu)) { + struct task_struct *tsk = *per_cpu_ptr(ht->store, cpu); - if (ht->pre_unpark) - ht->pre_unpark(cpu); - kthread_unpark(tsk); + if (ht->pre_unpark) + ht->pre_unpark(cpu); + kthread_unpark(tsk); + } } void smpboot_unpark_threads(unsigned int cpu) @@ -314,3 +316,30 @@ void smpboot_unregister_percpu_thread(struct smp_hotplug_thread *plug_thread) put_online_cpus(); } EXPORT_SYMBOL_GPL(smpboot_unregister_percpu_thread); + +/** + * smpboot_repark_percpu_thread - Adjust which per_cpu hotplug threads stay parked + * @plug_thread: Hotplug thread descriptor + * + * After changing what the valid_cpu() callback will return, call this + * function to let appropriate threads park and unpark. + */ +void smpboot_repark_percpu_thread(struct smp_hotplug_thread *plug_thread) +{ + unsigned int cpu; + + if (!plug_thread->valid_cpu) + return; + + get_online_cpus(); + mutex_lock(&smpboot_threads_lock); + for_each_online_cpu(cpu) { + if (plug_thread->valid_cpu(cpu)) + smpboot_unpark_thread(plug_thread, cpu); + else + smpboot_park_thread(plug_thread, cpu); + } + mutex_unlock(&smpboot_threads_lock); + put_online_cpus(); +} +EXPORT_SYMBOL_GPL(smpboot_repark_percpu_thread); -- 2.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/