linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/20] clockevents_notify() removal
@ 2015-04-01 22:02 Rafael J. Wysocki
  2015-04-01 22:03 ` [PATCH 01/20] clockevents: Provide explicit broadcast control functions Rafael J. Wysocki
                   ` (20 more replies)
  0 siblings, 21 replies; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-01 22:02 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Thomas Gleixner, Ingo Molnar, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List

Hi,

This is the next batch of patches from Thomas that remove clockevents_notify().

I've reordered the set (to put more stratightforward things to the front) and
rebased it on top of the timers material currently queued up for 4.1.

This series in based on the bleeding-edge branch of the linux-pm tree (which
for all practical purposes is my linux-next branch with timers/core from tip
merged into it).

Please let me know how to proceed with these.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 01/20] clockevents: Provide explicit broadcast control functions
  2015-04-01 22:02 [PATCH 00/20] clockevents_notify() removal Rafael J. Wysocki
@ 2015-04-01 22:03 ` Rafael J. Wysocki
  2015-04-01 22:04 ` [PATCH 02/20] x86, amd_idle: Use explicit broadcast control function Rafael J. Wysocki
                   ` (19 subsequent siblings)
  20 siblings, 0 replies; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-01 22:03 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Thomas Gleixner, Ingo Molnar, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List, Tony Lindgren,
	Len Brown, Daniel Lezcano

From: Thomas Gleixner <tglx@linutronix.de>

clockevents_notify() is a leftover from the early design of the
clockevents facility. It's really not a notification mechanism, it's a
multiplex call. We are way better off to have explicit calls instead of this
monstrosity.

Split out the broadcast control into a separate function and provide
inline helpers. Switch clockevents_notify() over. This will go away
once all callers are converted.

This also gets rid of the nested locking of clockevents_lock and
broadcast_lock. The broadcast control functions do not require
clockevents_lock. Only the managing functions
(setup/shutdown/suspend/resume of the broadcast device require 
clockevents_lock.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Tony Lindgren <tony@atomide.com>
Cc: Len Brown <lenb@kernel.org>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 include/linux/tick.h         |   25 +++++++++++++++++
 kernel/time/clockevents.c    |    6 +++-
 kernel/time/tick-broadcast.c |   62 ++++++++++++++++++-------------------------
 kernel/time/tick-internal.h  |    2 -
 4 files changed, 57 insertions(+), 38 deletions(-)

Index: linux-pm/include/linux/tick.h
===================================================================
--- linux-pm.orig/include/linux/tick.h
+++ linux-pm/include/linux/tick.h
@@ -36,6 +36,31 @@ extern void tick_irq_enter(void);
 static inline void tick_irq_enter(void) { }
 #endif
 
+enum tick_broadcast_mode {
+	TICK_BROADCAST_OFF,
+	TICK_BROADCAST_ON,
+	TICK_BROADCAST_FORCE,
+};
+
+#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
+extern void tick_broadcast_control(enum tick_broadcast_mode mode);
+#else
+static inline void tick_broadcast_control(enum tick_broadcast_mode mode) { }
+#endif /* BROADCAST */
+
+static inline void tick_broadcast_enable(void)
+{
+	tick_broadcast_control(TICK_BROADCAST_ON);
+}
+static inline void tick_broadcast_disable(void)
+{
+	tick_broadcast_control(TICK_BROADCAST_OFF);
+}
+static inline void tick_broadcast_force(void)
+{
+	tick_broadcast_control(TICK_BROADCAST_FORCE);
+}
+
 #ifdef CONFIG_NO_HZ_COMMON
 extern int tick_nohz_tick_stopped(void);
 extern void tick_nohz_idle_enter(void);
Index: linux-pm/kernel/time/clockevents.c
===================================================================
--- linux-pm.orig/kernel/time/clockevents.c
+++ linux-pm/kernel/time/clockevents.c
@@ -656,9 +656,13 @@ int clockevents_notify(unsigned long rea
 
 	switch (reason) {
 	case CLOCK_EVT_NOTIFY_BROADCAST_ON:
+		tick_broadcast_enable();
+		break;
 	case CLOCK_EVT_NOTIFY_BROADCAST_OFF:
+		tick_broadcast_disable();
+		break;
 	case CLOCK_EVT_NOTIFY_BROADCAST_FORCE:
-		tick_broadcast_on_off(reason, arg);
+		tick_broadcast_force();
 		break;
 
 	case CLOCK_EVT_NOTIFY_BROADCAST_ENTER:
Index: linux-pm/kernel/time/tick-broadcast.c
===================================================================
--- linux-pm.orig/kernel/time/tick-broadcast.c
+++ linux-pm/kernel/time/tick-broadcast.c
@@ -33,7 +33,7 @@ static cpumask_var_t tick_broadcast_mask
 static cpumask_var_t tick_broadcast_on;
 static cpumask_var_t tmpmask;
 static DEFINE_RAW_SPINLOCK(tick_broadcast_lock);
-static int tick_broadcast_force;
+static int tick_broadcast_forced;
 
 #ifdef CONFIG_TICK_ONESHOT
 static void tick_broadcast_clear_oneshot(int cpu);
@@ -326,49 +326,54 @@ unlock:
 	raw_spin_unlock(&tick_broadcast_lock);
 }
 
-/*
- * Powerstate information: The system enters/leaves a state, where
- * affected devices might stop
+/**
+ * tick_broadcast_control - Enable/disable or force broadcast mode
+ * @mode:	The selected broadcast mode
+ *
+ * Called when the system enters a state where affected tick devices
+ * might stop. Note: TICK_BROADCAST_FORCE cannot be undone.
+ *
+ * Called with interrupts disabled, so clockevents_lock is not
+ * required here because the local clock event device cannot go away
+ * under us.
  */
-static void tick_do_broadcast_on_off(unsigned long *reason)
+void tick_broadcast_control(enum tick_broadcast_mode mode)
 {
 	struct clock_event_device *bc, *dev;
 	struct tick_device *td;
-	unsigned long flags;
 	int cpu, bc_stopped;
 
-	raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
-
-	cpu = smp_processor_id();
-	td = &per_cpu(tick_cpu_device, cpu);
+	td = this_cpu_ptr(&tick_cpu_device);
 	dev = td->evtdev;
-	bc = tick_broadcast_device.evtdev;
 
 	/*
 	 * Is the device not affected by the powerstate ?
 	 */
 	if (!dev || !(dev->features & CLOCK_EVT_FEAT_C3STOP))
-		goto out;
+		return;
 
 	if (!tick_device_is_functional(dev))
-		goto out;
+		return;
 
+	raw_spin_lock(&tick_broadcast_lock);
+	cpu = smp_processor_id();
+	bc = tick_broadcast_device.evtdev;
 	bc_stopped = cpumask_empty(tick_broadcast_mask);
 
-	switch (*reason) {
-	case CLOCK_EVT_NOTIFY_BROADCAST_ON:
-	case CLOCK_EVT_NOTIFY_BROADCAST_FORCE:
+	switch (mode) {
+	case TICK_BROADCAST_FORCE:
+		tick_broadcast_forced = 1;
+	case TICK_BROADCAST_ON:
 		cpumask_set_cpu(cpu, tick_broadcast_on);
 		if (!cpumask_test_and_set_cpu(cpu, tick_broadcast_mask)) {
 			if (tick_broadcast_device.mode ==
 			    TICKDEV_MODE_PERIODIC)
 				clockevents_shutdown(dev);
 		}
-		if (*reason == CLOCK_EVT_NOTIFY_BROADCAST_FORCE)
-			tick_broadcast_force = 1;
 		break;
-	case CLOCK_EVT_NOTIFY_BROADCAST_OFF:
-		if (tick_broadcast_force)
+
+	case TICK_BROADCAST_OFF:
+		if (tick_broadcast_forced)
 			break;
 		cpumask_clear_cpu(cpu, tick_broadcast_on);
 		if (!tick_device_is_functional(dev))
@@ -390,22 +395,9 @@ static void tick_do_broadcast_on_off(uns
 		else
 			tick_broadcast_setup_oneshot(bc);
 	}
-out:
-	raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
-}
-
-/*
- * Powerstate information: The system enters/leaves a state, where
- * affected devices might stop.
- */
-void tick_broadcast_on_off(unsigned long reason, int *oncpu)
-{
-	if (!cpumask_test_cpu(*oncpu, cpu_online_mask))
-		printk(KERN_ERR "tick-broadcast: ignoring broadcast for "
-		       "offline CPU #%d\n", *oncpu);
-	else
-		tick_do_broadcast_on_off(&reason);
+	raw_spin_unlock(&tick_broadcast_lock);
 }
+EXPORT_SYMBOL_GPL(tick_broadcast_control);
 
 /*
  * Set the periodic handler depending on broadcast on/off
Index: linux-pm/kernel/time/tick-internal.h
===================================================================
--- linux-pm.orig/kernel/time/tick-internal.h
+++ linux-pm/kernel/time/tick-internal.h
@@ -85,7 +85,6 @@ static inline int tick_check_oneshot_cha
 extern int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu);
 extern void tick_install_broadcast_device(struct clock_event_device *dev);
 extern int tick_is_broadcast_device(struct clock_event_device *dev);
-extern void tick_broadcast_on_off(unsigned long reason, int *oncpu);
 extern void tick_shutdown_broadcast(unsigned int *cpup);
 extern void tick_suspend_broadcast(void);
 extern void tick_resume_broadcast(void);
@@ -100,7 +99,6 @@ static inline void tick_install_broadcas
 static inline int tick_is_broadcast_device(struct clock_event_device *dev) { return 0; }
 static inline int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu) { return 0; }
 static inline void tick_do_periodic_broadcast(struct clock_event_device *d) { }
-static inline void tick_broadcast_on_off(unsigned long reason, int *oncpu) { }
 static inline void tick_shutdown_broadcast(unsigned int *cpup) { }
 static inline void tick_suspend_broadcast(void) { }
 static inline void tick_resume_broadcast(void) { }


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 02/20] x86, amd_idle: Use explicit broadcast control function
  2015-04-01 22:02 [PATCH 00/20] clockevents_notify() removal Rafael J. Wysocki
  2015-04-01 22:03 ` [PATCH 01/20] clockevents: Provide explicit broadcast control functions Rafael J. Wysocki
@ 2015-04-01 22:04 ` Rafael J. Wysocki
  2015-04-01 22:05 ` [PATCH 03/20] ACPI / PAD: " Rafael J. Wysocki
                   ` (18 subsequent siblings)
  20 siblings, 0 replies; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-01 22:04 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Thomas Gleixner, Ingo Molnar, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List

From: Thomas Gleixner <tglx@linutronix.de>

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 arch/x86/kernel/process.c |    9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

Index: linux-pm/arch/x86/kernel/process.c
===================================================================
--- linux-pm.orig/arch/x86/kernel/process.c
+++ linux-pm/arch/x86/kernel/process.c
@@ -9,7 +9,7 @@
 #include <linux/sched.h>
 #include <linux/module.h>
 #include <linux/pm.h>
-#include <linux/clockchips.h>
+#include <linux/tick.h>
 #include <linux/random.h>
 #include <linux/user-return-notifier.h>
 #include <linux/dmi.h>
@@ -377,11 +377,8 @@ static void amd_e400_idle(void)
 
 		if (!cpumask_test_cpu(cpu, amd_e400_c1e_mask)) {
 			cpumask_set_cpu(cpu, amd_e400_c1e_mask);
-			/*
-			 * Force broadcast so ACPI can not interfere.
-			 */
-			clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_FORCE,
-					   &cpu);
+			/* Force broadcast so ACPI can not interfere. */
+			tick_broadcast_force();
 			pr_info("Switch to broadcast mode on CPU%d\n", cpu);
 		}
 		clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 03/20] ACPI / PAD: Use explicit broadcast control function
  2015-04-01 22:02 [PATCH 00/20] clockevents_notify() removal Rafael J. Wysocki
  2015-04-01 22:03 ` [PATCH 01/20] clockevents: Provide explicit broadcast control functions Rafael J. Wysocki
  2015-04-01 22:04 ` [PATCH 02/20] x86, amd_idle: Use explicit broadcast control function Rafael J. Wysocki
@ 2015-04-01 22:05 ` Rafael J. Wysocki
  2015-04-01 22:06 ` [PATCH 04/20] ACPI / processor: " Rafael J. Wysocki
                   ` (17 subsequent siblings)
  20 siblings, 0 replies; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-01 22:05 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Thomas Gleixner, Ingo Molnar, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List, Len Brown

From: Thomas Gleixner <tglx@linutronix.de>

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Len Brown <lenb@kernel.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/acpi_pad.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

Index: linux-pm/drivers/acpi/acpi_pad.c
===================================================================
--- linux-pm.orig/drivers/acpi/acpi_pad.c
+++ linux-pm/drivers/acpi/acpi_pad.c
@@ -26,7 +26,7 @@
 #include <linux/kthread.h>
 #include <linux/freezer.h>
 #include <linux/cpu.h>
-#include <linux/clockchips.h>
+#include <linux/tick.h>
 #include <linux/slab.h>
 #include <linux/acpi.h>
 #include <asm/mwait.h>
@@ -172,9 +172,8 @@ static int power_saving_thread(void *dat
 				mark_tsc_unstable("TSC halts in idle");
 				tsc_marked_unstable = 1;
 			}
-			clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu);
-
 			local_irq_disable();
+			tick_broadcast_enable();
 			cpu = smp_processor_id();
 			clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
 			stop_critical_timings();


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 04/20] ACPI / processor: Use explicit broadcast control function
  2015-04-01 22:02 [PATCH 00/20] clockevents_notify() removal Rafael J. Wysocki
                   ` (2 preceding siblings ...)
  2015-04-01 22:05 ` [PATCH 03/20] ACPI / PAD: " Rafael J. Wysocki
@ 2015-04-01 22:06 ` Rafael J. Wysocki
  2015-04-01 22:07 ` [PATCH 05/20] cpuidle: " Rafael J. Wysocki
                   ` (16 subsequent siblings)
  20 siblings, 0 replies; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-01 22:06 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Thomas Gleixner, Ingo Molnar, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List

From: Thomas Gleixner <tglx@linutronix.de>

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/processor_idle.c |   11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

Index: linux-pm/drivers/acpi/processor_idle.c
===================================================================
--- linux-pm.orig/drivers/acpi/processor_idle.c
+++ linux-pm/drivers/acpi/processor_idle.c
@@ -32,7 +32,7 @@
 #include <linux/acpi.h>
 #include <linux/dmi.h>
 #include <linux/sched.h>       /* need_resched() */
-#include <linux/clockchips.h>
+#include <linux/tick.h>
 #include <linux/cpuidle.h>
 #include <linux/syscore_ops.h>
 #include <acpi/processor.h>
@@ -157,12 +157,11 @@ static void lapic_timer_check_state(int
 static void __lapic_timer_propagate_broadcast(void *arg)
 {
 	struct acpi_processor *pr = (struct acpi_processor *) arg;
-	unsigned long reason;
 
-	reason = pr->power.timer_broadcast_on_state < INT_MAX ?
-		CLOCK_EVT_NOTIFY_BROADCAST_ON : CLOCK_EVT_NOTIFY_BROADCAST_OFF;
-
-	clockevents_notify(reason, &pr->id);
+	if (pr->power.timer_broadcast_on_state < INT_MAX)
+		tick_broadcast_enable();
+	else
+		tick_broadcast_disable();
 }
 
 static void lapic_timer_propagate_broadcast(struct acpi_processor *pr)


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 05/20] cpuidle: Use explicit broadcast control function
  2015-04-01 22:02 [PATCH 00/20] clockevents_notify() removal Rafael J. Wysocki
                   ` (3 preceding siblings ...)
  2015-04-01 22:06 ` [PATCH 04/20] ACPI / processor: " Rafael J. Wysocki
@ 2015-04-01 22:07 ` Rafael J. Wysocki
  2015-04-01 22:09 ` [PATCH 06/20] intel_idle: " Rafael J. Wysocki
                   ` (15 subsequent siblings)
  20 siblings, 0 replies; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-01 22:07 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Thomas Gleixner, Ingo Molnar, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List,
	Daniel Lezcano

From: Thomas Gleixner <tglx@linutronix.de>

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/cpuidle/driver.c |   25 ++++++++++++-------------
 1 file changed, 12 insertions(+), 13 deletions(-)

Index: linux-pm/drivers/cpuidle/driver.c
===================================================================
--- linux-pm.orig/drivers/cpuidle/driver.c
+++ linux-pm/drivers/cpuidle/driver.c
@@ -13,7 +13,7 @@
 #include <linux/sched.h>
 #include <linux/cpuidle.h>
 #include <linux/cpumask.h>
-#include <linux/clockchips.h>
+#include <linux/tick.h>
 
 #include "cpuidle.h"
 
@@ -130,21 +130,20 @@ static inline void __cpuidle_unset_drive
 #endif
 
 /**
- * cpuidle_setup_broadcast_timer - enable/disable the broadcast timer
+ * cpuidle_setup_broadcast_timer - enable/disable the broadcast timer on a cpu
  * @arg: a void pointer used to match the SMP cross call API
  *
- * @arg is used as a value of type 'long' with one of the two values:
- * - CLOCK_EVT_NOTIFY_BROADCAST_ON
- * - CLOCK_EVT_NOTIFY_BROADCAST_OFF
- *
- * Set the broadcast timer notification for the current CPU.  This function
- * is executed per CPU by an SMP cross call.  It not supposed to be called
- * directly.
+ * If @arg is NULL broadcast is disabled otherwise enabled
+ *
+ * This function is executed per CPU by an SMP cross call.  It's not
+ * supposed to be called directly.
  */
 static void cpuidle_setup_broadcast_timer(void *arg)
 {
-	int cpu = smp_processor_id();
-	clockevents_notify((long)(arg), &cpu);
+	if (arg)
+		tick_broadcast_enable();
+	else
+		tick_broadcast_disable();
 }
 
 /**
@@ -239,7 +238,7 @@ static int __cpuidle_register_driver(str
 
 	if (drv->bctimer)
 		on_each_cpu_mask(drv->cpumask, cpuidle_setup_broadcast_timer,
-				 (void *)CLOCK_EVT_NOTIFY_BROADCAST_ON, 1);
+				 (void *)1, 1);
 
 	poll_idle_init(drv);
 
@@ -263,7 +262,7 @@ static void __cpuidle_unregister_driver(
 	if (drv->bctimer) {
 		drv->bctimer = 0;
 		on_each_cpu_mask(drv->cpumask, cpuidle_setup_broadcast_timer,
-				 (void *)CLOCK_EVT_NOTIFY_BROADCAST_OFF, 1);
+				 NULL, 1);
 	}
 
 	__cpuidle_unset_driver(drv);


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 06/20] intel_idle: Use explicit broadcast control function
  2015-04-01 22:02 [PATCH 00/20] clockevents_notify() removal Rafael J. Wysocki
                   ` (4 preceding siblings ...)
  2015-04-01 22:07 ` [PATCH 05/20] cpuidle: " Rafael J. Wysocki
@ 2015-04-01 22:09 ` Rafael J. Wysocki
  2015-04-01 22:10 ` [PATCH 07/20] ARM: OMAP: " Rafael J. Wysocki
                   ` (14 subsequent siblings)
  20 siblings, 0 replies; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-01 22:09 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Thomas Gleixner, Ingo Molnar, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List, Len Brown

From: Thomas Gleixner <tglx@linutronix.de>

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Len Brown <lenb@kernel.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/idle/intel_idle.c |   13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

Index: linux-pm/drivers/idle/intel_idle.c
===================================================================
--- linux-pm.orig/drivers/idle/intel_idle.c
+++ linux-pm/drivers/idle/intel_idle.c
@@ -55,7 +55,7 @@
 
 #include <linux/kernel.h>
 #include <linux/cpuidle.h>
-#include <linux/clockchips.h>
+#include <linux/tick.h>
 #include <trace/events/power.h>
 #include <linux/sched.h>
 #include <linux/notifier.h>
@@ -668,13 +668,12 @@ static void intel_idle_freeze(struct cpu
 
 static void __setup_broadcast_timer(void *arg)
 {
-	unsigned long reason = (unsigned long)arg;
-	int cpu = smp_processor_id();
-
-	reason = reason ?
-		CLOCK_EVT_NOTIFY_BROADCAST_ON : CLOCK_EVT_NOTIFY_BROADCAST_OFF;
+	unsigned long on = (unsigned long)arg;
 
-	clockevents_notify(reason, &cpu);
+	if (on)
+		tick_broadcast_enable();
+	else
+		tick_broadcast_disable();
 }
 
 static int cpu_hotplug_notify(struct notifier_block *n,


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 07/20] ARM: OMAP: Use explicit broadcast control function
  2015-04-01 22:02 [PATCH 00/20] clockevents_notify() removal Rafael J. Wysocki
                   ` (5 preceding siblings ...)
  2015-04-01 22:09 ` [PATCH 06/20] intel_idle: " Rafael J. Wysocki
@ 2015-04-01 22:10 ` Rafael J. Wysocki
  2015-04-01 22:11 ` [PATCH 08/20] clockevents: Remove the broadcast control leftovers Rafael J. Wysocki
                   ` (13 subsequent siblings)
  20 siblings, 0 replies; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-01 22:10 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Thomas Gleixner, Ingo Molnar, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List, Tony Lindgren

From: Thomas Gleixner <tglx@linutronix.de>

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Tony Lindgren <tony@atomide.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 arch/arm/mach-omap2/cpuidle44xx.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

Index: linux-pm/arch/arm/mach-omap2/cpuidle44xx.c
===================================================================
--- linux-pm.orig/arch/arm/mach-omap2/cpuidle44xx.c
+++ linux-pm/arch/arm/mach-omap2/cpuidle44xx.c
@@ -14,7 +14,7 @@
 #include <linux/cpuidle.h>
 #include <linux/cpu_pm.h>
 #include <linux/export.h>
-#include <linux/clockchips.h>
+#include <linux/tick.h>
 
 #include <asm/cpuidle.h>
 
@@ -183,8 +183,7 @@ fail:
  */
 static void omap_setup_broadcast_timer(void *arg)
 {
-	int cpu = smp_processor_id();
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu);
+	tick_broadcast_enable();
 }
 
 static struct cpuidle_driver omap4_idle_driver = {


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 08/20] clockevents: Remove the broadcast control leftovers
  2015-04-01 22:02 [PATCH 00/20] clockevents_notify() removal Rafael J. Wysocki
                   ` (6 preceding siblings ...)
  2015-04-01 22:10 ` [PATCH 07/20] ARM: OMAP: " Rafael J. Wysocki
@ 2015-04-01 22:11 ` Rafael J. Wysocki
  2015-04-01 22:13 ` [PATCH 09/20] clockevents: Provide explicit broadcast oneshot control functions Rafael J. Wysocki
                   ` (12 subsequent siblings)
  20 siblings, 0 replies; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-01 22:11 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Thomas Gleixner, Ingo Molnar, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List

From: Thomas Gleixner <tglx@linutronix.de>

All users converted. Remove the notify leftovers.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 include/linux/clockchips.h |    3 ---
 kernel/time/clockevents.c  |   10 ----------
 2 files changed, 13 deletions(-)

Index: linux-pm/include/linux/clockchips.h
===================================================================
--- linux-pm.orig/include/linux/clockchips.h
+++ linux-pm/include/linux/clockchips.h
@@ -11,9 +11,6 @@
 /* Clock event notification values */
 enum clock_event_nofitiers {
 	CLOCK_EVT_NOTIFY_ADD,
-	CLOCK_EVT_NOTIFY_BROADCAST_ON,
-	CLOCK_EVT_NOTIFY_BROADCAST_OFF,
-	CLOCK_EVT_NOTIFY_BROADCAST_FORCE,
 	CLOCK_EVT_NOTIFY_BROADCAST_ENTER,
 	CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
 	CLOCK_EVT_NOTIFY_CPU_DYING,
Index: linux-pm/kernel/time/clockevents.c
===================================================================
--- linux-pm.orig/kernel/time/clockevents.c
+++ linux-pm/kernel/time/clockevents.c
@@ -655,16 +655,6 @@ int clockevents_notify(unsigned long rea
 	raw_spin_lock_irqsave(&clockevents_lock, flags);
 
 	switch (reason) {
-	case CLOCK_EVT_NOTIFY_BROADCAST_ON:
-		tick_broadcast_enable();
-		break;
-	case CLOCK_EVT_NOTIFY_BROADCAST_OFF:
-		tick_broadcast_disable();
-		break;
-	case CLOCK_EVT_NOTIFY_BROADCAST_FORCE:
-		tick_broadcast_force();
-		break;
-
 	case CLOCK_EVT_NOTIFY_BROADCAST_ENTER:
 	case CLOCK_EVT_NOTIFY_BROADCAST_EXIT:
 		ret = tick_broadcast_oneshot_control(reason);


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 09/20] clockevents: Provide explicit broadcast oneshot control functions
  2015-04-01 22:02 [PATCH 00/20] clockevents_notify() removal Rafael J. Wysocki
                   ` (7 preceding siblings ...)
  2015-04-01 22:11 ` [PATCH 08/20] clockevents: Remove the broadcast control leftovers Rafael J. Wysocki
@ 2015-04-01 22:13 ` Rafael J. Wysocki
  2015-04-01 22:15 ` [PATCH 10/20] x86, amd_idle: Use " Rafael J. Wysocki
                   ` (11 subsequent siblings)
  20 siblings, 0 replies; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-01 22:13 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Thomas Gleixner, Ingo Molnar, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List, Tony Lindgren,
	Stephen Warren, Thierry Reding, Alexandre Courbot,
	Daniel Lezcano, Len Brown

From: Thomas Gleixner <tglx@linutronix.de>

clockevents_notify() is a leftover from the early design of the
clockevents facility. It's really not a notification mechanism, it's a
multiplex call. We are way better off to have explicit calls instead of this
monstrosity.

Split out the broadcast oneshot control into a separate function and
provide inline helpers. Switch clockevents_notify() over. This will go
away once all callers are converted.

This also gets rid of the nested locking of clockevents_lock and
broadcast_lock. The broadcast oneshot control functions do not require
clockevents_lock. Only the managing functions
(setup/shutdown/suspend/resume of the broadcast device require
clockevents_lock.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Tony Lindgren <tony@atomide.com>
Cc: Stephen Warren <swarren@wwwdotorg.org>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Alexandre Courbot <gnurou@gmail.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Len Brown <lenb@kernel.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 include/linux/tick.h         |   19 +++++++++++++++++++
 kernel/time/clockevents.c    |    4 +++-
 kernel/time/tick-broadcast.c |   28 +++++++++++++++++-----------
 kernel/time/tick-internal.h  |    2 --
 4 files changed, 39 insertions(+), 14 deletions(-)

Index: linux-pm/include/linux/tick.h
===================================================================
--- linux-pm.orig/include/linux/tick.h
+++ linux-pm/include/linux/tick.h
@@ -42,12 +42,23 @@ enum tick_broadcast_mode {
 	TICK_BROADCAST_FORCE,
 };
 
+enum tick_broadcast_state {
+	TICK_BROADCAST_EXIT,
+	TICK_BROADCAST_ENTER,
+};
+
 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
 extern void tick_broadcast_control(enum tick_broadcast_mode mode);
 #else
 static inline void tick_broadcast_control(enum tick_broadcast_mode mode) { }
 #endif /* BROADCAST */
 
+#if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) && defined(CONFIG_TICK_ONESHOT)
+extern int tick_broadcast_oneshot_control(enum tick_broadcast_state state);
+#else
+static inline int tick_broadcast_oneshot_control(enum tick_broadcast_state state) { return 0; }
+#endif
+
 static inline void tick_broadcast_enable(void)
 {
 	tick_broadcast_control(TICK_BROADCAST_ON);
@@ -60,6 +71,14 @@ static inline void tick_broadcast_force(
 {
 	tick_broadcast_control(TICK_BROADCAST_FORCE);
 }
+static inline int tick_broadcast_enter(void)
+{
+	return tick_broadcast_oneshot_control(TICK_BROADCAST_ENTER);
+}
+static inline void tick_broadcast_exit(void)
+{
+	tick_broadcast_oneshot_control(TICK_BROADCAST_EXIT);
+}
 
 #ifdef CONFIG_NO_HZ_COMMON
 extern int tick_nohz_tick_stopped(void);
Index: linux-pm/kernel/time/clockevents.c
===================================================================
--- linux-pm.orig/kernel/time/clockevents.c
+++ linux-pm/kernel/time/clockevents.c
@@ -656,8 +656,10 @@ int clockevents_notify(unsigned long rea
 
 	switch (reason) {
 	case CLOCK_EVT_NOTIFY_BROADCAST_ENTER:
+		tick_broadcast_enter();
+		break;
 	case CLOCK_EVT_NOTIFY_BROADCAST_EXIT:
-		ret = tick_broadcast_oneshot_control(reason);
+		tick_broadcast_exit();
 		break;
 
 	case CLOCK_EVT_NOTIFY_CPU_DYING:
Index: linux-pm/kernel/time/tick-broadcast.c
===================================================================
--- linux-pm.orig/kernel/time/tick-broadcast.c
+++ linux-pm/kernel/time/tick-broadcast.c
@@ -682,18 +682,23 @@ static void broadcast_move_bc(int deadcp
 	clockevents_program_event(bc, bc->next_event, 1);
 }
 
-/*
- * Powerstate information: The system enters/leaves a state, where
- * affected devices might stop
+/**
+ * tick_broadcast_oneshot_control - Enter/exit broadcast oneshot mode
+ * @state:	The target state (enter/exit)
+ *
+ * The system enters/leaves a state, where affected devices might stop
  * Returns 0 on success, -EBUSY if the cpu is used to broadcast wakeups.
+ *
+ * Called with interrupts disabled, so clockevents_lock is not
+ * required here because the local clock event device cannot go away
+ * under us.
  */
-int tick_broadcast_oneshot_control(unsigned long reason)
+int tick_broadcast_oneshot_control(enum tick_broadcast_state state)
 {
 	struct clock_event_device *bc, *dev;
 	struct tick_device *td;
-	unsigned long flags;
-	ktime_t now;
 	int cpu, ret = 0;
+	ktime_t now;
 
 	/*
 	 * Periodic mode does not care about the enter/exit of power
@@ -706,17 +711,17 @@ int tick_broadcast_oneshot_control(unsig
 	 * We are called with preemtion disabled from the depth of the
 	 * idle code, so we can't be moved away.
 	 */
-	cpu = smp_processor_id();
-	td = &per_cpu(tick_cpu_device, cpu);
+	td = this_cpu_ptr(&tick_cpu_device);
 	dev = td->evtdev;
 
 	if (!(dev->features & CLOCK_EVT_FEAT_C3STOP))
 		return 0;
 
+	raw_spin_lock(&tick_broadcast_lock);
 	bc = tick_broadcast_device.evtdev;
+	cpu = smp_processor_id();
 
-	raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
-	if (reason == CLOCK_EVT_NOTIFY_BROADCAST_ENTER) {
+	if (state == TICK_BROADCAST_ENTER) {
 		if (!cpumask_test_and_set_cpu(cpu, tick_broadcast_oneshot_mask)) {
 			WARN_ON_ONCE(cpumask_test_cpu(cpu, tick_broadcast_pending_mask));
 			broadcast_shutdown_local(bc, dev);
@@ -808,9 +813,10 @@ int tick_broadcast_oneshot_control(unsig
 		}
 	}
 out:
-	raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
+	raw_spin_unlock(&tick_broadcast_lock);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(tick_broadcast_oneshot_control);
 
 /*
  * Reset the one shot broadcast for a cpu
Index: linux-pm/kernel/time/tick-internal.h
===================================================================
--- linux-pm.orig/kernel/time/tick-internal.h
+++ linux-pm/kernel/time/tick-internal.h
@@ -118,7 +118,6 @@ static inline void tick_set_periodic_han
 /* Functions related to oneshot broadcasting */
 #if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) && defined(CONFIG_TICK_ONESHOT)
 extern void tick_broadcast_setup_oneshot(struct clock_event_device *bc);
-extern int tick_broadcast_oneshot_control(unsigned long reason);
 extern void tick_broadcast_switch_to_oneshot(void);
 extern void tick_shutdown_broadcast_oneshot(unsigned int *cpup);
 extern int tick_broadcast_oneshot_active(void);
@@ -127,7 +126,6 @@ bool tick_broadcast_oneshot_available(vo
 extern struct cpumask *tick_get_broadcast_oneshot_mask(void);
 #else /* BROADCAST && ONESHOT */
 static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc) { BUG(); }
-static inline int tick_broadcast_oneshot_control(unsigned long reason) { return 0; }
 static inline void tick_broadcast_switch_to_oneshot(void) { }
 static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { }
 static inline int tick_broadcast_oneshot_active(void) { return 0; }


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 10/20] x86, amd_idle: Use explicit broadcast oneshot control functions
  2015-04-01 22:02 [PATCH 00/20] clockevents_notify() removal Rafael J. Wysocki
                   ` (8 preceding siblings ...)
  2015-04-01 22:13 ` [PATCH 09/20] clockevents: Provide explicit broadcast oneshot control functions Rafael J. Wysocki
@ 2015-04-01 22:15 ` Rafael J. Wysocki
  2015-04-01 22:16 ` [PATCH 11/20] ACPI / PAD: Use explicit broadcast oneshot control function Rafael J. Wysocki
                   ` (10 subsequent siblings)
  20 siblings, 0 replies; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-01 22:15 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Thomas Gleixner, Ingo Molnar, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List

From: Thomas Gleixner <tglx@linutronix.de>

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 arch/x86/kernel/process.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Index: linux-pm/arch/x86/kernel/process.c
===================================================================
--- linux-pm.orig/arch/x86/kernel/process.c
+++ linux-pm/arch/x86/kernel/process.c
@@ -381,7 +381,7 @@ static void amd_e400_idle(void)
 			tick_broadcast_force();
 			pr_info("Switch to broadcast mode on CPU%d\n", cpu);
 		}
-		clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
+		tick_broadcast_enter();
 
 		default_idle();
 
@@ -390,7 +390,7 @@ static void amd_e400_idle(void)
 		 * called with interrupts disabled.
 		 */
 		local_irq_disable();
-		clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
+		tick_broadcast_exit();
 		local_irq_enable();
 	} else
 		default_idle();


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 11/20] ACPI / PAD: Use explicit broadcast oneshot control function
  2015-04-01 22:02 [PATCH 00/20] clockevents_notify() removal Rafael J. Wysocki
                   ` (9 preceding siblings ...)
  2015-04-01 22:15 ` [PATCH 10/20] x86, amd_idle: Use " Rafael J. Wysocki
@ 2015-04-01 22:16 ` Rafael J. Wysocki
  2015-04-01 22:17 ` [PATCH 12/20] ACPI / processor: Use explicit broadcast controll function Rafael J. Wysocki
                   ` (9 subsequent siblings)
  20 siblings, 0 replies; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-01 22:16 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Thomas Gleixner, Ingo Molnar, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List

From: Thomas Gleixner <tglx@linutronix.de>

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Len Brown <lenb@kernel.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/acpi_pad.c |    6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

Index: linux-pm/drivers/acpi/acpi_pad.c
===================================================================
--- linux-pm.orig/drivers/acpi/acpi_pad.c
+++ linux-pm/drivers/acpi/acpi_pad.c
@@ -150,7 +150,6 @@ static int power_saving_thread(void *dat
 	sched_setscheduler(current, SCHED_RR, &param);
 
 	while (!kthread_should_stop()) {
-		int cpu;
 		unsigned long expire_time;
 
 		try_to_freeze();
@@ -174,14 +173,13 @@ static int power_saving_thread(void *dat
 			}
 			local_irq_disable();
 			tick_broadcast_enable();
-			cpu = smp_processor_id();
-			clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
+			tick_broadcast_enter();
 			stop_critical_timings();
 
 			mwait_idle_with_hints(power_saving_mwait_eax, 1);
 
 			start_critical_timings();
-			clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
+			tick_broadcast_exit();
 			local_irq_enable();
 
 			if (time_before(expire_time, jiffies)) {


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 12/20] ACPI / processor: Use explicit broadcast controll function
  2015-04-01 22:02 [PATCH 00/20] clockevents_notify() removal Rafael J. Wysocki
                   ` (10 preceding siblings ...)
  2015-04-01 22:16 ` [PATCH 11/20] ACPI / PAD: Use explicit broadcast oneshot control function Rafael J. Wysocki
@ 2015-04-01 22:17 ` Rafael J. Wysocki
  2015-04-01 22:20 ` [PATCH 13/20] intel_idle: Use explicit broadcast oneshot control function Rafael J. Wysocki
                   ` (8 subsequent siblings)
  20 siblings, 0 replies; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-01 22:17 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Thomas Gleixner, Ingo Molnar, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List

From: Thomas Gleixner <tglx@linutronix.de>

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/processor_idle.c |    9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

Index: linux-pm/drivers/acpi/processor_idle.c
===================================================================
--- linux-pm.orig/drivers/acpi/processor_idle.c
+++ linux-pm/drivers/acpi/processor_idle.c
@@ -178,11 +178,10 @@ static void lapic_timer_state_broadcast(
 	int state = cx - pr->power.states;
 
 	if (state >= pr->power.timer_broadcast_on_state) {
-		unsigned long reason;
-
-		reason = broadcast ?  CLOCK_EVT_NOTIFY_BROADCAST_ENTER :
-			CLOCK_EVT_NOTIFY_BROADCAST_EXIT;
-		clockevents_notify(reason, &pr->id);
+		if (broadcast)
+			tick_broadcast_enter();
+		else
+			tick_broadcast_exit();
 	}
 }
 


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 13/20] intel_idle: Use explicit broadcast oneshot control function
  2015-04-01 22:02 [PATCH 00/20] clockevents_notify() removal Rafael J. Wysocki
                   ` (11 preceding siblings ...)
  2015-04-01 22:17 ` [PATCH 12/20] ACPI / processor: Use explicit broadcast controll function Rafael J. Wysocki
@ 2015-04-01 22:20 ` Rafael J. Wysocki
  2015-04-01 22:20 ` [PATCH 14/20] ARM: OMAP: " Rafael J. Wysocki
                   ` (7 subsequent siblings)
  20 siblings, 0 replies; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-01 22:20 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Thomas Gleixner, Ingo Molnar, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List, Len Brown

From: Thomas Gleixner <tglx@linutronix.de>

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Len Brown <lenb@kernel.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/idle/intel_idle.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Index: linux-pm/drivers/idle/intel_idle.c
===================================================================
--- linux-pm.orig/drivers/idle/intel_idle.c
+++ linux-pm/drivers/idle/intel_idle.c
@@ -638,12 +638,12 @@ static int intel_idle(struct cpuidle_dev
 		leave_mm(cpu);
 
 	if (!(lapic_timer_reliable_states & (1 << (cstate))))
-		clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
+		tick_broadcast_enter();
 
 	mwait_idle_with_hints(eax, ecx);
 
 	if (!(lapic_timer_reliable_states & (1 << (cstate))))
-		clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
+		tick_broadcast_exit();
 
 	return index;
 }

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 14/20] ARM: OMAP: Use explicit broadcast oneshot control function
  2015-04-01 22:02 [PATCH 00/20] clockevents_notify() removal Rafael J. Wysocki
                   ` (12 preceding siblings ...)
  2015-04-01 22:20 ` [PATCH 13/20] intel_idle: Use explicit broadcast oneshot control function Rafael J. Wysocki
@ 2015-04-01 22:20 ` Rafael J. Wysocki
  2015-04-01 22:21 ` [PATCH 15/20] ARM: tegra: " Rafael J. Wysocki
                   ` (6 subsequent siblings)
  20 siblings, 0 replies; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-01 22:20 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Thomas Gleixner, Ingo Molnar, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List, Tony Lindgren

From: Thomas Gleixner <tglx@linutronix.de>

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Tony Lindgren <tony@atomide.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 arch/arm/mach-omap2/cpuidle44xx.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

Index: linux-pm/arch/arm/mach-omap2/cpuidle44xx.c
===================================================================
--- linux-pm.orig/arch/arm/mach-omap2/cpuidle44xx.c
+++ linux-pm/arch/arm/mach-omap2/cpuidle44xx.c
@@ -83,7 +83,6 @@ static int omap_enter_idle_coupled(struc
 {
 	struct idle_statedata *cx = state_ptr + index;
 	u32 mpuss_can_lose_context = 0;
-	int cpu_id = smp_processor_id();
 
 	/*
 	 * CPU0 has to wait and stay ON until CPU1 is OFF state.
@@ -111,7 +110,7 @@ static int omap_enter_idle_coupled(struc
 	mpuss_can_lose_context = (cx->mpu_state == PWRDM_POWER_RET) &&
 				 (cx->mpu_logic_state == PWRDM_POWER_OFF);
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu_id);
+	tick_broadcast_enter();
 
 	/*
 	 * Call idle CPU PM enter notifier chain so that
@@ -168,7 +167,7 @@ static int omap_enter_idle_coupled(struc
 	if (dev->cpu == 0 && mpuss_can_lose_context)
 		cpu_cluster_pm_exit();
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id);
+	tick_broadcast_exit();
 
 fail:
 	cpuidle_coupled_parallel_barrier(dev, &abort_barrier);

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 15/20] ARM: tegra: Use explicit broadcast oneshot control function
  2015-04-01 22:02 [PATCH 00/20] clockevents_notify() removal Rafael J. Wysocki
                   ` (13 preceding siblings ...)
  2015-04-01 22:20 ` [PATCH 14/20] ARM: OMAP: " Rafael J. Wysocki
@ 2015-04-01 22:21 ` Rafael J. Wysocki
  2015-04-01 22:22 ` [PATCH 16/20] sched/idle: " Rafael J. Wysocki
                   ` (5 subsequent siblings)
  20 siblings, 0 replies; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-01 22:21 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Thomas Gleixner, Ingo Molnar, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List,
	Stephen Warren, Thierry Reding, Alexandre Courbot

From: Thomas Gleixner <tglx@linutronix.de>

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Stephen Warren <swarren@wwwdotorg.org>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Alexandre Courbot <gnurou@gmail.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 arch/arm/mach-tegra/cpuidle-tegra114.c |    6 +++---
 arch/arm/mach-tegra/cpuidle-tegra20.c  |   10 +++++-----
 arch/arm/mach-tegra/cpuidle-tegra30.c  |   10 +++++-----
 3 files changed, 13 insertions(+), 13 deletions(-)

Index: linux-pm/arch/arm/mach-tegra/cpuidle-tegra114.c
===================================================================
--- linux-pm.orig/arch/arm/mach-tegra/cpuidle-tegra114.c
+++ linux-pm/arch/arm/mach-tegra/cpuidle-tegra114.c
@@ -15,7 +15,7 @@
  */
 
 #include <asm/firmware.h>
-#include <linux/clockchips.h>
+#include <linux/tick.h>
 #include <linux/cpuidle.h>
 #include <linux/cpu_pm.h>
 #include <linux/kernel.h>
@@ -44,7 +44,7 @@ static int tegra114_idle_power_down(stru
 	tegra_set_cpu_in_lp2();
 	cpu_pm_enter();
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
+	tick_broadcast_enter();
 
 	call_firmware_op(prepare_idle);
 
@@ -52,7 +52,7 @@ static int tegra114_idle_power_down(stru
 	if (call_firmware_op(do_idle, 0) == -ENOSYS)
 		cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
+	tick_broadcast_exit();
 
 	cpu_pm_exit();
 	tegra_clear_cpu_in_lp2();
Index: linux-pm/arch/arm/mach-tegra/cpuidle-tegra20.c
===================================================================
--- linux-pm.orig/arch/arm/mach-tegra/cpuidle-tegra20.c
+++ linux-pm/arch/arm/mach-tegra/cpuidle-tegra20.c
@@ -20,7 +20,7 @@
  */
 
 #include <linux/clk/tegra.h>
-#include <linux/clockchips.h>
+#include <linux/tick.h>
 #include <linux/cpuidle.h>
 #include <linux/cpu_pm.h>
 #include <linux/kernel.h>
@@ -135,11 +135,11 @@ static bool tegra20_cpu_cluster_power_do
 	if (tegra20_reset_cpu_1() || !tegra_cpu_rail_off_ready())
 		return false;
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
+	tick_broadcast_enter();
 
 	tegra_idle_lp2_last();
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
+	tick_broadcast_exit();
 
 	if (cpu_online(1))
 		tegra20_wake_cpu1_from_reset();
@@ -152,13 +152,13 @@ static bool tegra20_idle_enter_lp2_cpu_1
 					 struct cpuidle_driver *drv,
 					 int index)
 {
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
+	tick_broadcast_enter();
 
 	cpu_suspend(0, tegra20_sleep_cpu_secondary_finish);
 
 	tegra20_cpu_clear_resettable();
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
+	tick_broadcast_exit();
 
 	return true;
 }
Index: linux-pm/arch/arm/mach-tegra/cpuidle-tegra30.c
===================================================================
--- linux-pm.orig/arch/arm/mach-tegra/cpuidle-tegra30.c
+++ linux-pm/arch/arm/mach-tegra/cpuidle-tegra30.c
@@ -20,7 +20,7 @@
  */
 
 #include <linux/clk/tegra.h>
-#include <linux/clockchips.h>
+#include <linux/tick.h>
 #include <linux/cpuidle.h>
 #include <linux/cpu_pm.h>
 #include <linux/kernel.h>
@@ -75,11 +75,11 @@ static bool tegra30_cpu_cluster_power_do
 		return false;
 	}
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
+	tick_broadcast_enter();
 
 	tegra_idle_lp2_last();
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
+	tick_broadcast_exit();
 
 	return true;
 }
@@ -89,13 +89,13 @@ static bool tegra30_cpu_core_power_down(
 					struct cpuidle_driver *drv,
 					int index)
 {
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
+	tick_broadcast_enter();
 
 	smp_wmb();
 
 	cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
+	tick_broadcast_exit();
 
 	return true;
 }


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 16/20] sched/idle: Use explicit broadcast oneshot control function
  2015-04-01 22:02 [PATCH 00/20] clockevents_notify() removal Rafael J. Wysocki
                   ` (14 preceding siblings ...)
  2015-04-01 22:21 ` [PATCH 15/20] ARM: tegra: " Rafael J. Wysocki
@ 2015-04-01 22:22 ` Rafael J. Wysocki
  2015-04-28 10:11   ` Linus Walleij
  2015-04-01 22:23 ` [PATCH 17/20] clockevents: Remove broadcast oneshot control leftovers Rafael J. Wysocki
                   ` (4 subsequent siblings)
  20 siblings, 1 reply; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-01 22:22 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Thomas Gleixner, Ingo Molnar, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List

From: Thomas Gleixner <tglx@linutronix.de>

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 kernel/sched/idle.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

Index: linux-pm/kernel/sched/idle.c
===================================================================
--- linux-pm.orig/kernel/sched/idle.c
+++ linux-pm/kernel/sched/idle.c
@@ -158,8 +158,7 @@ static void cpuidle_idle_call(void)
 	 * is used from another cpu as a broadcast timer, this call may
 	 * fail if it is not available
 	 */
-	if (broadcast &&
-	    clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu))
+	if (broadcast && tick_broadcast_enter())
 		goto use_default;
 
 	/* Take note of the planned idle state. */
@@ -176,7 +175,7 @@ static void cpuidle_idle_call(void)
 	idle_set_state(this_rq(), NULL);
 
 	if (broadcast)
-		clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
+		tick_broadcast_exit();
 
 	/*
 	 * Give the governor an opportunity to reflect on the outcome


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 17/20] clockevents: Remove broadcast oneshot control leftovers
  2015-04-01 22:02 [PATCH 00/20] clockevents_notify() removal Rafael J. Wysocki
                   ` (15 preceding siblings ...)
  2015-04-01 22:22 ` [PATCH 16/20] sched/idle: " Rafael J. Wysocki
@ 2015-04-01 22:23 ` Rafael J. Wysocki
  2015-04-01 22:24 ` [PATCH 18/20] clockevents: Make tick handover explicit Rafael J. Wysocki
                   ` (3 subsequent siblings)
  20 siblings, 0 replies; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-01 22:23 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Thomas Gleixner, Ingo Molnar, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

All users converted. Remove the notify leftovers.

Original-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 include/linux/clockchips.h |    2 --
 kernel/time/clockevents.c  |    7 -------
 2 files changed, 9 deletions(-)

Index: linux-pm/include/linux/clockchips.h
===================================================================
--- linux-pm.orig/include/linux/clockchips.h
+++ linux-pm/include/linux/clockchips.h
@@ -11,8 +11,6 @@
 /* Clock event notification values */
 enum clock_event_nofitiers {
 	CLOCK_EVT_NOTIFY_ADD,
-	CLOCK_EVT_NOTIFY_BROADCAST_ENTER,
-	CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
 	CLOCK_EVT_NOTIFY_CPU_DYING,
 	CLOCK_EVT_NOTIFY_CPU_DEAD,
 };
Index: linux-pm/kernel/time/clockevents.c
===================================================================
--- linux-pm.orig/kernel/time/clockevents.c
+++ linux-pm/kernel/time/clockevents.c
@@ -655,13 +655,6 @@ int clockevents_notify(unsigned long rea
 	raw_spin_lock_irqsave(&clockevents_lock, flags);
 
 	switch (reason) {
-	case CLOCK_EVT_NOTIFY_BROADCAST_ENTER:
-		tick_broadcast_enter();
-		break;
-	case CLOCK_EVT_NOTIFY_BROADCAST_EXIT:
-		tick_broadcast_exit();
-		break;
-
 	case CLOCK_EVT_NOTIFY_CPU_DYING:
 		tick_handover_do_timer(arg);
 		break;


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 18/20]  clockevents: Make tick handover explicit
  2015-04-01 22:02 [PATCH 00/20] clockevents_notify() removal Rafael J. Wysocki
                   ` (16 preceding siblings ...)
  2015-04-01 22:23 ` [PATCH 17/20] clockevents: Remove broadcast oneshot control leftovers Rafael J. Wysocki
@ 2015-04-01 22:24 ` Rafael J. Wysocki
  2015-04-01 22:25 ` [PATCH 19/20] clockevents: Cleanup dead cpu explicitely Rafael J. Wysocki
                   ` (2 subsequent siblings)
  20 siblings, 0 replies; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-01 22:24 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Thomas Gleixner, Ingo Molnar, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List

From: Thomas Gleixner <tglx@linutronix.de>

clockevents_notify() is a leftover from the early design of the
clockevents facility. It's really not a notification mechanism, it's a
multiplex call. We are way better off to have explicit calls instead of this
monstrosity.

Split out the tick_handover call and invoke it explicitely from the
hotplug code. Temporary solution will be cleaned up in later patches.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
[ rjw: Rebase ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 include/linux/clockchips.h  |    1 -
 include/linux/tick.h        |    2 ++
 kernel/cpu.c                |    3 +++
 kernel/time/clockevents.c   |    4 ----
 kernel/time/hrtimer.c       |    4 ----
 kernel/time/tick-common.c   |    9 ++++++---
 kernel/time/tick-internal.h |    1 -
 7 files changed, 11 insertions(+), 13 deletions(-)

Index: linux-pm/include/linux/clockchips.h
===================================================================
--- linux-pm.orig/include/linux/clockchips.h
+++ linux-pm/include/linux/clockchips.h
@@ -11,7 +11,6 @@
 /* Clock event notification values */
 enum clock_event_nofitiers {
 	CLOCK_EVT_NOTIFY_ADD,
-	CLOCK_EVT_NOTIFY_CPU_DYING,
 	CLOCK_EVT_NOTIFY_CPU_DEAD,
 };
 
Index: linux-pm/include/linux/tick.h
===================================================================
--- linux-pm.orig/include/linux/tick.h
+++ linux-pm/include/linux/tick.h
@@ -19,12 +19,14 @@ extern void tick_unfreeze(void);
 extern void tick_suspend_local(void);
 /* Should be core only, but XEN resume magic and ARM BL switcher require it */
 extern void tick_resume_local(void);
+extern void tick_handover_do_timer(void);
 #else /* CONFIG_GENERIC_CLOCKEVENTS */
 static inline void tick_init(void) { }
 static inline void tick_freeze(void) { }
 static inline void tick_unfreeze(void) { }
 static inline void tick_suspend_local(void) { }
 static inline void tick_resume_local(void) { }
+static inline void tick_handover_do_timer(void) { }
 #endif /* !CONFIG_GENERIC_CLOCKEVENTS */
 
 #ifdef CONFIG_TICK_ONESHOT
Index: linux-pm/kernel/cpu.c
===================================================================
--- linux-pm.orig/kernel/cpu.c
+++ linux-pm/kernel/cpu.c
@@ -20,6 +20,7 @@
 #include <linux/gfp.h>
 #include <linux/suspend.h>
 #include <linux/lockdep.h>
+#include <linux/tick.h>
 #include <trace/events/power.h>
 
 #include "smpboot.h"
@@ -338,6 +339,8 @@ static int __ref take_cpu_down(void *_pa
 		return err;
 
 	cpu_notify(CPU_DYING | param->mod, param->hcpu);
+	/* Give up timekeeping duties */
+	tick_handover_do_timer();
 	/* Park the stopper thread */
 	kthread_park(current);
 	return 0;
Index: linux-pm/kernel/time/clockevents.c
===================================================================
--- linux-pm.orig/kernel/time/clockevents.c
+++ linux-pm/kernel/time/clockevents.c
@@ -655,10 +655,6 @@ int clockevents_notify(unsigned long rea
 	raw_spin_lock_irqsave(&clockevents_lock, flags);
 
 	switch (reason) {
-	case CLOCK_EVT_NOTIFY_CPU_DYING:
-		tick_handover_do_timer(arg);
-		break;
-
 	case CLOCK_EVT_NOTIFY_CPU_DEAD:
 		tick_shutdown_broadcast_oneshot(arg);
 		tick_shutdown_broadcast(arg);
Index: linux-pm/kernel/time/hrtimer.c
===================================================================
--- linux-pm.orig/kernel/time/hrtimer.c
+++ linux-pm/kernel/time/hrtimer.c
@@ -1707,10 +1707,6 @@ static int hrtimer_cpu_notify(struct not
 		break;
 
 #ifdef CONFIG_HOTPLUG_CPU
-	case CPU_DYING:
-	case CPU_DYING_FROZEN:
-		clockevents_notify(CLOCK_EVT_NOTIFY_CPU_DYING, &scpu);
-		break;
 	case CPU_DEAD:
 	case CPU_DEAD_FROZEN:
 	{
Index: linux-pm/kernel/time/tick-common.c
===================================================================
--- linux-pm.orig/kernel/time/tick-common.c
+++ linux-pm/kernel/time/tick-common.c
@@ -332,20 +332,23 @@ out_bc:
 	tick_install_broadcast_device(newdev);
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
 /*
  * Transfer the do_timer job away from a dying cpu.
  *
- * Called with interrupts disabled.
+ * Called with interrupts disabled. Not locking required. If
+ * tick_do_timer_cpu is owned by this cpu, nothing can change it.
  */
-void tick_handover_do_timer(int *cpup)
+void tick_handover_do_timer(void)
 {
-	if (*cpup == tick_do_timer_cpu) {
+	if (tick_do_timer_cpu == smp_processor_id()) {
 		int cpu = cpumask_first(cpu_online_mask);
 
 		tick_do_timer_cpu = (cpu < nr_cpu_ids) ? cpu :
 			TICK_DO_TIMER_NONE;
 	}
 }
+#endif
 
 /*
  * Shutdown an event device on a given cpu:
Index: linux-pm/kernel/time/tick-internal.h
===================================================================
--- linux-pm.orig/kernel/time/tick-internal.h
+++ linux-pm/kernel/time/tick-internal.h
@@ -20,7 +20,6 @@ extern int tick_do_timer_cpu __read_most
 extern void tick_setup_periodic(struct clock_event_device *dev, int broadcast);
 extern void tick_handle_periodic(struct clock_event_device *dev);
 extern void tick_check_new_device(struct clock_event_device *dev);
-extern void tick_handover_do_timer(int *cpup);
 extern void tick_shutdown(unsigned int *cpup);
 extern void tick_suspend(void);
 extern void tick_resume(void);


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 19/20] clockevents: Cleanup dead cpu explicitely
  2015-04-01 22:02 [PATCH 00/20] clockevents_notify() removal Rafael J. Wysocki
                   ` (17 preceding siblings ...)
  2015-04-01 22:24 ` [PATCH 18/20] clockevents: Make tick handover explicit Rafael J. Wysocki
@ 2015-04-01 22:25 ` Rafael J. Wysocki
  2015-04-01 22:26 ` [PATCH 20/20] timekeeping: Get rid of stale comment Rafael J. Wysocki
  2015-04-02 12:39 ` [PATCH 00/20] clockevents_notify() removal Ingo Molnar
  20 siblings, 0 replies; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-01 22:25 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Thomas Gleixner, Ingo Molnar, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List

From: Thomas Gleixner <tglx@linutronix.de>

clockevents_notify() is a leftover from the early design of the
clockevents facility. It's really not a notification mechanism, it's a
multiplex call. We are way better off to have explicit calls instead of this
monstrosity.

Split out the cleanup function for a dead cpu and invoke it directly
from the cpu down code. Make it conditional on CPU_HOTPLUG as well.

Temporary change, will be refined in the future.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
[ rjw: Rebased, added clockevents_notify() removal ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 include/linux/clockchips.h   |    6 -----
 include/linux/tick.h         |    2 +
 kernel/cpu.c                 |    1 
 kernel/time/clockevents.c    |   51 +++++++++++++++++--------------------------
 kernel/time/hrtimer.c        |    3 --
 kernel/time/tick-broadcast.c |   29 ++++++++++++------------
 kernel/time/tick-common.c    |    6 ++---
 kernel/time/tick-internal.h  |   10 ++++----
 8 files changed, 47 insertions(+), 61 deletions(-)

Index: linux-pm/include/linux/clockchips.h
===================================================================
--- linux-pm.orig/include/linux/clockchips.h
+++ linux-pm/include/linux/clockchips.h
@@ -8,12 +8,6 @@
 #ifndef _LINUX_CLOCKCHIPS_H
 #define _LINUX_CLOCKCHIPS_H
 
-/* Clock event notification values */
-enum clock_event_nofitiers {
-	CLOCK_EVT_NOTIFY_ADD,
-	CLOCK_EVT_NOTIFY_CPU_DEAD,
-};
-
 #ifdef CONFIG_GENERIC_CLOCKEVENTS
 
 #include <linux/clocksource.h>
Index: linux-pm/include/linux/tick.h
===================================================================
--- linux-pm.orig/include/linux/tick.h
+++ linux-pm/include/linux/tick.h
@@ -20,6 +20,7 @@ extern void tick_suspend_local(void);
 /* Should be core only, but XEN resume magic and ARM BL switcher require it */
 extern void tick_resume_local(void);
 extern void tick_handover_do_timer(void);
+extern void tick_cleanup_dead_cpu(int cpu);
 #else /* CONFIG_GENERIC_CLOCKEVENTS */
 static inline void tick_init(void) { }
 static inline void tick_freeze(void) { }
@@ -27,6 +28,7 @@ static inline void tick_unfreeze(void) {
 static inline void tick_suspend_local(void) { }
 static inline void tick_resume_local(void) { }
 static inline void tick_handover_do_timer(void) { }
+static inline void tick_cleanup_dead_cpu(int cpu) { }
 #endif /* !CONFIG_GENERIC_CLOCKEVENTS */
 
 #ifdef CONFIG_TICK_ONESHOT
Index: linux-pm/kernel/cpu.c
===================================================================
--- linux-pm.orig/kernel/cpu.c
+++ linux-pm/kernel/cpu.c
@@ -418,6 +418,7 @@ static int __ref _cpu_down(unsigned int
 	__cpu_die(cpu);
 
 	/* CPU is completely dead: tell everyone.  Too late to complain. */
+	tick_cleanup_dead_cpu(cpu);
 	cpu_notify_nofail(CPU_DEAD | mod, hcpu);
 
 	check_for_tasks(cpu);
Index: linux-pm/kernel/time/clockevents.c
===================================================================
--- linux-pm.orig/kernel/time/clockevents.c
+++ linux-pm/kernel/time/clockevents.c
@@ -642,49 +642,40 @@ void clockevents_resume(void)
 			dev->resume(dev);
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
 /**
- * clockevents_notify - notification about relevant events
- * Returns 0 on success, any other value on error
+ * tick_cleanup_dead_cpu - Cleanup the tick and clockevents of a dead cpu
  */
-int clockevents_notify(unsigned long reason, void *arg)
+void tick_cleanup_dead_cpu(int cpu)
 {
 	struct clock_event_device *dev, *tmp;
 	unsigned long flags;
-	int cpu, ret = 0;
 
 	raw_spin_lock_irqsave(&clockevents_lock, flags);
 
-	switch (reason) {
-	case CLOCK_EVT_NOTIFY_CPU_DEAD:
-		tick_shutdown_broadcast_oneshot(arg);
-		tick_shutdown_broadcast(arg);
-		tick_shutdown(arg);
-		/*
-		 * Unregister the clock event devices which were
-		 * released from the users in the notify chain.
-		 */
-		list_for_each_entry_safe(dev, tmp, &clockevents_released, list)
+	tick_shutdown_broadcast_oneshot(cpu);
+	tick_shutdown_broadcast(cpu);
+	tick_shutdown(cpu);
+	/*
+	 * Unregister the clock event devices which were
+	 * released from the users in the notify chain.
+	 */
+	list_for_each_entry_safe(dev, tmp, &clockevents_released, list)
+		list_del(&dev->list);
+	/*
+	 * Now check whether the CPU has left unused per cpu devices
+	 */
+	list_for_each_entry_safe(dev, tmp, &clockevent_devices, list) {
+		if (cpumask_test_cpu(cpu, dev->cpumask) &&
+		    cpumask_weight(dev->cpumask) == 1 &&
+		    !tick_is_broadcast_device(dev)) {
+			BUG_ON(dev->state != CLOCK_EVT_STATE_DETACHED);
 			list_del(&dev->list);
-		/*
-		 * Now check whether the CPU has left unused per cpu devices
-		 */
-		cpu = *((int *)arg);
-		list_for_each_entry_safe(dev, tmp, &clockevent_devices, list) {
-			if (cpumask_test_cpu(cpu, dev->cpumask) &&
-			    cpumask_weight(dev->cpumask) == 1 &&
-			    !tick_is_broadcast_device(dev)) {
-				BUG_ON(dev->state != CLOCK_EVT_STATE_DETACHED);
-				list_del(&dev->list);
-			}
 		}
-		break;
-	default:
-		break;
 	}
 	raw_spin_unlock_irqrestore(&clockevents_lock, flags);
-	return ret;
 }
-EXPORT_SYMBOL_GPL(clockevents_notify);
+#endif
 
 #ifdef CONFIG_SYSFS
 struct bus_type clockevents_subsys = {
Index: linux-pm/kernel/time/hrtimer.c
===================================================================
--- linux-pm.orig/kernel/time/hrtimer.c
+++ linux-pm/kernel/time/hrtimer.c
@@ -1709,11 +1709,8 @@ static int hrtimer_cpu_notify(struct not
 #ifdef CONFIG_HOTPLUG_CPU
 	case CPU_DEAD:
 	case CPU_DEAD_FROZEN:
-	{
-		clockevents_notify(CLOCK_EVT_NOTIFY_CPU_DEAD, &scpu);
 		migrate_hrtimers(scpu);
 		break;
-	}
 #endif
 
 	default:
Index: linux-pm/kernel/time/tick-broadcast.c
===================================================================
--- linux-pm.orig/kernel/time/tick-broadcast.c
+++ linux-pm/kernel/time/tick-broadcast.c
@@ -410,14 +410,14 @@ void tick_set_periodic_handler(struct cl
 		dev->event_handler = tick_handle_periodic_broadcast;
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
 /*
  * Remove a CPU from broadcasting
  */
-void tick_shutdown_broadcast(unsigned int *cpup)
+void tick_shutdown_broadcast(unsigned int cpu)
 {
 	struct clock_event_device *bc;
 	unsigned long flags;
-	unsigned int cpu = *cpup;
 
 	raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
 
@@ -432,6 +432,7 @@ void tick_shutdown_broadcast(unsigned in
 
 	raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
 }
+#endif
 
 void tick_suspend_broadcast(void)
 {
@@ -672,16 +673,6 @@ static void broadcast_shutdown_local(str
 	clockevents_set_state(dev, CLOCK_EVT_STATE_SHUTDOWN);
 }
 
-static void broadcast_move_bc(int deadcpu)
-{
-	struct clock_event_device *bc = tick_broadcast_device.evtdev;
-
-	if (!bc || !broadcast_needs_cpu(bc, deadcpu))
-		return;
-	/* This moves the broadcast assignment to this cpu */
-	clockevents_program_event(bc, bc->next_event, 1);
-}
-
 /**
  * tick_broadcast_oneshot_control - Enter/exit broadcast oneshot mode
  * @state:	The target state (enter/exit)
@@ -903,14 +894,23 @@ void tick_broadcast_switch_to_oneshot(vo
 	raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
+static void broadcast_move_bc(int deadcpu)
+{
+	struct clock_event_device *bc = tick_broadcast_device.evtdev;
+
+	if (!bc || !broadcast_needs_cpu(bc, deadcpu))
+		return;
+	/* This moves the broadcast assignment to this cpu */
+	clockevents_program_event(bc, bc->next_event, 1);
+}
 
 /*
  * Remove a dead CPU from broadcasting
  */
-void tick_shutdown_broadcast_oneshot(unsigned int *cpup)
+void tick_shutdown_broadcast_oneshot(unsigned int cpu)
 {
 	unsigned long flags;
-	unsigned int cpu = *cpup;
 
 	raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
 
@@ -926,6 +926,7 @@ void tick_shutdown_broadcast_oneshot(uns
 
 	raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
 }
+#endif
 
 /*
  * Check, whether the broadcast device is in one shot mode
Index: linux-pm/kernel/time/tick-common.c
===================================================================
--- linux-pm.orig/kernel/time/tick-common.c
+++ linux-pm/kernel/time/tick-common.c
@@ -348,7 +348,6 @@ void tick_handover_do_timer(void)
 			TICK_DO_TIMER_NONE;
 	}
 }
-#endif
 
 /*
  * Shutdown an event device on a given cpu:
@@ -357,9 +356,9 @@ void tick_handover_do_timer(void)
  * access the hardware device itself.
  * We just set the mode and remove it from the lists.
  */
-void tick_shutdown(unsigned int *cpup)
+void tick_shutdown(unsigned int cpu)
 {
-	struct tick_device *td = &per_cpu(tick_cpu_device, *cpup);
+	struct tick_device *td = &per_cpu(tick_cpu_device, cpu);
 	struct clock_event_device *dev = td->evtdev;
 
 	td->mode = TICKDEV_MODE_PERIODIC;
@@ -375,6 +374,7 @@ void tick_shutdown(unsigned int *cpup)
 		td->evtdev = NULL;
 	}
 }
+#endif
 
 /**
  * tick_suspend_local - Suspend the local tick device
Index: linux-pm/kernel/time/tick-internal.h
===================================================================
--- linux-pm.orig/kernel/time/tick-internal.h
+++ linux-pm/kernel/time/tick-internal.h
@@ -20,7 +20,7 @@ extern int tick_do_timer_cpu __read_most
 extern void tick_setup_periodic(struct clock_event_device *dev, int broadcast);
 extern void tick_handle_periodic(struct clock_event_device *dev);
 extern void tick_check_new_device(struct clock_event_device *dev);
-extern void tick_shutdown(unsigned int *cpup);
+extern void tick_shutdown(unsigned int cpu);
 extern void tick_suspend(void);
 extern void tick_resume(void);
 extern bool tick_check_replacement(struct clock_event_device *curdev,
@@ -84,7 +84,7 @@ static inline int tick_check_oneshot_cha
 extern int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu);
 extern void tick_install_broadcast_device(struct clock_event_device *dev);
 extern int tick_is_broadcast_device(struct clock_event_device *dev);
-extern void tick_shutdown_broadcast(unsigned int *cpup);
+extern void tick_shutdown_broadcast(unsigned int cpu);
 extern void tick_suspend_broadcast(void);
 extern void tick_resume_broadcast(void);
 extern bool tick_resume_check_broadcast(void);
@@ -98,7 +98,7 @@ static inline void tick_install_broadcas
 static inline int tick_is_broadcast_device(struct clock_event_device *dev) { return 0; }
 static inline int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu) { return 0; }
 static inline void tick_do_periodic_broadcast(struct clock_event_device *d) { }
-static inline void tick_shutdown_broadcast(unsigned int *cpup) { }
+static inline void tick_shutdown_broadcast(unsigned int cpu) { }
 static inline void tick_suspend_broadcast(void) { }
 static inline void tick_resume_broadcast(void) { }
 static inline bool tick_resume_check_broadcast(void) { return false; }
@@ -118,7 +118,7 @@ static inline void tick_set_periodic_han
 #if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) && defined(CONFIG_TICK_ONESHOT)
 extern void tick_broadcast_setup_oneshot(struct clock_event_device *bc);
 extern void tick_broadcast_switch_to_oneshot(void);
-extern void tick_shutdown_broadcast_oneshot(unsigned int *cpup);
+extern void tick_shutdown_broadcast_oneshot(unsigned int cpu);
 extern int tick_broadcast_oneshot_active(void);
 extern void tick_check_oneshot_broadcast_this_cpu(void);
 bool tick_broadcast_oneshot_available(void);
@@ -126,7 +126,7 @@ extern struct cpumask *tick_get_broadcas
 #else /* BROADCAST && ONESHOT */
 static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc) { BUG(); }
 static inline void tick_broadcast_switch_to_oneshot(void) { }
-static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { }
+static inline void tick_shutdown_broadcast_oneshot(unsigned int cpu) { }
 static inline int tick_broadcast_oneshot_active(void) { return 0; }
 static inline void tick_check_oneshot_broadcast_this_cpu(void) { }
 static inline bool tick_broadcast_oneshot_available(void) { return tick_oneshot_possible(); }


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 20/20] timekeeping: Get rid of stale comment
  2015-04-01 22:02 [PATCH 00/20] clockevents_notify() removal Rafael J. Wysocki
                   ` (18 preceding siblings ...)
  2015-04-01 22:25 ` [PATCH 19/20] clockevents: Cleanup dead cpu explicitely Rafael J. Wysocki
@ 2015-04-01 22:26 ` Rafael J. Wysocki
  2015-04-01 23:57   ` John Stultz
  2015-04-02 12:39 ` [PATCH 00/20] clockevents_notify() removal Ingo Molnar
  20 siblings, 1 reply; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-01 22:26 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Thomas Gleixner, Ingo Molnar, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List, John Stultz

From: Thomas Gleixner <tglx@linutronix.de>

Arch specific management of xtime/jiffies/wall_to_monotonic is gone
for quite a while. Zap the stale comment.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: John Stultz <john.stultz@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 kernel/time/timekeeping.c |    4 ----
 1 file changed, 4 deletions(-)

Index: linux-pm/kernel/time/timekeeping.c
===================================================================
--- linux-pm.orig/kernel/time/timekeeping.c
+++ linux-pm/kernel/time/timekeeping.c
@@ -1307,10 +1307,6 @@ void timekeeping_inject_sleeptime64(stru
 
 /**
  * timekeeping_resume - Resumes the generic timekeeping subsystem.
- *
- * This is for the generic clocksource timekeeping.
- * xtime/wall_to_monotonic/jiffies/etc are
- * still managed by arch specific suspend/resume code.
  */
 void timekeeping_resume(void)
 {


^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 20/20] timekeeping: Get rid of stale comment
  2015-04-01 22:26 ` [PATCH 20/20] timekeeping: Get rid of stale comment Rafael J. Wysocki
@ 2015-04-01 23:57   ` John Stultz
  0 siblings, 0 replies; 90+ messages in thread
From: John Stultz @ 2015-04-01 23:57 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Peter Zijlstra, Thomas Gleixner, Ingo Molnar, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List

On Wed, Apr 1, 2015 at 3:26 PM, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> From: Thomas Gleixner <tglx@linutronix.de>
>
> Arch specific management of xtime/jiffies/wall_to_monotonic is gone
> for quite a while. Zap the stale comment.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Cc: John Stultz <john.stultz@linaro.org>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Acked-by: John Stultz <john.stultz@linaro.org>

thanks
-john

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 00/20] clockevents_notify() removal
  2015-04-01 22:02 [PATCH 00/20] clockevents_notify() removal Rafael J. Wysocki
                   ` (19 preceding siblings ...)
  2015-04-01 22:26 ` [PATCH 20/20] timekeeping: Get rid of stale comment Rafael J. Wysocki
@ 2015-04-02 12:39 ` Ingo Molnar
  2015-04-02 22:19   ` Rafael J. Wysocki
  20 siblings, 1 reply; 90+ messages in thread
From: Ingo Molnar @ 2015-04-02 12:39 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Peter Zijlstra, Thomas Gleixner, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List


* Rafael J. Wysocki <rjw@rjwysocki.net> wrote:

> Hi,
> 
> This is the next batch of patches from Thomas that remove clockevents_notify().
> 
> I've reordered the set (to put more stratightforward things to the front) and
> rebased it on top of the timers material currently queued up for 4.1.
> 
> This series in based on the bleeding-edge branch of the linux-pm tree (which
> for all practical purposes is my linux-next branch with timers/core from tip
> merged into it).
> 
> Please let me know how to proceed with these.

Would you mind to resend these merged on top of the very latest 
tip:timers/core (or tip:master) tree?

These changes conflict (mildly) with the other series from Thomas 
which needed some fixes/enhancements.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 00/20] clockevents_notify() removal
  2015-04-02 12:39 ` [PATCH 00/20] clockevents_notify() removal Ingo Molnar
@ 2015-04-02 22:19   ` Rafael J. Wysocki
  2015-04-02 23:45     ` [v2][PATCH 00/21] " Rafael J. Wysocki
  0 siblings, 1 reply; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-02 22:19 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Peter Zijlstra, Thomas Gleixner, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List

On Thursday, April 02, 2015 02:39:35 PM Ingo Molnar wrote:
> 
> * Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> 
> > Hi,
> > 
> > This is the next batch of patches from Thomas that remove clockevents_notify().
> > 
> > I've reordered the set (to put more stratightforward things to the front) and
> > rebased it on top of the timers material currently queued up for 4.1.
> > 
> > This series in based on the bleeding-edge branch of the linux-pm tree (which
> > for all practical purposes is my linux-next branch with timers/core from tip
> > merged into it).
> > 
> > Please let me know how to proceed with these.
> 
> Would you mind to resend these merged on top of the very latest 
> tip:timers/core (or tip:master) tree?
> 
> These changes conflict (mildly) with the other series from Thomas 
> which needed some fixes/enhancements.

I'll do that later today.

This series also depends on:

http://git.kernel.org/cgit/linux/kernel/git/rafael/linux-pm.git/commit/?h=acpi-pad&id=6e9f8b5f1f319cbdb4cfe3696fc74fbe39318960

which is in my acpi-pad branch at the moment, but I'll add it to the front of
the series in case you prefer to apply it directly.

Thanks,
Rafael


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [v2][PATCH 00/21] clockevents_notify() removal
  2015-04-02 22:19   ` Rafael J. Wysocki
@ 2015-04-02 23:45     ` Rafael J. Wysocki
  2015-04-02 23:46       ` [v2][PATCH 01/21] ACPI / PAD: Remove the local APIC nonsense Rafael J. Wysocki
                         ` (21 more replies)
  0 siblings, 22 replies; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-02 23:45 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Peter Zijlstra, Thomas Gleixner, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List

On Friday, April 03, 2015 12:19:41 AM Rafael J. Wysocki wrote:
> On Thursday, April 02, 2015 02:39:35 PM Ingo Molnar wrote:
> > 
> > * Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> > 
> > > Hi,
> > > 
> > > This is the next batch of patches from Thomas that remove clockevents_notify().
> > > 
> > > I've reordered the set (to put more stratightforward things to the front) and
> > > rebased it on top of the timers material currently queued up for 4.1.
> > > 
> > > This series in based on the bleeding-edge branch of the linux-pm tree (which
> > > for all practical purposes is my linux-next branch with timers/core from tip
> > > merged into it).
> > > 
> > > Please let me know how to proceed with these.
> > 
> > Would you mind to resend these merged on top of the very latest 
> > tip:timers/core (or tip:master) tree?
> > 
> > These changes conflict (mildly) with the other series from Thomas 
> > which needed some fixes/enhancements.
> 
> I'll do that later today.
> 
> This series also depends on:
> 
> http://git.kernel.org/cgit/linux/kernel/git/rafael/linux-pm.git/commit/?h=acpi-pad&id=6e9f8b5f1f319cbdb4cfe3696fc74fbe39318960
> 
> which is in my acpi-pad branch at the moment, but I'll add it to the front of
> the series in case you prefer to apply it directly.

The patches follow as per the above.  [2-21/21] rebased on top of the current
timers/core.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [v2][PATCH 01/21] ACPI / PAD: Remove the local APIC nonsense
  2015-04-02 23:45     ` [v2][PATCH 00/21] " Rafael J. Wysocki
@ 2015-04-02 23:46       ` Rafael J. Wysocki
  2015-04-03  8:21         ` [tip:timers/core] ACPI/PAD: " tip-bot for Thomas Gleixner
  2015-04-03  0:01       ` [v2][PATCH 02/21] clockevents: Provide explicit broadcast control functions Rafael J. Wysocki
                         ` (20 subsequent siblings)
  21 siblings, 1 reply; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-02 23:46 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Peter Zijlstra, Thomas Gleixner, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List

From: Thomas Gleixner <tglx@linutronix.de>

While looking through the (ab)use of the clockevents_notify() function
I stumbled over the following gem in the acpi_pad code:

  if (lapic_detected_unstable && !lapic_marked_unstable) {
     /* LAPIC could halt in idle, so notify users */
     for_each_online_cpu(i)
       clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &i);
     lapic_marked_unstable = 1;
  }

This code calls on the cpu which detects the lapic unstable condition
first clockevents_notify() to tell the core code that the broadcast
should be enabled on all online cpus. Brilliant stuff that as it
notifies the core code a num_online_cpus() times that the broadcast
should be enabled on the current cpu.

This probably has never been noticed because that code got never
tested with NOHZ=n and HIGHRES_TIMER=n or it just worked by chance
because one of the other mechanisms told the core in the right way
that the local apic timer is wreckaged.

Sigh, this is:

 - The 4th incarnation of idle drivers which has their own mechanism
   to detect and deal with X86_FEATURE_ARAT.

 - The 2nd incarnation of fake idle mechanisms with a different set of
   brainmelting bugs.

 - Has been merged against an explicit NAK of the scheduler
   maintainer with the promise to improve it over time.

 - Another example of featuritis driven trainwreck engineering.

 - Another pointless waste of my time.

Fix this nonsense by removing that lapic detection and notification
logic and simply call into the clockevents code unconditonally. The
ARAT feature is marked in the lapic clockevent already so the core
code will just ignore the requests and return.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c
index c7b105c0e1d3..1686e9f756fd 100644
--- a/drivers/acpi/acpi_pad.c
+++ b/drivers/acpi/acpi_pad.c
@@ -41,8 +41,6 @@ static unsigned long power_saving_mwait_eax;
 
 static unsigned char tsc_detected_unstable;
 static unsigned char tsc_marked_unstable;
-static unsigned char lapic_detected_unstable;
-static unsigned char lapic_marked_unstable;
 
 static void power_saving_mwait_init(void)
 {
@@ -82,13 +80,10 @@ static void power_saving_mwait_init(void)
 		 */
 		if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
 			tsc_detected_unstable = 1;
-		if (!boot_cpu_has(X86_FEATURE_ARAT))
-			lapic_detected_unstable = 1;
 		break;
 	default:
-		/* TSC & LAPIC could halt in idle */
+		/* TSC could halt in idle */
 		tsc_detected_unstable = 1;
-		lapic_detected_unstable = 1;
 	}
 #endif
 }
@@ -177,28 +172,17 @@ static int power_saving_thread(void *data)
 				mark_tsc_unstable("TSC halts in idle");
 				tsc_marked_unstable = 1;
 			}
-			if (lapic_detected_unstable && !lapic_marked_unstable) {
-				int i;
-				/* LAPIC could halt in idle, so notify users */
-				for_each_online_cpu(i)
-					clockevents_notify(
-						CLOCK_EVT_NOTIFY_BROADCAST_ON,
-						&i);
-				lapic_marked_unstable = 1;
-			}
+			clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu);
+
 			local_irq_disable();
 			cpu = smp_processor_id();
-			if (lapic_marked_unstable)
-				clockevents_notify(
-					CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
+			clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
 			stop_critical_timings();
 
 			mwait_idle_with_hints(power_saving_mwait_eax, 1);
 
 			start_critical_timings();
-			if (lapic_marked_unstable)
-				clockevents_notify(
-					CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
+			clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
 			local_irq_enable();
 
 			if (time_before(expire_time, jiffies)) {


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [v2][PATCH 02/21] clockevents: Provide explicit broadcast control functions
  2015-04-02 23:45     ` [v2][PATCH 00/21] " Rafael J. Wysocki
  2015-04-02 23:46       ` [v2][PATCH 01/21] ACPI / PAD: Remove the local APIC nonsense Rafael J. Wysocki
@ 2015-04-03  0:01       ` Rafael J. Wysocki
  2015-04-03  8:21         ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2015-04-03  0:01       ` [v2][PATCH 03/21] x86, amd_idle: Use explicit broadcast control function Rafael J. Wysocki
                         ` (19 subsequent siblings)
  21 siblings, 1 reply; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-03  0:01 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Peter Zijlstra, Thomas Gleixner, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List, Tony Lindgren,
	Len Brown, Daniel Lezcano

From: Thomas Gleixner <tglx@linutronix.de>

clockevents_notify() is a leftover from the early design of the
clockevents facility. It's really not a notification mechanism, it's a
multiplex call. We are way better off to have explicit calls instead of this
monstrosity.

Split out the broadcast control into a separate function and provide
inline helpers. Switch clockevents_notify() over. This will go away
once all callers are converted.

This also gets rid of the nested locking of clockevents_lock and
broadcast_lock. The broadcast control functions do not require
clockevents_lock. Only the managing functions
(setup/shutdown/suspend/resume of the broadcast device require 
clockevents_lock.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Tony Lindgren <tony@atomide.com>
Cc: Len Brown <lenb@kernel.org>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 include/linux/tick.h         |   25 +++++++++++++++++
 kernel/time/clockevents.c    |    6 +++-
 kernel/time/tick-broadcast.c |   62 ++++++++++++++++++-------------------------
 kernel/time/tick-internal.h  |    2 -
 4 files changed, 57 insertions(+), 38 deletions(-)

Index: linux-pm/include/linux/tick.h
===================================================================
--- linux-pm.orig/include/linux/tick.h
+++ linux-pm/include/linux/tick.h
@@ -42,6 +42,31 @@ extern void hotplug_cpu__broadcast_tick_
 static inline void hotplug_cpu__broadcast_tick_pull(int dead_cpu) { }
 #endif
 
+enum tick_broadcast_mode {
+	TICK_BROADCAST_OFF,
+	TICK_BROADCAST_ON,
+	TICK_BROADCAST_FORCE,
+};
+
+#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
+extern void tick_broadcast_control(enum tick_broadcast_mode mode);
+#else
+static inline void tick_broadcast_control(enum tick_broadcast_mode mode) { }
+#endif /* BROADCAST */
+
+static inline void tick_broadcast_enable(void)
+{
+	tick_broadcast_control(TICK_BROADCAST_ON);
+}
+static inline void tick_broadcast_disable(void)
+{
+	tick_broadcast_control(TICK_BROADCAST_OFF);
+}
+static inline void tick_broadcast_force(void)
+{
+	tick_broadcast_control(TICK_BROADCAST_FORCE);
+}
+
 #ifdef CONFIG_NO_HZ_COMMON
 extern int tick_nohz_tick_stopped(void);
 extern void tick_nohz_idle_enter(void);
Index: linux-pm/kernel/time/clockevents.c
===================================================================
--- linux-pm.orig/kernel/time/clockevents.c
+++ linux-pm/kernel/time/clockevents.c
@@ -656,9 +656,13 @@ int clockevents_notify(unsigned long rea
 
 	switch (reason) {
 	case CLOCK_EVT_NOTIFY_BROADCAST_ON:
+		tick_broadcast_enable();
+		break;
 	case CLOCK_EVT_NOTIFY_BROADCAST_OFF:
+		tick_broadcast_disable();
+		break;
 	case CLOCK_EVT_NOTIFY_BROADCAST_FORCE:
-		tick_broadcast_on_off(reason, arg);
+		tick_broadcast_force();
 		break;
 
 	case CLOCK_EVT_NOTIFY_BROADCAST_ENTER:
Index: linux-pm/kernel/time/tick-broadcast.c
===================================================================
--- linux-pm.orig/kernel/time/tick-broadcast.c
+++ linux-pm/kernel/time/tick-broadcast.c
@@ -33,7 +33,7 @@ static cpumask_var_t tick_broadcast_mask
 static cpumask_var_t tick_broadcast_on;
 static cpumask_var_t tmpmask;
 static DEFINE_RAW_SPINLOCK(tick_broadcast_lock);
-static int tick_broadcast_force;
+static int tick_broadcast_forced;
 
 #ifdef CONFIG_TICK_ONESHOT
 static void tick_broadcast_clear_oneshot(int cpu);
@@ -326,49 +326,54 @@ unlock:
 	raw_spin_unlock(&tick_broadcast_lock);
 }
 
-/*
- * Powerstate information: The system enters/leaves a state, where
- * affected devices might stop
+/**
+ * tick_broadcast_control - Enable/disable or force broadcast mode
+ * @mode:	The selected broadcast mode
+ *
+ * Called when the system enters a state where affected tick devices
+ * might stop. Note: TICK_BROADCAST_FORCE cannot be undone.
+ *
+ * Called with interrupts disabled, so clockevents_lock is not
+ * required here because the local clock event device cannot go away
+ * under us.
  */
-static void tick_do_broadcast_on_off(unsigned long *reason)
+void tick_broadcast_control(enum tick_broadcast_mode mode)
 {
 	struct clock_event_device *bc, *dev;
 	struct tick_device *td;
-	unsigned long flags;
 	int cpu, bc_stopped;
 
-	raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
-
-	cpu = smp_processor_id();
-	td = &per_cpu(tick_cpu_device, cpu);
+	td = this_cpu_ptr(&tick_cpu_device);
 	dev = td->evtdev;
-	bc = tick_broadcast_device.evtdev;
 
 	/*
 	 * Is the device not affected by the powerstate ?
 	 */
 	if (!dev || !(dev->features & CLOCK_EVT_FEAT_C3STOP))
-		goto out;
+		return;
 
 	if (!tick_device_is_functional(dev))
-		goto out;
+		return;
 
+	raw_spin_lock(&tick_broadcast_lock);
+	cpu = smp_processor_id();
+	bc = tick_broadcast_device.evtdev;
 	bc_stopped = cpumask_empty(tick_broadcast_mask);
 
-	switch (*reason) {
-	case CLOCK_EVT_NOTIFY_BROADCAST_ON:
-	case CLOCK_EVT_NOTIFY_BROADCAST_FORCE:
+	switch (mode) {
+	case TICK_BROADCAST_FORCE:
+		tick_broadcast_forced = 1;
+	case TICK_BROADCAST_ON:
 		cpumask_set_cpu(cpu, tick_broadcast_on);
 		if (!cpumask_test_and_set_cpu(cpu, tick_broadcast_mask)) {
 			if (tick_broadcast_device.mode ==
 			    TICKDEV_MODE_PERIODIC)
 				clockevents_shutdown(dev);
 		}
-		if (*reason == CLOCK_EVT_NOTIFY_BROADCAST_FORCE)
-			tick_broadcast_force = 1;
 		break;
-	case CLOCK_EVT_NOTIFY_BROADCAST_OFF:
-		if (tick_broadcast_force)
+
+	case TICK_BROADCAST_OFF:
+		if (tick_broadcast_forced)
 			break;
 		cpumask_clear_cpu(cpu, tick_broadcast_on);
 		if (!tick_device_is_functional(dev))
@@ -390,22 +395,9 @@ static void tick_do_broadcast_on_off(uns
 		else
 			tick_broadcast_setup_oneshot(bc);
 	}
-out:
-	raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
-}
-
-/*
- * Powerstate information: The system enters/leaves a state, where
- * affected devices might stop.
- */
-void tick_broadcast_on_off(unsigned long reason, int *oncpu)
-{
-	if (!cpumask_test_cpu(*oncpu, cpu_online_mask))
-		printk(KERN_ERR "tick-broadcast: ignoring broadcast for "
-		       "offline CPU #%d\n", *oncpu);
-	else
-		tick_do_broadcast_on_off(&reason);
+	raw_spin_unlock(&tick_broadcast_lock);
 }
+EXPORT_SYMBOL_GPL(tick_broadcast_control);
 
 /*
  * Set the periodic handler depending on broadcast on/off
Index: linux-pm/kernel/time/tick-internal.h
===================================================================
--- linux-pm.orig/kernel/time/tick-internal.h
+++ linux-pm/kernel/time/tick-internal.h
@@ -53,7 +53,6 @@ extern ssize_t sysfs_get_uname(const cha
 extern int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu);
 extern void tick_install_broadcast_device(struct clock_event_device *dev);
 extern int tick_is_broadcast_device(struct clock_event_device *dev);
-extern void tick_broadcast_on_off(unsigned long reason, int *oncpu);
 extern void tick_shutdown_broadcast(unsigned int *cpup);
 extern void tick_suspend_broadcast(void);
 extern void tick_resume_broadcast(void);
@@ -68,7 +67,6 @@ static inline void tick_install_broadcas
 static inline int tick_is_broadcast_device(struct clock_event_device *dev) { return 0; }
 static inline int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu) { return 0; }
 static inline void tick_do_periodic_broadcast(struct clock_event_device *d) { }
-static inline void tick_broadcast_on_off(unsigned long reason, int *oncpu) { }
 static inline void tick_shutdown_broadcast(unsigned int *cpup) { }
 static inline void tick_suspend_broadcast(void) { }
 static inline void tick_resume_broadcast(void) { }


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [v2][PATCH 03/21] x86, amd_idle: Use explicit broadcast control function
  2015-04-02 23:45     ` [v2][PATCH 00/21] " Rafael J. Wysocki
  2015-04-02 23:46       ` [v2][PATCH 01/21] ACPI / PAD: Remove the local APIC nonsense Rafael J. Wysocki
  2015-04-03  0:01       ` [v2][PATCH 02/21] clockevents: Provide explicit broadcast control functions Rafael J. Wysocki
@ 2015-04-03  0:01       ` Rafael J. Wysocki
  2015-04-03  8:22         ` [tip:timers/core] x86/amd/idle, clockevents: " tip-bot for Thomas Gleixner
  2015-04-03  0:01       ` [v2][PATCH 04/21] ACPI / PAD: " Rafael J. Wysocki
                         ` (18 subsequent siblings)
  21 siblings, 1 reply; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-03  0:01 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Peter Zijlstra, Thomas Gleixner, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List

From: Thomas Gleixner <tglx@linutronix.de>

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 arch/x86/kernel/process.c |    9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

Index: linux-pm/arch/x86/kernel/process.c
===================================================================
--- linux-pm.orig/arch/x86/kernel/process.c
+++ linux-pm/arch/x86/kernel/process.c
@@ -9,7 +9,7 @@
 #include <linux/sched.h>
 #include <linux/module.h>
 #include <linux/pm.h>
-#include <linux/clockchips.h>
+#include <linux/tick.h>
 #include <linux/random.h>
 #include <linux/user-return-notifier.h>
 #include <linux/dmi.h>
@@ -377,11 +377,8 @@ static void amd_e400_idle(void)
 
 		if (!cpumask_test_cpu(cpu, amd_e400_c1e_mask)) {
 			cpumask_set_cpu(cpu, amd_e400_c1e_mask);
-			/*
-			 * Force broadcast so ACPI can not interfere.
-			 */
-			clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_FORCE,
-					   &cpu);
+			/* Force broadcast so ACPI can not interfere. */
+			tick_broadcast_force();
 			pr_info("Switch to broadcast mode on CPU%d\n", cpu);
 		}
 		clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [v2][PATCH 04/21] ACPI / PAD: Use explicit broadcast control function
  2015-04-02 23:45     ` [v2][PATCH 00/21] " Rafael J. Wysocki
                         ` (2 preceding siblings ...)
  2015-04-03  0:01       ` [v2][PATCH 03/21] x86, amd_idle: Use explicit broadcast control function Rafael J. Wysocki
@ 2015-04-03  0:01       ` Rafael J. Wysocki
  2015-04-03  8:22         ` [tip:timers/core] ACPI/PAD: " tip-bot for Thomas Gleixner
  2015-04-03  0:02       ` [v2][PATCH 05/21] ACPI / processor: " Rafael J. Wysocki
                         ` (17 subsequent siblings)
  21 siblings, 1 reply; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-03  0:01 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Peter Zijlstra, Thomas Gleixner, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List, Len Brown

From: Thomas Gleixner <tglx@linutronix.de>

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Len Brown <lenb@kernel.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/acpi_pad.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

Index: linux-pm/drivers/acpi/acpi_pad.c
===================================================================
--- linux-pm.orig/drivers/acpi/acpi_pad.c
+++ linux-pm/drivers/acpi/acpi_pad.c
@@ -26,7 +26,7 @@
 #include <linux/kthread.h>
 #include <linux/freezer.h>
 #include <linux/cpu.h>
-#include <linux/clockchips.h>
+#include <linux/tick.h>
 #include <linux/slab.h>
 #include <linux/acpi.h>
 #include <asm/mwait.h>
@@ -172,9 +172,8 @@ static int power_saving_thread(void *dat
 				mark_tsc_unstable("TSC halts in idle");
 				tsc_marked_unstable = 1;
 			}
-			clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu);
-
 			local_irq_disable();
+			tick_broadcast_enable();
 			cpu = smp_processor_id();
 			clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
 			stop_critical_timings();

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [v2][PATCH 05/21] ACPI / processor: Use explicit broadcast control function
  2015-04-02 23:45     ` [v2][PATCH 00/21] " Rafael J. Wysocki
                         ` (3 preceding siblings ...)
  2015-04-03  0:01       ` [v2][PATCH 04/21] ACPI / PAD: " Rafael J. Wysocki
@ 2015-04-03  0:02       ` Rafael J. Wysocki
  2015-04-03  8:22         ` [tip:timers/core] ACPI/processor: " tip-bot for Thomas Gleixner
  2015-04-03  0:02       ` [v2][PATCH 06/21] cpuidle: " Rafael J. Wysocki
                         ` (16 subsequent siblings)
  21 siblings, 1 reply; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-03  0:02 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Peter Zijlstra, Thomas Gleixner, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List

From: Thomas Gleixner <tglx@linutronix.de>

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/processor_idle.c |   11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

Index: linux-pm/drivers/acpi/processor_idle.c
===================================================================
--- linux-pm.orig/drivers/acpi/processor_idle.c
+++ linux-pm/drivers/acpi/processor_idle.c
@@ -32,7 +32,7 @@
 #include <linux/acpi.h>
 #include <linux/dmi.h>
 #include <linux/sched.h>       /* need_resched() */
-#include <linux/clockchips.h>
+#include <linux/tick.h>
 #include <linux/cpuidle.h>
 #include <linux/syscore_ops.h>
 #include <acpi/processor.h>
@@ -157,12 +157,11 @@ static void lapic_timer_check_state(int
 static void __lapic_timer_propagate_broadcast(void *arg)
 {
 	struct acpi_processor *pr = (struct acpi_processor *) arg;
-	unsigned long reason;
 
-	reason = pr->power.timer_broadcast_on_state < INT_MAX ?
-		CLOCK_EVT_NOTIFY_BROADCAST_ON : CLOCK_EVT_NOTIFY_BROADCAST_OFF;
-
-	clockevents_notify(reason, &pr->id);
+	if (pr->power.timer_broadcast_on_state < INT_MAX)
+		tick_broadcast_enable();
+	else
+		tick_broadcast_disable();
 }
 
 static void lapic_timer_propagate_broadcast(struct acpi_processor *pr)

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [v2][PATCH 06/21] cpuidle: Use explicit broadcast control function
  2015-04-02 23:45     ` [v2][PATCH 00/21] " Rafael J. Wysocki
                         ` (4 preceding siblings ...)
  2015-04-03  0:02       ` [v2][PATCH 05/21] ACPI / processor: " Rafael J. Wysocki
@ 2015-04-03  0:02       ` Rafael J. Wysocki
  2015-04-03  8:23         ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2015-04-03  0:02       ` [v2][PATCH 07/21] intel_idle: " Rafael J. Wysocki
                         ` (15 subsequent siblings)
  21 siblings, 1 reply; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-03  0:02 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Peter Zijlstra, Thomas Gleixner, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List,
	Daniel Lezcano

From: Thomas Gleixner <tglx@linutronix.de>

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/cpuidle/driver.c |   25 ++++++++++++-------------
 1 file changed, 12 insertions(+), 13 deletions(-)

Index: linux-pm/drivers/cpuidle/driver.c
===================================================================
--- linux-pm.orig/drivers/cpuidle/driver.c
+++ linux-pm/drivers/cpuidle/driver.c
@@ -13,7 +13,7 @@
 #include <linux/sched.h>
 #include <linux/cpuidle.h>
 #include <linux/cpumask.h>
-#include <linux/clockchips.h>
+#include <linux/tick.h>
 
 #include "cpuidle.h"
 
@@ -130,21 +130,20 @@ static inline void __cpuidle_unset_drive
 #endif
 
 /**
- * cpuidle_setup_broadcast_timer - enable/disable the broadcast timer
+ * cpuidle_setup_broadcast_timer - enable/disable the broadcast timer on a cpu
  * @arg: a void pointer used to match the SMP cross call API
  *
- * @arg is used as a value of type 'long' with one of the two values:
- * - CLOCK_EVT_NOTIFY_BROADCAST_ON
- * - CLOCK_EVT_NOTIFY_BROADCAST_OFF
- *
- * Set the broadcast timer notification for the current CPU.  This function
- * is executed per CPU by an SMP cross call.  It not supposed to be called
- * directly.
+ * If @arg is NULL broadcast is disabled otherwise enabled
+ *
+ * This function is executed per CPU by an SMP cross call.  It's not
+ * supposed to be called directly.
  */
 static void cpuidle_setup_broadcast_timer(void *arg)
 {
-	int cpu = smp_processor_id();
-	clockevents_notify((long)(arg), &cpu);
+	if (arg)
+		tick_broadcast_enable();
+	else
+		tick_broadcast_disable();
 }
 
 /**
@@ -239,7 +238,7 @@ static int __cpuidle_register_driver(str
 
 	if (drv->bctimer)
 		on_each_cpu_mask(drv->cpumask, cpuidle_setup_broadcast_timer,
-				 (void *)CLOCK_EVT_NOTIFY_BROADCAST_ON, 1);
+				 (void *)1, 1);
 
 	poll_idle_init(drv);
 
@@ -263,7 +262,7 @@ static void __cpuidle_unregister_driver(
 	if (drv->bctimer) {
 		drv->bctimer = 0;
 		on_each_cpu_mask(drv->cpumask, cpuidle_setup_broadcast_timer,
-				 (void *)CLOCK_EVT_NOTIFY_BROADCAST_OFF, 1);
+				 NULL, 1);
 	}
 
 	__cpuidle_unset_driver(drv);

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [v2][PATCH 07/21] intel_idle: Use explicit broadcast control function
  2015-04-02 23:45     ` [v2][PATCH 00/21] " Rafael J. Wysocki
                         ` (5 preceding siblings ...)
  2015-04-03  0:02       ` [v2][PATCH 06/21] cpuidle: " Rafael J. Wysocki
@ 2015-04-03  0:02       ` Rafael J. Wysocki
  2015-04-03  8:23         ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2015-04-03  0:02       ` [v2][PATCH 08/21] ARM: OMAP: " Rafael J. Wysocki
                         ` (14 subsequent siblings)
  21 siblings, 1 reply; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-03  0:02 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Peter Zijlstra, Thomas Gleixner, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List, Len Brown

From: Thomas Gleixner <tglx@linutronix.de>

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Len Brown <lenb@kernel.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/idle/intel_idle.c |   13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

Index: linux-pm/drivers/idle/intel_idle.c
===================================================================
--- linux-pm.orig/drivers/idle/intel_idle.c
+++ linux-pm/drivers/idle/intel_idle.c
@@ -55,7 +55,7 @@
 
 #include <linux/kernel.h>
 #include <linux/cpuidle.h>
-#include <linux/clockchips.h>
+#include <linux/tick.h>
 #include <trace/events/power.h>
 #include <linux/sched.h>
 #include <linux/notifier.h>
@@ -665,13 +665,12 @@ static void intel_idle_freeze(struct cpu
 
 static void __setup_broadcast_timer(void *arg)
 {
-	unsigned long reason = (unsigned long)arg;
-	int cpu = smp_processor_id();
-
-	reason = reason ?
-		CLOCK_EVT_NOTIFY_BROADCAST_ON : CLOCK_EVT_NOTIFY_BROADCAST_OFF;
+	unsigned long on = (unsigned long)arg;
 
-	clockevents_notify(reason, &cpu);
+	if (on)
+		tick_broadcast_enable();
+	else
+		tick_broadcast_disable();
 }
 
 static int cpu_hotplug_notify(struct notifier_block *n,

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [v2][PATCH 08/21] ARM: OMAP: Use explicit broadcast control function
  2015-04-02 23:45     ` [v2][PATCH 00/21] " Rafael J. Wysocki
                         ` (6 preceding siblings ...)
  2015-04-03  0:02       ` [v2][PATCH 07/21] intel_idle: " Rafael J. Wysocki
@ 2015-04-03  0:02       ` Rafael J. Wysocki
  2015-04-03  8:23         ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2015-04-03  0:03       ` [v2][PATCH 09/21] clockevents: Remove the broadcast control leftovers Rafael J. Wysocki
                         ` (13 subsequent siblings)
  21 siblings, 1 reply; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-03  0:02 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Peter Zijlstra, Thomas Gleixner, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List, Tony Lindgren

From: Thomas Gleixner <tglx@linutronix.de>

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Tony Lindgren <tony@atomide.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 arch/arm/mach-omap2/cpuidle44xx.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

Index: linux-pm/arch/arm/mach-omap2/cpuidle44xx.c
===================================================================
--- linux-pm.orig/arch/arm/mach-omap2/cpuidle44xx.c
+++ linux-pm/arch/arm/mach-omap2/cpuidle44xx.c
@@ -14,7 +14,7 @@
 #include <linux/cpuidle.h>
 #include <linux/cpu_pm.h>
 #include <linux/export.h>
-#include <linux/clockchips.h>
+#include <linux/tick.h>
 
 #include <asm/cpuidle.h>
 
@@ -183,8 +183,7 @@ fail:
  */
 static void omap_setup_broadcast_timer(void *arg)
 {
-	int cpu = smp_processor_id();
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu);
+	tick_broadcast_enable();
 }
 
 static struct cpuidle_driver omap4_idle_driver = {

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [v2][PATCH 09/21] clockevents: Remove the broadcast control leftovers
  2015-04-02 23:45     ` [v2][PATCH 00/21] " Rafael J. Wysocki
                         ` (7 preceding siblings ...)
  2015-04-03  0:02       ` [v2][PATCH 08/21] ARM: OMAP: " Rafael J. Wysocki
@ 2015-04-03  0:03       ` Rafael J. Wysocki
  2015-04-03  8:23         ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2015-04-03  0:05       ` [v2][PATCH 10/21] clockevents: Provide explicit broadcast oneshot control functions Rafael J. Wysocki
                         ` (12 subsequent siblings)
  21 siblings, 1 reply; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-03  0:03 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Peter Zijlstra, Thomas Gleixner, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List

From: Thomas Gleixner <tglx@linutronix.de>

All users converted. Remove the notify leftovers.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 include/linux/clockchips.h |    3 ---
 kernel/time/clockevents.c  |   10 ----------
 2 files changed, 13 deletions(-)

Index: linux-pm/include/linux/clockchips.h
===================================================================
--- linux-pm.orig/include/linux/clockchips.h
+++ linux-pm/include/linux/clockchips.h
@@ -11,9 +11,6 @@
 /* Clock event notification values */
 enum clock_event_nofitiers {
 	CLOCK_EVT_NOTIFY_ADD,
-	CLOCK_EVT_NOTIFY_BROADCAST_ON,
-	CLOCK_EVT_NOTIFY_BROADCAST_OFF,
-	CLOCK_EVT_NOTIFY_BROADCAST_FORCE,
 	CLOCK_EVT_NOTIFY_BROADCAST_ENTER,
 	CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
 	CLOCK_EVT_NOTIFY_CPU_DYING,
Index: linux-pm/kernel/time/clockevents.c
===================================================================
--- linux-pm.orig/kernel/time/clockevents.c
+++ linux-pm/kernel/time/clockevents.c
@@ -655,16 +655,6 @@ int clockevents_notify(unsigned long rea
 	raw_spin_lock_irqsave(&clockevents_lock, flags);
 
 	switch (reason) {
-	case CLOCK_EVT_NOTIFY_BROADCAST_ON:
-		tick_broadcast_enable();
-		break;
-	case CLOCK_EVT_NOTIFY_BROADCAST_OFF:
-		tick_broadcast_disable();
-		break;
-	case CLOCK_EVT_NOTIFY_BROADCAST_FORCE:
-		tick_broadcast_force();
-		break;
-
 	case CLOCK_EVT_NOTIFY_BROADCAST_ENTER:
 	case CLOCK_EVT_NOTIFY_BROADCAST_EXIT:
 		ret = tick_broadcast_oneshot_control(reason);


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [v2][PATCH 10/21] clockevents: Provide explicit broadcast oneshot control functions
  2015-04-02 23:45     ` [v2][PATCH 00/21] " Rafael J. Wysocki
                         ` (8 preceding siblings ...)
  2015-04-03  0:03       ` [v2][PATCH 09/21] clockevents: Remove the broadcast control leftovers Rafael J. Wysocki
@ 2015-04-03  0:05       ` Rafael J. Wysocki
  2015-04-03  8:24         ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2015-04-03  0:05       ` [v2][PATCH 11/21] x86, amd_idle: Use " Rafael J. Wysocki
                         ` (11 subsequent siblings)
  21 siblings, 1 reply; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-03  0:05 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Peter Zijlstra, Thomas Gleixner, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List, Tony Lindgren,
	Stephen Warren, Thierry Reding, Alexandre Courbot,
	Daniel Lezcano, Len Brown

From: Thomas Gleixner <tglx@linutronix.de>

clockevents_notify() is a leftover from the early design of the
clockevents facility. It's really not a notification mechanism, it's a
multiplex call. We are way better off to have explicit calls instead of this
monstrosity.

Split out the broadcast oneshot control into a separate function and
provide inline helpers. Switch clockevents_notify() over. This will go
away once all callers are converted.

This also gets rid of the nested locking of clockevents_lock and
broadcast_lock. The broadcast oneshot control functions do not require
clockevents_lock. Only the managing functions
(setup/shutdown/suspend/resume of the broadcast device require
clockevents_lock.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Tony Lindgren <tony@atomide.com>
Cc: Stephen Warren <swarren@wwwdotorg.org>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Alexandre Courbot <gnurou@gmail.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Len Brown <lenb@kernel.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 include/linux/tick.h         |   19 +++++++++++++++++++
 kernel/time/clockevents.c    |    4 +++-
 kernel/time/tick-broadcast.c |   28 +++++++++++++++++-----------
 kernel/time/tick-internal.h  |    2 --
 4 files changed, 39 insertions(+), 14 deletions(-)

Index: linux-pm/include/linux/tick.h
===================================================================
--- linux-pm.orig/include/linux/tick.h
+++ linux-pm/include/linux/tick.h
@@ -48,12 +48,23 @@ enum tick_broadcast_mode {
 	TICK_BROADCAST_FORCE,
 };
 
+enum tick_broadcast_state {
+	TICK_BROADCAST_EXIT,
+	TICK_BROADCAST_ENTER,
+};
+
 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
 extern void tick_broadcast_control(enum tick_broadcast_mode mode);
 #else
 static inline void tick_broadcast_control(enum tick_broadcast_mode mode) { }
 #endif /* BROADCAST */
 
+#if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) && defined(CONFIG_TICK_ONESHOT)
+extern int tick_broadcast_oneshot_control(enum tick_broadcast_state state);
+#else
+static inline int tick_broadcast_oneshot_control(enum tick_broadcast_state state) { return 0; }
+#endif
+
 static inline void tick_broadcast_enable(void)
 {
 	tick_broadcast_control(TICK_BROADCAST_ON);
@@ -66,6 +77,14 @@ static inline void tick_broadcast_force(
 {
 	tick_broadcast_control(TICK_BROADCAST_FORCE);
 }
+static inline int tick_broadcast_enter(void)
+{
+	return tick_broadcast_oneshot_control(TICK_BROADCAST_ENTER);
+}
+static inline void tick_broadcast_exit(void)
+{
+	tick_broadcast_oneshot_control(TICK_BROADCAST_EXIT);
+}
 
 #ifdef CONFIG_NO_HZ_COMMON
 extern int tick_nohz_tick_stopped(void);
Index: linux-pm/kernel/time/clockevents.c
===================================================================
--- linux-pm.orig/kernel/time/clockevents.c
+++ linux-pm/kernel/time/clockevents.c
@@ -656,8 +656,10 @@ int clockevents_notify(unsigned long rea
 
 	switch (reason) {
 	case CLOCK_EVT_NOTIFY_BROADCAST_ENTER:
+		tick_broadcast_enter();
+		break;
 	case CLOCK_EVT_NOTIFY_BROADCAST_EXIT:
-		ret = tick_broadcast_oneshot_control(reason);
+		tick_broadcast_exit();
 		break;
 
 	case CLOCK_EVT_NOTIFY_CPU_DYING:
Index: linux-pm/kernel/time/tick-broadcast.c
===================================================================
--- linux-pm.orig/kernel/time/tick-broadcast.c
+++ linux-pm/kernel/time/tick-broadcast.c
@@ -687,18 +687,23 @@ void hotplug_cpu__broadcast_tick_pull(in
 	raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
 }
 
-/*
- * Powerstate information: The system enters/leaves a state, where
- * affected devices might stop
+/**
+ * tick_broadcast_oneshot_control - Enter/exit broadcast oneshot mode
+ * @state:	The target state (enter/exit)
+ *
+ * The system enters/leaves a state, where affected devices might stop
  * Returns 0 on success, -EBUSY if the cpu is used to broadcast wakeups.
+ *
+ * Called with interrupts disabled, so clockevents_lock is not
+ * required here because the local clock event device cannot go away
+ * under us.
  */
-int tick_broadcast_oneshot_control(unsigned long reason)
+int tick_broadcast_oneshot_control(enum tick_broadcast_state state)
 {
 	struct clock_event_device *bc, *dev;
 	struct tick_device *td;
-	unsigned long flags;
-	ktime_t now;
 	int cpu, ret = 0;
+	ktime_t now;
 
 	/*
 	 * Periodic mode does not care about the enter/exit of power
@@ -711,17 +716,17 @@ int tick_broadcast_oneshot_control(unsig
 	 * We are called with preemtion disabled from the depth of the
 	 * idle code, so we can't be moved away.
 	 */
-	cpu = smp_processor_id();
-	td = &per_cpu(tick_cpu_device, cpu);
+	td = this_cpu_ptr(&tick_cpu_device);
 	dev = td->evtdev;
 
 	if (!(dev->features & CLOCK_EVT_FEAT_C3STOP))
 		return 0;
 
+	raw_spin_lock(&tick_broadcast_lock);
 	bc = tick_broadcast_device.evtdev;
+	cpu = smp_processor_id();
 
-	raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
-	if (reason == CLOCK_EVT_NOTIFY_BROADCAST_ENTER) {
+	if (state == TICK_BROADCAST_ENTER) {
 		if (!cpumask_test_and_set_cpu(cpu, tick_broadcast_oneshot_mask)) {
 			WARN_ON_ONCE(cpumask_test_cpu(cpu, tick_broadcast_pending_mask));
 			broadcast_shutdown_local(bc, dev);
@@ -813,9 +818,10 @@ int tick_broadcast_oneshot_control(unsig
 		}
 	}
 out:
-	raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
+	raw_spin_unlock(&tick_broadcast_lock);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(tick_broadcast_oneshot_control);
 
 /*
  * Reset the one shot broadcast for a cpu
Index: linux-pm/kernel/time/tick-internal.h
===================================================================
--- linux-pm.orig/kernel/time/tick-internal.h
+++ linux-pm/kernel/time/tick-internal.h
@@ -119,7 +119,6 @@ static inline int tick_check_oneshot_cha
 /* Functions related to oneshot broadcasting */
 #if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) && defined(CONFIG_TICK_ONESHOT)
 extern void tick_broadcast_setup_oneshot(struct clock_event_device *bc);
-extern int tick_broadcast_oneshot_control(unsigned long reason);
 extern void tick_broadcast_switch_to_oneshot(void);
 extern void tick_shutdown_broadcast_oneshot(unsigned int *cpup);
 extern int tick_broadcast_oneshot_active(void);
@@ -128,7 +127,6 @@ bool tick_broadcast_oneshot_available(vo
 extern struct cpumask *tick_get_broadcast_oneshot_mask(void);
 #else /* !(BROADCAST && ONESHOT): */
 static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc) { BUG(); }
-static inline int tick_broadcast_oneshot_control(unsigned long reason) { return 0; }
 static inline void tick_broadcast_switch_to_oneshot(void) { }
 static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { }
 static inline int tick_broadcast_oneshot_active(void) { return 0; }


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [v2][PATCH 11/21] x86, amd_idle: Use explicit broadcast oneshot control functions
  2015-04-02 23:45     ` [v2][PATCH 00/21] " Rafael J. Wysocki
                         ` (9 preceding siblings ...)
  2015-04-03  0:05       ` [v2][PATCH 10/21] clockevents: Provide explicit broadcast oneshot control functions Rafael J. Wysocki
@ 2015-04-03  0:05       ` Rafael J. Wysocki
  2015-04-03  8:24         ` [tip:timers/core] x86/amd/idle, clockevents: " tip-bot for Thomas Gleixner
  2015-04-03  0:06       ` [v2][PATCH 12/21] ACPI / PAD: Use explicit broadcast oneshot control function Rafael J. Wysocki
                         ` (10 subsequent siblings)
  21 siblings, 1 reply; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-03  0:05 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Peter Zijlstra, Thomas Gleixner, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List

From: Thomas Gleixner <tglx@linutronix.de>

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 arch/x86/kernel/process.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Index: linux-pm/arch/x86/kernel/process.c
===================================================================
--- linux-pm.orig/arch/x86/kernel/process.c
+++ linux-pm/arch/x86/kernel/process.c
@@ -381,7 +381,7 @@ static void amd_e400_idle(void)
 			tick_broadcast_force();
 			pr_info("Switch to broadcast mode on CPU%d\n", cpu);
 		}
-		clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
+		tick_broadcast_enter();
 
 		default_idle();
 
@@ -390,7 +390,7 @@ static void amd_e400_idle(void)
 		 * called with interrupts disabled.
 		 */
 		local_irq_disable();
-		clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
+		tick_broadcast_exit();
 		local_irq_enable();
 	} else
 		default_idle();


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [v2][PATCH 12/21] ACPI / PAD: Use explicit broadcast oneshot control function
  2015-04-02 23:45     ` [v2][PATCH 00/21] " Rafael J. Wysocki
                         ` (10 preceding siblings ...)
  2015-04-03  0:05       ` [v2][PATCH 11/21] x86, amd_idle: Use " Rafael J. Wysocki
@ 2015-04-03  0:06       ` Rafael J. Wysocki
  2015-04-03  8:24         ` [tip:timers/core] ACPI/PAD: " tip-bot for Thomas Gleixner
  2015-04-03  0:12       ` [v2][PATCH 13/21] ACPI / processor: Use explicit broadcast controll function Rafael J. Wysocki
                         ` (9 subsequent siblings)
  21 siblings, 1 reply; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-03  0:06 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Peter Zijlstra, Thomas Gleixner, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List, Len Brown

From: Thomas Gleixner <tglx@linutronix.de>

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Len Brown <lenb@kernel.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/acpi_pad.c |    6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

Index: linux-pm/drivers/acpi/acpi_pad.c
===================================================================
--- linux-pm.orig/drivers/acpi/acpi_pad.c
+++ linux-pm/drivers/acpi/acpi_pad.c
@@ -150,7 +150,6 @@ static int power_saving_thread(void *dat
 	sched_setscheduler(current, SCHED_RR, &param);
 
 	while (!kthread_should_stop()) {
-		int cpu;
 		unsigned long expire_time;
 
 		try_to_freeze();
@@ -174,14 +173,13 @@ static int power_saving_thread(void *dat
 			}
 			local_irq_disable();
 			tick_broadcast_enable();
-			cpu = smp_processor_id();
-			clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
+			tick_broadcast_enter();
 			stop_critical_timings();
 
 			mwait_idle_with_hints(power_saving_mwait_eax, 1);
 
 			start_critical_timings();
-			clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
+			tick_broadcast_exit();
 			local_irq_enable();
 
 			if (time_before(expire_time, jiffies)) {


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [v2][PATCH 13/21] ACPI / processor: Use explicit broadcast controll function
  2015-04-02 23:45     ` [v2][PATCH 00/21] " Rafael J. Wysocki
                         ` (11 preceding siblings ...)
  2015-04-03  0:06       ` [v2][PATCH 12/21] ACPI / PAD: Use explicit broadcast oneshot control function Rafael J. Wysocki
@ 2015-04-03  0:12       ` Rafael J. Wysocki
  2015-04-03  8:25         ` [tip:timers/core] ACPI/idle: Use explicit broadcast control function tip-bot for Thomas Gleixner
  2015-04-03  0:14       ` [v2][PATCH 14/21] intel_idle: Use explicit broadcast oneshot " Rafael J. Wysocki
                         ` (8 subsequent siblings)
  21 siblings, 1 reply; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-03  0:12 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Peter Zijlstra, Thomas Gleixner, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List

From: Thomas Gleixner <tglx@linutronix.de>

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/processor_idle.c |    9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

Index: linux-pm/drivers/acpi/processor_idle.c
===================================================================
--- linux-pm.orig/drivers/acpi/processor_idle.c
+++ linux-pm/drivers/acpi/processor_idle.c
@@ -178,11 +178,10 @@ static void lapic_timer_state_broadcast(
 	int state = cx - pr->power.states;
 
 	if (state >= pr->power.timer_broadcast_on_state) {
-		unsigned long reason;
-
-		reason = broadcast ?  CLOCK_EVT_NOTIFY_BROADCAST_ENTER :
-			CLOCK_EVT_NOTIFY_BROADCAST_EXIT;
-		clockevents_notify(reason, &pr->id);
+		if (broadcast)
+			tick_broadcast_enter();
+		else
+			tick_broadcast_exit();
 	}
 }
 


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [v2][PATCH 14/21] intel_idle: Use explicit broadcast oneshot control function
  2015-04-02 23:45     ` [v2][PATCH 00/21] " Rafael J. Wysocki
                         ` (12 preceding siblings ...)
  2015-04-03  0:12       ` [v2][PATCH 13/21] ACPI / processor: Use explicit broadcast controll function Rafael J. Wysocki
@ 2015-04-03  0:14       ` Rafael J. Wysocki
  2015-04-03  8:25         ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2015-04-03  0:31       ` [v2][PATCH 15/21] ARM: OMAP: " Rafael J. Wysocki
                         ` (7 subsequent siblings)
  21 siblings, 1 reply; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-03  0:14 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Peter Zijlstra, Thomas Gleixner, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List, Len Brown

From: Thomas Gleixner <tglx@linutronix.de>

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Len Brown <lenb@kernel.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/idle/intel_idle.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Index: linux-pm/drivers/idle/intel_idle.c
===================================================================
--- linux-pm.orig/drivers/idle/intel_idle.c
+++ linux-pm/drivers/idle/intel_idle.c
@@ -638,12 +638,12 @@ static int intel_idle(struct cpuidle_dev
 		leave_mm(cpu);
 
 	if (!(lapic_timer_reliable_states & (1 << (cstate))))
-		clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
+		tick_broadcast_enter();
 
 	mwait_idle_with_hints(eax, ecx);
 
 	if (!(lapic_timer_reliable_states & (1 << (cstate))))
-		clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
+		tick_broadcast_exit();
 
 	return index;
 }

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [v2][PATCH 15/21] ARM: OMAP: Use explicit broadcast oneshot control function
  2015-04-02 23:45     ` [v2][PATCH 00/21] " Rafael J. Wysocki
                         ` (13 preceding siblings ...)
  2015-04-03  0:14       ` [v2][PATCH 14/21] intel_idle: Use explicit broadcast oneshot " Rafael J. Wysocki
@ 2015-04-03  0:31       ` Rafael J. Wysocki
  2015-04-03  8:25         ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2015-04-03  0:32       ` [v2][PATCH 16/21] ARM: tegra: " Rafael J. Wysocki
                         ` (6 subsequent siblings)
  21 siblings, 1 reply; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-03  0:31 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Peter Zijlstra, Thomas Gleixner, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List, Tony Lindgren

From: Thomas Gleixner <tglx@linutronix.de>

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Tony Lindgren <tony@atomide.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 arch/arm/mach-omap2/cpuidle44xx.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

Index: linux-pm/arch/arm/mach-omap2/cpuidle44xx.c
===================================================================
--- linux-pm.orig/arch/arm/mach-omap2/cpuidle44xx.c
+++ linux-pm/arch/arm/mach-omap2/cpuidle44xx.c
@@ -83,7 +83,6 @@ static int omap_enter_idle_coupled(struc
 {
 	struct idle_statedata *cx = state_ptr + index;
 	u32 mpuss_can_lose_context = 0;
-	int cpu_id = smp_processor_id();
 
 	/*
 	 * CPU0 has to wait and stay ON until CPU1 is OFF state.
@@ -111,7 +110,7 @@ static int omap_enter_idle_coupled(struc
 	mpuss_can_lose_context = (cx->mpu_state == PWRDM_POWER_RET) &&
 				 (cx->mpu_logic_state == PWRDM_POWER_OFF);
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu_id);
+	tick_broadcast_enter();
 
 	/*
 	 * Call idle CPU PM enter notifier chain so that
@@ -168,7 +167,7 @@ static int omap_enter_idle_coupled(struc
 	if (dev->cpu == 0 && mpuss_can_lose_context)
 		cpu_cluster_pm_exit();
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id);
+	tick_broadcast_exit();
 
 fail:
 	cpuidle_coupled_parallel_barrier(dev, &abort_barrier);

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [v2][PATCH 16/21] ARM: tegra: Use explicit broadcast oneshot control function
  2015-04-02 23:45     ` [v2][PATCH 00/21] " Rafael J. Wysocki
                         ` (14 preceding siblings ...)
  2015-04-03  0:31       ` [v2][PATCH 15/21] ARM: OMAP: " Rafael J. Wysocki
@ 2015-04-03  0:32       ` Rafael J. Wysocki
  2015-04-03  8:25         ` [tip:timers/core] ARM: Tegra: " tip-bot for Thomas Gleixner
  2015-04-03  0:34       ` [v2][PATCH 17/21] sched/idle: " Rafael J. Wysocki
                         ` (5 subsequent siblings)
  21 siblings, 1 reply; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-03  0:32 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Peter Zijlstra, Thomas Gleixner, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List,
	Stephen Warren, Thierry Reding, Alexandre Courbot

From: Thomas Gleixner <tglx@linutronix.de>

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Stephen Warren <swarren@wwwdotorg.org>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Alexandre Courbot <gnurou@gmail.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 arch/arm/mach-tegra/cpuidle-tegra114.c |    6 +++---
 arch/arm/mach-tegra/cpuidle-tegra20.c  |   10 +++++-----
 arch/arm/mach-tegra/cpuidle-tegra30.c  |   10 +++++-----
 3 files changed, 13 insertions(+), 13 deletions(-)

Index: linux-pm/arch/arm/mach-tegra/cpuidle-tegra114.c
===================================================================
--- linux-pm.orig/arch/arm/mach-tegra/cpuidle-tegra114.c
+++ linux-pm/arch/arm/mach-tegra/cpuidle-tegra114.c
@@ -15,7 +15,7 @@
  */
 
 #include <asm/firmware.h>
-#include <linux/clockchips.h>
+#include <linux/tick.h>
 #include <linux/cpuidle.h>
 #include <linux/cpu_pm.h>
 #include <linux/kernel.h>
@@ -44,7 +44,7 @@ static int tegra114_idle_power_down(stru
 	tegra_set_cpu_in_lp2();
 	cpu_pm_enter();
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
+	tick_broadcast_enter();
 
 	call_firmware_op(prepare_idle);
 
@@ -52,7 +52,7 @@ static int tegra114_idle_power_down(stru
 	if (call_firmware_op(do_idle, 0) == -ENOSYS)
 		cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
+	tick_broadcast_exit();
 
 	cpu_pm_exit();
 	tegra_clear_cpu_in_lp2();
Index: linux-pm/arch/arm/mach-tegra/cpuidle-tegra20.c
===================================================================
--- linux-pm.orig/arch/arm/mach-tegra/cpuidle-tegra20.c
+++ linux-pm/arch/arm/mach-tegra/cpuidle-tegra20.c
@@ -20,7 +20,7 @@
  */
 
 #include <linux/clk/tegra.h>
-#include <linux/clockchips.h>
+#include <linux/tick.h>
 #include <linux/cpuidle.h>
 #include <linux/cpu_pm.h>
 #include <linux/kernel.h>
@@ -135,11 +135,11 @@ static bool tegra20_cpu_cluster_power_do
 	if (tegra20_reset_cpu_1() || !tegra_cpu_rail_off_ready())
 		return false;
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
+	tick_broadcast_enter();
 
 	tegra_idle_lp2_last();
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
+	tick_broadcast_exit();
 
 	if (cpu_online(1))
 		tegra20_wake_cpu1_from_reset();
@@ -152,13 +152,13 @@ static bool tegra20_idle_enter_lp2_cpu_1
 					 struct cpuidle_driver *drv,
 					 int index)
 {
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
+	tick_broadcast_enter();
 
 	cpu_suspend(0, tegra20_sleep_cpu_secondary_finish);
 
 	tegra20_cpu_clear_resettable();
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
+	tick_broadcast_exit();
 
 	return true;
 }
Index: linux-pm/arch/arm/mach-tegra/cpuidle-tegra30.c
===================================================================
--- linux-pm.orig/arch/arm/mach-tegra/cpuidle-tegra30.c
+++ linux-pm/arch/arm/mach-tegra/cpuidle-tegra30.c
@@ -20,7 +20,7 @@
  */
 
 #include <linux/clk/tegra.h>
-#include <linux/clockchips.h>
+#include <linux/tick.h>
 #include <linux/cpuidle.h>
 #include <linux/cpu_pm.h>
 #include <linux/kernel.h>
@@ -75,11 +75,11 @@ static bool tegra30_cpu_cluster_power_do
 		return false;
 	}
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
+	tick_broadcast_enter();
 
 	tegra_idle_lp2_last();
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
+	tick_broadcast_exit();
 
 	return true;
 }
@@ -89,13 +89,13 @@ static bool tegra30_cpu_core_power_down(
 					struct cpuidle_driver *drv,
 					int index)
 {
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
+	tick_broadcast_enter();
 
 	smp_wmb();
 
 	cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
+	tick_broadcast_exit();
 
 	return true;
 }


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [v2][PATCH 17/21] sched/idle: Use explicit broadcast oneshot control function
  2015-04-02 23:45     ` [v2][PATCH 00/21] " Rafael J. Wysocki
                         ` (15 preceding siblings ...)
  2015-04-03  0:32       ` [v2][PATCH 16/21] ARM: tegra: " Rafael J. Wysocki
@ 2015-04-03  0:34       ` Rafael J. Wysocki
  2015-04-03  8:26         ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2015-04-03  0:36       ` [v2][PATCH 18/21] clockevents: Remove broadcast oneshot control leftovers Rafael J. Wysocki
                         ` (4 subsequent siblings)
  21 siblings, 1 reply; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-03  0:34 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Peter Zijlstra, Thomas Gleixner, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List

From: Thomas Gleixner <tglx@linutronix.de>

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 kernel/sched/idle.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

Index: linux-pm/kernel/sched/idle.c
===================================================================
--- linux-pm.orig/kernel/sched/idle.c
+++ linux-pm/kernel/sched/idle.c
@@ -158,8 +158,7 @@ static void cpuidle_idle_call(void)
 	 * is used from another cpu as a broadcast timer, this call may
 	 * fail if it is not available
 	 */
-	if (broadcast &&
-	    clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu))
+	if (broadcast && tick_broadcast_enter())
 		goto use_default;
 
 	/* Take note of the planned idle state. */
@@ -176,7 +175,7 @@ static void cpuidle_idle_call(void)
 	idle_set_state(this_rq(), NULL);
 
 	if (broadcast)
-		clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
+		tick_broadcast_exit();
 
 	/*
 	 * Give the governor an opportunity to reflect on the outcome


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [v2][PATCH 18/21] clockevents: Remove broadcast oneshot control leftovers
  2015-04-02 23:45     ` [v2][PATCH 00/21] " Rafael J. Wysocki
                         ` (16 preceding siblings ...)
  2015-04-03  0:34       ` [v2][PATCH 17/21] sched/idle: " Rafael J. Wysocki
@ 2015-04-03  0:36       ` Rafael J. Wysocki
  2015-04-03  8:26         ` [tip:timers/core] " tip-bot for Rafael J. Wysocki
  2015-04-03  0:37       ` [v2][PATCH 19/21] clockevents: Make tick handover explicit Rafael J. Wysocki
                         ` (3 subsequent siblings)
  21 siblings, 1 reply; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-03  0:36 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Peter Zijlstra, Thomas Gleixner, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

All users converted. Remove the notify leftovers.

Original-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 include/linux/clockchips.h |    2 --
 kernel/time/clockevents.c  |    7 -------
 2 files changed, 9 deletions(-)

Index: linux-pm/include/linux/clockchips.h
===================================================================
--- linux-pm.orig/include/linux/clockchips.h
+++ linux-pm/include/linux/clockchips.h
@@ -11,8 +11,6 @@
 /* Clock event notification values */
 enum clock_event_nofitiers {
 	CLOCK_EVT_NOTIFY_ADD,
-	CLOCK_EVT_NOTIFY_BROADCAST_ENTER,
-	CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
 	CLOCK_EVT_NOTIFY_CPU_DYING,
 	CLOCK_EVT_NOTIFY_CPU_DEAD,
 };
Index: linux-pm/kernel/time/clockevents.c
===================================================================
--- linux-pm.orig/kernel/time/clockevents.c
+++ linux-pm/kernel/time/clockevents.c
@@ -655,13 +655,6 @@ int clockevents_notify(unsigned long rea
 	raw_spin_lock_irqsave(&clockevents_lock, flags);
 
 	switch (reason) {
-	case CLOCK_EVT_NOTIFY_BROADCAST_ENTER:
-		tick_broadcast_enter();
-		break;
-	case CLOCK_EVT_NOTIFY_BROADCAST_EXIT:
-		tick_broadcast_exit();
-		break;
-
 	case CLOCK_EVT_NOTIFY_CPU_DYING:
 		tick_handover_do_timer(arg);
 		break;


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [v2][PATCH 19/21] clockevents: Make tick handover explicit
  2015-04-02 23:45     ` [v2][PATCH 00/21] " Rafael J. Wysocki
                         ` (17 preceding siblings ...)
  2015-04-03  0:36       ` [v2][PATCH 18/21] clockevents: Remove broadcast oneshot control leftovers Rafael J. Wysocki
@ 2015-04-03  0:37       ` Rafael J. Wysocki
  2015-04-03  8:26         ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2015-04-03  0:38       ` [v2][PATCH 20/21] clockevents: Cleanup dead cpu explicitely Rafael J. Wysocki
                         ` (2 subsequent siblings)
  21 siblings, 1 reply; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-03  0:37 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Peter Zijlstra, Thomas Gleixner, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List

From: Thomas Gleixner <tglx@linutronix.de>

clockevents_notify() is a leftover from the early design of the
clockevents facility. It's really not a notification mechanism, it's a
multiplex call. We are way better off to have explicit calls instead of this
monstrosity.

Split out the tick_handover call and invoke it explicitely from the
hotplug code. Temporary solution will be cleaned up in later patches.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
[ rjw: Rebase ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 include/linux/clockchips.h  |    1 -
 include/linux/tick.h        |    2 ++
 kernel/cpu.c                |    2 ++
 kernel/time/clockevents.c   |    4 ----
 kernel/time/hrtimer.c       |    4 ----
 kernel/time/tick-common.c   |    9 ++++++---
 kernel/time/tick-internal.h |    1 -
 7 files changed, 10 insertions(+), 13 deletions(-)

Index: linux-pm/include/linux/clockchips.h
===================================================================
--- linux-pm.orig/include/linux/clockchips.h
+++ linux-pm/include/linux/clockchips.h
@@ -11,7 +11,6 @@
 /* Clock event notification values */
 enum clock_event_nofitiers {
 	CLOCK_EVT_NOTIFY_ADD,
-	CLOCK_EVT_NOTIFY_CPU_DYING,
 	CLOCK_EVT_NOTIFY_CPU_DEAD,
 };
 
Index: linux-pm/include/linux/tick.h
===================================================================
--- linux-pm.orig/include/linux/tick.h
+++ linux-pm/include/linux/tick.h
@@ -19,12 +19,14 @@ extern void tick_unfreeze(void);
 extern void tick_suspend_local(void);
 /* Should be core only, but XEN resume magic and ARM BL switcher require it */
 extern void tick_resume_local(void);
+extern void tick_handover_do_timer(void);
 #else /* CONFIG_GENERIC_CLOCKEVENTS */
 static inline void tick_init(void) { }
 static inline void tick_freeze(void) { }
 static inline void tick_unfreeze(void) { }
 static inline void tick_suspend_local(void) { }
 static inline void tick_resume_local(void) { }
+static inline void tick_handover_do_timer(void) { }
 #endif /* !CONFIG_GENERIC_CLOCKEVENTS */
 
 #ifdef CONFIG_TICK_ONESHOT
Index: linux-pm/kernel/cpu.c
===================================================================
--- linux-pm.orig/kernel/cpu.c
+++ linux-pm/kernel/cpu.c
@@ -339,6 +339,8 @@ static int __ref take_cpu_down(void *_pa
 		return err;
 
 	cpu_notify(CPU_DYING | param->mod, param->hcpu);
+	/* Give up timekeeping duties */
+	tick_handover_do_timer();
 	/* Park the stopper thread */
 	kthread_park(current);
 	return 0;
Index: linux-pm/kernel/time/clockevents.c
===================================================================
--- linux-pm.orig/kernel/time/clockevents.c
+++ linux-pm/kernel/time/clockevents.c
@@ -655,10 +655,6 @@ int clockevents_notify(unsigned long rea
 	raw_spin_lock_irqsave(&clockevents_lock, flags);
 
 	switch (reason) {
-	case CLOCK_EVT_NOTIFY_CPU_DYING:
-		tick_handover_do_timer(arg);
-		break;
-
 	case CLOCK_EVT_NOTIFY_CPU_DEAD:
 		tick_shutdown_broadcast_oneshot(arg);
 		tick_shutdown_broadcast(arg);
Index: linux-pm/kernel/time/hrtimer.c
===================================================================
--- linux-pm.orig/kernel/time/hrtimer.c
+++ linux-pm/kernel/time/hrtimer.c
@@ -1707,10 +1707,6 @@ static int hrtimer_cpu_notify(struct not
 		break;
 
 #ifdef CONFIG_HOTPLUG_CPU
-	case CPU_DYING:
-	case CPU_DYING_FROZEN:
-		clockevents_notify(CLOCK_EVT_NOTIFY_CPU_DYING, &scpu);
-		break;
 	case CPU_DEAD:
 	case CPU_DEAD_FROZEN:
 	{
Index: linux-pm/kernel/time/tick-common.c
===================================================================
--- linux-pm.orig/kernel/time/tick-common.c
+++ linux-pm/kernel/time/tick-common.c
@@ -332,20 +332,23 @@ out_bc:
 	tick_install_broadcast_device(newdev);
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
 /*
  * Transfer the do_timer job away from a dying cpu.
  *
- * Called with interrupts disabled.
+ * Called with interrupts disabled. Not locking required. If
+ * tick_do_timer_cpu is owned by this cpu, nothing can change it.
  */
-void tick_handover_do_timer(int *cpup)
+void tick_handover_do_timer(void)
 {
-	if (*cpup == tick_do_timer_cpu) {
+	if (tick_do_timer_cpu == smp_processor_id()) {
 		int cpu = cpumask_first(cpu_online_mask);
 
 		tick_do_timer_cpu = (cpu < nr_cpu_ids) ? cpu :
 			TICK_DO_TIMER_NONE;
 	}
 }
+#endif
 
 /*
  * Shutdown an event device on a given cpu:
Index: linux-pm/kernel/time/tick-internal.h
===================================================================
--- linux-pm.orig/kernel/time/tick-internal.h
+++ linux-pm/kernel/time/tick-internal.h
@@ -20,7 +20,6 @@ extern int tick_do_timer_cpu __read_most
 extern void tick_setup_periodic(struct clock_event_device *dev, int broadcast);
 extern void tick_handle_periodic(struct clock_event_device *dev);
 extern void tick_check_new_device(struct clock_event_device *dev);
-extern void tick_handover_do_timer(int *cpup);
 extern void tick_shutdown(unsigned int *cpup);
 extern void tick_suspend(void);
 extern void tick_resume(void);


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [v2][PATCH 20/21] clockevents: Cleanup dead cpu explicitely
  2015-04-02 23:45     ` [v2][PATCH 00/21] " Rafael J. Wysocki
                         ` (18 preceding siblings ...)
  2015-04-03  0:37       ` [v2][PATCH 19/21] clockevents: Make tick handover explicit Rafael J. Wysocki
@ 2015-04-03  0:38       ` Rafael J. Wysocki
  2015-04-03  8:26         ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2015-04-03  0:39       ` [v2][PATCH 21/21] timekeeping: Get rid of stale comment Rafael J. Wysocki
  2015-04-03  6:45       ` [v2][PATCH 00/21] clockevents_notify() removal Ingo Molnar
  21 siblings, 1 reply; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-03  0:38 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Peter Zijlstra, Thomas Gleixner, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List

From: Thomas Gleixner <tglx@linutronix.de>

clockevents_notify() is a leftover from the early design of the
clockevents facility. It's really not a notification mechanism, it's a
multiplex call. We are way better off to have explicit calls instead of this
monstrosity.

Split out the cleanup function for a dead cpu and invoke it directly
from the cpu down code. Make it conditional on CPU_HOTPLUG as well.

Temporary change, will be refined in the future.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
[ rjw: Rebased, added clockevents_notify() removal ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 include/linux/clockchips.h   |    6 -----
 include/linux/tick.h         |    2 +
 kernel/cpu.c                 |    1 
 kernel/time/clockevents.c    |   51 +++++++++++++++++--------------------------
 kernel/time/hrtimer.c        |    3 --
 kernel/time/tick-broadcast.c |   39 ++++++++++++++++----------------
 kernel/time/tick-common.c    |    6 ++---
 kernel/time/tick-internal.h  |   10 ++++----
 8 files changed, 52 insertions(+), 66 deletions(-)

Index: linux-pm/include/linux/clockchips.h
===================================================================
--- linux-pm.orig/include/linux/clockchips.h
+++ linux-pm/include/linux/clockchips.h
@@ -8,12 +8,6 @@
 #ifndef _LINUX_CLOCKCHIPS_H
 #define _LINUX_CLOCKCHIPS_H
 
-/* Clock event notification values */
-enum clock_event_nofitiers {
-	CLOCK_EVT_NOTIFY_ADD,
-	CLOCK_EVT_NOTIFY_CPU_DEAD,
-};
-
 #ifdef CONFIG_GENERIC_CLOCKEVENTS
 
 # include <linux/clocksource.h>
Index: linux-pm/include/linux/tick.h
===================================================================
--- linux-pm.orig/include/linux/tick.h
+++ linux-pm/include/linux/tick.h
@@ -20,6 +20,7 @@ extern void tick_suspend_local(void);
 /* Should be core only, but XEN resume magic and ARM BL switcher require it */
 extern void tick_resume_local(void);
 extern void tick_handover_do_timer(void);
+extern void tick_cleanup_dead_cpu(int cpu);
 #else /* CONFIG_GENERIC_CLOCKEVENTS */
 static inline void tick_init(void) { }
 static inline void tick_freeze(void) { }
@@ -27,6 +28,7 @@ static inline void tick_unfreeze(void) {
 static inline void tick_suspend_local(void) { }
 static inline void tick_resume_local(void) { }
 static inline void tick_handover_do_timer(void) { }
+static inline void tick_cleanup_dead_cpu(int cpu) { }
 #endif /* !CONFIG_GENERIC_CLOCKEVENTS */
 
 #ifdef CONFIG_TICK_ONESHOT
Index: linux-pm/kernel/cpu.c
===================================================================
--- linux-pm.orig/kernel/cpu.c
+++ linux-pm/kernel/cpu.c
@@ -419,6 +419,7 @@ static int __ref _cpu_down(unsigned int
 	__cpu_die(cpu);
 
 	/* CPU is completely dead: tell everyone.  Too late to complain. */
+	tick_cleanup_dead_cpu(cpu);
 	cpu_notify_nofail(CPU_DEAD | mod, hcpu);
 
 	check_for_tasks(cpu);
Index: linux-pm/kernel/time/clockevents.c
===================================================================
--- linux-pm.orig/kernel/time/clockevents.c
+++ linux-pm/kernel/time/clockevents.c
@@ -642,49 +642,40 @@ void clockevents_resume(void)
 			dev->resume(dev);
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
 /**
- * clockevents_notify - notification about relevant events
- * Returns 0 on success, any other value on error
+ * tick_cleanup_dead_cpu - Cleanup the tick and clockevents of a dead cpu
  */
-int clockevents_notify(unsigned long reason, void *arg)
+void tick_cleanup_dead_cpu(int cpu)
 {
 	struct clock_event_device *dev, *tmp;
 	unsigned long flags;
-	int cpu, ret = 0;
 
 	raw_spin_lock_irqsave(&clockevents_lock, flags);
 
-	switch (reason) {
-	case CLOCK_EVT_NOTIFY_CPU_DEAD:
-		tick_shutdown_broadcast_oneshot(arg);
-		tick_shutdown_broadcast(arg);
-		tick_shutdown(arg);
-		/*
-		 * Unregister the clock event devices which were
-		 * released from the users in the notify chain.
-		 */
-		list_for_each_entry_safe(dev, tmp, &clockevents_released, list)
+	tick_shutdown_broadcast_oneshot(cpu);
+	tick_shutdown_broadcast(cpu);
+	tick_shutdown(cpu);
+	/*
+	 * Unregister the clock event devices which were
+	 * released from the users in the notify chain.
+	 */
+	list_for_each_entry_safe(dev, tmp, &clockevents_released, list)
+		list_del(&dev->list);
+	/*
+	 * Now check whether the CPU has left unused per cpu devices
+	 */
+	list_for_each_entry_safe(dev, tmp, &clockevent_devices, list) {
+		if (cpumask_test_cpu(cpu, dev->cpumask) &&
+		    cpumask_weight(dev->cpumask) == 1 &&
+		    !tick_is_broadcast_device(dev)) {
+			BUG_ON(dev->state != CLOCK_EVT_STATE_DETACHED);
 			list_del(&dev->list);
-		/*
-		 * Now check whether the CPU has left unused per cpu devices
-		 */
-		cpu = *((int *)arg);
-		list_for_each_entry_safe(dev, tmp, &clockevent_devices, list) {
-			if (cpumask_test_cpu(cpu, dev->cpumask) &&
-			    cpumask_weight(dev->cpumask) == 1 &&
-			    !tick_is_broadcast_device(dev)) {
-				BUG_ON(dev->state != CLOCK_EVT_STATE_DETACHED);
-				list_del(&dev->list);
-			}
 		}
-		break;
-	default:
-		break;
 	}
 	raw_spin_unlock_irqrestore(&clockevents_lock, flags);
-	return ret;
 }
-EXPORT_SYMBOL_GPL(clockevents_notify);
+#endif
 
 #ifdef CONFIG_SYSFS
 struct bus_type clockevents_subsys = {
Index: linux-pm/kernel/time/hrtimer.c
===================================================================
--- linux-pm.orig/kernel/time/hrtimer.c
+++ linux-pm/kernel/time/hrtimer.c
@@ -1709,11 +1709,8 @@ static int hrtimer_cpu_notify(struct not
 #ifdef CONFIG_HOTPLUG_CPU
 	case CPU_DEAD:
 	case CPU_DEAD_FROZEN:
-	{
-		clockevents_notify(CLOCK_EVT_NOTIFY_CPU_DEAD, &scpu);
 		migrate_hrtimers(scpu);
 		break;
-	}
 #endif
 
 	default:
Index: linux-pm/kernel/time/tick-broadcast.c
===================================================================
--- linux-pm.orig/kernel/time/tick-broadcast.c
+++ linux-pm/kernel/time/tick-broadcast.c
@@ -410,14 +410,14 @@ void tick_set_periodic_handler(struct cl
 		dev->event_handler = tick_handle_periodic_broadcast;
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
 /*
  * Remove a CPU from broadcasting
  */
-void tick_shutdown_broadcast(unsigned int *cpup)
+void tick_shutdown_broadcast(unsigned int cpu)
 {
 	struct clock_event_device *bc;
 	unsigned long flags;
-	unsigned int cpu = *cpup;
 
 	raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
 
@@ -432,6 +432,7 @@ void tick_shutdown_broadcast(unsigned in
 
 	raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
 }
+#endif
 
 void tick_suspend_broadcast(void)
 {
@@ -672,21 +673,6 @@ static void broadcast_shutdown_local(str
 	clockevents_set_state(dev, CLOCK_EVT_STATE_SHUTDOWN);
 }
 
-void hotplug_cpu__broadcast_tick_pull(int deadcpu)
-{
-	struct clock_event_device *bc;
-	unsigned long flags;
-
-	raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
-	bc = tick_broadcast_device.evtdev;
-
-	if (bc && broadcast_needs_cpu(bc, deadcpu)) {
-		/* This moves the broadcast assignment to this CPU: */
-		clockevents_program_event(bc, bc->next_event, 1);
-	}
-	raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
-}
-
 /**
  * tick_broadcast_oneshot_control - Enter/exit broadcast oneshot mode
  * @state:	The target state (enter/exit)
@@ -908,14 +894,28 @@ void tick_broadcast_switch_to_oneshot(vo
 	raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
+void hotplug_cpu__broadcast_tick_pull(int deadcpu)
+{
+	struct clock_event_device *bc;
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
+	bc = tick_broadcast_device.evtdev;
+
+	if (bc && broadcast_needs_cpu(bc, deadcpu)) {
+		/* This moves the broadcast assignment to this CPU: */
+		clockevents_program_event(bc, bc->next_event, 1);
+	}
+	raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
+}
 
 /*
  * Remove a dead CPU from broadcasting
  */
-void tick_shutdown_broadcast_oneshot(unsigned int *cpup)
+void tick_shutdown_broadcast_oneshot(unsigned int cpu)
 {
 	unsigned long flags;
-	unsigned int cpu = *cpup;
 
 	raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
 
@@ -929,6 +929,7 @@ void tick_shutdown_broadcast_oneshot(uns
 
 	raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
 }
+#endif
 
 /*
  * Check, whether the broadcast device is in one shot mode
Index: linux-pm/kernel/time/tick-common.c
===================================================================
--- linux-pm.orig/kernel/time/tick-common.c
+++ linux-pm/kernel/time/tick-common.c
@@ -348,7 +348,6 @@ void tick_handover_do_timer(void)
 			TICK_DO_TIMER_NONE;
 	}
 }
-#endif
 
 /*
  * Shutdown an event device on a given cpu:
@@ -357,9 +356,9 @@ void tick_handover_do_timer(void)
  * access the hardware device itself.
  * We just set the mode and remove it from the lists.
  */
-void tick_shutdown(unsigned int *cpup)
+void tick_shutdown(unsigned int cpu)
 {
-	struct tick_device *td = &per_cpu(tick_cpu_device, *cpup);
+	struct tick_device *td = &per_cpu(tick_cpu_device, cpu);
 	struct clock_event_device *dev = td->evtdev;
 
 	td->mode = TICKDEV_MODE_PERIODIC;
@@ -375,6 +374,7 @@ void tick_shutdown(unsigned int *cpup)
 		td->evtdev = NULL;
 	}
 }
+#endif
 
 /**
  * tick_suspend_local - Suspend the local tick device
Index: linux-pm/kernel/time/tick-internal.h
===================================================================
--- linux-pm.orig/kernel/time/tick-internal.h
+++ linux-pm/kernel/time/tick-internal.h
@@ -20,7 +20,7 @@ extern int tick_do_timer_cpu __read_most
 extern void tick_setup_periodic(struct clock_event_device *dev, int broadcast);
 extern void tick_handle_periodic(struct clock_event_device *dev);
 extern void tick_check_new_device(struct clock_event_device *dev);
-extern void tick_shutdown(unsigned int *cpup);
+extern void tick_shutdown(unsigned int cpu);
 extern void tick_suspend(void);
 extern void tick_resume(void);
 extern bool tick_check_replacement(struct clock_event_device *curdev,
@@ -52,7 +52,7 @@ extern ssize_t sysfs_get_uname(const cha
 extern int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu);
 extern void tick_install_broadcast_device(struct clock_event_device *dev);
 extern int tick_is_broadcast_device(struct clock_event_device *dev);
-extern void tick_shutdown_broadcast(unsigned int *cpup);
+extern void tick_shutdown_broadcast(unsigned int cpu);
 extern void tick_suspend_broadcast(void);
 extern void tick_resume_broadcast(void);
 extern bool tick_resume_check_broadcast(void);
@@ -66,7 +66,7 @@ static inline void tick_install_broadcas
 static inline int tick_is_broadcast_device(struct clock_event_device *dev) { return 0; }
 static inline int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu) { return 0; }
 static inline void tick_do_periodic_broadcast(struct clock_event_device *d) { }
-static inline void tick_shutdown_broadcast(unsigned int *cpup) { }
+static inline void tick_shutdown_broadcast(unsigned int cpu) { }
 static inline void tick_suspend_broadcast(void) { }
 static inline void tick_resume_broadcast(void) { }
 static inline bool tick_resume_check_broadcast(void) { return false; }
@@ -119,7 +119,7 @@ static inline int tick_check_oneshot_cha
 #if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) && defined(CONFIG_TICK_ONESHOT)
 extern void tick_broadcast_setup_oneshot(struct clock_event_device *bc);
 extern void tick_broadcast_switch_to_oneshot(void);
-extern void tick_shutdown_broadcast_oneshot(unsigned int *cpup);
+extern void tick_shutdown_broadcast_oneshot(unsigned int cpu);
 extern int tick_broadcast_oneshot_active(void);
 extern void tick_check_oneshot_broadcast_this_cpu(void);
 bool tick_broadcast_oneshot_available(void);
@@ -127,7 +127,7 @@ extern struct cpumask *tick_get_broadcas
 #else /* !(BROADCAST && ONESHOT): */
 static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc) { BUG(); }
 static inline void tick_broadcast_switch_to_oneshot(void) { }
-static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { }
+static inline void tick_shutdown_broadcast_oneshot(unsigned int cpu) { }
 static inline int tick_broadcast_oneshot_active(void) { return 0; }
 static inline void tick_check_oneshot_broadcast_this_cpu(void) { }
 static inline bool tick_broadcast_oneshot_available(void) { return tick_oneshot_possible(); }


^ permalink raw reply	[flat|nested] 90+ messages in thread

* [v2][PATCH 21/21] timekeeping: Get rid of stale comment
  2015-04-02 23:45     ` [v2][PATCH 00/21] " Rafael J. Wysocki
                         ` (19 preceding siblings ...)
  2015-04-03  0:38       ` [v2][PATCH 20/21] clockevents: Cleanup dead cpu explicitely Rafael J. Wysocki
@ 2015-04-03  0:39       ` Rafael J. Wysocki
  2015-04-03  8:27         ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2015-04-03  6:45       ` [v2][PATCH 00/21] clockevents_notify() removal Ingo Molnar
  21 siblings, 1 reply; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-03  0:39 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Peter Zijlstra, Thomas Gleixner, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List, John Stultz

From: Thomas Gleixner <tglx@linutronix.de>

Arch specific management of xtime/jiffies/wall_to_monotonic is gone
for quite a while. Zap the stale comment.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: John Stultz <john.stultz@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 kernel/time/timekeeping.c |    4 ----
 1 file changed, 4 deletions(-)

Index: linux-pm/kernel/time/timekeeping.c
===================================================================
--- linux-pm.orig/kernel/time/timekeeping.c
+++ linux-pm/kernel/time/timekeeping.c
@@ -1307,10 +1307,6 @@ void timekeeping_inject_sleeptime64(stru
 
 /**
  * timekeeping_resume - Resumes the generic timekeeping subsystem.
- *
- * This is for the generic clocksource timekeeping.
- * xtime/wall_to_monotonic/jiffies/etc are
- * still managed by arch specific suspend/resume code.
  */
 void timekeeping_resume(void)
 {


^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [v2][PATCH 00/21] clockevents_notify() removal
  2015-04-02 23:45     ` [v2][PATCH 00/21] " Rafael J. Wysocki
                         ` (20 preceding siblings ...)
  2015-04-03  0:39       ` [v2][PATCH 21/21] timekeeping: Get rid of stale comment Rafael J. Wysocki
@ 2015-04-03  6:45       ` Ingo Molnar
  21 siblings, 0 replies; 90+ messages in thread
From: Ingo Molnar @ 2015-04-03  6:45 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Peter Zijlstra, Thomas Gleixner, Linux PM list,
	Linux Kernel Mailing List, ACPI Devel Maling List


* Rafael J. Wysocki <rjw@rjwysocki.net> wrote:

> On Friday, April 03, 2015 12:19:41 AM Rafael J. Wysocki wrote:
> > On Thursday, April 02, 2015 02:39:35 PM Ingo Molnar wrote:
> > > 
> > > * Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> > > 
> > > > Hi,
> > > > 
> > > > This is the next batch of patches from Thomas that remove clockevents_notify().
> > > > 
> > > > I've reordered the set (to put more stratightforward things to the front) and
> > > > rebased it on top of the timers material currently queued up for 4.1.
> > > > 
> > > > This series in based on the bleeding-edge branch of the linux-pm tree (which
> > > > for all practical purposes is my linux-next branch with timers/core from tip
> > > > merged into it).
> > > > 
> > > > Please let me know how to proceed with these.
> > > 
> > > Would you mind to resend these merged on top of the very latest 
> > > tip:timers/core (or tip:master) tree?
> > > 
> > > These changes conflict (mildly) with the other series from Thomas 
> > > which needed some fixes/enhancements.
> > 
> > I'll do that later today.
> > 
> > This series also depends on:
> > 
> > http://git.kernel.org/cgit/linux/kernel/git/rafael/linux-pm.git/commit/?h=acpi-pad&id=6e9f8b5f1f319cbdb4cfe3696fc74fbe39318960
> > 
> > which is in my acpi-pad branch at the moment, but I'll add it to the front of
> > the series in case you prefer to apply it directly.
> 
> The patches follow as per the above.  [2-21/21] rebased on top of the current
> timers/core.

Thanks! I picked them up into tip:timers/core and will push them out 
after some testing.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [tip:timers/core] ACPI/PAD: Remove the local APIC nonsense
  2015-04-02 23:46       ` [v2][PATCH 01/21] ACPI / PAD: Remove the local APIC nonsense Rafael J. Wysocki
@ 2015-04-03  8:21         ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 90+ messages in thread
From: tip-bot for Thomas Gleixner @ 2015-04-03  8:21 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: tglx, bp, mingo, torvalds, rafael.j.wysocki, linux-kernel, peterz, hpa

Commit-ID:  3ff70551a942b4c1d3c2e96e31a5c6e369a6d0be
Gitweb:     http://git.kernel.org/tip/3ff70551a942b4c1d3c2e96e31a5c6e369a6d0be
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 3 Apr 2015 01:46:34 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:44:31 +0200

ACPI/PAD: Remove the local APIC nonsense

While looking through the (ab)use of the clockevents_notify()
function I stumbled over the following gem in the acpi_pad code:

  if (lapic_detected_unstable && !lapic_marked_unstable) {
     /* LAPIC could halt in idle, so notify users */
     for_each_online_cpu(i)
       clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &i);
     lapic_marked_unstable = 1;
  }

This code calls on the cpu which detects the lapic unstable
condition first clockevents_notify() to tell the core code that
the broadcast should be enabled on all online cpus. Brilliant
stuff that as it notifies the core code a num_online_cpus()
times that the broadcast should be enabled on the current cpu.

This probably has never been noticed because that code got never
tested with NOHZ=n and HIGHRES_TIMER=n or it just worked by
chance because one of the other mechanisms told the core in the
right way that the local apic timer is wreckaged.

Sigh, this is:

 - The 4th incarnation of idle drivers which has their own mechanism
   to detect and deal with X86_FEATURE_ARAT.

 - The 2nd incarnation of fake idle mechanisms with a different set of
   brainmelting bugs.

 - Has been merged against an explicit NAK of the scheduler
   maintainer with the promise to improve it over time.

 - Another example of featuritis driven trainwreck engineering.

 - Another pointless waste of my time.

Fix this nonsense by removing that lapic detection and
notification logic and simply call into the clockevents code
unconditonally. The ARAT feature is marked in the lapic
clockevent already so the core code will just ignore the
requests and return.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1887788.RObRuI4tSv@vostro.rjw.lan
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 drivers/acpi/acpi_pad.c | 26 +++++---------------------
 1 file changed, 5 insertions(+), 21 deletions(-)

diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c
index c7b105c..1686e9f 100644
--- a/drivers/acpi/acpi_pad.c
+++ b/drivers/acpi/acpi_pad.c
@@ -41,8 +41,6 @@ static unsigned long power_saving_mwait_eax;
 
 static unsigned char tsc_detected_unstable;
 static unsigned char tsc_marked_unstable;
-static unsigned char lapic_detected_unstable;
-static unsigned char lapic_marked_unstable;
 
 static void power_saving_mwait_init(void)
 {
@@ -82,13 +80,10 @@ static void power_saving_mwait_init(void)
 		 */
 		if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
 			tsc_detected_unstable = 1;
-		if (!boot_cpu_has(X86_FEATURE_ARAT))
-			lapic_detected_unstable = 1;
 		break;
 	default:
-		/* TSC & LAPIC could halt in idle */
+		/* TSC could halt in idle */
 		tsc_detected_unstable = 1;
-		lapic_detected_unstable = 1;
 	}
 #endif
 }
@@ -177,28 +172,17 @@ static int power_saving_thread(void *data)
 				mark_tsc_unstable("TSC halts in idle");
 				tsc_marked_unstable = 1;
 			}
-			if (lapic_detected_unstable && !lapic_marked_unstable) {
-				int i;
-				/* LAPIC could halt in idle, so notify users */
-				for_each_online_cpu(i)
-					clockevents_notify(
-						CLOCK_EVT_NOTIFY_BROADCAST_ON,
-						&i);
-				lapic_marked_unstable = 1;
-			}
+			clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu);
+
 			local_irq_disable();
 			cpu = smp_processor_id();
-			if (lapic_marked_unstable)
-				clockevents_notify(
-					CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
+			clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
 			stop_critical_timings();
 
 			mwait_idle_with_hints(power_saving_mwait_eax, 1);
 
 			start_critical_timings();
-			if (lapic_marked_unstable)
-				clockevents_notify(
-					CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
+			clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
 			local_irq_enable();
 
 			if (time_before(expire_time, jiffies)) {

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [tip:timers/core] clockevents: Provide explicit broadcast control functions
  2015-04-03  0:01       ` [v2][PATCH 02/21] clockevents: Provide explicit broadcast control functions Rafael J. Wysocki
@ 2015-04-03  8:21         ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 90+ messages in thread
From: tip-bot for Thomas Gleixner @ 2015-04-03  8:21 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: daniel.lezcano, lenb, hpa, mingo, tglx, linux-kernel, tony,
	peterz, rafael.j.wysocki

Commit-ID:  592a438ff3fea61d303c5784c209b3f1fd3e16df
Gitweb:     http://git.kernel.org/tip/592a438ff3fea61d303c5784c209b3f1fd3e16df
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 3 Apr 2015 02:01:10 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:44:31 +0200

clockevents: Provide explicit broadcast control functions

clockevents_notify() is a leftover from the early design of the
clockevents facility. It's really not a notification mechanism,
it's a multiplex call. We are way better off to have explicit
calls instead of this monstrosity.

Split out the broadcast control into a separate function and
provide inline helpers. Switch clockevents_notify() over. This
will go away once all callers are converted.

This also gets rid of the nested locking of clockevents_lock and
broadcast_lock. The broadcast control functions do not require
clockevents_lock. Only the managing functions
(setup/shutdown/suspend/resume of the broadcast device require
clockevents_lock.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Len Brown <lenb@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Tony Lindgren <tony@atomide.com>
Link: http://lkml.kernel.org/r/8086559.ttsuS0n1Xr@vostro.rjw.lan
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 include/linux/tick.h         | 25 ++++++++++++++++++
 kernel/time/clockevents.c    |  6 ++++-
 kernel/time/tick-broadcast.c | 62 +++++++++++++++++++-------------------------
 kernel/time/tick-internal.h  |  2 --
 4 files changed, 57 insertions(+), 38 deletions(-)

diff --git a/include/linux/tick.h b/include/linux/tick.h
index f9ff225..4bb2363 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -42,6 +42,31 @@ extern void hotplug_cpu__broadcast_tick_pull(int dead_cpu);
 static inline void hotplug_cpu__broadcast_tick_pull(int dead_cpu) { }
 #endif
 
+enum tick_broadcast_mode {
+	TICK_BROADCAST_OFF,
+	TICK_BROADCAST_ON,
+	TICK_BROADCAST_FORCE,
+};
+
+#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
+extern void tick_broadcast_control(enum tick_broadcast_mode mode);
+#else
+static inline void tick_broadcast_control(enum tick_broadcast_mode mode) { }
+#endif /* BROADCAST */
+
+static inline void tick_broadcast_enable(void)
+{
+	tick_broadcast_control(TICK_BROADCAST_ON);
+}
+static inline void tick_broadcast_disable(void)
+{
+	tick_broadcast_control(TICK_BROADCAST_OFF);
+}
+static inline void tick_broadcast_force(void)
+{
+	tick_broadcast_control(TICK_BROADCAST_FORCE);
+}
+
 #ifdef CONFIG_NO_HZ_COMMON
 extern int tick_nohz_tick_stopped(void);
 extern void tick_nohz_idle_enter(void);
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
index 7af6148..599ff8d 100644
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -656,9 +656,13 @@ int clockevents_notify(unsigned long reason, void *arg)
 
 	switch (reason) {
 	case CLOCK_EVT_NOTIFY_BROADCAST_ON:
+		tick_broadcast_enable();
+		break;
 	case CLOCK_EVT_NOTIFY_BROADCAST_OFF:
+		tick_broadcast_disable();
+		break;
 	case CLOCK_EVT_NOTIFY_BROADCAST_FORCE:
-		tick_broadcast_on_off(reason, arg);
+		tick_broadcast_force();
 		break;
 
 	case CLOCK_EVT_NOTIFY_BROADCAST_ENTER:
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
index f5e0fd5..1a0bee0 100644
--- a/kernel/time/tick-broadcast.c
+++ b/kernel/time/tick-broadcast.c
@@ -33,7 +33,7 @@ static cpumask_var_t tick_broadcast_mask;
 static cpumask_var_t tick_broadcast_on;
 static cpumask_var_t tmpmask;
 static DEFINE_RAW_SPINLOCK(tick_broadcast_lock);
-static int tick_broadcast_force;
+static int tick_broadcast_forced;
 
 #ifdef CONFIG_TICK_ONESHOT
 static void tick_broadcast_clear_oneshot(int cpu);
@@ -326,49 +326,54 @@ unlock:
 	raw_spin_unlock(&tick_broadcast_lock);
 }
 
-/*
- * Powerstate information: The system enters/leaves a state, where
- * affected devices might stop
+/**
+ * tick_broadcast_control - Enable/disable or force broadcast mode
+ * @mode:	The selected broadcast mode
+ *
+ * Called when the system enters a state where affected tick devices
+ * might stop. Note: TICK_BROADCAST_FORCE cannot be undone.
+ *
+ * Called with interrupts disabled, so clockevents_lock is not
+ * required here because the local clock event device cannot go away
+ * under us.
  */
-static void tick_do_broadcast_on_off(unsigned long *reason)
+void tick_broadcast_control(enum tick_broadcast_mode mode)
 {
 	struct clock_event_device *bc, *dev;
 	struct tick_device *td;
-	unsigned long flags;
 	int cpu, bc_stopped;
 
-	raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
-
-	cpu = smp_processor_id();
-	td = &per_cpu(tick_cpu_device, cpu);
+	td = this_cpu_ptr(&tick_cpu_device);
 	dev = td->evtdev;
-	bc = tick_broadcast_device.evtdev;
 
 	/*
 	 * Is the device not affected by the powerstate ?
 	 */
 	if (!dev || !(dev->features & CLOCK_EVT_FEAT_C3STOP))
-		goto out;
+		return;
 
 	if (!tick_device_is_functional(dev))
-		goto out;
+		return;
 
+	raw_spin_lock(&tick_broadcast_lock);
+	cpu = smp_processor_id();
+	bc = tick_broadcast_device.evtdev;
 	bc_stopped = cpumask_empty(tick_broadcast_mask);
 
-	switch (*reason) {
-	case CLOCK_EVT_NOTIFY_BROADCAST_ON:
-	case CLOCK_EVT_NOTIFY_BROADCAST_FORCE:
+	switch (mode) {
+	case TICK_BROADCAST_FORCE:
+		tick_broadcast_forced = 1;
+	case TICK_BROADCAST_ON:
 		cpumask_set_cpu(cpu, tick_broadcast_on);
 		if (!cpumask_test_and_set_cpu(cpu, tick_broadcast_mask)) {
 			if (tick_broadcast_device.mode ==
 			    TICKDEV_MODE_PERIODIC)
 				clockevents_shutdown(dev);
 		}
-		if (*reason == CLOCK_EVT_NOTIFY_BROADCAST_FORCE)
-			tick_broadcast_force = 1;
 		break;
-	case CLOCK_EVT_NOTIFY_BROADCAST_OFF:
-		if (tick_broadcast_force)
+
+	case TICK_BROADCAST_OFF:
+		if (tick_broadcast_forced)
 			break;
 		cpumask_clear_cpu(cpu, tick_broadcast_on);
 		if (!tick_device_is_functional(dev))
@@ -390,22 +395,9 @@ static void tick_do_broadcast_on_off(unsigned long *reason)
 		else
 			tick_broadcast_setup_oneshot(bc);
 	}
-out:
-	raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
-}
-
-/*
- * Powerstate information: The system enters/leaves a state, where
- * affected devices might stop.
- */
-void tick_broadcast_on_off(unsigned long reason, int *oncpu)
-{
-	if (!cpumask_test_cpu(*oncpu, cpu_online_mask))
-		printk(KERN_ERR "tick-broadcast: ignoring broadcast for "
-		       "offline CPU #%d\n", *oncpu);
-	else
-		tick_do_broadcast_on_off(&reason);
+	raw_spin_unlock(&tick_broadcast_lock);
 }
+EXPORT_SYMBOL_GPL(tick_broadcast_control);
 
 /*
  * Set the periodic handler depending on broadcast on/off
diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h
index b6ba0a4..62e331d 100644
--- a/kernel/time/tick-internal.h
+++ b/kernel/time/tick-internal.h
@@ -53,7 +53,6 @@ extern ssize_t sysfs_get_uname(const char *buf, char *dst, size_t cnt);
 extern int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu);
 extern void tick_install_broadcast_device(struct clock_event_device *dev);
 extern int tick_is_broadcast_device(struct clock_event_device *dev);
-extern void tick_broadcast_on_off(unsigned long reason, int *oncpu);
 extern void tick_shutdown_broadcast(unsigned int *cpup);
 extern void tick_suspend_broadcast(void);
 extern void tick_resume_broadcast(void);
@@ -68,7 +67,6 @@ static inline void tick_install_broadcast_device(struct clock_event_device *dev)
 static inline int tick_is_broadcast_device(struct clock_event_device *dev) { return 0; }
 static inline int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu) { return 0; }
 static inline void tick_do_periodic_broadcast(struct clock_event_device *d) { }
-static inline void tick_broadcast_on_off(unsigned long reason, int *oncpu) { }
 static inline void tick_shutdown_broadcast(unsigned int *cpup) { }
 static inline void tick_suspend_broadcast(void) { }
 static inline void tick_resume_broadcast(void) { }

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [tip:timers/core] x86/amd/idle, clockevents: Use explicit broadcast control function
  2015-04-03  0:01       ` [v2][PATCH 03/21] x86, amd_idle: Use explicit broadcast control function Rafael J. Wysocki
@ 2015-04-03  8:22         ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 90+ messages in thread
From: tip-bot for Thomas Gleixner @ 2015-04-03  8:22 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: tglx, peterz, rafael.j.wysocki, hpa, mingo, linux-kernel

Commit-ID:  162a688e84df49c5bcc855a5e5bf812d0ec89ad5
Gitweb:     http://git.kernel.org/tip/162a688e84df49c5bcc855a5e5bf812d0ec89ad5
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 3 Apr 2015 02:01:28 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:44:31 +0200

x86/amd/idle, clockevents: Use explicit broadcast control function

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1528188.S1pjqkSL1P@vostro.rjw.lan
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/kernel/process.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 046e2d6..e94b733 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -9,7 +9,7 @@
 #include <linux/sched.h>
 #include <linux/module.h>
 #include <linux/pm.h>
-#include <linux/clockchips.h>
+#include <linux/tick.h>
 #include <linux/random.h>
 #include <linux/user-return-notifier.h>
 #include <linux/dmi.h>
@@ -377,11 +377,8 @@ static void amd_e400_idle(void)
 
 		if (!cpumask_test_cpu(cpu, amd_e400_c1e_mask)) {
 			cpumask_set_cpu(cpu, amd_e400_c1e_mask);
-			/*
-			 * Force broadcast so ACPI can not interfere.
-			 */
-			clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_FORCE,
-					   &cpu);
+			/* Force broadcast so ACPI can not interfere. */
+			tick_broadcast_force();
 			pr_info("Switch to broadcast mode on CPU%d\n", cpu);
 		}
 		clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [tip:timers/core] ACPI/PAD: Use explicit broadcast control function
  2015-04-03  0:01       ` [v2][PATCH 04/21] ACPI / PAD: " Rafael J. Wysocki
@ 2015-04-03  8:22         ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 90+ messages in thread
From: tip-bot for Thomas Gleixner @ 2015-04-03  8:22 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: mingo, tglx, peterz, linux-kernel, lenb, hpa, rafael.j.wysocki

Commit-ID:  979081e7440056da28b19e57acf20098caf49103
Gitweb:     http://git.kernel.org/tip/979081e7440056da28b19e57acf20098caf49103
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 3 Apr 2015 02:01:49 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:44:32 +0200

ACPI/PAD: Use explicit broadcast control function

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Len Brown <lenb@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1521832.mm0ZfkTzTA@vostro.rjw.lan
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 drivers/acpi/acpi_pad.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c
index 1686e9f..244dbc9 100644
--- a/drivers/acpi/acpi_pad.c
+++ b/drivers/acpi/acpi_pad.c
@@ -26,7 +26,7 @@
 #include <linux/kthread.h>
 #include <linux/freezer.h>
 #include <linux/cpu.h>
-#include <linux/clockchips.h>
+#include <linux/tick.h>
 #include <linux/slab.h>
 #include <linux/acpi.h>
 #include <asm/mwait.h>
@@ -172,9 +172,8 @@ static int power_saving_thread(void *data)
 				mark_tsc_unstable("TSC halts in idle");
 				tsc_marked_unstable = 1;
 			}
-			clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu);
-
 			local_irq_disable();
+			tick_broadcast_enable();
 			cpu = smp_processor_id();
 			clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
 			stop_critical_timings();

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [tip:timers/core] ACPI/processor: Use explicit broadcast control function
  2015-04-03  0:02       ` [v2][PATCH 05/21] ACPI / processor: " Rafael J. Wysocki
@ 2015-04-03  8:22         ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 90+ messages in thread
From: tip-bot for Thomas Gleixner @ 2015-04-03  8:22 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, rafael.j.wysocki, peterz, hpa, mingo, tglx

Commit-ID:  ee41eebf9cef624b2e766a4b8688eeeedb65114c
Gitweb:     http://git.kernel.org/tip/ee41eebf9cef624b2e766a4b8688eeeedb65114c
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 3 Apr 2015 02:02:00 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:44:32 +0200

ACPI/processor: Use explicit broadcast control function

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/25071624.dkenaL3SGT@vostro.rjw.lan
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 drivers/acpi/processor_idle.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index c6bb9f1..be54797 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -32,7 +32,7 @@
 #include <linux/acpi.h>
 #include <linux/dmi.h>
 #include <linux/sched.h>       /* need_resched() */
-#include <linux/clockchips.h>
+#include <linux/tick.h>
 #include <linux/cpuidle.h>
 #include <linux/syscore_ops.h>
 #include <acpi/processor.h>
@@ -157,12 +157,11 @@ static void lapic_timer_check_state(int state, struct acpi_processor *pr,
 static void __lapic_timer_propagate_broadcast(void *arg)
 {
 	struct acpi_processor *pr = (struct acpi_processor *) arg;
-	unsigned long reason;
 
-	reason = pr->power.timer_broadcast_on_state < INT_MAX ?
-		CLOCK_EVT_NOTIFY_BROADCAST_ON : CLOCK_EVT_NOTIFY_BROADCAST_OFF;
-
-	clockevents_notify(reason, &pr->id);
+	if (pr->power.timer_broadcast_on_state < INT_MAX)
+		tick_broadcast_enable();
+	else
+		tick_broadcast_disable();
 }
 
 static void lapic_timer_propagate_broadcast(struct acpi_processor *pr)

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [tip:timers/core] cpuidle: Use explicit broadcast control function
  2015-04-03  0:02       ` [v2][PATCH 06/21] cpuidle: " Rafael J. Wysocki
@ 2015-04-03  8:23         ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 90+ messages in thread
From: tip-bot for Thomas Gleixner @ 2015-04-03  8:23 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: tglx, mingo, linux-kernel, hpa, daniel.lezcano, rafael.j.wysocki, peterz

Commit-ID:  ee7a1438b548fb5e206058d6bd0e2a5adf081dbf
Gitweb:     http://git.kernel.org/tip/ee7a1438b548fb5e206058d6bd0e2a5adf081dbf
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 3 Apr 2015 02:02:18 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:44:32 +0200

cpuidle: Use explicit broadcast control function

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/2106401.cYdJzzA6Ic@vostro.rjw.lan
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 drivers/cpuidle/driver.c | 23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c
index 2697e87..5db1478 100644
--- a/drivers/cpuidle/driver.c
+++ b/drivers/cpuidle/driver.c
@@ -13,7 +13,7 @@
 #include <linux/sched.h>
 #include <linux/cpuidle.h>
 #include <linux/cpumask.h>
-#include <linux/clockchips.h>
+#include <linux/tick.h>
 
 #include "cpuidle.h"
 
@@ -130,21 +130,20 @@ static inline void __cpuidle_unset_driver(struct cpuidle_driver *drv)
 #endif
 
 /**
- * cpuidle_setup_broadcast_timer - enable/disable the broadcast timer
+ * cpuidle_setup_broadcast_timer - enable/disable the broadcast timer on a cpu
  * @arg: a void pointer used to match the SMP cross call API
  *
- * @arg is used as a value of type 'long' with one of the two values:
- * - CLOCK_EVT_NOTIFY_BROADCAST_ON
- * - CLOCK_EVT_NOTIFY_BROADCAST_OFF
+ * If @arg is NULL broadcast is disabled otherwise enabled
  *
- * Set the broadcast timer notification for the current CPU.  This function
- * is executed per CPU by an SMP cross call.  It not supposed to be called
- * directly.
+ * This function is executed per CPU by an SMP cross call.  It's not
+ * supposed to be called directly.
  */
 static void cpuidle_setup_broadcast_timer(void *arg)
 {
-	int cpu = smp_processor_id();
-	clockevents_notify((long)(arg), &cpu);
+	if (arg)
+		tick_broadcast_enable();
+	else
+		tick_broadcast_disable();
 }
 
 /**
@@ -239,7 +238,7 @@ static int __cpuidle_register_driver(struct cpuidle_driver *drv)
 
 	if (drv->bctimer)
 		on_each_cpu_mask(drv->cpumask, cpuidle_setup_broadcast_timer,
-				 (void *)CLOCK_EVT_NOTIFY_BROADCAST_ON, 1);
+				 (void *)1, 1);
 
 	poll_idle_init(drv);
 
@@ -263,7 +262,7 @@ static void __cpuidle_unregister_driver(struct cpuidle_driver *drv)
 	if (drv->bctimer) {
 		drv->bctimer = 0;
 		on_each_cpu_mask(drv->cpumask, cpuidle_setup_broadcast_timer,
-				 (void *)CLOCK_EVT_NOTIFY_BROADCAST_OFF, 1);
+				 NULL, 1);
 	}
 
 	__cpuidle_unset_driver(drv);

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [tip:timers/core] intel_idle: Use explicit broadcast control function
  2015-04-03  0:02       ` [v2][PATCH 07/21] intel_idle: " Rafael J. Wysocki
@ 2015-04-03  8:23         ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 90+ messages in thread
From: tip-bot for Thomas Gleixner @ 2015-04-03  8:23 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: peterz, linux-kernel, tglx, rafael.j.wysocki, hpa, lenb, mingo

Commit-ID:  76962caa4b691ad09556903602143fc8b16802ae
Gitweb:     http://git.kernel.org/tip/76962caa4b691ad09556903602143fc8b16802ae
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 3 Apr 2015 02:02:34 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:44:32 +0200

intel_idle: Use explicit broadcast control function

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Len Brown <lenb@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/3878165.rXNXrtVNuy@vostro.rjw.lan
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 drivers/idle/intel_idle.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index b0e5852..93f84f7 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -55,7 +55,7 @@
 
 #include <linux/kernel.h>
 #include <linux/cpuidle.h>
-#include <linux/clockchips.h>
+#include <linux/tick.h>
 #include <trace/events/power.h>
 #include <linux/sched.h>
 #include <linux/notifier.h>
@@ -665,13 +665,12 @@ static void intel_idle_freeze(struct cpuidle_device *dev,
 
 static void __setup_broadcast_timer(void *arg)
 {
-	unsigned long reason = (unsigned long)arg;
-	int cpu = smp_processor_id();
-
-	reason = reason ?
-		CLOCK_EVT_NOTIFY_BROADCAST_ON : CLOCK_EVT_NOTIFY_BROADCAST_OFF;
+	unsigned long on = (unsigned long)arg;
 
-	clockevents_notify(reason, &cpu);
+	if (on)
+		tick_broadcast_enable();
+	else
+		tick_broadcast_disable();
 }
 
 static int cpu_hotplug_notify(struct notifier_block *n,

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [tip:timers/core] ARM: OMAP: Use explicit broadcast control function
  2015-04-03  0:02       ` [v2][PATCH 08/21] ARM: OMAP: " Rafael J. Wysocki
@ 2015-04-03  8:23         ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 90+ messages in thread
From: tip-bot for Thomas Gleixner @ 2015-04-03  8:23 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: rafael.j.wysocki, peterz, tglx, mingo, linux-kernel, tony, hpa

Commit-ID:  fa8589fe3bfafadd80677c8eabae97dc5dab22c0
Gitweb:     http://git.kernel.org/tip/fa8589fe3bfafadd80677c8eabae97dc5dab22c0
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 3 Apr 2015 02:02:47 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:44:33 +0200

ARM: OMAP: Use explicit broadcast control function

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Tony Lindgren <tony@atomide.com>
Link: http://lkml.kernel.org/r/2124877.3nbWGILHCV@vostro.rjw.lan
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/arm/mach-omap2/cpuidle44xx.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
index 01e398a..9284dc5 100644
--- a/arch/arm/mach-omap2/cpuidle44xx.c
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -14,7 +14,7 @@
 #include <linux/cpuidle.h>
 #include <linux/cpu_pm.h>
 #include <linux/export.h>
-#include <linux/clockchips.h>
+#include <linux/tick.h>
 
 #include <asm/cpuidle.h>
 #include <asm/proc-fns.h>
@@ -184,8 +184,7 @@ fail:
  */
 static void omap_setup_broadcast_timer(void *arg)
 {
-	int cpu = smp_processor_id();
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu);
+	tick_broadcast_enable();
 }
 
 static struct cpuidle_driver omap4_idle_driver = {

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [tip:timers/core] clockevents: Remove the broadcast control leftovers
  2015-04-03  0:03       ` [v2][PATCH 09/21] clockevents: Remove the broadcast control leftovers Rafael J. Wysocki
@ 2015-04-03  8:23         ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 90+ messages in thread
From: tip-bot for Thomas Gleixner @ 2015-04-03  8:23 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: peterz, mingo, tglx, rafael.j.wysocki, hpa, linux-kernel

Commit-ID:  89feddbfe7023ccfb4a6d7f5e3f5161d91b28b18
Gitweb:     http://git.kernel.org/tip/89feddbfe7023ccfb4a6d7f5e3f5161d91b28b18
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 3 Apr 2015 02:03:42 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:44:33 +0200

clockevents: Remove the broadcast control leftovers

All users converted. Remove the notify leftovers.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/2076318.76XJZ8QYP3@vostro.rjw.lan
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 include/linux/clockchips.h |  3 ---
 kernel/time/clockevents.c  | 10 ----------
 2 files changed, 13 deletions(-)

diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
index caeca76..438fafa 100644
--- a/include/linux/clockchips.h
+++ b/include/linux/clockchips.h
@@ -11,9 +11,6 @@
 /* Clock event notification values */
 enum clock_event_nofitiers {
 	CLOCK_EVT_NOTIFY_ADD,
-	CLOCK_EVT_NOTIFY_BROADCAST_ON,
-	CLOCK_EVT_NOTIFY_BROADCAST_OFF,
-	CLOCK_EVT_NOTIFY_BROADCAST_FORCE,
 	CLOCK_EVT_NOTIFY_BROADCAST_ENTER,
 	CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
 	CLOCK_EVT_NOTIFY_CPU_DYING,
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
index 599ff8d..dba0b83 100644
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -655,16 +655,6 @@ int clockevents_notify(unsigned long reason, void *arg)
 	raw_spin_lock_irqsave(&clockevents_lock, flags);
 
 	switch (reason) {
-	case CLOCK_EVT_NOTIFY_BROADCAST_ON:
-		tick_broadcast_enable();
-		break;
-	case CLOCK_EVT_NOTIFY_BROADCAST_OFF:
-		tick_broadcast_disable();
-		break;
-	case CLOCK_EVT_NOTIFY_BROADCAST_FORCE:
-		tick_broadcast_force();
-		break;
-
 	case CLOCK_EVT_NOTIFY_BROADCAST_ENTER:
 	case CLOCK_EVT_NOTIFY_BROADCAST_EXIT:
 		ret = tick_broadcast_oneshot_control(reason);

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [tip:timers/core] clockevents: Provide explicit broadcast oneshot control functions
  2015-04-03  0:05       ` [v2][PATCH 10/21] clockevents: Provide explicit broadcast oneshot control functions Rafael J. Wysocki
@ 2015-04-03  8:24         ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 90+ messages in thread
From: tip-bot for Thomas Gleixner @ 2015-04-03  8:24 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: hpa, peterz, tony, linux-kernel, daniel.lezcano, lenb,
	rafael.j.wysocki, gnurou, tglx, swarren, mingo, thierry.reding

Commit-ID:  1fe5d5c3c9ba0c4ade18e3325cba0ffe35127941
Gitweb:     http://git.kernel.org/tip/1fe5d5c3c9ba0c4ade18e3325cba0ffe35127941
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 3 Apr 2015 02:05:15 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:44:33 +0200

clockevents: Provide explicit broadcast oneshot control functions

clockevents_notify() is a leftover from the early design of the
clockevents facility. It's really not a notification mechanism,
it's a multiplex call. We are way better off to have explicit
calls instead of this monstrosity.

Split out the broadcast oneshot control into a separate function
and provide inline helpers. Switch clockevents_notify() over.
This will go away once all callers are converted.

This also gets rid of the nested locking of clockevents_lock and
broadcast_lock. The broadcast oneshot control functions do not
require clockevents_lock. Only the managing functions
(setup/shutdown/suspend/resume of the broadcast device require
clockevents_lock.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Alexandre Courbot <gnurou@gmail.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Len Brown <lenb@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephen Warren <swarren@wwwdotorg.org>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Tony Lindgren <tony@atomide.com>
Link: http://lkml.kernel.org/r/13000649.8qZuEDV0OA@vostro.rjw.lan
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 include/linux/tick.h         | 19 +++++++++++++++++++
 kernel/time/clockevents.c    |  4 +++-
 kernel/time/tick-broadcast.c | 28 +++++++++++++++++-----------
 kernel/time/tick-internal.h  |  2 --
 4 files changed, 39 insertions(+), 14 deletions(-)

diff --git a/include/linux/tick.h b/include/linux/tick.h
index 4bb2363..6119321 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -48,12 +48,23 @@ enum tick_broadcast_mode {
 	TICK_BROADCAST_FORCE,
 };
 
+enum tick_broadcast_state {
+	TICK_BROADCAST_EXIT,
+	TICK_BROADCAST_ENTER,
+};
+
 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
 extern void tick_broadcast_control(enum tick_broadcast_mode mode);
 #else
 static inline void tick_broadcast_control(enum tick_broadcast_mode mode) { }
 #endif /* BROADCAST */
 
+#if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) && defined(CONFIG_TICK_ONESHOT)
+extern int tick_broadcast_oneshot_control(enum tick_broadcast_state state);
+#else
+static inline int tick_broadcast_oneshot_control(enum tick_broadcast_state state) { return 0; }
+#endif
+
 static inline void tick_broadcast_enable(void)
 {
 	tick_broadcast_control(TICK_BROADCAST_ON);
@@ -66,6 +77,14 @@ static inline void tick_broadcast_force(void)
 {
 	tick_broadcast_control(TICK_BROADCAST_FORCE);
 }
+static inline int tick_broadcast_enter(void)
+{
+	return tick_broadcast_oneshot_control(TICK_BROADCAST_ENTER);
+}
+static inline void tick_broadcast_exit(void)
+{
+	tick_broadcast_oneshot_control(TICK_BROADCAST_EXIT);
+}
 
 #ifdef CONFIG_NO_HZ_COMMON
 extern int tick_nohz_tick_stopped(void);
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
index dba0b83..7791b1c 100644
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -656,8 +656,10 @@ int clockevents_notify(unsigned long reason, void *arg)
 
 	switch (reason) {
 	case CLOCK_EVT_NOTIFY_BROADCAST_ENTER:
+		tick_broadcast_enter();
+		break;
 	case CLOCK_EVT_NOTIFY_BROADCAST_EXIT:
-		ret = tick_broadcast_oneshot_control(reason);
+		tick_broadcast_exit();
 		break;
 
 	case CLOCK_EVT_NOTIFY_CPU_DYING:
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
index 1a0bee0..55e43f2 100644
--- a/kernel/time/tick-broadcast.c
+++ b/kernel/time/tick-broadcast.c
@@ -687,18 +687,23 @@ void hotplug_cpu__broadcast_tick_pull(int deadcpu)
 	raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
 }
 
-/*
- * Powerstate information: The system enters/leaves a state, where
- * affected devices might stop
+/**
+ * tick_broadcast_oneshot_control - Enter/exit broadcast oneshot mode
+ * @state:	The target state (enter/exit)
+ *
+ * The system enters/leaves a state, where affected devices might stop
  * Returns 0 on success, -EBUSY if the cpu is used to broadcast wakeups.
+ *
+ * Called with interrupts disabled, so clockevents_lock is not
+ * required here because the local clock event device cannot go away
+ * under us.
  */
-int tick_broadcast_oneshot_control(unsigned long reason)
+int tick_broadcast_oneshot_control(enum tick_broadcast_state state)
 {
 	struct clock_event_device *bc, *dev;
 	struct tick_device *td;
-	unsigned long flags;
-	ktime_t now;
 	int cpu, ret = 0;
+	ktime_t now;
 
 	/*
 	 * Periodic mode does not care about the enter/exit of power
@@ -711,17 +716,17 @@ int tick_broadcast_oneshot_control(unsigned long reason)
 	 * We are called with preemtion disabled from the depth of the
 	 * idle code, so we can't be moved away.
 	 */
-	cpu = smp_processor_id();
-	td = &per_cpu(tick_cpu_device, cpu);
+	td = this_cpu_ptr(&tick_cpu_device);
 	dev = td->evtdev;
 
 	if (!(dev->features & CLOCK_EVT_FEAT_C3STOP))
 		return 0;
 
+	raw_spin_lock(&tick_broadcast_lock);
 	bc = tick_broadcast_device.evtdev;
+	cpu = smp_processor_id();
 
-	raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
-	if (reason == CLOCK_EVT_NOTIFY_BROADCAST_ENTER) {
+	if (state == TICK_BROADCAST_ENTER) {
 		if (!cpumask_test_and_set_cpu(cpu, tick_broadcast_oneshot_mask)) {
 			WARN_ON_ONCE(cpumask_test_cpu(cpu, tick_broadcast_pending_mask));
 			broadcast_shutdown_local(bc, dev);
@@ -813,9 +818,10 @@ int tick_broadcast_oneshot_control(unsigned long reason)
 		}
 	}
 out:
-	raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
+	raw_spin_unlock(&tick_broadcast_lock);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(tick_broadcast_oneshot_control);
 
 /*
  * Reset the one shot broadcast for a cpu
diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h
index 62e331d..0266f9d 100644
--- a/kernel/time/tick-internal.h
+++ b/kernel/time/tick-internal.h
@@ -117,7 +117,6 @@ static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
 /* Functions related to oneshot broadcasting */
 #if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) && defined(CONFIG_TICK_ONESHOT)
 extern void tick_broadcast_setup_oneshot(struct clock_event_device *bc);
-extern int tick_broadcast_oneshot_control(unsigned long reason);
 extern void tick_broadcast_switch_to_oneshot(void);
 extern void tick_shutdown_broadcast_oneshot(unsigned int *cpup);
 extern int tick_broadcast_oneshot_active(void);
@@ -126,7 +125,6 @@ bool tick_broadcast_oneshot_available(void);
 extern struct cpumask *tick_get_broadcast_oneshot_mask(void);
 #else /* !(BROADCAST && ONESHOT): */
 static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc) { BUG(); }
-static inline int tick_broadcast_oneshot_control(unsigned long reason) { return 0; }
 static inline void tick_broadcast_switch_to_oneshot(void) { }
 static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { }
 static inline int tick_broadcast_oneshot_active(void) { return 0; }

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [tip:timers/core] x86/amd/idle, clockevents: Use explicit broadcast oneshot control functions
  2015-04-03  0:05       ` [v2][PATCH 11/21] x86, amd_idle: Use " Rafael J. Wysocki
@ 2015-04-03  8:24         ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 90+ messages in thread
From: tip-bot for Thomas Gleixner @ 2015-04-03  8:24 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: tglx, peterz, linux-kernel, hpa, rafael.j.wysocki, mingo

Commit-ID:  435c350e8197488f12c97e7df28a9c2199bd1673
Gitweb:     http://git.kernel.org/tip/435c350e8197488f12c97e7df28a9c2199bd1673
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 3 Apr 2015 02:05:53 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:44:34 +0200

x86/amd/idle, clockevents: Use explicit broadcast oneshot control functions

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/8569669.lgxIty9PKW@vostro.rjw.lan
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/kernel/process.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index e94b733..2f43c62 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -381,7 +381,7 @@ static void amd_e400_idle(void)
 			tick_broadcast_force();
 			pr_info("Switch to broadcast mode on CPU%d\n", cpu);
 		}
-		clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
+		tick_broadcast_enter();
 
 		default_idle();
 
@@ -390,7 +390,7 @@ static void amd_e400_idle(void)
 		 * called with interrupts disabled.
 		 */
 		local_irq_disable();
-		clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
+		tick_broadcast_exit();
 		local_irq_enable();
 	} else
 		default_idle();

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [tip:timers/core] ACPI/PAD: Use explicit broadcast oneshot control function
  2015-04-03  0:06       ` [v2][PATCH 12/21] ACPI / PAD: Use explicit broadcast oneshot control function Rafael J. Wysocki
@ 2015-04-03  8:24         ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 90+ messages in thread
From: tip-bot for Thomas Gleixner @ 2015-04-03  8:24 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: peterz, lenb, hpa, tglx, rafael.j.wysocki, linux-kernel, mingo

Commit-ID:  c79521354e71a1fbcee040ee3147cadc0f8e3c97
Gitweb:     http://git.kernel.org/tip/c79521354e71a1fbcee040ee3147cadc0f8e3c97
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 3 Apr 2015 02:06:37 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:44:34 +0200

ACPI/PAD: Use explicit broadcast oneshot control function

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Len Brown <lenb@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1552509.UntNmyqF5v@vostro.rjw.lan
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 drivers/acpi/acpi_pad.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c
index 244dbc9..6bc9cbc 100644
--- a/drivers/acpi/acpi_pad.c
+++ b/drivers/acpi/acpi_pad.c
@@ -150,7 +150,6 @@ static int power_saving_thread(void *data)
 	sched_setscheduler(current, SCHED_RR, &param);
 
 	while (!kthread_should_stop()) {
-		int cpu;
 		unsigned long expire_time;
 
 		try_to_freeze();
@@ -174,14 +173,13 @@ static int power_saving_thread(void *data)
 			}
 			local_irq_disable();
 			tick_broadcast_enable();
-			cpu = smp_processor_id();
-			clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
+			tick_broadcast_enter();
 			stop_critical_timings();
 
 			mwait_idle_with_hints(power_saving_mwait_eax, 1);
 
 			start_critical_timings();
-			clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
+			tick_broadcast_exit();
 			local_irq_enable();
 
 			if (time_before(expire_time, jiffies)) {

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [tip:timers/core] ACPI/idle: Use explicit broadcast control function
  2015-04-03  0:12       ` [v2][PATCH 13/21] ACPI / processor: Use explicit broadcast controll function Rafael J. Wysocki
@ 2015-04-03  8:25         ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 90+ messages in thread
From: tip-bot for Thomas Gleixner @ 2015-04-03  8:25 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, rafael.j.wysocki, hpa, mingo, tglx, peterz

Commit-ID:  7815701c5cd7276b712d898b3cf49c55e587dbb1
Gitweb:     http://git.kernel.org/tip/7815701c5cd7276b712d898b3cf49c55e587dbb1
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 3 Apr 2015 02:12:03 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:44:34 +0200

ACPI/idle: Use explicit broadcast control function

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/2653377.MSAlfA939I@vostro.rjw.lan
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 drivers/acpi/processor_idle.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index be54797..5335519 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -178,11 +178,10 @@ static void lapic_timer_state_broadcast(struct acpi_processor *pr,
 	int state = cx - pr->power.states;
 
 	if (state >= pr->power.timer_broadcast_on_state) {
-		unsigned long reason;
-
-		reason = broadcast ?  CLOCK_EVT_NOTIFY_BROADCAST_ENTER :
-			CLOCK_EVT_NOTIFY_BROADCAST_EXIT;
-		clockevents_notify(reason, &pr->id);
+		if (broadcast)
+			tick_broadcast_enter();
+		else
+			tick_broadcast_exit();
 	}
 }
 

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [tip:timers/core] intel_idle: Use explicit broadcast oneshot control function
  2015-04-03  0:14       ` [v2][PATCH 14/21] intel_idle: Use explicit broadcast oneshot " Rafael J. Wysocki
@ 2015-04-03  8:25         ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 90+ messages in thread
From: tip-bot for Thomas Gleixner @ 2015-04-03  8:25 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, peterz, hpa, rafael.j.wysocki, tglx, mingo, lenb

Commit-ID:  f6cee191fc6b286f9056a13456c4c8ade0aeb890
Gitweb:     http://git.kernel.org/tip/f6cee191fc6b286f9056a13456c4c8ade0aeb890
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 3 Apr 2015 02:14:23 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:44:35 +0200

intel_idle: Use explicit broadcast oneshot control function

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Len Brown <lenb@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20714596.QMfNNPbuyU@vostro.rjw.lan
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 drivers/idle/intel_idle.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index 93f84f7..5c979d0 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -638,12 +638,12 @@ static int intel_idle(struct cpuidle_device *dev,
 		leave_mm(cpu);
 
 	if (!(lapic_timer_reliable_states & (1 << (cstate))))
-		clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
+		tick_broadcast_enter();
 
 	mwait_idle_with_hints(eax, ecx);
 
 	if (!(lapic_timer_reliable_states & (1 << (cstate))))
-		clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
+		tick_broadcast_exit();
 
 	return index;
 }

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [tip:timers/core] ARM: OMAP: Use explicit broadcast oneshot control function
  2015-04-03  0:31       ` [v2][PATCH 15/21] ARM: OMAP: " Rafael J. Wysocki
@ 2015-04-03  8:25         ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 90+ messages in thread
From: tip-bot for Thomas Gleixner @ 2015-04-03  8:25 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, peterz, tglx, hpa, tony, rafael.j.wysocki, mingo

Commit-ID:  fb7f0398a98020def9429ddd7b4a8fc2d948b092
Gitweb:     http://git.kernel.org/tip/fb7f0398a98020def9429ddd7b4a8fc2d948b092
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 3 Apr 2015 02:31:29 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:44:35 +0200

ARM: OMAP: Use explicit broadcast oneshot control function

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Tony Lindgren <tony@atomide.com>
Link: http://lkml.kernel.org/r/3123047.uVjevtxDV7@vostro.rjw.lan
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/arm/mach-omap2/cpuidle44xx.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
index 9284dc5..57d4298 100644
--- a/arch/arm/mach-omap2/cpuidle44xx.c
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -84,7 +84,6 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
 {
 	struct idle_statedata *cx = state_ptr + index;
 	u32 mpuss_can_lose_context = 0;
-	int cpu_id = smp_processor_id();
 
 	/*
 	 * CPU0 has to wait and stay ON until CPU1 is OFF state.
@@ -112,7 +111,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
 	mpuss_can_lose_context = (cx->mpu_state == PWRDM_POWER_RET) &&
 				 (cx->mpu_logic_state == PWRDM_POWER_OFF);
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu_id);
+	tick_broadcast_enter();
 
 	/*
 	 * Call idle CPU PM enter notifier chain so that
@@ -169,7 +168,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
 	if (dev->cpu == 0 && mpuss_can_lose_context)
 		cpu_cluster_pm_exit();
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id);
+	tick_broadcast_exit();
 
 fail:
 	cpuidle_coupled_parallel_barrier(dev, &abort_barrier);

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [tip:timers/core] ARM: Tegra: Use explicit broadcast oneshot control function
  2015-04-03  0:32       ` [v2][PATCH 16/21] ARM: tegra: " Rafael J. Wysocki
@ 2015-04-03  8:25         ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 90+ messages in thread
From: tip-bot for Thomas Gleixner @ 2015-04-03  8:25 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: hpa, mingo, tglx, gnurou, swarren, rafael.j.wysocki,
	thierry.reding, peterz, linux-kernel

Commit-ID:  a0b4122447a3c1a467ce4e4f1bb863e1170394d5
Gitweb:     http://git.kernel.org/tip/a0b4122447a3c1a467ce4e4f1bb863e1170394d5
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 3 Apr 2015 02:32:14 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:44:35 +0200

ARM: Tegra: Use explicit broadcast oneshot control function

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Alexandre Courbot <gnurou@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephen Warren <swarren@wwwdotorg.org>
Cc: Thierry Reding <thierry.reding@gmail.com>
Link: http://lkml.kernel.org/r/2131111.rjxRLX1eZB@vostro.rjw.lan
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/arm/mach-tegra/cpuidle-tegra114.c |  6 +++---
 arch/arm/mach-tegra/cpuidle-tegra20.c  | 10 +++++-----
 arch/arm/mach-tegra/cpuidle-tegra30.c  | 10 +++++-----
 3 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/arch/arm/mach-tegra/cpuidle-tegra114.c b/arch/arm/mach-tegra/cpuidle-tegra114.c
index f2b586d..155807f 100644
--- a/arch/arm/mach-tegra/cpuidle-tegra114.c
+++ b/arch/arm/mach-tegra/cpuidle-tegra114.c
@@ -15,7 +15,7 @@
  */
 
 #include <asm/firmware.h>
-#include <linux/clockchips.h>
+#include <linux/tick.h>
 #include <linux/cpuidle.h>
 #include <linux/cpu_pm.h>
 #include <linux/kernel.h>
@@ -44,7 +44,7 @@ static int tegra114_idle_power_down(struct cpuidle_device *dev,
 	tegra_set_cpu_in_lp2();
 	cpu_pm_enter();
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
+	tick_broadcast_enter();
 
 	call_firmware_op(prepare_idle);
 
@@ -52,7 +52,7 @@ static int tegra114_idle_power_down(struct cpuidle_device *dev,
 	if (call_firmware_op(do_idle, 0) == -ENOSYS)
 		cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
+	tick_broadcast_exit();
 
 	cpu_pm_exit();
 	tegra_clear_cpu_in_lp2();
diff --git a/arch/arm/mach-tegra/cpuidle-tegra20.c b/arch/arm/mach-tegra/cpuidle-tegra20.c
index 4f25a7c..48844ae 100644
--- a/arch/arm/mach-tegra/cpuidle-tegra20.c
+++ b/arch/arm/mach-tegra/cpuidle-tegra20.c
@@ -20,7 +20,7 @@
  */
 
 #include <linux/clk/tegra.h>
-#include <linux/clockchips.h>
+#include <linux/tick.h>
 #include <linux/cpuidle.h>
 #include <linux/cpu_pm.h>
 #include <linux/kernel.h>
@@ -136,11 +136,11 @@ static bool tegra20_cpu_cluster_power_down(struct cpuidle_device *dev,
 	if (tegra20_reset_cpu_1() || !tegra_cpu_rail_off_ready())
 		return false;
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
+	tick_broadcast_enter();
 
 	tegra_idle_lp2_last();
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
+	tick_broadcast_exit();
 
 	if (cpu_online(1))
 		tegra20_wake_cpu1_from_reset();
@@ -153,13 +153,13 @@ static bool tegra20_idle_enter_lp2_cpu_1(struct cpuidle_device *dev,
 					 struct cpuidle_driver *drv,
 					 int index)
 {
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
+	tick_broadcast_enter();
 
 	cpu_suspend(0, tegra20_sleep_cpu_secondary_finish);
 
 	tegra20_cpu_clear_resettable();
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
+	tick_broadcast_exit();
 
 	return true;
 }
diff --git a/arch/arm/mach-tegra/cpuidle-tegra30.c b/arch/arm/mach-tegra/cpuidle-tegra30.c
index f8815ed..84d809a 100644
--- a/arch/arm/mach-tegra/cpuidle-tegra30.c
+++ b/arch/arm/mach-tegra/cpuidle-tegra30.c
@@ -20,7 +20,7 @@
  */
 
 #include <linux/clk/tegra.h>
-#include <linux/clockchips.h>
+#include <linux/tick.h>
 #include <linux/cpuidle.h>
 #include <linux/cpu_pm.h>
 #include <linux/kernel.h>
@@ -76,11 +76,11 @@ static bool tegra30_cpu_cluster_power_down(struct cpuidle_device *dev,
 		return false;
 	}
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
+	tick_broadcast_enter();
 
 	tegra_idle_lp2_last();
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
+	tick_broadcast_exit();
 
 	return true;
 }
@@ -90,13 +90,13 @@ static bool tegra30_cpu_core_power_down(struct cpuidle_device *dev,
 					struct cpuidle_driver *drv,
 					int index)
 {
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
+	tick_broadcast_enter();
 
 	smp_wmb();
 
 	cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
 
-	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
+	tick_broadcast_exit();
 
 	return true;
 }

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [tip:timers/core] sched/idle: Use explicit broadcast oneshot control function
  2015-04-03  0:34       ` [v2][PATCH 17/21] sched/idle: " Rafael J. Wysocki
@ 2015-04-03  8:26         ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 90+ messages in thread
From: tip-bot for Thomas Gleixner @ 2015-04-03  8:26 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: tglx, hpa, mingo, rafael.j.wysocki, peterz, linux-kernel

Commit-ID:  335f49196fd6011521f078cb44f445847e5aa183
Gitweb:     http://git.kernel.org/tip/335f49196fd6011521f078cb44f445847e5aa183
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 3 Apr 2015 02:34:49 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:44:36 +0200

sched/idle: Use explicit broadcast oneshot control function

Replace the clockevents_notify() call with an explicit function call.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/6422336.RMm7oUHcXh@vostro.rjw.lan
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 kernel/sched/idle.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c
index 80014a1..4d207d2 100644
--- a/kernel/sched/idle.c
+++ b/kernel/sched/idle.c
@@ -158,8 +158,7 @@ static void cpuidle_idle_call(void)
 	 * is used from another cpu as a broadcast timer, this call may
 	 * fail if it is not available
 	 */
-	if (broadcast &&
-	    clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu))
+	if (broadcast && tick_broadcast_enter())
 		goto use_default;
 
 	/* Take note of the planned idle state. */
@@ -176,7 +175,7 @@ static void cpuidle_idle_call(void)
 	idle_set_state(this_rq(), NULL);
 
 	if (broadcast)
-		clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
+		tick_broadcast_exit();
 
 	/*
 	 * Give the governor an opportunity to reflect on the outcome

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [tip:timers/core] clockevents: Remove broadcast oneshot control leftovers
  2015-04-03  0:36       ` [v2][PATCH 18/21] clockevents: Remove broadcast oneshot control leftovers Rafael J. Wysocki
@ 2015-04-03  8:26         ` tip-bot for Rafael J. Wysocki
  0 siblings, 0 replies; 90+ messages in thread
From: tip-bot for Rafael J. Wysocki @ 2015-04-03  8:26 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, torvalds, tglx, rafael.j.wysocki, akpm, hpa,
	peterz, mingo, john.stultz

Commit-ID:  ffa48c0d76803057ee89bf220305466d74256d7b
Gitweb:     http://git.kernel.org/tip/ffa48c0d76803057ee89bf220305466d74256d7b
Author:     Rafael J. Wysocki <rafael.j.wysocki@intel.com>
AuthorDate: Fri, 3 Apr 2015 02:36:10 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:44:36 +0200

clockevents: Remove broadcast oneshot control leftovers

Now that all users are converted over to explicit calls into the
clockevents state machine, remove the notification chain leftovers.

Original-from: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/14018863.NQUzkFuafr@vostro.rjw.lan
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 include/linux/clockchips.h | 2 --
 kernel/time/clockevents.c  | 7 -------
 2 files changed, 9 deletions(-)

diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
index 438fafa..f97f498 100644
--- a/include/linux/clockchips.h
+++ b/include/linux/clockchips.h
@@ -11,8 +11,6 @@
 /* Clock event notification values */
 enum clock_event_nofitiers {
 	CLOCK_EVT_NOTIFY_ADD,
-	CLOCK_EVT_NOTIFY_BROADCAST_ENTER,
-	CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
 	CLOCK_EVT_NOTIFY_CPU_DYING,
 	CLOCK_EVT_NOTIFY_CPU_DEAD,
 };
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
index 7791b1c..be9abf3 100644
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -655,13 +655,6 @@ int clockevents_notify(unsigned long reason, void *arg)
 	raw_spin_lock_irqsave(&clockevents_lock, flags);
 
 	switch (reason) {
-	case CLOCK_EVT_NOTIFY_BROADCAST_ENTER:
-		tick_broadcast_enter();
-		break;
-	case CLOCK_EVT_NOTIFY_BROADCAST_EXIT:
-		tick_broadcast_exit();
-		break;
-
 	case CLOCK_EVT_NOTIFY_CPU_DYING:
 		tick_handover_do_timer(arg);
 		break;

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [tip:timers/core] clockevents: Make tick handover explicit
  2015-04-03  0:37       ` [v2][PATCH 19/21] clockevents: Make tick handover explicit Rafael J. Wysocki
@ 2015-04-03  8:26         ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 90+ messages in thread
From: tip-bot for Thomas Gleixner @ 2015-04-03  8:26 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: hpa, mingo, akpm, peterz, rafael.j.wysocki, linux-kernel,
	john.stultz, tglx, torvalds

Commit-ID:  52c063d1adbc16c76e70fffa20727fcd4e9343b3
Gitweb:     http://git.kernel.org/tip/52c063d1adbc16c76e70fffa20727fcd4e9343b3
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 3 Apr 2015 02:37:24 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:44:36 +0200

clockevents: Make tick handover explicit

clockevents_notify() is a leftover from the early design of the
clockevents facility. It's really not a notification mechanism,
it's a multiplex call. We are way better off to have explicit
calls instead of this monstrosity.

Split out the tick_handover call and invoke it explicitely from
the hotplug code. Temporary solution will be cleaned up in later
patches.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
[ Rebase ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Link: http://lkml.kernel.org/r/1658173.RkEEILFiQZ@vostro.rjw.lan
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 include/linux/clockchips.h  | 1 -
 include/linux/tick.h        | 2 ++
 kernel/cpu.c                | 2 ++
 kernel/time/clockevents.c   | 4 ----
 kernel/time/hrtimer.c       | 4 ----
 kernel/time/tick-common.c   | 9 ++++++---
 kernel/time/tick-internal.h | 1 -
 7 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
index f97f498..f4bde22 100644
--- a/include/linux/clockchips.h
+++ b/include/linux/clockchips.h
@@ -11,7 +11,6 @@
 /* Clock event notification values */
 enum clock_event_nofitiers {
 	CLOCK_EVT_NOTIFY_ADD,
-	CLOCK_EVT_NOTIFY_CPU_DYING,
 	CLOCK_EVT_NOTIFY_CPU_DEAD,
 };
 
diff --git a/include/linux/tick.h b/include/linux/tick.h
index 6119321..2c68fa3 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -19,12 +19,14 @@ extern void tick_unfreeze(void);
 extern void tick_suspend_local(void);
 /* Should be core only, but XEN resume magic and ARM BL switcher require it */
 extern void tick_resume_local(void);
+extern void tick_handover_do_timer(void);
 #else /* CONFIG_GENERIC_CLOCKEVENTS */
 static inline void tick_init(void) { }
 static inline void tick_freeze(void) { }
 static inline void tick_unfreeze(void) { }
 static inline void tick_suspend_local(void) { }
 static inline void tick_resume_local(void) { }
+static inline void tick_handover_do_timer(void) { }
 #endif /* !CONFIG_GENERIC_CLOCKEVENTS */
 
 #ifdef CONFIG_TICK_ONESHOT
diff --git a/kernel/cpu.c b/kernel/cpu.c
index af5db20..eba7eaa 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -339,6 +339,8 @@ static int __ref take_cpu_down(void *_param)
 		return err;
 
 	cpu_notify(CPU_DYING | param->mod, param->hcpu);
+	/* Give up timekeeping duties */
+	tick_handover_do_timer();
 	/* Park the stopper thread */
 	kthread_park(current);
 	return 0;
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
index be9abf3..88fb3b9 100644
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -655,10 +655,6 @@ int clockevents_notify(unsigned long reason, void *arg)
 	raw_spin_lock_irqsave(&clockevents_lock, flags);
 
 	switch (reason) {
-	case CLOCK_EVT_NOTIFY_CPU_DYING:
-		tick_handover_do_timer(arg);
-		break;
-
 	case CLOCK_EVT_NOTIFY_CPU_DEAD:
 		tick_shutdown_broadcast_oneshot(arg);
 		tick_shutdown_broadcast(arg);
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index 721d29b..6a7a64e 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -1707,10 +1707,6 @@ static int hrtimer_cpu_notify(struct notifier_block *self,
 		break;
 
 #ifdef CONFIG_HOTPLUG_CPU
-	case CPU_DYING:
-	case CPU_DYING_FROZEN:
-		clockevents_notify(CLOCK_EVT_NOTIFY_CPU_DYING, &scpu);
-		break;
 	case CPU_DEAD:
 	case CPU_DEAD_FROZEN:
 	{
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
index e28ba5c..055c868 100644
--- a/kernel/time/tick-common.c
+++ b/kernel/time/tick-common.c
@@ -332,20 +332,23 @@ out_bc:
 	tick_install_broadcast_device(newdev);
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
 /*
  * Transfer the do_timer job away from a dying cpu.
  *
- * Called with interrupts disabled.
+ * Called with interrupts disabled. Not locking required. If
+ * tick_do_timer_cpu is owned by this cpu, nothing can change it.
  */
-void tick_handover_do_timer(int *cpup)
+void tick_handover_do_timer(void)
 {
-	if (*cpup == tick_do_timer_cpu) {
+	if (tick_do_timer_cpu == smp_processor_id()) {
 		int cpu = cpumask_first(cpu_online_mask);
 
 		tick_do_timer_cpu = (cpu < nr_cpu_ids) ? cpu :
 			TICK_DO_TIMER_NONE;
 	}
 }
+#endif
 
 /*
  * Shutdown an event device on a given cpu:
diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h
index 0266f9d..aabcb5d 100644
--- a/kernel/time/tick-internal.h
+++ b/kernel/time/tick-internal.h
@@ -20,7 +20,6 @@ extern int tick_do_timer_cpu __read_mostly;
 extern void tick_setup_periodic(struct clock_event_device *dev, int broadcast);
 extern void tick_handle_periodic(struct clock_event_device *dev);
 extern void tick_check_new_device(struct clock_event_device *dev);
-extern void tick_handover_do_timer(int *cpup);
 extern void tick_shutdown(unsigned int *cpup);
 extern void tick_suspend(void);
 extern void tick_resume(void);

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [tip:timers/core] clockevents: Cleanup dead cpu explicitely
  2015-04-03  0:38       ` [v2][PATCH 20/21] clockevents: Cleanup dead cpu explicitely Rafael J. Wysocki
@ 2015-04-03  8:26         ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 90+ messages in thread
From: tip-bot for Thomas Gleixner @ 2015-04-03  8:26 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: rafael.j.wysocki, mingo, hpa, tglx, linux-kernel, peterz

Commit-ID:  a49b116dcb1265f238f3169507424257b0519069
Gitweb:     http://git.kernel.org/tip/a49b116dcb1265f238f3169507424257b0519069
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 3 Apr 2015 02:38:05 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:44:37 +0200

clockevents: Cleanup dead cpu explicitely

clockevents_notify() is a leftover from the early design of the
clockevents facility. It's really not a notification mechanism,
it's a multiplex call. We are way better off to have explicit
calls instead of this monstrosity.

Split out the cleanup function for a dead cpu and invoke it
directly from the cpu down code. Make it conditional on
CPU_HOTPLUG as well.

Temporary change, will be refined in the future.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
[ Rebased, added clockevents_notify() removal ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1735025.raBZdQHM3m@vostro.rjw.lan
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 include/linux/clockchips.h   |  6 ------
 include/linux/tick.h         |  2 ++
 kernel/cpu.c                 |  1 +
 kernel/time/clockevents.c    | 51 ++++++++++++++++++--------------------------
 kernel/time/hrtimer.c        |  3 ---
 kernel/time/tick-broadcast.c | 39 ++++++++++++++++-----------------
 kernel/time/tick-common.c    |  6 +++---
 kernel/time/tick-internal.h  | 10 ++++-----
 8 files changed, 52 insertions(+), 66 deletions(-)

diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
index f4bde22..96c280b 100644
--- a/include/linux/clockchips.h
+++ b/include/linux/clockchips.h
@@ -8,12 +8,6 @@
 #ifndef _LINUX_CLOCKCHIPS_H
 #define _LINUX_CLOCKCHIPS_H
 
-/* Clock event notification values */
-enum clock_event_nofitiers {
-	CLOCK_EVT_NOTIFY_ADD,
-	CLOCK_EVT_NOTIFY_CPU_DEAD,
-};
-
 #ifdef CONFIG_GENERIC_CLOCKEVENTS
 
 # include <linux/clocksource.h>
diff --git a/include/linux/tick.h b/include/linux/tick.h
index 2c68fa3..f8492da5 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -20,6 +20,7 @@ extern void tick_suspend_local(void);
 /* Should be core only, but XEN resume magic and ARM BL switcher require it */
 extern void tick_resume_local(void);
 extern void tick_handover_do_timer(void);
+extern void tick_cleanup_dead_cpu(int cpu);
 #else /* CONFIG_GENERIC_CLOCKEVENTS */
 static inline void tick_init(void) { }
 static inline void tick_freeze(void) { }
@@ -27,6 +28,7 @@ static inline void tick_unfreeze(void) { }
 static inline void tick_suspend_local(void) { }
 static inline void tick_resume_local(void) { }
 static inline void tick_handover_do_timer(void) { }
+static inline void tick_cleanup_dead_cpu(int cpu) { }
 #endif /* !CONFIG_GENERIC_CLOCKEVENTS */
 
 #ifdef CONFIG_TICK_ONESHOT
diff --git a/kernel/cpu.c b/kernel/cpu.c
index eba7eaa..82eea9c 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -419,6 +419,7 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
 	__cpu_die(cpu);
 
 	/* CPU is completely dead: tell everyone.  Too late to complain. */
+	tick_cleanup_dead_cpu(cpu);
 	cpu_notify_nofail(CPU_DEAD | mod, hcpu);
 
 	check_for_tasks(cpu);
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
index 88fb3b9..25d942d 100644
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -642,49 +642,40 @@ void clockevents_resume(void)
 			dev->resume(dev);
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
 /**
- * clockevents_notify - notification about relevant events
- * Returns 0 on success, any other value on error
+ * tick_cleanup_dead_cpu - Cleanup the tick and clockevents of a dead cpu
  */
-int clockevents_notify(unsigned long reason, void *arg)
+void tick_cleanup_dead_cpu(int cpu)
 {
 	struct clock_event_device *dev, *tmp;
 	unsigned long flags;
-	int cpu, ret = 0;
 
 	raw_spin_lock_irqsave(&clockevents_lock, flags);
 
-	switch (reason) {
-	case CLOCK_EVT_NOTIFY_CPU_DEAD:
-		tick_shutdown_broadcast_oneshot(arg);
-		tick_shutdown_broadcast(arg);
-		tick_shutdown(arg);
-		/*
-		 * Unregister the clock event devices which were
-		 * released from the users in the notify chain.
-		 */
-		list_for_each_entry_safe(dev, tmp, &clockevents_released, list)
+	tick_shutdown_broadcast_oneshot(cpu);
+	tick_shutdown_broadcast(cpu);
+	tick_shutdown(cpu);
+	/*
+	 * Unregister the clock event devices which were
+	 * released from the users in the notify chain.
+	 */
+	list_for_each_entry_safe(dev, tmp, &clockevents_released, list)
+		list_del(&dev->list);
+	/*
+	 * Now check whether the CPU has left unused per cpu devices
+	 */
+	list_for_each_entry_safe(dev, tmp, &clockevent_devices, list) {
+		if (cpumask_test_cpu(cpu, dev->cpumask) &&
+		    cpumask_weight(dev->cpumask) == 1 &&
+		    !tick_is_broadcast_device(dev)) {
+			BUG_ON(dev->state != CLOCK_EVT_STATE_DETACHED);
 			list_del(&dev->list);
-		/*
-		 * Now check whether the CPU has left unused per cpu devices
-		 */
-		cpu = *((int *)arg);
-		list_for_each_entry_safe(dev, tmp, &clockevent_devices, list) {
-			if (cpumask_test_cpu(cpu, dev->cpumask) &&
-			    cpumask_weight(dev->cpumask) == 1 &&
-			    !tick_is_broadcast_device(dev)) {
-				BUG_ON(dev->state != CLOCK_EVT_STATE_DETACHED);
-				list_del(&dev->list);
-			}
 		}
-		break;
-	default:
-		break;
 	}
 	raw_spin_unlock_irqrestore(&clockevents_lock, flags);
-	return ret;
 }
-EXPORT_SYMBOL_GPL(clockevents_notify);
+#endif
 
 #ifdef CONFIG_SYSFS
 struct bus_type clockevents_subsys = {
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index 6a7a64e..76d4bd9 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -1709,11 +1709,8 @@ static int hrtimer_cpu_notify(struct notifier_block *self,
 #ifdef CONFIG_HOTPLUG_CPU
 	case CPU_DEAD:
 	case CPU_DEAD_FROZEN:
-	{
-		clockevents_notify(CLOCK_EVT_NOTIFY_CPU_DEAD, &scpu);
 		migrate_hrtimers(scpu);
 		break;
-	}
 #endif
 
 	default:
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
index 55e43f2..7e8ca4f 100644
--- a/kernel/time/tick-broadcast.c
+++ b/kernel/time/tick-broadcast.c
@@ -410,14 +410,14 @@ void tick_set_periodic_handler(struct clock_event_device *dev, int broadcast)
 		dev->event_handler = tick_handle_periodic_broadcast;
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
 /*
  * Remove a CPU from broadcasting
  */
-void tick_shutdown_broadcast(unsigned int *cpup)
+void tick_shutdown_broadcast(unsigned int cpu)
 {
 	struct clock_event_device *bc;
 	unsigned long flags;
-	unsigned int cpu = *cpup;
 
 	raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
 
@@ -432,6 +432,7 @@ void tick_shutdown_broadcast(unsigned int *cpup)
 
 	raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
 }
+#endif
 
 void tick_suspend_broadcast(void)
 {
@@ -672,21 +673,6 @@ static void broadcast_shutdown_local(struct clock_event_device *bc,
 	clockevents_set_state(dev, CLOCK_EVT_STATE_SHUTDOWN);
 }
 
-void hotplug_cpu__broadcast_tick_pull(int deadcpu)
-{
-	struct clock_event_device *bc;
-	unsigned long flags;
-
-	raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
-	bc = tick_broadcast_device.evtdev;
-
-	if (bc && broadcast_needs_cpu(bc, deadcpu)) {
-		/* This moves the broadcast assignment to this CPU: */
-		clockevents_program_event(bc, bc->next_event, 1);
-	}
-	raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
-}
-
 /**
  * tick_broadcast_oneshot_control - Enter/exit broadcast oneshot mode
  * @state:	The target state (enter/exit)
@@ -908,14 +894,28 @@ void tick_broadcast_switch_to_oneshot(void)
 	raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
+void hotplug_cpu__broadcast_tick_pull(int deadcpu)
+{
+	struct clock_event_device *bc;
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
+	bc = tick_broadcast_device.evtdev;
+
+	if (bc && broadcast_needs_cpu(bc, deadcpu)) {
+		/* This moves the broadcast assignment to this CPU: */
+		clockevents_program_event(bc, bc->next_event, 1);
+	}
+	raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
+}
 
 /*
  * Remove a dead CPU from broadcasting
  */
-void tick_shutdown_broadcast_oneshot(unsigned int *cpup)
+void tick_shutdown_broadcast_oneshot(unsigned int cpu)
 {
 	unsigned long flags;
-	unsigned int cpu = *cpup;
 
 	raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
 
@@ -929,6 +929,7 @@ void tick_shutdown_broadcast_oneshot(unsigned int *cpup)
 
 	raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
 }
+#endif
 
 /*
  * Check, whether the broadcast device is in one shot mode
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
index 055c868..fac3e98 100644
--- a/kernel/time/tick-common.c
+++ b/kernel/time/tick-common.c
@@ -348,7 +348,6 @@ void tick_handover_do_timer(void)
 			TICK_DO_TIMER_NONE;
 	}
 }
-#endif
 
 /*
  * Shutdown an event device on a given cpu:
@@ -357,9 +356,9 @@ void tick_handover_do_timer(void)
  * access the hardware device itself.
  * We just set the mode and remove it from the lists.
  */
-void tick_shutdown(unsigned int *cpup)
+void tick_shutdown(unsigned int cpu)
 {
-	struct tick_device *td = &per_cpu(tick_cpu_device, *cpup);
+	struct tick_device *td = &per_cpu(tick_cpu_device, cpu);
 	struct clock_event_device *dev = td->evtdev;
 
 	td->mode = TICKDEV_MODE_PERIODIC;
@@ -375,6 +374,7 @@ void tick_shutdown(unsigned int *cpup)
 		td->evtdev = NULL;
 	}
 }
+#endif
 
 /**
  * tick_suspend_local - Suspend the local tick device
diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h
index aabcb5d..b64fdd8 100644
--- a/kernel/time/tick-internal.h
+++ b/kernel/time/tick-internal.h
@@ -20,7 +20,7 @@ extern int tick_do_timer_cpu __read_mostly;
 extern void tick_setup_periodic(struct clock_event_device *dev, int broadcast);
 extern void tick_handle_periodic(struct clock_event_device *dev);
 extern void tick_check_new_device(struct clock_event_device *dev);
-extern void tick_shutdown(unsigned int *cpup);
+extern void tick_shutdown(unsigned int cpu);
 extern void tick_suspend(void);
 extern void tick_resume(void);
 extern bool tick_check_replacement(struct clock_event_device *curdev,
@@ -52,7 +52,7 @@ extern ssize_t sysfs_get_uname(const char *buf, char *dst, size_t cnt);
 extern int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu);
 extern void tick_install_broadcast_device(struct clock_event_device *dev);
 extern int tick_is_broadcast_device(struct clock_event_device *dev);
-extern void tick_shutdown_broadcast(unsigned int *cpup);
+extern void tick_shutdown_broadcast(unsigned int cpu);
 extern void tick_suspend_broadcast(void);
 extern void tick_resume_broadcast(void);
 extern bool tick_resume_check_broadcast(void);
@@ -66,7 +66,7 @@ static inline void tick_install_broadcast_device(struct clock_event_device *dev)
 static inline int tick_is_broadcast_device(struct clock_event_device *dev) { return 0; }
 static inline int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu) { return 0; }
 static inline void tick_do_periodic_broadcast(struct clock_event_device *d) { }
-static inline void tick_shutdown_broadcast(unsigned int *cpup) { }
+static inline void tick_shutdown_broadcast(unsigned int cpu) { }
 static inline void tick_suspend_broadcast(void) { }
 static inline void tick_resume_broadcast(void) { }
 static inline bool tick_resume_check_broadcast(void) { return false; }
@@ -117,7 +117,7 @@ static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
 #if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) && defined(CONFIG_TICK_ONESHOT)
 extern void tick_broadcast_setup_oneshot(struct clock_event_device *bc);
 extern void tick_broadcast_switch_to_oneshot(void);
-extern void tick_shutdown_broadcast_oneshot(unsigned int *cpup);
+extern void tick_shutdown_broadcast_oneshot(unsigned int cpu);
 extern int tick_broadcast_oneshot_active(void);
 extern void tick_check_oneshot_broadcast_this_cpu(void);
 bool tick_broadcast_oneshot_available(void);
@@ -125,7 +125,7 @@ extern struct cpumask *tick_get_broadcast_oneshot_mask(void);
 #else /* !(BROADCAST && ONESHOT): */
 static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc) { BUG(); }
 static inline void tick_broadcast_switch_to_oneshot(void) { }
-static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { }
+static inline void tick_shutdown_broadcast_oneshot(unsigned int cpu) { }
 static inline int tick_broadcast_oneshot_active(void) { return 0; }
 static inline void tick_check_oneshot_broadcast_this_cpu(void) { }
 static inline bool tick_broadcast_oneshot_available(void) { return tick_oneshot_possible(); }

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [tip:timers/core] timekeeping: Get rid of stale comment
  2015-04-03  0:39       ` [v2][PATCH 21/21] timekeeping: Get rid of stale comment Rafael J. Wysocki
@ 2015-04-03  8:27         ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 90+ messages in thread
From: tip-bot for Thomas Gleixner @ 2015-04-03  8:27 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: john.stultz, tglx, rafael.j.wysocki, hpa, peterz, linux-kernel, mingo

Commit-ID:  347c6f6dda1098318088feb8e60188f0161e743d
Gitweb:     http://git.kernel.org/tip/347c6f6dda1098318088feb8e60188f0161e743d
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 3 Apr 2015 02:39:05 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:44:37 +0200

timekeeping: Get rid of stale comment

Arch specific management of xtime/jiffies/wall_to_monotonic is
gone for quite a while. Zap the stale comment.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: John Stultz <john.stultz@linaro.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/2422730.dmO29q661S@vostro.rjw.lan
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 kernel/time/timekeeping.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 79b9bc6..946acb7 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1354,10 +1354,6 @@ void timekeeping_inject_sleeptime64(struct timespec64 *delta)
 
 /**
  * timekeeping_resume - Resumes the generic timekeeping subsystem.
- *
- * This is for the generic clocksource timekeeping.
- * xtime/wall_to_monotonic/jiffies/etc are
- * still managed by arch specific suspend/resume code.
  */
 void timekeeping_resume(void)
 {

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 16/20] sched/idle: Use explicit broadcast oneshot control function
  2015-04-01 22:22 ` [PATCH 16/20] sched/idle: " Rafael J. Wysocki
@ 2015-04-28 10:11   ` Linus Walleij
  2015-04-28 10:17     ` Sudeep Holla
  2015-04-28 10:34     ` Daniel Lezcano
  0 siblings, 2 replies; 90+ messages in thread
From: Linus Walleij @ 2015-04-28 10:11 UTC (permalink / raw)
  To: Rafael J. Wysocki, Linux PM list, Thomas Gleixner
  Cc: Peter Zijlstra, Ingo Molnar, Linux Kernel Mailing List,
	ACPI Devel Maling List

On Thu, Apr 2, 2015 at 12:22 AM, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:

> From: Thomas Gleixner <tglx@linutronix.de>
>
> Replace the clockevents_notify() call with an explicit function call.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

For some reason this makes my Ux500 system arbitrarily hang,
especially during boot. Bisected down to this commit.
Since the entire changeset is removing the notifications
altogether I can't just revert it.

Disabling CONFIG_CPU_IDLE removes the problem.

Tried registering a stub driver (I just #if 0 all the code in
drivers/cpuidle/cpuidle-ux500.c) it still crashes.

That makes me think something inside the cpuidle subsystem
is locking up after this, but my other idea is that the timer
may be involved in some way, like this is stressing the timer
in some new yet untested way.

Has anyone else seen problems with this or is it only
ux500?

I'm looking closer at it but feel a bit clueless...

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 16/20] sched/idle: Use explicit broadcast oneshot control function
  2015-04-28 10:11   ` Linus Walleij
@ 2015-04-28 10:17     ` Sudeep Holla
  2015-04-28 10:34     ` Daniel Lezcano
  1 sibling, 0 replies; 90+ messages in thread
From: Sudeep Holla @ 2015-04-28 10:17 UTC (permalink / raw)
  To: Linus Walleij, Rafael J. Wysocki, Linux PM list, Thomas Gleixner
  Cc: Sudeep Holla, Peter Zijlstra, Ingo Molnar,
	Linux Kernel Mailing List, ACPI Devel Maling List



On 28/04/15 11:11, Linus Walleij wrote:
> On Thu, Apr 2, 2015 at 12:22 AM, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
>
>> From: Thomas Gleixner <tglx@linutronix.de>
>>
>> Replace the clockevents_notify() call with an explicit function call.
>>
>> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
>> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> For some reason this makes my Ux500 system arbitrarily hang,
> especially during boot. Bisected down to this commit.
> Since the entire changeset is removing the notifications
> altogether I can't just revert it.
>
> Disabling CONFIG_CPU_IDLE removes the problem.
>
> Tried registering a stub driver (I just #if 0 all the code in
> drivers/cpuidle/cpuidle-ux500.c) it still crashes.
>
> That makes me think something inside the cpuidle subsystem
> is locking up after this, but my other idea is that the timer
> may be involved in some way, like this is stressing the timer
> in some new yet untested way.
>
> Has anyone else seen problems with this or is it only
> ux500?
>
> I'm looking closer at it but feel a bit clueless...
>

Yes I am too in similar situation with my Vexpress platform.
I did report with the lockdep logs[1] before v4.1-rc1.
I still see the issue with v4.1-rc1.

Regards,
Sudeep

[1] https://lkml.org/lkml/2015/4/23/329

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 16/20] sched/idle: Use explicit broadcast oneshot control function
  2015-04-28 10:11   ` Linus Walleij
  2015-04-28 10:17     ` Sudeep Holla
@ 2015-04-28 10:34     ` Daniel Lezcano
  2015-04-28 10:42       ` Sudeep Holla
  1 sibling, 1 reply; 90+ messages in thread
From: Daniel Lezcano @ 2015-04-28 10:34 UTC (permalink / raw)
  To: Linus Walleij, Rafael J. Wysocki, Linux PM list, Thomas Gleixner
  Cc: Peter Zijlstra, Ingo Molnar, Linux Kernel Mailing List,
	ACPI Devel Maling List

On 04/28/2015 12:11 PM, Linus Walleij wrote:
> On Thu, Apr 2, 2015 at 12:22 AM, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
>
>> From: Thomas Gleixner <tglx@linutronix.de>
>>
>> Replace the clockevents_notify() call with an explicit function call.
>>
>> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
>> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> For some reason this makes my Ux500 system arbitrarily hang,
> especially during boot. Bisected down to this commit.
> Since the entire changeset is removing the notifications
> altogether I can't just revert it.
>
> Disabling CONFIG_CPU_IDLE removes the problem.
>
> Tried registering a stub driver (I just #if 0 all the code in
> drivers/cpuidle/cpuidle-ux500.c) it still crashes.
>
> That makes me think something inside the cpuidle subsystem
> is locking up after this, but my other idea is that the timer
> may be involved in some way, like this is stressing the timer
> in some new yet untested way.
>
> Has anyone else seen problems with this or is it only
> ux500?
>
> I'm looking closer at it but feel a bit clueless...

If you keep the #if 0 and remove the CPUIDLE_FLAG_TIMER_STOP flag, does 
it still crash ?

> To unsubscribe from this list: send the line "unsubscribe linux-pm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


-- 
  <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 16/20] sched/idle: Use explicit broadcast oneshot control function
  2015-04-28 10:34     ` Daniel Lezcano
@ 2015-04-28 10:42       ` Sudeep Holla
  2015-04-28 12:19         ` Rafael J. Wysocki
  0 siblings, 1 reply; 90+ messages in thread
From: Sudeep Holla @ 2015-04-28 10:42 UTC (permalink / raw)
  To: Daniel Lezcano, Linus Walleij, Rafael J. Wysocki, Linux PM list,
	Thomas Gleixner
  Cc: Sudeep Holla, Peter Zijlstra, Ingo Molnar,
	Linux Kernel Mailing List, ACPI Devel Maling List



On 28/04/15 11:34, Daniel Lezcano wrote:
> On 04/28/2015 12:11 PM, Linus Walleij wrote:
>> On Thu, Apr 2, 2015 at 12:22 AM, Rafael J. Wysocki
>> <rjw@rjwysocki.net> wrote:
>>
>>> From: Thomas Gleixner <tglx@linutronix.de>
>>>
>>> Replace the clockevents_notify() call with an explicit function
>>> call.
>>>
>>> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
>>> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>>
>> For some reason this makes my Ux500 system arbitrarily hang,
>> especially during boot. Bisected down to this commit. Since the
>> entire changeset is removing the notifications altogether I can't
>> just revert it.
>>
>> Disabling CONFIG_CPU_IDLE removes the problem.
>>
>> Tried registering a stub driver (I just #if 0 all the code in
>> drivers/cpuidle/cpuidle-ux500.c) it still crashes.
>>
>> That makes me think something inside the cpuidle subsystem is
>> locking up after this, but my other idea is that the timer may be
>> involved in some way, like this is stressing the timer in some new
>> yet untested way.
>>
>> Has anyone else seen problems with this or is it only ux500?
>>
>> I'm looking closer at it but feel a bit clueless...
>
> If you keep the #if 0 and remove the CPUIDLE_FLAG_TIMER_STOP flag,
> does it still crash ?
>

At-least I observed issue only when I am using hardware broadcast timer.
It doesn't hang when I am using hrtimer as broadcast timer in which case
one of the cpu will be not enter deeper idle states that lose timer.
I will rerun on v4.1-rc1 and post the complete log.

Regards,
Sudeep

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 16/20] sched/idle: Use explicit broadcast oneshot control function
  2015-04-28 10:42       ` Sudeep Holla
@ 2015-04-28 12:19         ` Rafael J. Wysocki
  2015-04-28 12:37           ` Linus Walleij
  2015-04-28 13:04           ` Sudeep Holla
  0 siblings, 2 replies; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-28 12:19 UTC (permalink / raw)
  To: Sudeep Holla
  Cc: Daniel Lezcano, Linus Walleij, Rafael J. Wysocki, Linux PM list,
	Thomas Gleixner, Peter Zijlstra, Ingo Molnar,
	Linux Kernel Mailing List, ACPI Devel Maling List

On Tue, Apr 28, 2015 at 12:42 PM, Sudeep Holla <sudeep.holla@arm.com> wrote:
>
>
> On 28/04/15 11:34, Daniel Lezcano wrote:
>>
>> On 04/28/2015 12:11 PM, Linus Walleij wrote:
>>>
>>> On Thu, Apr 2, 2015 at 12:22 AM, Rafael J. Wysocki
>>> <rjw@rjwysocki.net> wrote:
>>>
>>>> From: Thomas Gleixner <tglx@linutronix.de>
>>>>
>>>> Replace the clockevents_notify() call with an explicit function
>>>> call.
>>>>
>>>> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
>>>> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>>>
>>>
>>> For some reason this makes my Ux500 system arbitrarily hang,
>>> especially during boot. Bisected down to this commit. Since the
>>> entire changeset is removing the notifications altogether I can't
>>> just revert it.
>>>
>>> Disabling CONFIG_CPU_IDLE removes the problem.
>>>
>>> Tried registering a stub driver (I just #if 0 all the code in
>>> drivers/cpuidle/cpuidle-ux500.c) it still crashes.
>>>
>>> That makes me think something inside the cpuidle subsystem is
>>> locking up after this, but my other idea is that the timer may be
>>> involved in some way, like this is stressing the timer in some new
>>> yet untested way.
>>>
>>> Has anyone else seen problems with this or is it only ux500?
>>>
>>> I'm looking closer at it but feel a bit clueless...
>>
>>
>> If you keep the #if 0 and remove the CPUIDLE_FLAG_TIMER_STOP flag,
>> does it still crash ?
>>
>
> At-least I observed issue only when I am using hardware broadcast timer.
> It doesn't hang when I am using hrtimer as broadcast timer in which case
> one of the cpu will be not enter deeper idle states that lose timer.
> I will rerun on v4.1-rc1 and post the complete log.

So the bug here is that cpuidle_enter() enables interrupts, so the
assumption about them being not enabled made by
tick_broadcast_oneshot_control() is actually not valid.

It looks like we need to acquire the clockevents_lock at least in this
particular case.  Let me see where to put it and I'll send a patch for
testing.

Rafael

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 16/20] sched/idle: Use explicit broadcast oneshot control function
  2015-04-28 12:19         ` Rafael J. Wysocki
@ 2015-04-28 12:37           ` Linus Walleij
  2015-04-28 13:31             ` Rafael J. Wysocki
  2015-04-28 13:04           ` Sudeep Holla
  1 sibling, 1 reply; 90+ messages in thread
From: Linus Walleij @ 2015-04-28 12:37 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Sudeep Holla, Daniel Lezcano, Rafael J. Wysocki, Linux PM list,
	Thomas Gleixner, Peter Zijlstra, Ingo Molnar,
	Linux Kernel Mailing List, ACPI Devel Maling List

On Tue, Apr 28, 2015 at 2:19 PM, Rafael J. Wysocki <rafael@kernel.org> wrote:
> Sudeep:
>> At-least I observed issue only when I am using hardware broadcast timer.
>> It doesn't hang when I am using hrtimer as broadcast timer in which case
>> one of the cpu will be not enter deeper idle states that lose timer.
>> I will rerun on v4.1-rc1 and post the complete log.
>
> So the bug here is that cpuidle_enter() enables interrupts, so the
> assumption about them being not enabled made by
> tick_broadcast_oneshot_control() is actually not valid.
>
> It looks like we need to acquire the clockevents_lock at least in this
> particular case.  Let me see where to put it and I'll send a patch for
> testing.

Aha that looks very much like it. Put me on the patch and I'll
take it for a spin.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 16/20] sched/idle: Use explicit broadcast oneshot control function
  2015-04-28 12:19         ` Rafael J. Wysocki
  2015-04-28 12:37           ` Linus Walleij
@ 2015-04-28 13:04           ` Sudeep Holla
  1 sibling, 0 replies; 90+ messages in thread
From: Sudeep Holla @ 2015-04-28 13:04 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Sudeep Holla, Daniel Lezcano, Linus Walleij, Rafael J. Wysocki,
	Linux PM list, Thomas Gleixner, Peter Zijlstra, Ingo Molnar,
	Linux Kernel Mailing List, ACPI Devel Maling List

Hi Rafael,

On 28/04/15 13:19, Rafael J. Wysocki wrote:
> On Tue, Apr 28, 2015 at 12:42 PM, Sudeep Holla <sudeep.holla@arm.com> wrote:

[...]

>>
>> At-least I observed issue only when I am using hardware broadcast timer.
>> It doesn't hang when I am using hrtimer as broadcast timer in which case
>> one of the cpu will be not enter deeper idle states that lose timer.
>> I will rerun on v4.1-rc1 and post the complete log.
>
> So the bug here is that cpuidle_enter() enables interrupts, so the
> assumption about them being not enabled made by
> tick_broadcast_oneshot_control() is actually not valid.
>
> It looks like we need to acquire the clockevents_lock at least in this
> particular case.  Let me see where to put it and I'll send a patch for
> testing.
>

Thanks for looking at this, I can also help in testing. Sending the 
complete log again with v4.1-rc1 if it's any useful.

Regards,
Sudeep

--->8

BUG: spinlock lockup suspected on CPU#0, swapper/0/0
  lock: tick_broadcast_lock+0x0/0x40, .magic: dead4ead, .owner: 
swapper/0/0, .owner_cpu: 0
CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.1.0-rc1 #16
Hardware name: ARM-Versatile Express
[<c0014b1d>] (unwind_backtrace) from [<c0011659>] (show_stack+0x11/0x14)
[<c0011659>] (show_stack) from [<c05192ed>] (dump_stack+0x6d/0x78)
[<c05192ed>] (dump_stack) from [<c005c897>] (do_raw_spin_lock+0xc3/0x144)
[<c005c897>] (do_raw_spin_lock) from [<c00811f9>] 
(tick_handle_oneshot_broadcast+0x25/0x164)
[<c00811f9>] (tick_handle_oneshot_broadcast) from [<c001dd21>] 
(sp804_timer_interrupt+0x31/0x34)
[<c001dd21>] (sp804_timer_interrupt) from [<c0067ee1>] 
(handle_irq_event_percpu+0x45/0x154)
[<c0067ee1>] (handle_irq_event_percpu) from [<c006801f>] 
(handle_irq_event+0x2f/0x44)
[<c006801f>] (handle_irq_event) from [<c0069edb>] 
(handle_fasteoi_irq+0x6f/0xf0)
[<c0069edb>] (handle_fasteoi_irq) from [<c00677c7>] 
(generic_handle_irq+0x23/0x2c)
[<c00677c7>] (generic_handle_irq) from [<c0067a0d>] 
(__handle_domain_irq+0x45/0x84)
[<c0067a0d>] (__handle_domain_irq) from [<c0009303>] 
(gic_handle_irq+0x27/0x50)
[<c0009303>] (gic_handle_irq) from [<c0011eff>] (__irq_svc+0x3f/0x64)
Exception stack(0xc07ebf08 to 0xc07ebf50)
bf00:                   00000000 c1038814 00000001 00000001 c07f3f80 
ee78dec0
bf20: 00000000 c1038810 00000000 00000001 c07ebf88 c0520fc8 00000000 
c07ebf50
bf40: c008151d c02e104e 40000173 ffffffff
[<c0011eff>] (__irq_svc) from [<c02e104e>] (_test_and_clear_bit+0x26/0x48)
[<c02e104e>] (_test_and_clear_bit) from [<c008151d>] 
(tick_broadcast_oneshot_control+0x159/0x1ec)
[<c008151d>] (tick_broadcast_oneshot_control) from [<c0050273>] 
(cpu_startup_entry+0x2c3/0x2f8)
[<c0050273>] (cpu_startup_entry) from [<c0782a47>] 
(start_kernel+0x327/0x330)
BUG: spinlock lockup suspected on CPU#3, swapper/3/0
BUG: spinlock lockup suspected on CPU#4, swapper/4/0
  lock: tick_broadcast_lock+0x0/0x40, .magic: dead4ead, .owner: 
swapper/0/0, .owner_cpu: 0
CPU: 4 PID: 0 Comm: swapper/4 Not tainted 4.1.0-rc1 #16
Hardware name: ARM-Versatile Express
[<c0014b1d>] (unwind_backtrace) from [<c0011659>] (show_stack+0x11/0x14)
[<c0011659>] (show_stack) from [<c05192ed>] (dump_stack+0x6d/0x78)
BUG: spinlock lockup suspected on CPU#2, swapper/2/0
[<c05192ed>] (dump_stack) from [<c005c897>] (do_raw_spin_lock+0xc3/0x144)
  lock: tick_broadcast_lock+0x0/0x40, .magic: dead4ead, .owner: 
swapper/0/0, .owner_cpu: 0
[<c005c897>] (do_raw_spin_lock) from [<c0081409>] 
(tick_broadcast_oneshot_control+0x45/0x1ec)
[<c0081409>] (tick_broadcast_oneshot_control) from [<c0050273>] 
(cpu_startup_entry+0x2c3/0x2f8)
[<c0050273>] (cpu_startup_entry) from [<800093d1>] (0x800093d1)
CPU: 2 PID: 0 Comm: swapper/2 Not tainted 4.1.0-rc1 #16
Hardware name: ARM-Versatile Express
[<c0014b1d>] (unwind_backtrace) from [<c0011659>] (show_stack+0x11/0x14)
[<c0011659>] (show_stack) from [<c05192ed>] (dump_stack+0x6d/0x78)
[<c05192ed>] (dump_stack) from [<c005c897>] (do_raw_spin_lock+0xc3/0x144)
[<c005c897>] (do_raw_spin_lock) from [<c0081409>] 
(tick_broadcast_oneshot_control+0x45/0x1ec)
[<c0081409>] (tick_broadcast_oneshot_control) from [<c0050273>] 
(cpu_startup_entry+0x2c3/0x2f8)
[<c0050273>] (cpu_startup_entry) from [<800093d1>] (0x800093d1)
  lock: tick_broadcast_lock+0x0/0x40, .magic: dead4ead, .owner: 
swapper/0/0, .owner_cpu: 0
CPU: 3 PID: 0 Comm: swapper/3 Not tainted 4.1.0-rc1 #16
Hardware name: ARM-Versatile Express
[<c0014b1d>] (unwind_backtrace) from [<c0011659>] (show_stack+0x11/0x14)
[<c0011659>] (show_stack) from [<c05192ed>] (dump_stack+0x6d/0x78)
[<c05192ed>] (dump_stack) from [<c005c897>] (do_raw_spin_lock+0xc3/0x144)
[<c005c897>] (do_raw_spin_lock) from [<c0081409>] 
(tick_broadcast_oneshot_control+0x45/0x1ec)
[<c0081409>] (tick_broadcast_oneshot_control) from [<c0050273>] 
(cpu_startup_entry+0x2c3/0x2f8)
[<c0050273>] (cpu_startup_entry) from [<800093d1>] (0x800093d1)






^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 16/20] sched/idle: Use explicit broadcast oneshot control function
  2015-04-28 12:37           ` Linus Walleij
@ 2015-04-28 13:31             ` Rafael J. Wysocki
  2015-04-28 13:37               ` Rafael J. Wysocki
  0 siblings, 1 reply; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-28 13:31 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Rafael J. Wysocki, Sudeep Holla, Daniel Lezcano, Linux PM list,
	Thomas Gleixner, Peter Zijlstra, Ingo Molnar,
	Linux Kernel Mailing List, ACPI Devel Maling List

On Tuesday, April 28, 2015 02:37:10 PM Linus Walleij wrote:
> On Tue, Apr 28, 2015 at 2:19 PM, Rafael J. Wysocki <rafael@kernel.org> wrote:
> > Sudeep:
> >> At-least I observed issue only when I am using hardware broadcast timer.
> >> It doesn't hang when I am using hrtimer as broadcast timer in which case
> >> one of the cpu will be not enter deeper idle states that lose timer.
> >> I will rerun on v4.1-rc1 and post the complete log.
> >
> > So the bug here is that cpuidle_enter() enables interrupts, so the
> > assumption about them being not enabled made by
> > tick_broadcast_oneshot_control() is actually not valid.
> >
> > It looks like we need to acquire the clockevents_lock at least in this
> > particular case.  Let me see where to put it and I'll send a patch for
> > testing.
> 
> Aha that looks very much like it. Put me on the patch and I'll
> take it for a spin.

OK, so something like the below for starters (the _irqsave variant is used to
avoid adding one more WARN_ON(irqs_disabled()) in there).

I haven't tested it, but then I can't reproduce the original issue in the
first place.

---
 include/linux/clockchips.h |    2 ++
 kernel/sched/idle.c        |    2 +-
 kernel/time/clockevents.c  |   15 +++++++++++++++
 3 files changed, 18 insertions(+), 1 deletion(-)

Index: linux-pm/include/linux/clockchips.h
===================================================================
--- linux-pm.orig/include/linux/clockchips.h
+++ linux-pm/include/linux/clockchips.h
@@ -198,9 +198,11 @@ extern int tick_receive_broadcast(void);
 # if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) && defined(CONFIG_TICK_ONESHOT)
 extern void tick_setup_hrtimer_broadcast(void);
 extern int tick_check_broadcast_expired(void);
+extern void tick_broadcast_exit_idle(void);
 # else
 static inline int tick_check_broadcast_expired(void) { return 0; }
 static inline void tick_setup_hrtimer_broadcast(void) { }
+static inline void tick_broadcast_exit_idle(void) { }
 # endif
 
 extern int clockevents_notify(unsigned long reason, void *arg);
Index: linux-pm/kernel/time/clockevents.c
===================================================================
--- linux-pm.orig/kernel/time/clockevents.c
+++ linux-pm/kernel/time/clockevents.c
@@ -735,6 +735,21 @@ static ssize_t sysfs_unbind_tick_dev(str
 static DEVICE_ATTR(unbind_device, 0200, NULL, sysfs_unbind_tick_dev);
 
 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
+/**
+ * tick_broadcast_exit_idle - Broadcast oneshot mode exit for the idle loop.
+ *
+ * The idle loop exits the broadcast oneshot mode with interrupts enabled, so
+ * clockevents_lock needs to be acquired around that.
+ */
+void tick_broadcast_exit_idle(void)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&clockevents_lock, flags);
+	tick_broadcast_exit();
+	raw_spin_unlock_irqrestore(&clockevents_lock, flags);
+}
+
 static struct device tick_bc_dev = {
 	.init_name	= "broadcast",
 	.id		= 0,
Index: linux-pm/kernel/sched/idle.c
===================================================================
--- linux-pm.orig/kernel/sched/idle.c
+++ linux-pm/kernel/sched/idle.c
@@ -175,7 +175,7 @@ static void cpuidle_idle_call(void)
 	idle_set_state(this_rq(), NULL);
 
 	if (broadcast)
-		tick_broadcast_exit();
+		tick_broadcast_exit_idle();
 
 	/*
 	 * Give the governor an opportunity to reflect on the outcome


^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 16/20] sched/idle: Use explicit broadcast oneshot control function
  2015-04-28 13:31             ` Rafael J. Wysocki
@ 2015-04-28 13:37               ` Rafael J. Wysocki
  2015-04-28 14:14                 ` Rafael J. Wysocki
  0 siblings, 1 reply; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-28 13:37 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Rafael J. Wysocki, Sudeep Holla, Daniel Lezcano, Linux PM list,
	Thomas Gleixner, Peter Zijlstra, Ingo Molnar,
	Linux Kernel Mailing List, ACPI Devel Maling List

On Tuesday, April 28, 2015 03:31:54 PM Rafael J. Wysocki wrote:
> On Tuesday, April 28, 2015 02:37:10 PM Linus Walleij wrote:
> > On Tue, Apr 28, 2015 at 2:19 PM, Rafael J. Wysocki <rafael@kernel.org> wrote:
> > > Sudeep:
> > >> At-least I observed issue only when I am using hardware broadcast timer.
> > >> It doesn't hang when I am using hrtimer as broadcast timer in which case
> > >> one of the cpu will be not enter deeper idle states that lose timer.
> > >> I will rerun on v4.1-rc1 and post the complete log.
> > >
> > > So the bug here is that cpuidle_enter() enables interrupts, so the
> > > assumption about them being not enabled made by
> > > tick_broadcast_oneshot_control() is actually not valid.
> > >
> > > It looks like we need to acquire the clockevents_lock at least in this
> > > particular case.  Let me see where to put it and I'll send a patch for
> > > testing.
> > 
> > Aha that looks very much like it. Put me on the patch and I'll
> > take it for a spin.
> 
> OK, so something like the below for starters (the _irqsave variant is used to
> avoid adding one more WARN_ON(irqs_disabled()) in there).
> 
> I haven't tested it, but then I can't reproduce the original issue in the
> first place.

Of course, the whole "broadcast" thing could be done from cpuidle_enter()
in the first place, but then we could not avoid the problem with the cpuidle
*callback* enabling interrupts possibly in there anyway (not to mention the
"coupled" stuff).


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 16/20] sched/idle: Use explicit broadcast oneshot control function
  2015-04-28 14:14                 ` Rafael J. Wysocki
@ 2015-04-28 13:58                   ` Sudeep Holla
  2015-04-29  0:50                     ` Rafael J. Wysocki
  0 siblings, 1 reply; 90+ messages in thread
From: Sudeep Holla @ 2015-04-28 13:58 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linus Walleij, Sudeep Holla, Rafael J. Wysocki, Daniel Lezcano,
	Linux PM list, Thomas Gleixner, Peter Zijlstra, Ingo Molnar,
	Linux Kernel Mailing List, ACPI Devel Maling List



On 28/04/15 15:14, Rafael J. Wysocki wrote:
> On Tuesday, April 28, 2015 03:37:44 PM Rafael J. Wysocki wrote:
>> On Tuesday, April 28, 2015 03:31:54 PM Rafael J. Wysocki wrote:
>>> On Tuesday, April 28, 2015 02:37:10 PM Linus Walleij wrote:
>>>> On Tue, Apr 28, 2015 at 2:19 PM, Rafael J. Wysocki <rafael@kernel.org> wrote:
>>>>> Sudeep:
>>>>>> At-least I observed issue only when I am using hardware broadcast timer.
>>>>>> It doesn't hang when I am using hrtimer as broadcast timer in which case
>>>>>> one of the cpu will be not enter deeper idle states that lose timer.
>>>>>> I will rerun on v4.1-rc1 and post the complete log.
>>>>>
>>>>> So the bug here is that cpuidle_enter() enables interrupts, so the
>>>>> assumption about them being not enabled made by
>>>>> tick_broadcast_oneshot_control() is actually not valid.
>>>>>
>>>>> It looks like we need to acquire the clockevents_lock at least in this
>>>>> particular case.  Let me see where to put it and I'll send a patch for
>>>>> testing.
>>>>
>>>> Aha that looks very much like it. Put me on the patch and I'll
>>>> take it for a spin.
>>>
>>> OK, so something like the below for starters (the _irqsave variant is used to
>>> avoid adding one more WARN_ON(irqs_disabled()) in there).
>>>
>>> I haven't tested it, but then I can't reproduce the original issue in the
>>> first place.
>>
>> Of course, the whole "broadcast" thing could be done from cpuidle_enter()
>> in the first place, but then we could not avoid the problem with the cpuidle
>> *callback* enabling interrupts possibly in there anyway (not to mention the
>> "coupled" stuff).
>
> That said, if the given state is marked with CPUIDLE_FLAG_TIMER_STOP, I really
> wouldn't expect it to re-enable interrupts on exit and the "coupled" thing
> seems to be fundamentally at odds with that flag either.
>
> So it should be possible to move the "broadcast" logic into the cpuidle layer,
> which I'm going to try to do.
>

Makes sense.

> Please test the patch I've sent, though, as it should bring the code back to
> where it was before the clockevents_notify() removal and it'd be good to verify
> that.
>

I tested your patch and it works now. Anyways I am continuing to run
stress tests on my board. I will report if I find any issues.

Regards,
Sudeep

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 16/20] sched/idle: Use explicit broadcast oneshot control function
  2015-04-28 13:37               ` Rafael J. Wysocki
@ 2015-04-28 14:14                 ` Rafael J. Wysocki
  2015-04-28 13:58                   ` Sudeep Holla
  0 siblings, 1 reply; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-28 14:14 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Rafael J. Wysocki, Sudeep Holla, Daniel Lezcano, Linux PM list,
	Thomas Gleixner, Peter Zijlstra, Ingo Molnar,
	Linux Kernel Mailing List, ACPI Devel Maling List

On Tuesday, April 28, 2015 03:37:44 PM Rafael J. Wysocki wrote:
> On Tuesday, April 28, 2015 03:31:54 PM Rafael J. Wysocki wrote:
> > On Tuesday, April 28, 2015 02:37:10 PM Linus Walleij wrote:
> > > On Tue, Apr 28, 2015 at 2:19 PM, Rafael J. Wysocki <rafael@kernel.org> wrote:
> > > > Sudeep:
> > > >> At-least I observed issue only when I am using hardware broadcast timer.
> > > >> It doesn't hang when I am using hrtimer as broadcast timer in which case
> > > >> one of the cpu will be not enter deeper idle states that lose timer.
> > > >> I will rerun on v4.1-rc1 and post the complete log.
> > > >
> > > > So the bug here is that cpuidle_enter() enables interrupts, so the
> > > > assumption about them being not enabled made by
> > > > tick_broadcast_oneshot_control() is actually not valid.
> > > >
> > > > It looks like we need to acquire the clockevents_lock at least in this
> > > > particular case.  Let me see where to put it and I'll send a patch for
> > > > testing.
> > > 
> > > Aha that looks very much like it. Put me on the patch and I'll
> > > take it for a spin.
> > 
> > OK, so something like the below for starters (the _irqsave variant is used to
> > avoid adding one more WARN_ON(irqs_disabled()) in there).
> > 
> > I haven't tested it, but then I can't reproduce the original issue in the
> > first place.
> 
> Of course, the whole "broadcast" thing could be done from cpuidle_enter()
> in the first place, but then we could not avoid the problem with the cpuidle
> *callback* enabling interrupts possibly in there anyway (not to mention the
> "coupled" stuff).

That said, if the given state is marked with CPUIDLE_FLAG_TIMER_STOP, I really
wouldn't expect it to re-enable interrupts on exit and the "coupled" thing
seems to be fundamentally at odds with that flag either.

So it should be possible to move the "broadcast" logic into the cpuidle layer,
which I'm going to try to do.

Please test the patch I've sent, though, as it should bring the code back to
where it was before the clockevents_notify() removal and it'd be good to verify
that.

Rafael


^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 16/20] sched/idle: Use explicit broadcast oneshot control function
  2015-04-28 13:58                   ` Sudeep Holla
@ 2015-04-29  0:50                     ` Rafael J. Wysocki
  2015-04-29  1:04                       ` Rafael J. Wysocki
  0 siblings, 1 reply; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-29  0:50 UTC (permalink / raw)
  To: Sudeep Holla, Peter Zijlstra
  Cc: Linus Walleij, Rafael J. Wysocki, Daniel Lezcano, Linux PM list,
	Thomas Gleixner, Ingo Molnar, Linux Kernel Mailing List,
	ACPI Devel Maling List

On Tuesday, April 28, 2015 02:58:37 PM Sudeep Holla wrote:
> 
> On 28/04/15 15:14, Rafael J. Wysocki wrote:
> > On Tuesday, April 28, 2015 03:37:44 PM Rafael J. Wysocki wrote:
> >> On Tuesday, April 28, 2015 03:31:54 PM Rafael J. Wysocki wrote:
> >>> On Tuesday, April 28, 2015 02:37:10 PM Linus Walleij wrote:
> >>>> On Tue, Apr 28, 2015 at 2:19 PM, Rafael J. Wysocki <rafael@kernel.org> wrote:
> >>>>> Sudeep:
> >>>>>> At-least I observed issue only when I am using hardware broadcast timer.
> >>>>>> It doesn't hang when I am using hrtimer as broadcast timer in which case
> >>>>>> one of the cpu will be not enter deeper idle states that lose timer.
> >>>>>> I will rerun on v4.1-rc1 and post the complete log.
> >>>>>
> >>>>> So the bug here is that cpuidle_enter() enables interrupts, so the
> >>>>> assumption about them being not enabled made by
> >>>>> tick_broadcast_oneshot_control() is actually not valid.
> >>>>>
> >>>>> It looks like we need to acquire the clockevents_lock at least in this
> >>>>> particular case.  Let me see where to put it and I'll send a patch for
> >>>>> testing.
> >>>>
> >>>> Aha that looks very much like it. Put me on the patch and I'll
> >>>> take it for a spin.
> >>>
> >>> OK, so something like the below for starters (the _irqsave variant is used to
> >>> avoid adding one more WARN_ON(irqs_disabled()) in there).
> >>>
> >>> I haven't tested it, but then I can't reproduce the original issue in the
> >>> first place.
> >>
> >> Of course, the whole "broadcast" thing could be done from cpuidle_enter()
> >> in the first place, but then we could not avoid the problem with the cpuidle
> >> *callback* enabling interrupts possibly in there anyway (not to mention the
> >> "coupled" stuff).
> >
> > That said, if the given state is marked with CPUIDLE_FLAG_TIMER_STOP, I really
> > wouldn't expect it to re-enable interrupts on exit and the "coupled" thing
> > seems to be fundamentally at odds with that flag either.
> >
> > So it should be possible to move the "broadcast" logic into the cpuidle layer,
> > which I'm going to try to do.
> >
> 
> Makes sense.
> 
> > Please test the patch I've sent, though, as it should bring the code back to
> > where it was before the clockevents_notify() removal and it'd be good to verify
> > that.
> >
> 
> I tested your patch and it works now. Anyways I am continuing to run
> stress tests on my board. I will report if I find any issues.

Great, thanks!

Below is the patch I came up with in the meantime.

This moves the "switch to broadcast" timer logic into
cpuidle_enter_state() which allows tick_broadcast_exit() to be
called directly with interrupts disabled (as required), but
it also adds a fallback branch reflecting the 4.0 and earlier
behavior for idle states that enable interrupts on exit
from their ->enter callbacks.

I'm not aware of any valid cases when CPUIDLE_FLAG_TIMER_STOP can be
set for such states, but people may try to add stuff like that in the
future, so it's better to catch that (hence the WARN_ON_ONCE) and do
our best to handle it gracefully anyway, IMO.

The "if (entered_state == -EBUSY)" check is conservative.  It may
be better to do "if (entered_state < 0)" and fall back to the default
on all errors, but that's not what we do today (I guess the concern
would be "what if the state ->enter returns an error after entering
and exiting the idle state, in which case we may miss a wakeup event
if we fall back to the default").

---
 drivers/cpuidle/cpuidle.c  |   16 ++++++++++++++++
 include/linux/clockchips.h |    2 ++
 kernel/sched/idle.c        |   16 ++--------------
 kernel/time/clockevents.c  |   13 +++++++++++++
 4 files changed, 33 insertions(+), 14 deletions(-)

Index: linux-pm/include/linux/clockchips.h
===================================================================
--- linux-pm.orig/include/linux/clockchips.h
+++ linux-pm/include/linux/clockchips.h
@@ -198,9 +198,11 @@ extern int tick_receive_broadcast(void);
 # if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) && defined(CONFIG_TICK_ONESHOT)
 extern void tick_setup_hrtimer_broadcast(void);
 extern int tick_check_broadcast_expired(void);
+extern void tick_broadcast_exit_idle_fallback(void);
 # else
 static inline int tick_check_broadcast_expired(void) { return 0; }
 static inline void tick_setup_hrtimer_broadcast(void) { }
+static inline void tick_broadcast_exit_idle_fallback(void) { }
 # endif
 
 extern int clockevents_notify(unsigned long reason, void *arg);
Index: linux-pm/kernel/time/clockevents.c
===================================================================
--- linux-pm.orig/kernel/time/clockevents.c
+++ linux-pm/kernel/time/clockevents.c
@@ -735,6 +735,19 @@ static ssize_t sysfs_unbind_tick_dev(str
 static DEVICE_ATTR(unbind_device, 0200, NULL, sysfs_unbind_tick_dev);
 
 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
+/**
+ * tick_broadcast_exit_idle_fallback - Fallback broadcast oneshot mode exit.
+ *
+ * Called from within the CPU idle subsystem when exiting the broadcast oneshot
+ * mode with interrupts enabled (fallback case only).
+ */
+void tick_broadcast_exit_idle_fallback(void)
+{
+	raw_spin_lock_irq(&clockevents_lock);
+	tick_broadcast_exit();
+	raw_spin_unlock_irq(&clockevents_lock);
+}
+
 static struct device tick_bc_dev = {
 	.init_name	= "broadcast",
 	.id		= 0,
Index: linux-pm/kernel/sched/idle.c
===================================================================
--- linux-pm.orig/kernel/sched/idle.c
+++ linux-pm/kernel/sched/idle.c
@@ -81,7 +81,6 @@ static void cpuidle_idle_call(void)
 	struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
 	struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
 	int next_state, entered_state;
-	unsigned int broadcast;
 	bool reflect;
 
 	/*
@@ -150,17 +149,6 @@ static void cpuidle_idle_call(void)
 		goto exit_idle;
 	}
 
-	broadcast = drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP;
-
-	/*
-	 * Tell the time framework to switch to a broadcast timer
-	 * because our local timer will be shutdown. If a local timer
-	 * is used from another cpu as a broadcast timer, this call may
-	 * fail if it is not available
-	 */
-	if (broadcast && tick_broadcast_enter())
-		goto use_default;
-
 	/* Take note of the planned idle state. */
 	idle_set_state(this_rq(), &drv->states[next_state]);
 
@@ -174,8 +162,8 @@ static void cpuidle_idle_call(void)
 	/* The cpu is no longer idle or about to enter idle. */
 	idle_set_state(this_rq(), NULL);
 
-	if (broadcast)
-		tick_broadcast_exit();
+	if (entered_state == -EBUSY)
+		goto use_default;
 
 	/*
 	 * Give the governor an opportunity to reflect on the outcome
Index: linux-pm/drivers/cpuidle/cpuidle.c
===================================================================
--- linux-pm.orig/drivers/cpuidle/cpuidle.c
+++ linux-pm/drivers/cpuidle/cpuidle.c
@@ -158,9 +158,18 @@ int cpuidle_enter_state(struct cpuidle_d
 	int entered_state;
 
 	struct cpuidle_state *target_state = &drv->states[index];
+	bool broadcast = !!(target_state->flags & CPUIDLE_FLAG_TIMER_STOP);
 	ktime_t time_start, time_end;
 	s64 diff;
 
+	/*
+	 * Tell the time framework to switch to a broadcast timer because our
+	 * local timer will be shut down.  If a local timer is used from another
+	 * CPU as a broadcast timer, this call may fail if it is not available.
+	 */
+	if (broadcast && tick_broadcast_enter())
+		return -EBUSY;
+
 	trace_cpu_idle_rcuidle(index, dev->cpu);
 	time_start = ktime_get();
 
@@ -169,6 +178,13 @@ int cpuidle_enter_state(struct cpuidle_d
 	time_end = ktime_get();
 	trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu);
 
+	if (broadcast) {
+		if (WARN_ON_ONCE(!irqs_disabled()))
+			tick_broadcast_exit_idle_fallback();
+		else
+			tick_broadcast_exit();
+	}
+
 	if (!cpuidle_state_is_coupled(dev, drv, entered_state))
 		local_irq_enable();
 


^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 16/20] sched/idle: Use explicit broadcast oneshot control function
  2015-04-29  0:50                     ` Rafael J. Wysocki
@ 2015-04-29  1:04                       ` Rafael J. Wysocki
  2015-04-29  7:10                         ` Linus Walleij
                                           ` (4 more replies)
  0 siblings, 5 replies; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-29  1:04 UTC (permalink / raw)
  To: Sudeep Holla, Peter Zijlstra
  Cc: Linus Walleij, Rafael J. Wysocki, Daniel Lezcano, Linux PM list,
	Thomas Gleixner, Ingo Molnar, Linux Kernel Mailing List,
	ACPI Devel Maling List

On Wednesday, April 29, 2015 02:50:22 AM Rafael J. Wysocki wrote:
> On Tuesday, April 28, 2015 02:58:37 PM Sudeep Holla wrote:
> > 
> > On 28/04/15 15:14, Rafael J. Wysocki wrote:
> > > On Tuesday, April 28, 2015 03:37:44 PM Rafael J. Wysocki wrote:
> > >> On Tuesday, April 28, 2015 03:31:54 PM Rafael J. Wysocki wrote:
> > >>> On Tuesday, April 28, 2015 02:37:10 PM Linus Walleij wrote:
> > >>>> On Tue, Apr 28, 2015 at 2:19 PM, Rafael J. Wysocki <rafael@kernel.org> wrote:
> > >>>>> Sudeep:
> > >>>>>> At-least I observed issue only when I am using hardware broadcast timer.
> > >>>>>> It doesn't hang when I am using hrtimer as broadcast timer in which case
> > >>>>>> one of the cpu will be not enter deeper idle states that lose timer.
> > >>>>>> I will rerun on v4.1-rc1 and post the complete log.
> > >>>>>
> > >>>>> So the bug here is that cpuidle_enter() enables interrupts, so the
> > >>>>> assumption about them being not enabled made by
> > >>>>> tick_broadcast_oneshot_control() is actually not valid.
> > >>>>>
> > >>>>> It looks like we need to acquire the clockevents_lock at least in this
> > >>>>> particular case.  Let me see where to put it and I'll send a patch for
> > >>>>> testing.
> > >>>>
> > >>>> Aha that looks very much like it. Put me on the patch and I'll
> > >>>> take it for a spin.
> > >>>
> > >>> OK, so something like the below for starters (the _irqsave variant is used to
> > >>> avoid adding one more WARN_ON(irqs_disabled()) in there).
> > >>>
> > >>> I haven't tested it, but then I can't reproduce the original issue in the
> > >>> first place.
> > >>
> > >> Of course, the whole "broadcast" thing could be done from cpuidle_enter()
> > >> in the first place, but then we could not avoid the problem with the cpuidle
> > >> *callback* enabling interrupts possibly in there anyway (not to mention the
> > >> "coupled" stuff).
> > >
> > > That said, if the given state is marked with CPUIDLE_FLAG_TIMER_STOP, I really
> > > wouldn't expect it to re-enable interrupts on exit and the "coupled" thing
> > > seems to be fundamentally at odds with that flag either.
> > >
> > > So it should be possible to move the "broadcast" logic into the cpuidle layer,
> > > which I'm going to try to do.
> > >
> > 
> > Makes sense.
> > 
> > > Please test the patch I've sent, though, as it should bring the code back to
> > > where it was before the clockevents_notify() removal and it'd be good to verify
> > > that.
> > >
> > 
> > I tested your patch and it works now. Anyways I am continuing to run
> > stress tests on my board. I will report if I find any issues.
> 
> Great, thanks!
> 
> Below is the patch I came up with in the meantime.
> 
> This moves the "switch to broadcast" timer logic into
> cpuidle_enter_state() which allows tick_broadcast_exit() to be
> called directly with interrupts disabled (as required), but
> it also adds a fallback branch reflecting the 4.0 and earlier
> behavior for idle states that enable interrupts on exit
> from their ->enter callbacks.
> 
> I'm not aware of any valid cases when CPUIDLE_FLAG_TIMER_STOP can be
> set for such states, but people may try to add stuff like that in the
> future, so it's better to catch that (hence the WARN_ON_ONCE) and do
> our best to handle it gracefully anyway, IMO.
> 
> The "if (entered_state == -EBUSY)" check is conservative.  It may
> be better to do "if (entered_state < 0)" and fall back to the default
> on all errors, but that's not what we do today (I guess the concern
> would be "what if the state ->enter returns an error after entering
> and exiting the idle state, in which case we may miss a wakeup event
> if we fall back to the default").

Actually, if my understanding of things is correct (the local clock event
device cannot go away from under code executed with interrupts disabled
on the local CPU), the simplified one below should be sufficient.

---
 drivers/cpuidle/cpuidle.c |   16 ++++++++++++++++
 kernel/sched/idle.c       |   16 ++--------------
 2 files changed, 18 insertions(+), 14 deletions(-)

Index: linux-pm/kernel/sched/idle.c
===================================================================
--- linux-pm.orig/kernel/sched/idle.c
+++ linux-pm/kernel/sched/idle.c
@@ -81,7 +81,6 @@ static void cpuidle_idle_call(void)
 	struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
 	struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
 	int next_state, entered_state;
-	unsigned int broadcast;
 	bool reflect;
 
 	/*
@@ -150,17 +149,6 @@ static void cpuidle_idle_call(void)
 		goto exit_idle;
 	}
 
-	broadcast = drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP;
-
-	/*
-	 * Tell the time framework to switch to a broadcast timer
-	 * because our local timer will be shutdown. If a local timer
-	 * is used from another cpu as a broadcast timer, this call may
-	 * fail if it is not available
-	 */
-	if (broadcast && tick_broadcast_enter())
-		goto use_default;
-
 	/* Take note of the planned idle state. */
 	idle_set_state(this_rq(), &drv->states[next_state]);
 
@@ -174,8 +162,8 @@ static void cpuidle_idle_call(void)
 	/* The cpu is no longer idle or about to enter idle. */
 	idle_set_state(this_rq(), NULL);
 
-	if (broadcast)
-		tick_broadcast_exit();
+	if (entered_state == -EBUSY)
+		goto use_default;
 
 	/*
 	 * Give the governor an opportunity to reflect on the outcome
Index: linux-pm/drivers/cpuidle/cpuidle.c
===================================================================
--- linux-pm.orig/drivers/cpuidle/cpuidle.c
+++ linux-pm/drivers/cpuidle/cpuidle.c
@@ -158,9 +158,18 @@ int cpuidle_enter_state(struct cpuidle_d
 	int entered_state;
 
 	struct cpuidle_state *target_state = &drv->states[index];
+	bool broadcast = !!(target_state->flags & CPUIDLE_FLAG_TIMER_STOP);
 	ktime_t time_start, time_end;
 	s64 diff;
 
+	/*
+	 * Tell the time framework to switch to a broadcast timer because our
+	 * local timer will be shut down.  If a local timer is used from another
+	 * CPU as a broadcast timer, this call may fail if it is not available.
+	 */
+	if (broadcast && tick_broadcast_enter())
+		return -EBUSY;
+
 	trace_cpu_idle_rcuidle(index, dev->cpu);
 	time_start = ktime_get();
 
@@ -169,6 +178,13 @@ int cpuidle_enter_state(struct cpuidle_d
 	time_end = ktime_get();
 	trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu);
 
+	if (broadcast) {
+		if (WARN_ON_ONCE(!irqs_disabled()))
+			local_irq_disable();
+
+		tick_broadcast_exit();
+	}
+
 	if (!cpuidle_state_is_coupled(dev, drv, entered_state))
 		local_irq_enable();
 


^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 16/20] sched/idle: Use explicit broadcast oneshot control function
  2015-04-29  1:04                       ` Rafael J. Wysocki
@ 2015-04-29  7:10                         ` Linus Walleij
  2015-04-29  8:57                         ` Peter Zijlstra
                                           ` (3 subsequent siblings)
  4 siblings, 0 replies; 90+ messages in thread
From: Linus Walleij @ 2015-04-29  7:10 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Sudeep Holla, Peter Zijlstra, Rafael J. Wysocki, Daniel Lezcano,
	Linux PM list, Thomas Gleixner, Ingo Molnar,
	Linux Kernel Mailing List, ACPI Devel Maling List

On Wed, Apr 29, 2015 at 3:04 AM, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> On Wednesday, April 29, 2015 02:50:22 AM Rafael J. Wysocki wrote:

>> Below is the patch I came up with in the meantime.
>>
>> This moves the "switch to broadcast" timer logic into
>> cpuidle_enter_state() which allows tick_broadcast_exit() to be
>> called directly with interrupts disabled (as required), but
>> it also adds a fallback branch reflecting the 4.0 and earlier
>> behavior for idle states that enable interrupts on exit
>> from their ->enter callbacks.
>>
>> I'm not aware of any valid cases when CPUIDLE_FLAG_TIMER_STOP can be
>> set for such states, but people may try to add stuff like that in the
>> future, so it's better to catch that (hence the WARN_ON_ONCE) and do
>> our best to handle it gracefully anyway, IMO.
>>
>> The "if (entered_state == -EBUSY)" check is conservative.  It may
>> be better to do "if (entered_state < 0)" and fall back to the default
>> on all errors, but that's not what we do today (I guess the concern
>> would be "what if the state ->enter returns an error after entering
>> and exiting the idle state, in which case we may miss a wakeup event
>> if we fall back to the default").
>
> Actually, if my understanding of things is correct (the local clock event
> device cannot go away from under code executed with interrupts disabled
> on the local CPU), the simplified one below should be sufficient.

Rock solid, after this patch the issues are gone and system stable.
Using it as stabilizer base for all v4.2 work now.

Excellent work Rafael!

Tested-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 16/20] sched/idle: Use explicit broadcast oneshot control function
  2015-04-29  1:04                       ` Rafael J. Wysocki
  2015-04-29  7:10                         ` Linus Walleij
@ 2015-04-29  8:57                         ` Peter Zijlstra
  2015-04-29  9:44                         ` Daniel Lezcano
                                           ` (2 subsequent siblings)
  4 siblings, 0 replies; 90+ messages in thread
From: Peter Zijlstra @ 2015-04-29  8:57 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Sudeep Holla, Linus Walleij, Rafael J. Wysocki, Daniel Lezcano,
	Linux PM list, Thomas Gleixner, Ingo Molnar,
	Linux Kernel Mailing List, ACPI Devel Maling List

On Wed, Apr 29, 2015 at 03:04:47AM +0200, Rafael J. Wysocki wrote:
> > Below is the patch I came up with in the meantime.
> > 
> > This moves the "switch to broadcast" timer logic into
> > cpuidle_enter_state() which allows tick_broadcast_exit() to be
> > called directly with interrupts disabled (as required), but
> > it also adds a fallback branch reflecting the 4.0 and earlier
> > behavior for idle states that enable interrupts on exit
> > from their ->enter callbacks.
> > 
> > I'm not aware of any valid cases when CPUIDLE_FLAG_TIMER_STOP can be
> > set for such states, but people may try to add stuff like that in the
> > future, so it's better to catch that (hence the WARN_ON_ONCE) and do
> > our best to handle it gracefully anyway, IMO.
> > 
> > The "if (entered_state == -EBUSY)" check is conservative.  It may
> > be better to do "if (entered_state < 0)" and fall back to the default
> > on all errors, but that's not what we do today (I guess the concern
> > would be "what if the state ->enter returns an error after entering
> > and exiting the idle state, in which case we may miss a wakeup event
> > if we fall back to the default").
> 
> Actually, if my understanding of things is correct (the local clock event
> device cannot go away from under code executed with interrupts disabled
> on the local CPU), the simplified one below should be sufficient.

Afaict both tick_broadcast_{enter,exit}() end up calling
tick_broadcast_oneshot_control() which is serialized with the
tick_broadcast_lock.

But yes, the local device is strictly managed from the local cpu, so any
other CPU wanting to muck with it would have to IPI and therefore
disabling the local IRQs would make it safe.

Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>

> ---
>  drivers/cpuidle/cpuidle.c |   16 ++++++++++++++++
>  kernel/sched/idle.c       |   16 ++--------------
>  2 files changed, 18 insertions(+), 14 deletions(-)
> 
> Index: linux-pm/kernel/sched/idle.c
> ===================================================================
> --- linux-pm.orig/kernel/sched/idle.c
> +++ linux-pm/kernel/sched/idle.c
> @@ -81,7 +81,6 @@ static void cpuidle_idle_call(void)
>  	struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
>  	struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
>  	int next_state, entered_state;
> -	unsigned int broadcast;
>  	bool reflect;
>  
>  	/*
> @@ -150,17 +149,6 @@ static void cpuidle_idle_call(void)
>  		goto exit_idle;
>  	}
>  
> -	broadcast = drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP;
> -
> -	/*
> -	 * Tell the time framework to switch to a broadcast timer
> -	 * because our local timer will be shutdown. If a local timer
> -	 * is used from another cpu as a broadcast timer, this call may
> -	 * fail if it is not available
> -	 */
> -	if (broadcast && tick_broadcast_enter())
> -		goto use_default;
> -
>  	/* Take note of the planned idle state. */
>  	idle_set_state(this_rq(), &drv->states[next_state]);
>  
> @@ -174,8 +162,8 @@ static void cpuidle_idle_call(void)
>  	/* The cpu is no longer idle or about to enter idle. */
>  	idle_set_state(this_rq(), NULL);
>  
> -	if (broadcast)
> -		tick_broadcast_exit();
> +	if (entered_state == -EBUSY)
> +		goto use_default;
>  
>  	/*
>  	 * Give the governor an opportunity to reflect on the outcome
> Index: linux-pm/drivers/cpuidle/cpuidle.c
> ===================================================================
> --- linux-pm.orig/drivers/cpuidle/cpuidle.c
> +++ linux-pm/drivers/cpuidle/cpuidle.c
> @@ -158,9 +158,18 @@ int cpuidle_enter_state(struct cpuidle_d
>  	int entered_state;
>  
>  	struct cpuidle_state *target_state = &drv->states[index];
> +	bool broadcast = !!(target_state->flags & CPUIDLE_FLAG_TIMER_STOP);
>  	ktime_t time_start, time_end;
>  	s64 diff;
>  
> +	/*
> +	 * Tell the time framework to switch to a broadcast timer because our
> +	 * local timer will be shut down.  If a local timer is used from another
> +	 * CPU as a broadcast timer, this call may fail if it is not available.
> +	 */
> +	if (broadcast && tick_broadcast_enter())
> +		return -EBUSY;
> +
>  	trace_cpu_idle_rcuidle(index, dev->cpu);
>  	time_start = ktime_get();
>  
> @@ -169,6 +178,13 @@ int cpuidle_enter_state(struct cpuidle_d
>  	time_end = ktime_get();
>  	trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu);
>  
> +	if (broadcast) {
> +		if (WARN_ON_ONCE(!irqs_disabled()))
> +			local_irq_disable();
> +
> +		tick_broadcast_exit();
> +	}
> +
>  	if (!cpuidle_state_is_coupled(dev, drv, entered_state))
>  		local_irq_enable();
>  
> 

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 16/20] sched/idle: Use explicit broadcast oneshot control function
  2015-04-29  1:04                       ` Rafael J. Wysocki
  2015-04-29  7:10                         ` Linus Walleij
  2015-04-29  8:57                         ` Peter Zijlstra
@ 2015-04-29  9:44                         ` Daniel Lezcano
  2015-04-29  9:50                         ` Sudeep Holla
  2015-04-30  3:45                         ` [PATCH 16/20] sched/idle: Use explicit broadcast oneshot control function Preeti U Murthy
  4 siblings, 0 replies; 90+ messages in thread
From: Daniel Lezcano @ 2015-04-29  9:44 UTC (permalink / raw)
  To: Rafael J. Wysocki, Sudeep Holla, Peter Zijlstra
  Cc: Linus Walleij, Rafael J. Wysocki, Linux PM list, Thomas Gleixner,
	Ingo Molnar, Linux Kernel Mailing List, ACPI Devel Maling List

On 04/29/2015 03:04 AM, Rafael J. Wysocki wrote:
> On Wednesday, April 29, 2015 02:50:22 AM Rafael J. Wysocki wrote:
>> On Tuesday, April 28, 2015 02:58:37 PM Sudeep Holla wrote:
>>>
>>> On 28/04/15 15:14, Rafael J. Wysocki wrote:
>>>> On Tuesday, April 28, 2015 03:37:44 PM Rafael J. Wysocki wrote:
>>>>> On Tuesday, April 28, 2015 03:31:54 PM Rafael J. Wysocki wrote:
>>>>>> On Tuesday, April 28, 2015 02:37:10 PM Linus Walleij wrote:
>>>>>>> On Tue, Apr 28, 2015 at 2:19 PM, Rafael J. Wysocki <rafael@kernel.org> wrote:
>>>>>>>> Sudeep:
>>>>>>>>> At-least I observed issue only when I am using hardware broadcast timer.
>>>>>>>>> It doesn't hang when I am using hrtimer as broadcast timer in which case
>>>>>>>>> one of the cpu will be not enter deeper idle states that lose timer.
>>>>>>>>> I will rerun on v4.1-rc1 and post the complete log.
>>>>>>>>
>>>>>>>> So the bug here is that cpuidle_enter() enables interrupts, so the
>>>>>>>> assumption about them being not enabled made by
>>>>>>>> tick_broadcast_oneshot_control() is actually not valid.
>>>>>>>>
>>>>>>>> It looks like we need to acquire the clockevents_lock at least in this
>>>>>>>> particular case.  Let me see where to put it and I'll send a patch for
>>>>>>>> testing.
>>>>>>>
>>>>>>> Aha that looks very much like it. Put me on the patch and I'll
>>>>>>> take it for a spin.
>>>>>>
>>>>>> OK, so something like the below for starters (the _irqsave variant is used to
>>>>>> avoid adding one more WARN_ON(irqs_disabled()) in there).
>>>>>>
>>>>>> I haven't tested it, but then I can't reproduce the original issue in the
>>>>>> first place.
>>>>>
>>>>> Of course, the whole "broadcast" thing could be done from cpuidle_enter()
>>>>> in the first place, but then we could not avoid the problem with the cpuidle
>>>>> *callback* enabling interrupts possibly in there anyway (not to mention the
>>>>> "coupled" stuff).
>>>>
>>>> That said, if the given state is marked with CPUIDLE_FLAG_TIMER_STOP, I really
>>>> wouldn't expect it to re-enable interrupts on exit and the "coupled" thing
>>>> seems to be fundamentally at odds with that flag either.
>>>>
>>>> So it should be possible to move the "broadcast" logic into the cpuidle layer,
>>>> which I'm going to try to do.
>>>>
>>>
>>> Makes sense.
>>>
>>>> Please test the patch I've sent, though, as it should bring the code back to
>>>> where it was before the clockevents_notify() removal and it'd be good to verify
>>>> that.
>>>>
>>>
>>> I tested your patch and it works now. Anyways I am continuing to run
>>> stress tests on my board. I will report if I find any issues.
>>
>> Great, thanks!
>>
>> Below is the patch I came up with in the meantime.
>>
>> This moves the "switch to broadcast" timer logic into
>> cpuidle_enter_state() which allows tick_broadcast_exit() to be
>> called directly with interrupts disabled (as required), but
>> it also adds a fallback branch reflecting the 4.0 and earlier
>> behavior for idle states that enable interrupts on exit
>> from their ->enter callbacks.
>>
>> I'm not aware of any valid cases when CPUIDLE_FLAG_TIMER_STOP can be
>> set for such states, but people may try to add stuff like that in the
>> future, so it's better to catch that (hence the WARN_ON_ONCE) and do
>> our best to handle it gracefully anyway, IMO.
>>
>> The "if (entered_state == -EBUSY)" check is conservative.  It may
>> be better to do "if (entered_state < 0)" and fall back to the default
>> on all errors, but that's not what we do today (I guess the concern
>> would be "what if the state ->enter returns an error after entering
>> and exiting the idle state, in which case we may miss a wakeup event
>> if we fall back to the default").
>
> Actually, if my understanding of things is correct (the local clock event
> device cannot go away from under code executed with interrupts disabled
> on the local CPU), the simplified one below should be sufficient.

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>

> ---
>   drivers/cpuidle/cpuidle.c |   16 ++++++++++++++++
>   kernel/sched/idle.c       |   16 ++--------------
>   2 files changed, 18 insertions(+), 14 deletions(-)
>
> Index: linux-pm/kernel/sched/idle.c
> ===================================================================
> --- linux-pm.orig/kernel/sched/idle.c
> +++ linux-pm/kernel/sched/idle.c
> @@ -81,7 +81,6 @@ static void cpuidle_idle_call(void)
>   	struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
>   	struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
>   	int next_state, entered_state;
> -	unsigned int broadcast;
>   	bool reflect;
>
>   	/*
> @@ -150,17 +149,6 @@ static void cpuidle_idle_call(void)
>   		goto exit_idle;
>   	}
>
> -	broadcast = drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP;
> -
> -	/*
> -	 * Tell the time framework to switch to a broadcast timer
> -	 * because our local timer will be shutdown. If a local timer
> -	 * is used from another cpu as a broadcast timer, this call may
> -	 * fail if it is not available
> -	 */
> -	if (broadcast && tick_broadcast_enter())
> -		goto use_default;
> -
>   	/* Take note of the planned idle state. */
>   	idle_set_state(this_rq(), &drv->states[next_state]);
>
> @@ -174,8 +162,8 @@ static void cpuidle_idle_call(void)
>   	/* The cpu is no longer idle or about to enter idle. */
>   	idle_set_state(this_rq(), NULL);
>
> -	if (broadcast)
> -		tick_broadcast_exit();
> +	if (entered_state == -EBUSY)
> +		goto use_default;
>
>   	/*
>   	 * Give the governor an opportunity to reflect on the outcome
> Index: linux-pm/drivers/cpuidle/cpuidle.c
> ===================================================================
> --- linux-pm.orig/drivers/cpuidle/cpuidle.c
> +++ linux-pm/drivers/cpuidle/cpuidle.c
> @@ -158,9 +158,18 @@ int cpuidle_enter_state(struct cpuidle_d
>   	int entered_state;
>
>   	struct cpuidle_state *target_state = &drv->states[index];
> +	bool broadcast = !!(target_state->flags & CPUIDLE_FLAG_TIMER_STOP);
>   	ktime_t time_start, time_end;
>   	s64 diff;
>
> +	/*
> +	 * Tell the time framework to switch to a broadcast timer because our
> +	 * local timer will be shut down.  If a local timer is used from another
> +	 * CPU as a broadcast timer, this call may fail if it is not available.
> +	 */
> +	if (broadcast && tick_broadcast_enter())
> +		return -EBUSY;
> +
>   	trace_cpu_idle_rcuidle(index, dev->cpu);
>   	time_start = ktime_get();
>
> @@ -169,6 +178,13 @@ int cpuidle_enter_state(struct cpuidle_d
>   	time_end = ktime_get();
>   	trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu);
>
> +	if (broadcast) {
> +		if (WARN_ON_ONCE(!irqs_disabled()))
> +			local_irq_disable();
> +
> +		tick_broadcast_exit();
> +	}
> +
>   	if (!cpuidle_state_is_coupled(dev, drv, entered_state))
>   		local_irq_enable();
>
>


-- 
  <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 16/20] sched/idle: Use explicit broadcast oneshot control function
  2015-04-29  1:04                       ` Rafael J. Wysocki
                                           ` (2 preceding siblings ...)
  2015-04-29  9:44                         ` Daniel Lezcano
@ 2015-04-29  9:50                         ` Sudeep Holla
  2015-04-29 14:07                           ` [PATCH][Fix] cpuidle: Run tick_broadcast_exit() with disabled interrupts Rafael J. Wysocki
  2015-04-30  3:45                         ` [PATCH 16/20] sched/idle: Use explicit broadcast oneshot control function Preeti U Murthy
  4 siblings, 1 reply; 90+ messages in thread
From: Sudeep Holla @ 2015-04-29  9:50 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Peter Zijlstra, Sudeep Holla, Linus Walleij, Rafael J. Wysocki,
	Daniel Lezcano, Linux PM list, Thomas Gleixner, Ingo Molnar,
	Linux Kernel Mailing List, ACPI Devel Maling List

Hi Rafael,

On 29/04/15 02:04, Rafael J. Wysocki wrote:
> On Wednesday, April 29, 2015 02:50:22 AM Rafael J. Wysocki wrote:

[...]

>>
>> Below is the patch I came up with in the meantime.
>>
>> This moves the "switch to broadcast" timer logic into
>> cpuidle_enter_state() which allows tick_broadcast_exit() to be
>> called directly with interrupts disabled (as required), but
>> it also adds a fallback branch reflecting the 4.0 and earlier
>> behavior for idle states that enable interrupts on exit
>> from their ->enter callbacks.
>>
>> I'm not aware of any valid cases when CPUIDLE_FLAG_TIMER_STOP can be
>> set for such states, but people may try to add stuff like that in the
>> future, so it's better to catch that (hence the WARN_ON_ONCE) and do
>> our best to handle it gracefully anyway, IMO.
>>
>> The "if (entered_state == -EBUSY)" check is conservative.  It may
>> be better to do "if (entered_state < 0)" and fall back to the default
>> on all errors, but that's not what we do today (I guess the concern
>> would be "what if the state ->enter returns an error after entering
>> and exiting the idle state, in which case we may miss a wakeup event
>> if we fall back to the default").
>
> Actually, if my understanding of things is correct (the local clock event
> device cannot go away from under code executed with interrupts disabled
> on the local CPU), the simplified one below should be sufficient.
>

Tested-by: Sudeep Holla <sudeep.holla@arm.com>

Regards,
Sudeep

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH][Fix] cpuidle: Run tick_broadcast_exit() with disabled interrupts
  2015-04-29  9:50                         ` Sudeep Holla
@ 2015-04-29 14:07                           ` Rafael J. Wysocki
  2015-04-30  3:47                             ` Preeti U Murthy
  2015-04-30 20:12                             ` Nicolas Pitre
  0 siblings, 2 replies; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-29 14:07 UTC (permalink / raw)
  To: Sudeep Holla, Peter Zijlstra, Linus Walleij, Daniel Lezcano
  Cc: Rafael J. Wysocki, Linux PM list, Thomas Gleixner, Ingo Molnar,
	Linux Kernel Mailing List, ACPI Devel Maling List

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Commit 335f49196fd6 (sched/idle: Use explicit broadcast oneshot
control function) replaced clockevents_notify() invocations in
cpuidle_idle_call() with direct calls to tick_broadcast_enter()
and tick_broadcast_exit(), but it overlooked the fact that
interrupts were already enabled before calling the latter which
led to functional breakage on systems using idle states with the
CPUIDLE_FLAG_TIMER_STOP flag set.

Fix that by moving the invocations of tick_broadcast_enter()
and tick_broadcast_exit() down into cpuidle_enter_state() where
interrupts are still disabled when tick_broadcast_exit() is
called.  Also ensure that interrupts will be disabled before
running tick_broadcast_exit() even if they have been enabled by
the idle state's ->enter callback.  Trigger a WARN_ON_ONCE() in
that case, as we generally don't want that to happen for states
with CPUIDLE_FLAG_TIMER_STOP set.

Fixes: 335f49196fd6 (sched/idle: Use explicit broadcast oneshot control function)
Reported-and-tested-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Reported-and-tested-by: Sudeep Holla <sudeep.holla@arm.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---

Thanks for the testing and ACKs, here it goes again with all tags and
a changelog.

If anything is missing/incorrect, please let me know ASAP as I'm going to
push this to Linus in a couple of days.

---
 drivers/cpuidle/cpuidle.c |   16 ++++++++++++++++
 kernel/sched/idle.c       |   16 ++--------------
 2 files changed, 18 insertions(+), 14 deletions(-)

Index: linux-pm/kernel/sched/idle.c
===================================================================
--- linux-pm.orig/kernel/sched/idle.c
+++ linux-pm/kernel/sched/idle.c
@@ -81,7 +81,6 @@ static void cpuidle_idle_call(void)
 	struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
 	struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
 	int next_state, entered_state;
-	unsigned int broadcast;
 	bool reflect;
 
 	/*
@@ -150,17 +149,6 @@ static void cpuidle_idle_call(void)
 		goto exit_idle;
 	}
 
-	broadcast = drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP;
-
-	/*
-	 * Tell the time framework to switch to a broadcast timer
-	 * because our local timer will be shutdown. If a local timer
-	 * is used from another cpu as a broadcast timer, this call may
-	 * fail if it is not available
-	 */
-	if (broadcast && tick_broadcast_enter())
-		goto use_default;
-
 	/* Take note of the planned idle state. */
 	idle_set_state(this_rq(), &drv->states[next_state]);
 
@@ -174,8 +162,8 @@ static void cpuidle_idle_call(void)
 	/* The cpu is no longer idle or about to enter idle. */
 	idle_set_state(this_rq(), NULL);
 
-	if (broadcast)
-		tick_broadcast_exit();
+	if (entered_state == -EBUSY)
+		goto use_default;
 
 	/*
 	 * Give the governor an opportunity to reflect on the outcome
Index: linux-pm/drivers/cpuidle/cpuidle.c
===================================================================
--- linux-pm.orig/drivers/cpuidle/cpuidle.c
+++ linux-pm/drivers/cpuidle/cpuidle.c
@@ -158,9 +158,18 @@ int cpuidle_enter_state(struct cpuidle_d
 	int entered_state;
 
 	struct cpuidle_state *target_state = &drv->states[index];
+	bool broadcast = !!(target_state->flags & CPUIDLE_FLAG_TIMER_STOP);
 	ktime_t time_start, time_end;
 	s64 diff;
 
+	/*
+	 * Tell the time framework to switch to a broadcast timer because our
+	 * local timer will be shut down.  If a local timer is used from another
+	 * CPU as a broadcast timer, this call may fail if it is not available.
+	 */
+	if (broadcast && tick_broadcast_enter())
+		return -EBUSY;
+
 	trace_cpu_idle_rcuidle(index, dev->cpu);
 	time_start = ktime_get();
 
@@ -169,6 +178,13 @@ int cpuidle_enter_state(struct cpuidle_d
 	time_end = ktime_get();
 	trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu);
 
+	if (broadcast) {
+		if (WARN_ON_ONCE(!irqs_disabled()))
+			local_irq_disable();
+
+		tick_broadcast_exit();
+	}
+
 	if (!cpuidle_state_is_coupled(dev, drv, entered_state))
 		local_irq_enable();
 


^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 16/20] sched/idle: Use explicit broadcast oneshot control function
  2015-04-29  1:04                       ` Rafael J. Wysocki
                                           ` (3 preceding siblings ...)
  2015-04-29  9:50                         ` Sudeep Holla
@ 2015-04-30  3:45                         ` Preeti U Murthy
  4 siblings, 0 replies; 90+ messages in thread
From: Preeti U Murthy @ 2015-04-30  3:45 UTC (permalink / raw)
  To: Rafael J. Wysocki, Sudeep Holla, Peter Zijlstra
  Cc: Linus Walleij, Rafael J. Wysocki, Daniel Lezcano, Linux PM list,
	Thomas Gleixner, Ingo Molnar, Linux Kernel Mailing List,
	ACPI Devel Maling List

On 04/29/2015 06:34 AM, Rafael J. Wysocki wrote:
> On Wednesday, April 29, 2015 02:50:22 AM Rafael J. Wysocki wrote:
>> On Tuesday, April 28, 2015 02:58:37 PM Sudeep Holla wrote:
>>>
>>> On 28/04/15 15:14, Rafael J. Wysocki wrote:
>>>> On Tuesday, April 28, 2015 03:37:44 PM Rafael J. Wysocki wrote:
>>>>> On Tuesday, April 28, 2015 03:31:54 PM Rafael J. Wysocki wrote:
>>>>>> On Tuesday, April 28, 2015 02:37:10 PM Linus Walleij wrote:
>>>>>>> On Tue, Apr 28, 2015 at 2:19 PM, Rafael J. Wysocki <rafael@kernel.org> wrote:
>>>>>>>> Sudeep:
>>>>>>>>> At-least I observed issue only when I am using hardware broadcast timer.
>>>>>>>>> It doesn't hang when I am using hrtimer as broadcast timer in which case
>>>>>>>>> one of the cpu will be not enter deeper idle states that lose timer.
>>>>>>>>> I will rerun on v4.1-rc1 and post the complete log.
>>>>>>>>
>>>>>>>> So the bug here is that cpuidle_enter() enables interrupts, so the
>>>>>>>> assumption about them being not enabled made by
>>>>>>>> tick_broadcast_oneshot_control() is actually not valid.
>>>>>>>>
>>>>>>>> It looks like we need to acquire the clockevents_lock at least in this
>>>>>>>> particular case.  Let me see where to put it and I'll send a patch for
>>>>>>>> testing.
>>>>>>>
>>>>>>> Aha that looks very much like it. Put me on the patch and I'll
>>>>>>> take it for a spin.
>>>>>>
>>>>>> OK, so something like the below for starters (the _irqsave variant is used to
>>>>>> avoid adding one more WARN_ON(irqs_disabled()) in there).
>>>>>>
>>>>>> I haven't tested it, but then I can't reproduce the original issue in the
>>>>>> first place.
>>>>>
>>>>> Of course, the whole "broadcast" thing could be done from cpuidle_enter()
>>>>> in the first place, but then we could not avoid the problem with the cpuidle
>>>>> *callback* enabling interrupts possibly in there anyway (not to mention the
>>>>> "coupled" stuff).
>>>>
>>>> That said, if the given state is marked with CPUIDLE_FLAG_TIMER_STOP, I really
>>>> wouldn't expect it to re-enable interrupts on exit and the "coupled" thing
>>>> seems to be fundamentally at odds with that flag either.
>>>>
>>>> So it should be possible to move the "broadcast" logic into the cpuidle layer,
>>>> which I'm going to try to do.
>>>>
>>>
>>> Makes sense.
>>>
>>>> Please test the patch I've sent, though, as it should bring the code back to
>>>> where it was before the clockevents_notify() removal and it'd be good to verify
>>>> that.
>>>>
>>>
>>> I tested your patch and it works now. Anyways I am continuing to run
>>> stress tests on my board. I will report if I find any issues.
>>
>> Great, thanks!
>>
>> Below is the patch I came up with in the meantime.
>>
>> This moves the "switch to broadcast" timer logic into
>> cpuidle_enter_state() which allows tick_broadcast_exit() to be
>> called directly with interrupts disabled (as required), but
>> it also adds a fallback branch reflecting the 4.0 and earlier
>> behavior for idle states that enable interrupts on exit
>> from their ->enter callbacks.
>>
>> I'm not aware of any valid cases when CPUIDLE_FLAG_TIMER_STOP can be
>> set for such states, but people may try to add stuff like that in the
>> future, so it's better to catch that (hence the WARN_ON_ONCE) and do
>> our best to handle it gracefully anyway, IMO.
>>
>> The "if (entered_state == -EBUSY)" check is conservative.  It may
>> be better to do "if (entered_state < 0)" and fall back to the default
>> on all errors, but that's not what we do today (I guess the concern
>> would be "what if the state ->enter returns an error after entering
>> and exiting the idle state, in which case we may miss a wakeup event
>> if we fall back to the default").
> 
> Actually, if my understanding of things is correct (the local clock event
> device cannot go away from under code executed with interrupts disabled
> on the local CPU), the simplified one below should be sufficient.
> 
> ---
>  drivers/cpuidle/cpuidle.c |   16 ++++++++++++++++
>  kernel/sched/idle.c       |   16 ++--------------
>  2 files changed, 18 insertions(+), 14 deletions(-)
> 
> Index: linux-pm/kernel/sched/idle.c
> ===================================================================
> --- linux-pm.orig/kernel/sched/idle.c
> +++ linux-pm/kernel/sched/idle.c
> @@ -81,7 +81,6 @@ static void cpuidle_idle_call(void)
>  	struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
>  	struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
>  	int next_state, entered_state;
> -	unsigned int broadcast;
>  	bool reflect;
> 
>  	/*
> @@ -150,17 +149,6 @@ static void cpuidle_idle_call(void)
>  		goto exit_idle;
>  	}
> 
> -	broadcast = drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP;
> -
> -	/*
> -	 * Tell the time framework to switch to a broadcast timer
> -	 * because our local timer will be shutdown. If a local timer
> -	 * is used from another cpu as a broadcast timer, this call may
> -	 * fail if it is not available
> -	 */
> -	if (broadcast && tick_broadcast_enter())
> -		goto use_default;
> -
>  	/* Take note of the planned idle state. */
>  	idle_set_state(this_rq(), &drv->states[next_state]);
> 
> @@ -174,8 +162,8 @@ static void cpuidle_idle_call(void)
>  	/* The cpu is no longer idle or about to enter idle. */
>  	idle_set_state(this_rq(), NULL);
> 
> -	if (broadcast)
> -		tick_broadcast_exit();
> +	if (entered_state == -EBUSY)
> +		goto use_default;
> 
>  	/*
>  	 * Give the governor an opportunity to reflect on the outcome
> Index: linux-pm/drivers/cpuidle/cpuidle.c
> ===================================================================
> --- linux-pm.orig/drivers/cpuidle/cpuidle.c
> +++ linux-pm/drivers/cpuidle/cpuidle.c
> @@ -158,9 +158,18 @@ int cpuidle_enter_state(struct cpuidle_d
>  	int entered_state;
> 
>  	struct cpuidle_state *target_state = &drv->states[index];
> +	bool broadcast = !!(target_state->flags & CPUIDLE_FLAG_TIMER_STOP);
>  	ktime_t time_start, time_end;
>  	s64 diff;
> 
> +	/*
> +	 * Tell the time framework to switch to a broadcast timer because our
> +	 * local timer will be shut down.  If a local timer is used from another
> +	 * CPU as a broadcast timer, this call may fail if it is not available.
> +	 */
> +	if (broadcast && tick_broadcast_enter())
> +		return -EBUSY;
> +
>  	trace_cpu_idle_rcuidle(index, dev->cpu);
>  	time_start = ktime_get();
> 
> @@ -169,6 +178,13 @@ int cpuidle_enter_state(struct cpuidle_d
>  	time_end = ktime_get();
>  	trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu);
> 
> +	if (broadcast) {
> +		if (WARN_ON_ONCE(!irqs_disabled()))
> +			local_irq_disable();
> +
> +		tick_broadcast_exit();
> +	}
> +
>  	if (!cpuidle_state_is_coupled(dev, drv, entered_state))
>  		local_irq_enable();
> 
> 

Looks good.

Reviewed-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH][Fix] cpuidle: Run tick_broadcast_exit() with disabled interrupts
  2015-04-29 14:07                           ` [PATCH][Fix] cpuidle: Run tick_broadcast_exit() with disabled interrupts Rafael J. Wysocki
@ 2015-04-30  3:47                             ` Preeti U Murthy
  2015-04-30 20:12                             ` Nicolas Pitre
  1 sibling, 0 replies; 90+ messages in thread
From: Preeti U Murthy @ 2015-04-30  3:47 UTC (permalink / raw)
  To: Rafael J. Wysocki, Sudeep Holla, Peter Zijlstra, Linus Walleij,
	Daniel Lezcano
  Cc: Rafael J. Wysocki, Linux PM list, Thomas Gleixner, Ingo Molnar,
	Linux Kernel Mailing List, ACPI Devel Maling List

On 04/29/2015 07:37 PM, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> 
> Commit 335f49196fd6 (sched/idle: Use explicit broadcast oneshot
> control function) replaced clockevents_notify() invocations in
> cpuidle_idle_call() with direct calls to tick_broadcast_enter()
> and tick_broadcast_exit(), but it overlooked the fact that
> interrupts were already enabled before calling the latter which
> led to functional breakage on systems using idle states with the
> CPUIDLE_FLAG_TIMER_STOP flag set.
> 
> Fix that by moving the invocations of tick_broadcast_enter()
> and tick_broadcast_exit() down into cpuidle_enter_state() where
> interrupts are still disabled when tick_broadcast_exit() is
> called.  Also ensure that interrupts will be disabled before
> running tick_broadcast_exit() even if they have been enabled by
> the idle state's ->enter callback.  Trigger a WARN_ON_ONCE() in
> that case, as we generally don't want that to happen for states
> with CPUIDLE_FLAG_TIMER_STOP set.
> 
> Fixes: 335f49196fd6 (sched/idle: Use explicit broadcast oneshot control function)
> Reported-and-tested-by: Linus Walleij <linus.walleij@linaro.org>
> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> Reported-and-tested-by: Sudeep Holla <sudeep.holla@arm.com>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
> 
> Thanks for the testing and ACKs, here it goes again with all tags and
> a changelog.
> 
> If anything is missing/incorrect, please let me know ASAP as I'm going to
> push this to Linus in a couple of days.
> 
> ---
>  drivers/cpuidle/cpuidle.c |   16 ++++++++++++++++
>  kernel/sched/idle.c       |   16 ++--------------
>  2 files changed, 18 insertions(+), 14 deletions(-)
> 
> Index: linux-pm/kernel/sched/idle.c
> ===================================================================
> --- linux-pm.orig/kernel/sched/idle.c
> +++ linux-pm/kernel/sched/idle.c
> @@ -81,7 +81,6 @@ static void cpuidle_idle_call(void)
>  	struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
>  	struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
>  	int next_state, entered_state;
> -	unsigned int broadcast;
>  	bool reflect;
> 
>  	/*
> @@ -150,17 +149,6 @@ static void cpuidle_idle_call(void)
>  		goto exit_idle;
>  	}
> 
> -	broadcast = drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP;
> -
> -	/*
> -	 * Tell the time framework to switch to a broadcast timer
> -	 * because our local timer will be shutdown. If a local timer
> -	 * is used from another cpu as a broadcast timer, this call may
> -	 * fail if it is not available
> -	 */
> -	if (broadcast && tick_broadcast_enter())
> -		goto use_default;
> -
>  	/* Take note of the planned idle state. */
>  	idle_set_state(this_rq(), &drv->states[next_state]);
> 
> @@ -174,8 +162,8 @@ static void cpuidle_idle_call(void)
>  	/* The cpu is no longer idle or about to enter idle. */
>  	idle_set_state(this_rq(), NULL);
> 
> -	if (broadcast)
> -		tick_broadcast_exit();
> +	if (entered_state == -EBUSY)
> +		goto use_default;
> 
>  	/*
>  	 * Give the governor an opportunity to reflect on the outcome
> Index: linux-pm/drivers/cpuidle/cpuidle.c
> ===================================================================
> --- linux-pm.orig/drivers/cpuidle/cpuidle.c
> +++ linux-pm/drivers/cpuidle/cpuidle.c
> @@ -158,9 +158,18 @@ int cpuidle_enter_state(struct cpuidle_d
>  	int entered_state;
> 
>  	struct cpuidle_state *target_state = &drv->states[index];
> +	bool broadcast = !!(target_state->flags & CPUIDLE_FLAG_TIMER_STOP);
>  	ktime_t time_start, time_end;
>  	s64 diff;
> 
> +	/*
> +	 * Tell the time framework to switch to a broadcast timer because our
> +	 * local timer will be shut down.  If a local timer is used from another
> +	 * CPU as a broadcast timer, this call may fail if it is not available.
> +	 */
> +	if (broadcast && tick_broadcast_enter())
> +		return -EBUSY;
> +
>  	trace_cpu_idle_rcuidle(index, dev->cpu);
>  	time_start = ktime_get();
> 
> @@ -169,6 +178,13 @@ int cpuidle_enter_state(struct cpuidle_d
>  	time_end = ktime_get();
>  	trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu);
> 
> +	if (broadcast) {
> +		if (WARN_ON_ONCE(!irqs_disabled()))
> +			local_irq_disable();
> +
> +		tick_broadcast_exit();
> +	}
> +
>  	if (!cpuidle_state_is_coupled(dev, drv, entered_state))
>  		local_irq_enable();
> 

Reviewed-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH][Fix] cpuidle: Run tick_broadcast_exit() with disabled interrupts
  2015-04-29 14:07                           ` [PATCH][Fix] cpuidle: Run tick_broadcast_exit() with disabled interrupts Rafael J. Wysocki
  2015-04-30  3:47                             ` Preeti U Murthy
@ 2015-04-30 20:12                             ` Nicolas Pitre
  2015-04-30 22:10                               ` Rafael J. Wysocki
  1 sibling, 1 reply; 90+ messages in thread
From: Nicolas Pitre @ 2015-04-30 20:12 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Sudeep Holla, Peter Zijlstra, Linus Walleij, Daniel Lezcano,
	Rafael J. Wysocki, Linux PM list, Thomas Gleixner, Ingo Molnar,
	Linux Kernel Mailing List, ACPI Devel Maling List

On Wed, 29 Apr 2015, Rafael J. Wysocki wrote:

> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> 
> Commit 335f49196fd6 (sched/idle: Use explicit broadcast oneshot
> control function) replaced clockevents_notify() invocations in
> cpuidle_idle_call() with direct calls to tick_broadcast_enter()
> and tick_broadcast_exit(), but it overlooked the fact that
> interrupts were already enabled before calling the latter which
> led to functional breakage on systems using idle states with the
> CPUIDLE_FLAG_TIMER_STOP flag set.
> 
> Fix that by moving the invocations of tick_broadcast_enter()
> and tick_broadcast_exit() down into cpuidle_enter_state() where
> interrupts are still disabled when tick_broadcast_exit() is
> called.  Also ensure that interrupts will be disabled before
> running tick_broadcast_exit() even if they have been enabled by
> the idle state's ->enter callback.  Trigger a WARN_ON_ONCE() in
> that case, as we generally don't want that to happen for states
> with CPUIDLE_FLAG_TIMER_STOP set.

Incidentally I was debugging this issue as well when I saw this thread.

And it turns out that I did report this issue 2 months ago:
http://article.gmane.org/gmane.linux.kernel/1892049
What happened?

> Fixes: 335f49196fd6 (sched/idle: Use explicit broadcast oneshot control function)
> Reported-and-tested-by: Linus Walleij <linus.walleij@linaro.org>
> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> Reported-and-tested-by: Sudeep Holla <sudeep.holla@arm.com>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Tested-by: Nicolas Pitre <nico@linaro.org>

> ---
> 
> Thanks for the testing and ACKs, here it goes again with all tags and
> a changelog.
> 
> If anything is missing/incorrect, please let me know ASAP as I'm going to
> push this to Linus in a couple of days.
> 
> ---
>  drivers/cpuidle/cpuidle.c |   16 ++++++++++++++++
>  kernel/sched/idle.c       |   16 ++--------------
>  2 files changed, 18 insertions(+), 14 deletions(-)
> 
> Index: linux-pm/kernel/sched/idle.c
> ===================================================================
> --- linux-pm.orig/kernel/sched/idle.c
> +++ linux-pm/kernel/sched/idle.c
> @@ -81,7 +81,6 @@ static void cpuidle_idle_call(void)
>  	struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
>  	struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
>  	int next_state, entered_state;
> -	unsigned int broadcast;
>  	bool reflect;
>  
>  	/*
> @@ -150,17 +149,6 @@ static void cpuidle_idle_call(void)
>  		goto exit_idle;
>  	}
>  
> -	broadcast = drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP;
> -
> -	/*
> -	 * Tell the time framework to switch to a broadcast timer
> -	 * because our local timer will be shutdown. If a local timer
> -	 * is used from another cpu as a broadcast timer, this call may
> -	 * fail if it is not available
> -	 */
> -	if (broadcast && tick_broadcast_enter())
> -		goto use_default;
> -
>  	/* Take note of the planned idle state. */
>  	idle_set_state(this_rq(), &drv->states[next_state]);
>  
> @@ -174,8 +162,8 @@ static void cpuidle_idle_call(void)
>  	/* The cpu is no longer idle or about to enter idle. */
>  	idle_set_state(this_rq(), NULL);
>  
> -	if (broadcast)
> -		tick_broadcast_exit();
> +	if (entered_state == -EBUSY)
> +		goto use_default;
>  
>  	/*
>  	 * Give the governor an opportunity to reflect on the outcome
> Index: linux-pm/drivers/cpuidle/cpuidle.c
> ===================================================================
> --- linux-pm.orig/drivers/cpuidle/cpuidle.c
> +++ linux-pm/drivers/cpuidle/cpuidle.c
> @@ -158,9 +158,18 @@ int cpuidle_enter_state(struct cpuidle_d
>  	int entered_state;
>  
>  	struct cpuidle_state *target_state = &drv->states[index];
> +	bool broadcast = !!(target_state->flags & CPUIDLE_FLAG_TIMER_STOP);
>  	ktime_t time_start, time_end;
>  	s64 diff;
>  
> +	/*
> +	 * Tell the time framework to switch to a broadcast timer because our
> +	 * local timer will be shut down.  If a local timer is used from another
> +	 * CPU as a broadcast timer, this call may fail if it is not available.
> +	 */
> +	if (broadcast && tick_broadcast_enter())
> +		return -EBUSY;
> +
>  	trace_cpu_idle_rcuidle(index, dev->cpu);
>  	time_start = ktime_get();
>  
> @@ -169,6 +178,13 @@ int cpuidle_enter_state(struct cpuidle_d
>  	time_end = ktime_get();
>  	trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu);
>  
> +	if (broadcast) {
> +		if (WARN_ON_ONCE(!irqs_disabled()))
> +			local_irq_disable();
> +
> +		tick_broadcast_exit();
> +	}
> +
>  	if (!cpuidle_state_is_coupled(dev, drv, entered_state))
>  		local_irq_enable();
>  
> 
> --
> 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/
> 
> 

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH][Fix] cpuidle: Run tick_broadcast_exit() with disabled interrupts
  2015-04-30 20:12                             ` Nicolas Pitre
@ 2015-04-30 22:10                               ` Rafael J. Wysocki
  0 siblings, 0 replies; 90+ messages in thread
From: Rafael J. Wysocki @ 2015-04-30 22:10 UTC (permalink / raw)
  To: Nicolas Pitre
  Cc: Sudeep Holla, Peter Zijlstra, Linus Walleij, Daniel Lezcano,
	Rafael J. Wysocki, Linux PM list, Thomas Gleixner, Ingo Molnar,
	Linux Kernel Mailing List, ACPI Devel Maling List

On Thursday, April 30, 2015 04:12:46 PM Nicolas Pitre wrote:
> On Wed, 29 Apr 2015, Rafael J. Wysocki wrote:
> 
> > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > 
> > Commit 335f49196fd6 (sched/idle: Use explicit broadcast oneshot
> > control function) replaced clockevents_notify() invocations in
> > cpuidle_idle_call() with direct calls to tick_broadcast_enter()
> > and tick_broadcast_exit(), but it overlooked the fact that
> > interrupts were already enabled before calling the latter which
> > led to functional breakage on systems using idle states with the
> > CPUIDLE_FLAG_TIMER_STOP flag set.
> > 
> > Fix that by moving the invocations of tick_broadcast_enter()
> > and tick_broadcast_exit() down into cpuidle_enter_state() where
> > interrupts are still disabled when tick_broadcast_exit() is
> > called.  Also ensure that interrupts will be disabled before
> > running tick_broadcast_exit() even if they have been enabled by
> > the idle state's ->enter callback.  Trigger a WARN_ON_ONCE() in
> > that case, as we generally don't want that to happen for states
> > with CPUIDLE_FLAG_TIMER_STOP set.
> 
> Incidentally I was debugging this issue as well when I saw this thread.
> 
> And it turns out that I did report this issue 2 months ago:
> http://article.gmane.org/gmane.linux.kernel/1892049
> What happened?

The patch series had been picked up by someone else (me), reordered and rebased
in the meantime and your report was missed.  Sorry about that.

> > Fixes: 335f49196fd6 (sched/idle: Use explicit broadcast oneshot control function)
> > Reported-and-tested-by: Linus Walleij <linus.walleij@linaro.org>
> > Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> > Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> > Reported-and-tested-by: Sudeep Holla <sudeep.holla@arm.com>
> > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> 
> Tested-by: Nicolas Pitre <nico@linaro.org>

Thanks!


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 90+ messages in thread

end of thread, other threads:[~2015-04-30 21:45 UTC | newest]

Thread overview: 90+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-01 22:02 [PATCH 00/20] clockevents_notify() removal Rafael J. Wysocki
2015-04-01 22:03 ` [PATCH 01/20] clockevents: Provide explicit broadcast control functions Rafael J. Wysocki
2015-04-01 22:04 ` [PATCH 02/20] x86, amd_idle: Use explicit broadcast control function Rafael J. Wysocki
2015-04-01 22:05 ` [PATCH 03/20] ACPI / PAD: " Rafael J. Wysocki
2015-04-01 22:06 ` [PATCH 04/20] ACPI / processor: " Rafael J. Wysocki
2015-04-01 22:07 ` [PATCH 05/20] cpuidle: " Rafael J. Wysocki
2015-04-01 22:09 ` [PATCH 06/20] intel_idle: " Rafael J. Wysocki
2015-04-01 22:10 ` [PATCH 07/20] ARM: OMAP: " Rafael J. Wysocki
2015-04-01 22:11 ` [PATCH 08/20] clockevents: Remove the broadcast control leftovers Rafael J. Wysocki
2015-04-01 22:13 ` [PATCH 09/20] clockevents: Provide explicit broadcast oneshot control functions Rafael J. Wysocki
2015-04-01 22:15 ` [PATCH 10/20] x86, amd_idle: Use " Rafael J. Wysocki
2015-04-01 22:16 ` [PATCH 11/20] ACPI / PAD: Use explicit broadcast oneshot control function Rafael J. Wysocki
2015-04-01 22:17 ` [PATCH 12/20] ACPI / processor: Use explicit broadcast controll function Rafael J. Wysocki
2015-04-01 22:20 ` [PATCH 13/20] intel_idle: Use explicit broadcast oneshot control function Rafael J. Wysocki
2015-04-01 22:20 ` [PATCH 14/20] ARM: OMAP: " Rafael J. Wysocki
2015-04-01 22:21 ` [PATCH 15/20] ARM: tegra: " Rafael J. Wysocki
2015-04-01 22:22 ` [PATCH 16/20] sched/idle: " Rafael J. Wysocki
2015-04-28 10:11   ` Linus Walleij
2015-04-28 10:17     ` Sudeep Holla
2015-04-28 10:34     ` Daniel Lezcano
2015-04-28 10:42       ` Sudeep Holla
2015-04-28 12:19         ` Rafael J. Wysocki
2015-04-28 12:37           ` Linus Walleij
2015-04-28 13:31             ` Rafael J. Wysocki
2015-04-28 13:37               ` Rafael J. Wysocki
2015-04-28 14:14                 ` Rafael J. Wysocki
2015-04-28 13:58                   ` Sudeep Holla
2015-04-29  0:50                     ` Rafael J. Wysocki
2015-04-29  1:04                       ` Rafael J. Wysocki
2015-04-29  7:10                         ` Linus Walleij
2015-04-29  8:57                         ` Peter Zijlstra
2015-04-29  9:44                         ` Daniel Lezcano
2015-04-29  9:50                         ` Sudeep Holla
2015-04-29 14:07                           ` [PATCH][Fix] cpuidle: Run tick_broadcast_exit() with disabled interrupts Rafael J. Wysocki
2015-04-30  3:47                             ` Preeti U Murthy
2015-04-30 20:12                             ` Nicolas Pitre
2015-04-30 22:10                               ` Rafael J. Wysocki
2015-04-30  3:45                         ` [PATCH 16/20] sched/idle: Use explicit broadcast oneshot control function Preeti U Murthy
2015-04-28 13:04           ` Sudeep Holla
2015-04-01 22:23 ` [PATCH 17/20] clockevents: Remove broadcast oneshot control leftovers Rafael J. Wysocki
2015-04-01 22:24 ` [PATCH 18/20] clockevents: Make tick handover explicit Rafael J. Wysocki
2015-04-01 22:25 ` [PATCH 19/20] clockevents: Cleanup dead cpu explicitely Rafael J. Wysocki
2015-04-01 22:26 ` [PATCH 20/20] timekeeping: Get rid of stale comment Rafael J. Wysocki
2015-04-01 23:57   ` John Stultz
2015-04-02 12:39 ` [PATCH 00/20] clockevents_notify() removal Ingo Molnar
2015-04-02 22:19   ` Rafael J. Wysocki
2015-04-02 23:45     ` [v2][PATCH 00/21] " Rafael J. Wysocki
2015-04-02 23:46       ` [v2][PATCH 01/21] ACPI / PAD: Remove the local APIC nonsense Rafael J. Wysocki
2015-04-03  8:21         ` [tip:timers/core] ACPI/PAD: " tip-bot for Thomas Gleixner
2015-04-03  0:01       ` [v2][PATCH 02/21] clockevents: Provide explicit broadcast control functions Rafael J. Wysocki
2015-04-03  8:21         ` [tip:timers/core] " tip-bot for Thomas Gleixner
2015-04-03  0:01       ` [v2][PATCH 03/21] x86, amd_idle: Use explicit broadcast control function Rafael J. Wysocki
2015-04-03  8:22         ` [tip:timers/core] x86/amd/idle, clockevents: " tip-bot for Thomas Gleixner
2015-04-03  0:01       ` [v2][PATCH 04/21] ACPI / PAD: " Rafael J. Wysocki
2015-04-03  8:22         ` [tip:timers/core] ACPI/PAD: " tip-bot for Thomas Gleixner
2015-04-03  0:02       ` [v2][PATCH 05/21] ACPI / processor: " Rafael J. Wysocki
2015-04-03  8:22         ` [tip:timers/core] ACPI/processor: " tip-bot for Thomas Gleixner
2015-04-03  0:02       ` [v2][PATCH 06/21] cpuidle: " Rafael J. Wysocki
2015-04-03  8:23         ` [tip:timers/core] " tip-bot for Thomas Gleixner
2015-04-03  0:02       ` [v2][PATCH 07/21] intel_idle: " Rafael J. Wysocki
2015-04-03  8:23         ` [tip:timers/core] " tip-bot for Thomas Gleixner
2015-04-03  0:02       ` [v2][PATCH 08/21] ARM: OMAP: " Rafael J. Wysocki
2015-04-03  8:23         ` [tip:timers/core] " tip-bot for Thomas Gleixner
2015-04-03  0:03       ` [v2][PATCH 09/21] clockevents: Remove the broadcast control leftovers Rafael J. Wysocki
2015-04-03  8:23         ` [tip:timers/core] " tip-bot for Thomas Gleixner
2015-04-03  0:05       ` [v2][PATCH 10/21] clockevents: Provide explicit broadcast oneshot control functions Rafael J. Wysocki
2015-04-03  8:24         ` [tip:timers/core] " tip-bot for Thomas Gleixner
2015-04-03  0:05       ` [v2][PATCH 11/21] x86, amd_idle: Use " Rafael J. Wysocki
2015-04-03  8:24         ` [tip:timers/core] x86/amd/idle, clockevents: " tip-bot for Thomas Gleixner
2015-04-03  0:06       ` [v2][PATCH 12/21] ACPI / PAD: Use explicit broadcast oneshot control function Rafael J. Wysocki
2015-04-03  8:24         ` [tip:timers/core] ACPI/PAD: " tip-bot for Thomas Gleixner
2015-04-03  0:12       ` [v2][PATCH 13/21] ACPI / processor: Use explicit broadcast controll function Rafael J. Wysocki
2015-04-03  8:25         ` [tip:timers/core] ACPI/idle: Use explicit broadcast control function tip-bot for Thomas Gleixner
2015-04-03  0:14       ` [v2][PATCH 14/21] intel_idle: Use explicit broadcast oneshot " Rafael J. Wysocki
2015-04-03  8:25         ` [tip:timers/core] " tip-bot for Thomas Gleixner
2015-04-03  0:31       ` [v2][PATCH 15/21] ARM: OMAP: " Rafael J. Wysocki
2015-04-03  8:25         ` [tip:timers/core] " tip-bot for Thomas Gleixner
2015-04-03  0:32       ` [v2][PATCH 16/21] ARM: tegra: " Rafael J. Wysocki
2015-04-03  8:25         ` [tip:timers/core] ARM: Tegra: " tip-bot for Thomas Gleixner
2015-04-03  0:34       ` [v2][PATCH 17/21] sched/idle: " Rafael J. Wysocki
2015-04-03  8:26         ` [tip:timers/core] " tip-bot for Thomas Gleixner
2015-04-03  0:36       ` [v2][PATCH 18/21] clockevents: Remove broadcast oneshot control leftovers Rafael J. Wysocki
2015-04-03  8:26         ` [tip:timers/core] " tip-bot for Rafael J. Wysocki
2015-04-03  0:37       ` [v2][PATCH 19/21] clockevents: Make tick handover explicit Rafael J. Wysocki
2015-04-03  8:26         ` [tip:timers/core] " tip-bot for Thomas Gleixner
2015-04-03  0:38       ` [v2][PATCH 20/21] clockevents: Cleanup dead cpu explicitely Rafael J. Wysocki
2015-04-03  8:26         ` [tip:timers/core] " tip-bot for Thomas Gleixner
2015-04-03  0:39       ` [v2][PATCH 21/21] timekeeping: Get rid of stale comment Rafael J. Wysocki
2015-04-03  8:27         ` [tip:timers/core] " tip-bot for Thomas Gleixner
2015-04-03  6:45       ` [v2][PATCH 00/21] clockevents_notify() removal Ingo Molnar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).