From patchwork Wed Oct 27 08:22:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhang, Rui" X-Patchwork-Id: 12586565 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 983D1C433FE for ; Wed, 27 Oct 2021 08:07:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7CE74610C7 for ; Wed, 27 Oct 2021 08:07:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239150AbhJ0IJn (ORCPT ); Wed, 27 Oct 2021 04:09:43 -0400 Received: from mga11.intel.com ([192.55.52.93]:5206 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235817AbhJ0IJl (ORCPT ); Wed, 27 Oct 2021 04:09:41 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10149"; a="227559464" X-IronPort-AV: E=Sophos;i="5.87,186,1631602800"; d="scan'208";a="227559464" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Oct 2021 01:07:16 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.87,186,1631602800"; d="scan'208";a="486559014" Received: from power-sh.sh.intel.com ([10.239.183.1]) by orsmga007.jf.intel.com with ESMTP; 27 Oct 2021 01:07:14 -0700 From: Zhang Rui To: linux-pm@vger.kernel.org Cc: rjw@rjwysocki.net, artem.bityutskiy@linux.intel.com, rui.zhang@intel.com Subject: [PATCH 1/3] intel_idle: cleanup code for handling with cpuidle framework Date: Wed, 27 Oct 2021 16:22:35 +0800 Message-Id: <20211027082237.26759-1-rui.zhang@intel.com> X-Mailer: git-send-email 2.17.1 Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Introduce two helper functions and move all the code that deals with the cpuidle framework into them. No functional change in this patch. Signed-off-by: Zhang Rui --- drivers/idle/intel_idle.c | 67 ++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index e6c543b5ee1d..ae9d8c43e6a5 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -1677,14 +1677,46 @@ static int intel_idle_cpu_online(unsigned int cpu) } /** - * intel_idle_cpuidle_devices_uninit - Unregister all cpuidle devices. + * intel_idle_cpuidle_unregister - unregister from cpuidle framework */ -static void __init intel_idle_cpuidle_devices_uninit(void) +static void __init intel_idle_cpuidle_unregister(struct cpuidle_driver *drv) { int i; for_each_online_cpu(i) cpuidle_unregister_device(per_cpu_ptr(intel_idle_cpuidle_devices, i)); + cpuidle_unregister_driver(drv); + free_percpu(intel_idle_cpuidle_devices); +} + +/** + * intel_idle_cpuidle_register - register to cpuidle framework + */ +static int __init intel_idle_cpuidle_register(struct cpuidle_driver *drv) +{ + int retval; + + intel_idle_cpuidle_devices = alloc_percpu(struct cpuidle_device); + if (!intel_idle_cpuidle_devices) + return -ENOMEM; + + retval = cpuidle_register_driver(drv); + if (retval) { + struct cpuidle_driver *drv = cpuidle_get_driver(); + + printk(KERN_DEBUG pr_fmt("intel_idle yielding to %s\n"), + drv ? drv->name : "none"); + free_percpu(intel_idle_cpuidle_devices); + return retval; + } + + retval = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "idle/intel:online", + intel_idle_cpu_online, NULL); + if (retval < 0) { + intel_idle_cpuidle_unregister(drv); + return retval; + } + return 0; } static int __init intel_idle_init(void) @@ -1740,37 +1772,14 @@ static int __init intel_idle_init(void) pr_debug("v" INTEL_IDLE_VERSION " model 0x%X\n", boot_cpu_data.x86_model); - intel_idle_cpuidle_devices = alloc_percpu(struct cpuidle_device); - if (!intel_idle_cpuidle_devices) - return -ENOMEM; - intel_idle_cpuidle_driver_init(&intel_idle_driver); - retval = cpuidle_register_driver(&intel_idle_driver); - if (retval) { - struct cpuidle_driver *drv = cpuidle_get_driver(); - printk(KERN_DEBUG pr_fmt("intel_idle yielding to %s\n"), - drv ? drv->name : "none"); - goto init_driver_fail; - } - - retval = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "idle/intel:online", - intel_idle_cpu_online, NULL); - if (retval < 0) - goto hp_setup_fail; - - pr_debug("Local APIC timer is reliable in %s\n", - boot_cpu_has(X86_FEATURE_ARAT) ? "all C-states" : "C1"); + retval = intel_idle_cpuidle_register(&intel_idle_driver); + if (!retval) + pr_debug("Local APIC timer is reliable in %s\n", + boot_cpu_has(X86_FEATURE_ARAT) ? "all C-states" : "C1"); - return 0; - -hp_setup_fail: - intel_idle_cpuidle_devices_uninit(); - cpuidle_unregister_driver(&intel_idle_driver); -init_driver_fail: - free_percpu(intel_idle_cpuidle_devices); return retval; - } device_initcall(intel_idle_init); From patchwork Wed Oct 27 08:22:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhang, Rui" X-Patchwork-Id: 12586563 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 58F7FC433F5 for ; Wed, 27 Oct 2021 08:07:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3C2B4610C7 for ; Wed, 27 Oct 2021 08:07:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239260AbhJ0IJn (ORCPT ); Wed, 27 Oct 2021 04:09:43 -0400 Received: from mga11.intel.com ([192.55.52.93]:5207 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239150AbhJ0IJm (ORCPT ); Wed, 27 Oct 2021 04:09:42 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10149"; a="227559470" X-IronPort-AV: E=Sophos;i="5.87,186,1631602800"; d="scan'208";a="227559470" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Oct 2021 01:07:17 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.87,186,1631602800"; d="scan'208";a="486559030" Received: from power-sh.sh.intel.com ([10.239.183.1]) by orsmga007.jf.intel.com with ESMTP; 27 Oct 2021 01:07:16 -0700 From: Zhang Rui To: linux-pm@vger.kernel.org Cc: rjw@rjwysocki.net, artem.bityutskiy@linux.intel.com, rui.zhang@intel.com Subject: [PATCH 2/3] intel_idle: cleanup cpuhotplug setup Date: Wed, 27 Oct 2021 16:22:36 +0800 Message-Id: <20211027082237.26759-2-rui.zhang@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211027082237.26759-1-rui.zhang@intel.com> References: <20211027082237.26759-1-rui.zhang@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Only limited number of CPUHP_AP_ONLINE_DYN callbacks can be registered, thus cpuhp_remove_state() should be invoked to release the resource when it is not used. Fixes: fb1013a01673 ("intel_idle: Convert to hotplug state machine") Signed-off-by: Zhang Rui --- drivers/idle/intel_idle.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index ae9d8c43e6a5..e7f2a5f85bf9 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -1676,6 +1676,8 @@ static int intel_idle_cpu_online(unsigned int cpu) return 0; } +static enum cpuhp_state intel_idle_cpuhp_state; + /** * intel_idle_cpuidle_unregister - unregister from cpuidle framework */ @@ -1683,6 +1685,8 @@ static void __init intel_idle_cpuidle_unregister(struct cpuidle_driver *drv) { int i; + if (intel_idle_cpuhp_state > 0) + cpuhp_remove_state(intel_idle_cpuhp_state); for_each_online_cpu(i) cpuidle_unregister_device(per_cpu_ptr(intel_idle_cpuidle_devices, i)); cpuidle_unregister_driver(drv); @@ -1710,11 +1714,11 @@ static int __init intel_idle_cpuidle_register(struct cpuidle_driver *drv) return retval; } - retval = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "idle/intel:online", - intel_idle_cpu_online, NULL); - if (retval < 0) { + intel_idle_cpuhp_state = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, + "idle/intel:online", intel_idle_cpu_online, NULL); + if (intel_idle_cpuhp_state < 0) { intel_idle_cpuidle_unregister(drv); - return retval; + return intel_idle_cpuhp_state; } return 0; } From patchwork Wed Oct 27 08:22:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhang, Rui" X-Patchwork-Id: 12586567 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B0673C4332F for ; Wed, 27 Oct 2021 08:07:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9932C610C7 for ; Wed, 27 Oct 2021 08:07:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239264AbhJ0IJo (ORCPT ); Wed, 27 Oct 2021 04:09:44 -0400 Received: from mga11.intel.com ([192.55.52.93]:5208 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235817AbhJ0IJo (ORCPT ); Wed, 27 Oct 2021 04:09:44 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10149"; a="227559474" X-IronPort-AV: E=Sophos;i="5.87,186,1631602800"; d="scan'208";a="227559474" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Oct 2021 01:07:19 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.87,186,1631602800"; d="scan'208";a="486559047" Received: from power-sh.sh.intel.com ([10.239.183.1]) by orsmga007.jf.intel.com with ESMTP; 27 Oct 2021 01:07:17 -0700 From: Zhang Rui To: linux-pm@vger.kernel.org Cc: rjw@rjwysocki.net, artem.bityutskiy@linux.intel.com, rui.zhang@intel.com Subject: [PATCH 3/3] intel_idle: fix cpuidle_device unregistration Date: Wed, 27 Oct 2021 16:22:37 +0800 Message-Id: <20211027082237.26759-3-rui.zhang@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211027082237.26759-1-rui.zhang@intel.com> References: <20211027082237.26759-1-rui.zhang@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org cpuidle_device is allocated as percpu data, and it is registered for every CPU that has ever been onlined. When unregistering, checking current online CPUs is not sufficient, because some cpu may be offlined later with its cpuidle_device registered. Fix this by using for_each_present_cpu() instead, and unregistering all the cpuidle_devices that have been registered. Signed-off-by: Zhang Rui --- drivers/idle/intel_idle.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index e7f2a5f85bf9..9e916e2adc89 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -1687,8 +1687,13 @@ static void __init intel_idle_cpuidle_unregister(struct cpuidle_driver *drv) if (intel_idle_cpuhp_state > 0) cpuhp_remove_state(intel_idle_cpuhp_state); - for_each_online_cpu(i) - cpuidle_unregister_device(per_cpu_ptr(intel_idle_cpuidle_devices, i)); + for_each_present_cpu(i) { + struct cpuidle_device *dev; + + dev = per_cpu_ptr(intel_idle_cpuidle_devices, i); + if (dev->registered) + cpuidle_unregister_device(dev); + } cpuidle_unregister_driver(drv); free_percpu(intel_idle_cpuidle_devices); }