Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1530810

[PATCH 04/22] idle/intel: Convert to hotplug state machine

From Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Newsgroups linux.kernel
Subject [PATCH 04/22] idle/intel: Convert to hotplug state machine
Date 2016-11-27 00:20 +0100
Message-ID <sHUqe-4EY-35@gated-at.bofh.it> (permalink)
References <sHUqd-4EY-3@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


Install the callbacks via the state machine and let the core invoke the
callbacks on the already online CPUs.

The two smp_call_function_single() invocations in intel_idle_cpu_init() have
been removed because intel_idle_cpu_init() is now invoked via the hotplug
callback which runs on the target CPU. The IRQ-off calling convention for
auto_demotion_disable() and c1e_promotion_disable() has not been preserved
because only those two modify the MSR during CPU intialization.

Cc: Len Brown <lenb@kernel.org>
Cc: linux-pm@vger.kernel.org
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 drivers/idle/intel_idle.c | 106 ++++++++++++++++++----------------------------
 1 file changed, 42 insertions(+), 64 deletions(-)

diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index f53b42a78186..d9631db1b4f5 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -98,8 +98,6 @@ static int intel_idle(struct cpuidle_device *dev,
 			struct cpuidle_driver *drv, int index);
 static void intel_idle_freeze(struct cpuidle_device *dev,
 			      struct cpuidle_driver *drv, int index);
-static int intel_idle_cpu_init(int cpu);
-
 static struct cpuidle_state *cpuidle_state_table;
 
 /*
@@ -907,50 +905,15 @@ static void intel_idle_freeze(struct cpuidle_device *dev,
 	mwait_idle_with_hints(eax, ecx);
 }
 
-static void __setup_broadcast_timer(void *arg)
+static void __setup_broadcast_timer(bool on)
 {
-	unsigned long on = (unsigned long)arg;
-
 	if (on)
 		tick_broadcast_enable();
 	else
 		tick_broadcast_disable();
 }
 
-static int cpu_hotplug_notify(struct notifier_block *n,
-			      unsigned long action, void *hcpu)
-{
-	int hotcpu = (unsigned long)hcpu;
-	struct cpuidle_device *dev;
-
-	switch (action & ~CPU_TASKS_FROZEN) {
-	case CPU_ONLINE:
-
-		if (lapic_timer_reliable_states != LAPIC_TIMER_ALWAYS_RELIABLE)
-			__setup_broadcast_timer((void *)true);
-
-		/*
-		 * Some systems can hotplug a cpu at runtime after
-		 * the kernel has booted, we have to initialize the
-		 * driver in this case
-		 */
-		dev = per_cpu_ptr(intel_idle_cpuidle_devices, hotcpu);
-		if (dev->registered)
-			break;
-
-		if (intel_idle_cpu_init(hotcpu))
-			return NOTIFY_BAD;
-
-		break;
-	}
-	return NOTIFY_OK;
-}
-
-static struct notifier_block cpu_hotplug_notifier = {
-	.notifier_call = cpu_hotplug_notify,
-};
-
-static void auto_demotion_disable(void *dummy)
+static void auto_demotion_disable(void)
 {
 	unsigned long long msr_bits;
 
@@ -958,7 +921,7 @@ static void auto_demotion_disable(void *dummy)
 	msr_bits &= ~(icpu->auto_demotion_disable_flags);
 	wrmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits);
 }
-static void c1e_promotion_disable(void *dummy)
+static void c1e_promotion_disable(void)
 {
 	unsigned long long msr_bits;
 
@@ -1372,12 +1335,11 @@ static void __init intel_idle_cpuidle_driver_init(void)
  * allocate, initialize, register cpuidle_devices
  * @cpu: cpu/core to initialize
  */
-static int intel_idle_cpu_init(int cpu)
+static int intel_idle_cpu_init(unsigned int cpu)
 {
 	struct cpuidle_device *dev;
 
 	dev = per_cpu_ptr(intel_idle_cpuidle_devices, cpu);
-
 	dev->cpu = cpu;
 
 	if (cpuidle_register_device(dev)) {
@@ -1386,17 +1348,38 @@ static int intel_idle_cpu_init(int cpu)
 	}
 
 	if (icpu->auto_demotion_disable_flags)
-		smp_call_function_single(cpu, auto_demotion_disable, NULL, 1);
+		auto_demotion_disable();
 
 	if (icpu->disable_promotion_to_c1e)
-		smp_call_function_single(cpu, c1e_promotion_disable, NULL, 1);
+		c1e_promotion_disable();
 
 	return 0;
 }
 
+static int intel_idle_cpu_online(unsigned int cpu)
+{
+	struct cpuidle_device *dev;
+
+	if (lapic_timer_reliable_states != LAPIC_TIMER_ALWAYS_RELIABLE)
+		__setup_broadcast_timer(true);
+
+	/*
+	 * Some systems can hotplug a cpu at runtime after
+	 * the kernel has booted, we have to initialize the
+	 * driver in this case
+	 */
+	dev = per_cpu_ptr(intel_idle_cpuidle_devices, cpu);
+	if (!dev->registered)
+		return intel_idle_cpu_init(cpu);
+
+	return 0;
+}
+
+static enum cpuhp_state hp_online;
+
 static int __init intel_idle_init(void)
 {
-	int retval, i;
+	int retval;
 
 	/* Do not load intel_idle at all for now if idle= is passed */
 	if (boot_option_idle_override != IDLE_NO_OVERRIDE)
@@ -1416,35 +1399,30 @@ static int __init intel_idle_init(void)
 		struct cpuidle_driver *drv = cpuidle_get_driver();
 		printk(KERN_DEBUG PREFIX "intel_idle yielding to %s",
 			drv ? drv->name : "none");
-		free_percpu(intel_idle_cpuidle_devices);
-		return retval;
+		goto init_driver_fail;
 	}
 
-	cpu_notifier_register_begin();
-
-	for_each_online_cpu(i) {
-		retval = intel_idle_cpu_init(i);
-		if (retval) {
-			intel_idle_cpuidle_devices_uninit();
-			cpu_notifier_register_done();
-			cpuidle_unregister_driver(&intel_idle_driver);
-			free_percpu(intel_idle_cpuidle_devices);
-			return retval;
-		}
-	}
-	__register_cpu_notifier(&cpu_hotplug_notifier);
-
 	if (boot_cpu_has(X86_FEATURE_ARAT))	/* Always Reliable APIC Timer */
 		lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE;
-	else
-		on_each_cpu(__setup_broadcast_timer, (void *)true, 1);
 
-	cpu_notifier_register_done();
+	retval = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "idle/intel:online",
+				   intel_idle_cpu_online, NULL);
+	if (retval < 0)
+		goto hp_setup_fail;
+	hp_online = retval;
 
 	pr_debug(PREFIX "lapic_timer_reliable_states 0x%x\n",
 		lapic_timer_reliable_states);
 
 	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);
 
-- 
2.10.2

Back to linux.kernel | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

cpu hotplug: convert more drivers (batch #6 and last) Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-27 00:20 +0100
  [PATCH 01/22] cpufreq/acpi-cpufreq: Convert to hotplug state machine Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-27 00:20 +0100
    Re: [PATCH 01/22] cpufreq/acpi-cpufreq: Convert to hotplug state  machine Viresh Kumar <viresh.kumar@linaro.org> - 2016-11-28 06:20 +0100
      Re: [PATCH 01/22] cpufreq/acpi-cpufreq: Convert to hotplug state  machine Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-28 10:50 +0100
        [PATCH 01/22 v2] cpufreq/acpi-cpufreq: Convert to hotplug state  machine Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-28 11:00 +0100
          Re: [PATCH 01/22 v2] cpufreq/acpi-cpufreq: Convert to hotplug state  machine Viresh Kumar <viresh.kumar@linaro.org> - 2016-11-28 11:00 +0100
          Re: [PATCH 01/22 v2] cpufreq/acpi-cpufreq: Convert to hotplug state machine "Rafael J. Wysocki" <rafael@kernel.org> - 2016-11-28 13:50 +0100
  [PATCH 13/22] iommu/vt-d: Convert to hotplug state machine Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-27 00:20 +0100
    [tip:smp/hotplug] iommu/vt-d: Convert to hotplug state machine tip-bot for Anna-Maria Gleixner <tipbot@zytor.com> - 2016-12-02 01:20 +0100
  [PATCH 11/22] mm/zswap: Convert dst-mem to hotplug state machine Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-27 00:20 +0100
    [tip:smp/hotplug] mm/zswap: Convert dst-mem to hotplug state  machine tip-bot for Sebastian Andrzej Siewior <tipbot@zytor.com> - 2016-12-02 01:20 +0100
  [PATCH 19/22] soc/fsl/qbman: Convert to hotplug state machine Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-27 00:20 +0100
    [tip:smp/hotplug] soc/fsl/qbman: Convert to hotplug state machine tip-bot for Sebastian Andrzej Siewior <tipbot@zytor.com> - 2016-12-02 01:20 +0100
  [PATCH 04/22] idle/intel: Convert to hotplug state machine Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-27 00:20 +0100
    Re: [PATCH 04/22] idle/intel: Convert to hotplug state machine Thomas Gleixner <tglx@linutronix.de> - 2016-11-28 18:40 +0100
      Re: [PATCH 04/22] idle/intel: Convert to hotplug state machine Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-29 10:50 +0100
        [PATCH 04/22 v2] idle/intel: Convert to hotplug state machine Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-29 11:00 +0100
  [PATCH 07/22] mm/vmstat: Drop get_online_cpus() from init_cpu_node_state/vmstat_cpu_dead() Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-27 00:20 +0100
    Re: [PATCH 07/22] mm/vmstat: Drop get_online_cpus() from  init_cpu_node_state/vmstat_cpu_dead() Michal Hocko <mhocko@kernel.org> - 2016-11-28 10:30 +0100
    [tip:smp/hotplug] mm/vmstat: Drop get_online_cpus() from  init_cpu_node_state/vmstat_cpu_dead() tip-bot for Sebastian Andrzej Siewior <tipbot@zytor.com> - 2016-12-02 01:20 +0100
  [PATCH 03/22] idle/intel: Remove superfluous SMP fuction call Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-27 00:20 +0100
  [PATCH 06/22] tracing/rb: Convert to hotplug state machine Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-27 00:20 +0100
    [tip:smp/hotplug] tracing/rb: Convert to hotplug state machine tip-bot for Sebastian Andrzej Siewior <tipbot@zytor.com> - 2016-12-02 01:20 +0100
      [linux-next] tracing/rb: NULL pointer dereference at  trace_rb_cpu_prepare() Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> - 2016-12-07 12:20 +0100
        [PATCH] tracing/rb: init the CPU mask on allocation Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-12-07 14:40 +0100
          [tip:smp/hotplug] tracing/rb: Init the CPU mask on allocation tip-bot for Sebastian Andrzej Siewior <tipbot@zytor.com> - 2016-12-07 14:50 +0100
          Re: [PATCH] tracing/rb: init the CPU mask on allocation Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> - 2016-12-07 15:40 +0100
  [PATCH 16/22] arm64/cpuinfo: Convert to hotplug state machine Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-27 00:20 +0100
    Re: [PATCH 16/22] arm64/cpuinfo: Convert to hotplug state machine Suzuki K Poulose <suzuki.poulose@arm.com> - 2016-11-29 18:30 +0100
    [tip:smp/hotplug] arm64/cpuinfo: Convert to hotplug state machine tip-bot for Anna-Maria Gleixner <tipbot@zytor.com> - 2016-12-02 01:20 +0100
  [PATCH 22/22] Remove obsolete cpu hotplug register / unregister functions Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-27 00:20 +0100
  [PATCH 18/22] zram: Convert to hotplug state machine Sebastian Andrzej Siewior <bigeasy@linutronix.de> - 2016-11-27 00:20 +0100
    [tip:smp/hotplug] zram: Convert to hotplug state machine tip-bot for Anna-Maria Gleixner <tipbot@zytor.com> - 2016-12-02 01:20 +0100

csiph-web