stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5] Fix race in hrtimer broadcast and take care of dependencies
@ 2015-05-13 11:49 Preeti U Murthy
  2015-05-13 11:50 ` [PATCH1/5] clockevents: Remove CONFIG_GENERIC_CLOCKEVENTS_BUILD Preeti U Murthy
                   ` (5 more replies)
  0 siblings, 6 replies; 9+ messages in thread
From: Preeti U Murthy @ 2015-05-13 11:49 UTC (permalink / raw)
  To: gregkh, stable; +Cc: mingo, linux

The intention was to backport only PATCH[5/5]: clockevents: Fix
cpu_down() race for hrtimer based broadcasting,

but this depends on commits upstream which did cleanup and
reorganization of code. However these commits cannot be cherry-picked as
is. There are a few minor changes upstream and hence these commits had
to be backported too. Reasons for backports are given below:

1. PATCH[1/5]: The upstream commit introduced a duplicate function which
was removed much later by commit:

        9eed56e889d: clockevents: Clean up clockchips.h

We do not need to cherry-pick the entire above commit because the backport
was a simple one.

2. PATCH[3/5]: There are newer functions introduced upstream through

        554ef3876c6: clockevents: Handle tick device's resume separately

Yet again we did not need to cherry pick the entire above commit,
firstly because it introduces significant new code, secondly because the
backport was a simple one.

3. PATCH[4/5]: The function clockevent_set_mode() was renamed to
clockevent_set_state() upstream by commit:

        77e32c89a7: clockevents: Manage device's state separately for
                    the core

We do not need to cherry-pick this commit for the same reason as in (2).

This series needs to be applied on top of stable-4.0. A new series will
be sent out for stable-3.19.
---

Preeti U Murthy (1):
      clockevents: Fix cpu_down() race for hrtimer based broadcasting

Thomas Gleixner (4):
      clockevents: Remove CONFIG_GENERIC_CLOCKEVENTS_BUILD
      tick: Move clocksource related stuff to timekeeping.h
      tick: Simplify tick-internal.h
      tick: Move core only declarations and functions to core


 include/linux/clockchips.h   |   23 ++----
 include/linux/tick.h         |  138 ++++++-----------------------------
 kernel/cpu.c                 |    2 +
 kernel/time/Kconfig          |    6 --
 kernel/time/Makefile         |    6 +-
 kernel/time/clockevents.c    |    3 -
 kernel/time/hrtimer.c        |    2 -
 kernel/time/jiffies.c        |    2 -
 kernel/time/ntp.c            |    1 
 kernel/time/tick-broadcast.c |   19 +++--
 kernel/time/tick-internal.h  |  166 ++++++++++++++++--------------------------
 kernel/time/tick-sched.c     |    7 ++
 kernel/time/tick-sched.h     |   64 ++++++++++++++++
 kernel/time/timekeeping.h    |    7 ++
 kernel/time/timer_list.c     |    2 -
 15 files changed, 190 insertions(+), 258 deletions(-)
 create mode 100644 kernel/time/tick-sched.h

--


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

* [PATCH1/5] clockevents: Remove CONFIG_GENERIC_CLOCKEVENTS_BUILD
  2015-05-13 11:49 [PATCH 0/5] Fix race in hrtimer broadcast and take care of dependencies Preeti U Murthy
@ 2015-05-13 11:50 ` Preeti U Murthy
  2015-05-13 11:50 ` [PATCH2/5] tick: Move clocksource related stuff to timekeeping.h Preeti U Murthy
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Preeti U Murthy @ 2015-05-13 11:50 UTC (permalink / raw)
  To: gregkh, stable; +Cc: mingo, linux

From: Thomas Gleixner <tglx@linutronix.de>

commit 9f083b74df3a7eaa100b456f2dc195512daf728e upstream

This option was for simpler migration to the clock events code.
Most architectures have been converted and the option has been
disfunctional as a standalone option for quite some time. Remove
it.

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/5021859.jl9OC1medj@vostro.rjw.lan
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
---

 include/linux/clockchips.h  |    8 ++------
 kernel/time/Kconfig         |    6 ------
 kernel/time/Makefile        |    6 ++----
 kernel/time/clockevents.c   |    3 ---
 kernel/time/tick-internal.h |    4 ++--
 5 files changed, 6 insertions(+), 21 deletions(-)

diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
index 2e4cb67..271d9f5 100644
--- a/include/linux/clockchips.h
+++ b/include/linux/clockchips.h
@@ -22,7 +22,7 @@ enum clock_event_nofitiers {
 	CLOCK_EVT_NOTIFY_CPU_DEAD,
 };
 
-#ifdef CONFIG_GENERIC_CLOCKEVENTS_BUILD
+#ifdef CONFIG_GENERIC_CLOCKEVENTS
 
 #include <linux/clocksource.h>
 #include <linux/cpumask.h>
@@ -194,13 +194,9 @@ static inline int tick_check_broadcast_expired(void) { return 0; }
 static inline void tick_setup_hrtimer_broadcast(void) {};
 #endif
 
-#ifdef CONFIG_GENERIC_CLOCKEVENTS
 extern int clockevents_notify(unsigned long reason, void *arg);
-#else
-static inline int clockevents_notify(unsigned long reason, void *arg) { return 0; }
-#endif
 
-#else /* CONFIG_GENERIC_CLOCKEVENTS_BUILD */
+#else /* CONFIG_GENERIC_CLOCKEVENTS */
 
 static inline void clockevents_suspend(void) {}
 static inline void clockevents_resume(void) {}
diff --git a/kernel/time/Kconfig b/kernel/time/Kconfig
index d626dc9..579ce1b 100644
--- a/kernel/time/Kconfig
+++ b/kernel/time/Kconfig
@@ -33,12 +33,6 @@ config ARCH_USES_GETTIMEOFFSET
 config GENERIC_CLOCKEVENTS
 	bool
 
-# Migration helper. Builds, but does not invoke
-config GENERIC_CLOCKEVENTS_BUILD
-	bool
-	default y
-	depends on GENERIC_CLOCKEVENTS
-
 # Architecture can handle broadcast in a driver-agnostic way
 config ARCH_HAS_TICK_BROADCAST
 	bool
diff --git a/kernel/time/Makefile b/kernel/time/Makefile
index c09c078..01f0312 100644
--- a/kernel/time/Makefile
+++ b/kernel/time/Makefile
@@ -2,15 +2,13 @@ obj-y += time.o timer.o hrtimer.o itimer.o posix-timers.o posix-cpu-timers.o
 obj-y += timekeeping.o ntp.o clocksource.o jiffies.o timer_list.o
 obj-y += timeconv.o timecounter.o posix-clock.o alarmtimer.o
 
-obj-$(CONFIG_GENERIC_CLOCKEVENTS_BUILD)		+= clockevents.o
-obj-$(CONFIG_GENERIC_CLOCKEVENTS)		+= tick-common.o
+obj-$(CONFIG_GENERIC_CLOCKEVENTS)		+= clockevents.o tick-common.o
 ifeq ($(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST),y)
  obj-y						+= tick-broadcast.o
  obj-$(CONFIG_TICK_ONESHOT)			+= tick-broadcast-hrtimer.o
 endif
 obj-$(CONFIG_GENERIC_SCHED_CLOCK)		+= sched_clock.o
-obj-$(CONFIG_TICK_ONESHOT)			+= tick-oneshot.o
-obj-$(CONFIG_TICK_ONESHOT)			+= tick-sched.o
+obj-$(CONFIG_TICK_ONESHOT)			+= tick-oneshot.o tick-sched.o
 obj-$(CONFIG_TIMER_STATS)			+= timer_stats.o
 obj-$(CONFIG_DEBUG_FS)				+= timekeeping_debug.o
 obj-$(CONFIG_TEST_UDELAY)			+= test_udelay.o
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
index 5544990..833e08c 100644
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -541,7 +541,6 @@ void clockevents_resume(void)
 			dev->resume(dev);
 }
 
-#ifdef CONFIG_GENERIC_CLOCKEVENTS
 /**
  * clockevents_notify - notification about relevant events
  * Returns 0 on success, any other value on error
@@ -727,5 +726,3 @@ static int __init clockevents_init_sysfs(void)
 }
 device_initcall(clockevents_init_sysfs);
 #endif /* SYSFS */
-
-#endif /* GENERIC_CLOCK_EVENTS */
diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h
index 366aeb4..f51bd6a 100644
--- a/kernel/time/tick-internal.h
+++ b/kernel/time/tick-internal.h
@@ -10,7 +10,7 @@ extern seqlock_t jiffies_lock;
 
 #define CS_NAME_LEN	32
 
-#ifdef CONFIG_GENERIC_CLOCKEVENTS_BUILD
+#ifdef CONFIG_GENERIC_CLOCKEVENTS
 
 #define TICK_DO_TIMER_NONE	-1
 #define TICK_DO_TIMER_BOOT	-2
@@ -166,7 +166,7 @@ static inline int tick_device_is_functional(struct clock_event_device *dev)
 
 int __clockevents_update_freq(struct clock_event_device *dev, u32 freq);
 
-#endif
+#endif /* GENERIC_CLOCKEVENTS */
 
 extern void do_timer(unsigned long ticks);
 extern void update_wall_time(void);


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

* [PATCH2/5] tick: Move clocksource related stuff to timekeeping.h
  2015-05-13 11:49 [PATCH 0/5] Fix race in hrtimer broadcast and take care of dependencies Preeti U Murthy
  2015-05-13 11:50 ` [PATCH1/5] clockevents: Remove CONFIG_GENERIC_CLOCKEVENTS_BUILD Preeti U Murthy
@ 2015-05-13 11:50 ` Preeti U Murthy
  2015-05-13 11:50 ` [PATCH3/5] tick: Simplify tick-internal.h Preeti U Murthy
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Preeti U Murthy @ 2015-05-13 11:50 UTC (permalink / raw)
  To: gregkh, stable; +Cc: mingo, linux

From: Thomas Gleixner <tglx@linutronix.de>

commit bfb83b27519aa7ed9510f601a8f825a2c1484bc2 upstream

Move clocksource related stuff to timekeeping.h and remove the
pointless include from ntp.c

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
[ rjw: Subject ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/2714218.nM5AEfAHj0@vostro.rjw.lan
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
---

 kernel/time/clocksource.c   |    2 +-
 kernel/time/jiffies.c       |    2 +-
 kernel/time/ntp.c           |    1 -
 kernel/time/tick-internal.h |    6 ------
 kernel/time/timekeeping.h   |    7 +++++++
 5 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index 4892352..00fb440 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -31,7 +31,7 @@
 #include <linux/tick.h>
 #include <linux/kthread.h>
 
-#include "tick-internal.h"
+#include "timekeeping.h"
 #include "timekeeping_internal.h"
 
 /**
diff --git a/kernel/time/jiffies.c b/kernel/time/jiffies.c
index a6a5bf5..5c33f9e 100644
--- a/kernel/time/jiffies.c
+++ b/kernel/time/jiffies.c
@@ -25,7 +25,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 
-#include "tick-internal.h"
+#include "timekeeping.h"
 
 /* The Jiffies based clocksource is the lowest common
  * denominator clock source which should function on
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index 0f60b08..9ad60d0 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -17,7 +17,6 @@
 #include <linux/module.h>
 #include <linux/rtc.h>
 
-#include "tick-internal.h"
 #include "ntp_internal.h"
 
 /*
diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h
index f51bd6a..88e525f 100644
--- a/kernel/time/tick-internal.h
+++ b/kernel/time/tick-internal.h
@@ -6,10 +6,6 @@
 
 #include "timekeeping.h"
 
-extern seqlock_t jiffies_lock;
-
-#define CS_NAME_LEN	32
-
 #ifdef CONFIG_GENERIC_CLOCKEVENTS
 
 #define TICK_DO_TIMER_NONE	-1
@@ -168,5 +164,3 @@ int __clockevents_update_freq(struct clock_event_device *dev, u32 freq);
 
 #endif /* GENERIC_CLOCKEVENTS */
 
-extern void do_timer(unsigned long ticks);
-extern void update_wall_time(void);
diff --git a/kernel/time/timekeeping.h b/kernel/time/timekeeping.h
index 1d91416..ead8794 100644
--- a/kernel/time/timekeeping.h
+++ b/kernel/time/timekeeping.h
@@ -19,4 +19,11 @@ extern void timekeeping_clocktai(struct timespec *ts);
 extern int timekeeping_suspend(void);
 extern void timekeeping_resume(void);
 
+extern void do_timer(unsigned long ticks);
+extern void update_wall_time(void);
+
+extern seqlock_t jiffies_lock;
+
+#define CS_NAME_LEN	32
+
 #endif


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

* [PATCH3/5] tick: Simplify tick-internal.h
  2015-05-13 11:49 [PATCH 0/5] Fix race in hrtimer broadcast and take care of dependencies Preeti U Murthy
  2015-05-13 11:50 ` [PATCH1/5] clockevents: Remove CONFIG_GENERIC_CLOCKEVENTS_BUILD Preeti U Murthy
  2015-05-13 11:50 ` [PATCH2/5] tick: Move clocksource related stuff to timekeeping.h Preeti U Murthy
@ 2015-05-13 11:50 ` Preeti U Murthy
  2015-06-29 22:49   ` Greg KH
  2015-05-13 11:50 ` [PATCH4/5] tick: Move core only declarations and functions to core Preeti U Murthy
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 9+ messages in thread
From: Preeti U Murthy @ 2015-05-13 11:50 UTC (permalink / raw)
  To: gregkh, stable; +Cc: mingo, linux

From: Thomas Gleixner <tglx@linutronix.de>

commit b7475eb599ddb2e8cab2dc86ff38a9507463ad6b upstream

tick-internal.h is pretty confusing as a lot of the stub inlines
are there several times.

Distangle the maze and make clear functional sections.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
[ rjw: Subject ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/16068264.vcNp79HLaT@vostro.rjw.lan
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
---

 kernel/time/tick-internal.h |  145 +++++++++++++++----------------------------
 1 file changed, 49 insertions(+), 96 deletions(-)

diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h
index 88e525f..43adaec 100644
--- a/kernel/time/tick-internal.h
+++ b/kernel/time/tick-internal.h
@@ -27,13 +27,18 @@ extern bool tick_check_replacement(struct clock_event_device *curdev,
 				   struct clock_event_device *newdev);
 extern void tick_install_replacement(struct clock_event_device *dev);
 
+/* Check, if the device is functional or a dummy for broadcast */
+static inline int tick_device_is_functional(struct clock_event_device *dev)
+{
+	return !(dev->features & CLOCK_EVT_FEAT_DUMMY);
+}
+ 
 extern void clockevents_shutdown(struct clock_event_device *dev);
-
+extern int __clockevents_update_freq(struct clock_event_device *dev, u32 freq);
 extern ssize_t sysfs_get_uname(const char *buf, char *dst, size_t cnt);
+#endif /* GENERIC_CLOCKEVENTS */
 
-/*
- * NO_HZ / high resolution timer shared code
- */
+/* Oneshot related functions */
 #ifdef CONFIG_TICK_ONESHOT
 extern void tick_setup_oneshot(struct clock_event_device *newdev,
 			       void (*handler)(struct clock_event_device *),
@@ -42,69 +47,19 @@ extern int tick_program_event(ktime_t expires, int force);
 extern void tick_oneshot_notify(void);
 extern int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *));
 extern void tick_resume_oneshot(void);
-# ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
-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_resume_broadcast_oneshot(struct clock_event_device *bc);
-extern int tick_broadcast_oneshot_active(void);
-extern void tick_check_oneshot_broadcast_this_cpu(void);
-bool tick_broadcast_oneshot_available(void);
-# else /* BROADCAST */
-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; }
-static inline void tick_check_oneshot_broadcast_this_cpu(void) { }
-static inline bool tick_broadcast_oneshot_available(void) { return true; }
-# endif /* !BROADCAST */
-
+static inline bool tick_oneshot_possible(void) { return true; }
 #else /* !ONESHOT */
 static inline
 void tick_setup_oneshot(struct clock_event_device *newdev,
 			void (*handler)(struct clock_event_device *),
-			ktime_t nextevt)
-{
-	BUG();
-}
-static inline void tick_resume_oneshot(void)
-{
-	BUG();
-}
-static inline int tick_program_event(ktime_t expires, int force)
-{
-	return 0;
-}
+			ktime_t nextevt) { BUG(); }
+static inline void tick_resume_oneshot(void) { BUG(); }
+static inline int tick_program_event(ktime_t expires, int force) { return 0; }
 static inline void tick_oneshot_notify(void) { }
-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_shutdown_broadcast_oneshot(unsigned int *cpup) { }
-static inline int tick_resume_broadcast_oneshot(struct clock_event_device *bc)
-{
-	return 0;
-}
-static inline int tick_broadcast_oneshot_active(void) { return 0; }
-static inline bool tick_broadcast_oneshot_available(void) { return false; }
+static inline bool tick_oneshot_possible(void) { return false; }
 #endif /* !TICK_ONESHOT */
 
-/* NO_HZ_FULL internal */
-#ifdef CONFIG_NO_HZ_FULL
-extern void tick_nohz_init(void);
-# else
-static inline void tick_nohz_init(void) { }
-#endif
-
-/*
- * Broadcasting support
- */
+/* Broadcasting support */
 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
 extern int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu);
 extern void tick_install_broadcast_device(struct clock_event_device *dev);
@@ -114,53 +69,51 @@ extern void tick_shutdown_broadcast(unsigned int *cpup);
 extern void tick_suspend_broadcast(void);
 extern int tick_resume_broadcast(void);
 extern void tick_broadcast_init(void);
-extern void
-tick_set_periodic_handler(struct clock_event_device *dev, int broadcast);
-int tick_broadcast_update_freq(struct clock_event_device *dev, u32 freq);
-
+extern void tick_set_periodic_handler(struct clock_event_device *dev, int broadcast);
+extern int tick_broadcast_update_freq(struct clock_event_device *dev, u32 freq);
 #else /* !BROADCAST */
-
-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_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 int tick_resume_broadcast(void) { return 0; }
 static inline void tick_broadcast_init(void) { }
-static inline int tick_broadcast_update_freq(struct clock_event_device *dev,
-					     u32 freq) { return -ENODEV; }
+static inline int tick_broadcast_update_freq(struct clock_event_device *dev, u32 freq) { return -ENODEV; }
 
-/*
- * Set the periodic handler in non broadcast mode
- */
-static inline void tick_set_periodic_handler(struct clock_event_device *dev,
-					     int broadcast)
+/* Set the periodic handler in non broadcast mode */
+static inline void tick_set_periodic_handler(struct clock_event_device *dev, int broadcast)
 {
 	dev->event_handler = tick_handle_periodic;
 }
 #endif /* !BROADCAST */
 
-/*
- * Check, if the device is functional or a dummy for broadcast
- */
-static inline int tick_device_is_functional(struct clock_event_device *dev)
-{
-	return !(dev->features & CLOCK_EVT_FEAT_DUMMY);
-}
-
-int __clockevents_update_freq(struct clock_event_device *dev, u32 freq);
-
-#endif /* GENERIC_CLOCKEVENTS */
+/* 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_resume_broadcast_oneshot(struct clock_event_device *bc);
+extern int tick_broadcast_oneshot_active(void);
+extern void tick_check_oneshot_broadcast_this_cpu(void);
+bool tick_broadcast_oneshot_available(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_resume_broadcast_oneshot(struct clock_event_device *bc) { return 0; }
+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(); }
+#endif /* !BROADCAST && ONESHOT */
 
+/* NO_HZ_FULL internal */
+#ifdef CONFIG_NO_HZ_FULL
+extern void tick_nohz_init(void);
+# else
+static inline void tick_nohz_init(void) { }
+#endif


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

* [PATCH4/5] tick: Move core only declarations and functions to core
  2015-05-13 11:49 [PATCH 0/5] Fix race in hrtimer broadcast and take care of dependencies Preeti U Murthy
                   ` (2 preceding siblings ...)
  2015-05-13 11:50 ` [PATCH3/5] tick: Simplify tick-internal.h Preeti U Murthy
@ 2015-05-13 11:50 ` Preeti U Murthy
  2015-05-13 11:50 ` [PATCH5/5] clockevents: Fix cpu_down() race for hrtimer based broadcasting Preeti U Murthy
  2015-06-18  8:06 ` [PATCH 0/5] Fix race in hrtimer broadcast and take care of dependencies Preeti U Murthy
  5 siblings, 0 replies; 9+ messages in thread
From: Preeti U Murthy @ 2015-05-13 11:50 UTC (permalink / raw)
  To: gregkh, stable; +Cc: mingo, linux

From: Thomas Gleixner <tglx@linutronix.de>

commit c1797baf6880174f899ce3960d0598f5bbeeb7ff upstream

No point to expose everything to the world. People just believe
such functions can be abused for whatever purposes. Sigh.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
[ Rebased on top of 4.0-rc5 ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Nicolas Pitre <nico@linaro.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/28017337.VbCUc39Gme@vostro.rjw.lan
[ Merged to latest timers/core ]
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
---

 include/linux/clockchips.h  |   15 ++---
 include/linux/tick.h        |  134 ++++++-------------------------------------
 kernel/time/clocksource.c   |    2 -
 kernel/time/hrtimer.c       |    2 -
 kernel/time/tick-internal.h |   15 +++++
 kernel/time/tick-sched.c    |    7 ++
 kernel/time/tick-sched.h    |   64 +++++++++++++++++++++
 kernel/time/timer_list.c    |    2 -
 8 files changed, 112 insertions(+), 129 deletions(-)
 create mode 100644 kernel/time/tick-sched.h

diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
index 271d9f5..82b47c5 100644
--- a/include/linux/clockchips.h
+++ b/include/linux/clockchips.h
@@ -158,15 +158,6 @@ extern void clockevents_config_and_register(struct clock_event_device *dev,
 
 extern int clockevents_update_freq(struct clock_event_device *ce, u32 freq);
 
-extern void clockevents_exchange_device(struct clock_event_device *old,
-					struct clock_event_device *new);
-extern void clockevents_set_mode(struct clock_event_device *dev,
-				 enum clock_event_mode mode);
-extern int clockevents_program_event(struct clock_event_device *dev,
-				     ktime_t expires, bool force);
-
-extern void clockevents_handle_noop(struct clock_event_device *dev);
-
 static inline void
 clockevents_calc_mult_shift(struct clock_event_device *ce, u32 freq, u32 minsec)
 {
@@ -174,6 +165,12 @@ clockevents_calc_mult_shift(struct clock_event_device *ce, u32 freq, u32 minsec)
 				      freq, minsec);
 }
 
+/* Should be core only, but is abused by arm bl_switcher */
+extern void clockevents_set_mode(struct clock_event_device *dev,
+				 enum clock_event_mode state);
+extern int clockevents_program_event(struct clock_event_device *dev,
+				     ktime_t expires, bool force);
+
 extern void clockevents_suspend(void);
 extern void clockevents_resume(void);
 
diff --git a/include/linux/tick.h b/include/linux/tick.h
index 9c085dc..f9a2d26 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -1,7 +1,5 @@
-/*  linux/include/linux/tick.h
- *
- *  This file contains the structure definitions for tick related functions
- *
+/*
+ * Tick related global functions
  */
 #ifndef _LINUX_TICK_H
 #define _LINUX_TICK_H
@@ -9,13 +7,12 @@
 #include <linux/clockchips.h>
 #include <linux/irqflags.h>
 #include <linux/percpu.h>
-#include <linux/hrtimer.h>
 #include <linux/context_tracking_state.h>
 #include <linux/cpumask.h>
 #include <linux/sched.h>
 
+/* ARM BL switcher abuse support */
 #ifdef CONFIG_GENERIC_CLOCKEVENTS
-
 enum tick_device_mode {
 	TICKDEV_MODE_PERIODIC,
 	TICKDEV_MODE_ONESHOT,
@@ -25,133 +22,38 @@ struct tick_device {
 	struct clock_event_device *evtdev;
 	enum tick_device_mode mode;
 };
-
-enum tick_nohz_mode {
-	NOHZ_MODE_INACTIVE,
-	NOHZ_MODE_LOWRES,
-	NOHZ_MODE_HIGHRES,
-};
-
-/**
- * struct tick_sched - sched tick emulation and no idle tick control/stats
- * @sched_timer:	hrtimer to schedule the periodic tick in high
- *			resolution mode
- * @last_tick:		Store the last tick expiry time when the tick
- *			timer is modified for nohz sleeps. This is necessary
- *			to resume the tick timer operation in the timeline
- *			when the CPU returns from nohz sleep.
- * @tick_stopped:	Indicator that the idle tick has been stopped
- * @idle_jiffies:	jiffies at the entry to idle for idle time accounting
- * @idle_calls:		Total number of idle calls
- * @idle_sleeps:	Number of idle calls, where the sched tick was stopped
- * @idle_entrytime:	Time when the idle call was entered
- * @idle_waketime:	Time when the idle was interrupted
- * @idle_exittime:	Time when the idle state was left
- * @idle_sleeptime:	Sum of the time slept in idle with sched tick stopped
- * @iowait_sleeptime:	Sum of the time slept in idle with sched tick stopped, with IO outstanding
- * @sleep_length:	Duration of the current idle sleep
- * @do_timer_lst:	CPU was the last one doing do_timer before going idle
- */
-struct tick_sched {
-	struct hrtimer			sched_timer;
-	unsigned long			check_clocks;
-	enum tick_nohz_mode		nohz_mode;
-	ktime_t				last_tick;
-	int				inidle;
-	int				tick_stopped;
-	unsigned long			idle_jiffies;
-	unsigned long			idle_calls;
-	unsigned long			idle_sleeps;
-	int				idle_active;
-	ktime_t				idle_entrytime;
-	ktime_t				idle_waketime;
-	ktime_t				idle_exittime;
-	ktime_t				idle_sleeptime;
-	ktime_t				iowait_sleeptime;
-	ktime_t				sleep_length;
-	unsigned long			last_jiffies;
-	unsigned long			next_jiffies;
-	ktime_t				idle_expires;
-	int				do_timer_last;
-};
-
-extern void __init tick_init(void);
-extern int tick_is_oneshot_available(void);
 extern struct tick_device *tick_get_device(int cpu);
+#endif
 
+#ifdef CONFIG_GENERIC_CLOCKEVENTS
+extern void __init tick_init(void);
 extern void tick_freeze(void);
 extern void tick_unfreeze(void);
+#else /* CONFIG_GENERIC_CLOCKEVENTS */
+static inline void tick_init(void) { }
+static inline void tick_freeze(void) { }
+static inline void tick_unfreeze(void) { }
+#endif /* !CONFIG_GENERIC_CLOCKEVENTS */
 
-# ifdef CONFIG_HIGH_RES_TIMERS
-extern int tick_init_highres(void);
-extern int tick_program_event(ktime_t expires, int force);
-extern void tick_setup_sched_timer(void);
-# endif
-
-# if defined CONFIG_NO_HZ_COMMON || defined CONFIG_HIGH_RES_TIMERS
-extern void tick_cancel_sched_timer(int cpu);
-# else
-static inline void tick_cancel_sched_timer(int cpu) { }
-# endif
-
-# ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
-extern struct tick_device *tick_get_broadcast_device(void);
-extern struct cpumask *tick_get_broadcast_mask(void);
-
-#  ifdef CONFIG_TICK_ONESHOT
-extern struct cpumask *tick_get_broadcast_oneshot_mask(void);
-#  endif
-
-# endif /* BROADCAST */
-
-# ifdef CONFIG_TICK_ONESHOT
-extern void tick_clock_notify(void);
-extern int tick_check_oneshot_change(int allow_nohz);
-extern struct tick_sched *tick_get_tick_sched(int cpu);
+#ifdef CONFIG_TICK_ONESHOT
 extern void tick_irq_enter(void);
-extern int tick_oneshot_mode_active(void);
 #  ifndef arch_needs_cpu
 #   define arch_needs_cpu() (0)
 #  endif
 # else
-static inline void tick_clock_notify(void) { }
-static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
-static inline void tick_irq_enter(void) { }
-static inline int tick_oneshot_mode_active(void) { return 0; }
-# endif
-
-#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_cancel_sched_timer(int cpu) { }
-static inline void tick_clock_notify(void) { }
-static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
 static inline void tick_irq_enter(void) { }
-static inline int tick_oneshot_mode_active(void) { return 0; }
-#endif /* !CONFIG_GENERIC_CLOCKEVENTS */
-
-# ifdef CONFIG_NO_HZ_COMMON
-DECLARE_PER_CPU(struct tick_sched, tick_cpu_sched);
-
-static inline int tick_nohz_tick_stopped(void)
-{
-	return __this_cpu_read(tick_cpu_sched.tick_stopped);
-}
+#endif
 
+#ifdef CONFIG_NO_HZ_COMMON
+extern int tick_nohz_tick_stopped(void);
 extern void tick_nohz_idle_enter(void);
 extern void tick_nohz_idle_exit(void);
 extern void tick_nohz_irq_exit(void);
 extern ktime_t tick_nohz_get_sleep_length(void);
 extern u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time);
 extern u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time);
-
-# else /* !CONFIG_NO_HZ_COMMON */
-static inline int tick_nohz_tick_stopped(void)
-{
-	return 0;
-}
-
+#else /* !CONFIG_NO_HZ_COMMON */
+static inline int tick_nohz_tick_stopped(void) { return 0; }
 static inline void tick_nohz_idle_enter(void) { }
 static inline void tick_nohz_idle_exit(void) { }
 
@@ -163,7 +65,7 @@ static inline ktime_t tick_nohz_get_sleep_length(void)
 }
 static inline u64 get_cpu_idle_time_us(int cpu, u64 *unused) { return -1; }
 static inline u64 get_cpu_iowait_time_us(int cpu, u64 *unused) { return -1; }
-# endif /* !CONFIG_NO_HZ_COMMON */
+#endif /* !CONFIG_NO_HZ_COMMON */
 
 #ifdef CONFIG_NO_HZ_FULL
 extern bool tick_nohz_full_running;
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index 00fb440..4892352 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -31,7 +31,7 @@
 #include <linux/tick.h>
 #include <linux/kthread.h>
 
-#include "timekeeping.h"
+#include "tick-internal.h"
 #include "timekeeping_internal.h"
 
 /**
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index bee0c1f..721d29b 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -54,7 +54,7 @@
 
 #include <trace/events/timer.h>
 
-#include "timekeeping.h"
+#include "tick-internal.h"
 
 /*
  * The timer bases:
diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h
index 43adaec..9dfbbd9 100644
--- a/kernel/time/tick-internal.h
+++ b/kernel/time/tick-internal.h
@@ -5,6 +5,7 @@
 #include <linux/tick.h>
 
 #include "timekeeping.h"
+#include "tick-sched.h"
 
 #ifdef CONFIG_GENERIC_CLOCKEVENTS
 
@@ -26,6 +27,7 @@ extern void tick_resume(void);
 extern bool tick_check_replacement(struct clock_event_device *curdev,
 				   struct clock_event_device *newdev);
 extern void tick_install_replacement(struct clock_event_device *dev);
+extern int tick_is_oneshot_available(void);
 
 /* Check, if the device is functional or a dummy for broadcast */
 static inline int tick_device_is_functional(struct clock_event_device *dev)
@@ -34,6 +36,9 @@ static inline int tick_device_is_functional(struct clock_event_device *dev)
 }
  
 extern void clockevents_shutdown(struct clock_event_device *dev);
+extern void clockevents_exchange_device(struct clock_event_device *old,
+					struct clock_event_device *new);
+extern void clockevents_handle_noop(struct clock_event_device *dev);
 extern int __clockevents_update_freq(struct clock_event_device *dev, u32 freq);
 extern ssize_t sysfs_get_uname(const char *buf, char *dst, size_t cnt);
 #endif /* GENERIC_CLOCKEVENTS */
@@ -48,6 +53,10 @@ extern void tick_oneshot_notify(void);
 extern int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *));
 extern void tick_resume_oneshot(void);
 static inline bool tick_oneshot_possible(void) { return true; }
+extern int tick_oneshot_mode_active(void);
+extern void tick_clock_notify(void);
+extern int tick_check_oneshot_change(int allow_nohz);
+extern int tick_init_highres(void);
 #else /* !ONESHOT */
 static inline
 void tick_setup_oneshot(struct clock_event_device *newdev,
@@ -57,6 +66,9 @@ static inline void tick_resume_oneshot(void) { BUG(); }
 static inline int tick_program_event(ktime_t expires, int force) { return 0; }
 static inline void tick_oneshot_notify(void) { }
 static inline bool tick_oneshot_possible(void) { return false; }
+static inline int tick_oneshot_mode_active(void) { return 0; }
+static inline void tick_clock_notify(void) { }
+static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
 #endif /* !TICK_ONESHOT */
 
 /* Broadcasting support */
@@ -71,6 +83,8 @@ extern int tick_resume_broadcast(void);
 extern void tick_broadcast_init(void);
 extern void tick_set_periodic_handler(struct clock_event_device *dev, int broadcast);
 extern int tick_broadcast_update_freq(struct clock_event_device *dev, u32 freq);
+extern struct tick_device *tick_get_broadcast_device(void);
+extern struct cpumask *tick_get_broadcast_mask(void);
 #else /* !BROADCAST */
 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; }
@@ -100,6 +114,7 @@ extern int tick_resume_broadcast_oneshot(struct clock_event_device *bc);
 extern int tick_broadcast_oneshot_active(void);
 extern void tick_check_oneshot_broadcast_this_cpu(void);
 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; }
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index a4c4eda..9142591 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -34,7 +34,7 @@
 /*
  * Per cpu nohz control structure
  */
-DEFINE_PER_CPU(struct tick_sched, tick_cpu_sched);
+static DEFINE_PER_CPU(struct tick_sched, tick_cpu_sched);
 
 /*
  * The time, when the last jiffy update happened. Protected by jiffies_lock.
@@ -416,6 +416,11 @@ static int __init setup_tick_nohz(char *str)
 
 __setup("nohz=", setup_tick_nohz);
 
+int tick_nohz_tick_stopped(void)
+{
+	return __this_cpu_read(tick_cpu_sched.tick_stopped);
+}
+
 /**
  * tick_nohz_update_jiffies - update jiffies when idle was interrupted
  *
diff --git a/kernel/time/tick-sched.h b/kernel/time/tick-sched.h
new file mode 100644
index 0000000..9307432
--- /dev/null
+++ b/kernel/time/tick-sched.h
@@ -0,0 +1,64 @@
+#ifndef _TICK_SCHED_H
+#define _TICK_SCHED_H
+
+#include <linux/hrtimer.h>
+
+enum tick_nohz_mode {
+	NOHZ_MODE_INACTIVE,
+	NOHZ_MODE_LOWRES,
+	NOHZ_MODE_HIGHRES,
+};
+
+/**
+ * struct tick_sched - sched tick emulation and no idle tick control/stats
+ * @sched_timer:	hrtimer to schedule the periodic tick in high
+ *			resolution mode
+ * @last_tick:		Store the last tick expiry time when the tick
+ *			timer is modified for nohz sleeps. This is necessary
+ *			to resume the tick timer operation in the timeline
+ *			when the CPU returns from nohz sleep.
+ * @tick_stopped:	Indicator that the idle tick has been stopped
+ * @idle_jiffies:	jiffies at the entry to idle for idle time accounting
+ * @idle_calls:		Total number of idle calls
+ * @idle_sleeps:	Number of idle calls, where the sched tick was stopped
+ * @idle_entrytime:	Time when the idle call was entered
+ * @idle_waketime:	Time when the idle was interrupted
+ * @idle_exittime:	Time when the idle state was left
+ * @idle_sleeptime:	Sum of the time slept in idle with sched tick stopped
+ * @iowait_sleeptime:	Sum of the time slept in idle with sched tick stopped, with IO outstanding
+ * @sleep_length:	Duration of the current idle sleep
+ * @do_timer_lst:	CPU was the last one doing do_timer before going idle
+ */
+struct tick_sched {
+	struct hrtimer			sched_timer;
+	unsigned long			check_clocks;
+	enum tick_nohz_mode		nohz_mode;
+	ktime_t				last_tick;
+	int				inidle;
+	int				tick_stopped;
+	unsigned long			idle_jiffies;
+	unsigned long			idle_calls;
+	unsigned long			idle_sleeps;
+	int				idle_active;
+	ktime_t				idle_entrytime;
+	ktime_t				idle_waketime;
+	ktime_t				idle_exittime;
+	ktime_t				idle_sleeptime;
+	ktime_t				iowait_sleeptime;
+	ktime_t				sleep_length;
+	unsigned long			last_jiffies;
+	unsigned long			next_jiffies;
+	ktime_t				idle_expires;
+	int				do_timer_last;
+};
+
+extern struct tick_sched *tick_get_tick_sched(int cpu);
+
+extern void tick_setup_sched_timer(void);
+#if defined CONFIG_NO_HZ_COMMON || defined CONFIG_HIGH_RES_TIMERS
+extern void tick_cancel_sched_timer(int cpu);
+#else
+static inline void tick_cancel_sched_timer(int cpu) { }
+#endif
+
+#endif
diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c
index 61ed862..63b3434 100644
--- a/kernel/time/timer_list.c
+++ b/kernel/time/timer_list.c
@@ -16,10 +16,10 @@
 #include <linux/sched.h>
 #include <linux/seq_file.h>
 #include <linux/kallsyms.h>
-#include <linux/tick.h>
 
 #include <asm/uaccess.h>
 
+#include "tick-internal.h"
 
 struct timer_list_iter {
 	int cpu;


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

* [PATCH5/5] clockevents: Fix cpu_down() race for hrtimer based broadcasting
  2015-05-13 11:49 [PATCH 0/5] Fix race in hrtimer broadcast and take care of dependencies Preeti U Murthy
                   ` (3 preceding siblings ...)
  2015-05-13 11:50 ` [PATCH4/5] tick: Move core only declarations and functions to core Preeti U Murthy
@ 2015-05-13 11:50 ` Preeti U Murthy
  2015-06-18  8:06 ` [PATCH 0/5] Fix race in hrtimer broadcast and take care of dependencies Preeti U Murthy
  5 siblings, 0 replies; 9+ messages in thread
From: Preeti U Murthy @ 2015-05-13 11:50 UTC (permalink / raw)
  To: gregkh, stable; +Cc: mingo, linux

commit 345527b1edce8df719e0884500c76832a18211c3 upstream

It was found when doing a hotplug stress test on POWER, that the
machine either hit softlockups or rcu_sched stall warnings.  The
issue was traced to commit:

  7cba160ad789 ("powernv/cpuidle: Redesign idle states management")

which exposed the cpu_down() race with hrtimer based broadcast mode:

  5d1638acb9f6 ("tick: Introduce hrtimer based broadcast")

The race is the following:

Assume CPU1 is the CPU which holds the hrtimer broadcasting duty
before it is taken down.

        CPU0                                    CPU1

        cpu_down()                              take_cpu_down()
                                                disable_interrupts()

        cpu_die()

        while (CPU1 != CPU_DEAD) {
                msleep(100);
                switch_to_idle();
                stop_cpu_timer();
                schedule_broadcast();
        }

        tick_cleanup_cpu_dead()
                take_over_broadcast()

So after CPU1 disabled interrupts it cannot handle the broadcast
hrtimer anymore, so CPU0 will be stuck forever.

Fix this by explicitly taking over broadcast duty before cpu_die().

This is a temporary workaround. What we really want is a callback
in the clockevent device which allows us to do that from the dying
CPU by pushing the hrtimer onto a different cpu. That might involve
an IPI and is definitely more complex than this immediate fix.

Changelog was picked up from:

    https://lkml.org/lkml/2015/2/16/213

Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Nicolas Pitre <nico@linaro.org>
Signed-off-by: Preeti U. Murthy <preeti@linux.vnet.ibm.com>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: mpe@ellerman.id.au
Cc: nicolas.pitre@linaro.org
Cc: peterz@infradead.org
Cc: rjw@rjwysocki.net
Fixes:
http://linuxppc.10917.n7.nabble.com/offlining-cpus-breakage-td88619.html
Link:
http://lkml.kernel.org/r/20150330092410.24979.59887.stgit@preeti.in.ibm.com
[ Merged it to the latest timer tree, renamed the callback, tidied up the
changelog. ]
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
---

 include/linux/tick.h         |    6 ++++++
 kernel/cpu.c                 |    2 ++
 kernel/time/tick-broadcast.c |   19 +++++++++++--------
 3 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/include/linux/tick.h b/include/linux/tick.h
index f9a2d26..4b6258a 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -44,6 +44,12 @@ extern void tick_irq_enter(void);
 static inline void tick_irq_enter(void) { }
 #endif
 
+#if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) && defined(CONFIG_TICK_ONESHOT)
+extern void hotplug_cpu__broadcast_tick_pull(int dead_cpu);
+#else
+static inline void hotplug_cpu__broadcast_tick_pull(int dead_cpu) { }
+#endif
+
 #ifdef CONFIG_NO_HZ_COMMON
 extern int tick_nohz_tick_stopped(void);
 extern void tick_nohz_idle_enter(void);
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 1972b16..af5db20 100644
--- a/kernel/cpu.c
+++ b/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"
@@ -411,6 +412,7 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
 	while (!idle_cpu(cpu))
 		cpu_relax();
 
+	hotplug_cpu__broadcast_tick_pull(cpu);
 	/* This actually kills the CPU. */
 	__cpu_die(cpu);
 
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
index 066f0ec..25fb004 100644
--- a/kernel/time/tick-broadcast.c
+++ b/kernel/time/tick-broadcast.c
@@ -669,14 +669,19 @@ static void broadcast_shutdown_local(struct clock_event_device *bc,
 	clockevents_set_mode(dev, CLOCK_EVT_MODE_SHUTDOWN);
 }
 
-static void broadcast_move_bc(int deadcpu)
+void hotplug_cpu__broadcast_tick_pull(int deadcpu)
 {
-	struct clock_event_device *bc = tick_broadcast_device.evtdev;
+	struct clock_event_device *bc;
+	unsigned long flags;
 
-	if (!bc || !broadcast_needs_cpu(bc, deadcpu))
-		return;
-	/* This moves the broadcast assignment to this cpu */
-	clockevents_program_event(bc, bc->next_event, 1);
+	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);
 }
 
 /*
@@ -913,8 +918,6 @@ void tick_shutdown_broadcast_oneshot(unsigned int *cpup)
 	cpumask_clear_cpu(cpu, tick_broadcast_pending_mask);
 	cpumask_clear_cpu(cpu, tick_broadcast_force_mask);
 
-	broadcast_move_bc(cpu);
-
 	raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
 }
 


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

* Re: [PATCH 0/5] Fix race in hrtimer broadcast and take care of dependencies
  2015-05-13 11:49 [PATCH 0/5] Fix race in hrtimer broadcast and take care of dependencies Preeti U Murthy
                   ` (4 preceding siblings ...)
  2015-05-13 11:50 ` [PATCH5/5] clockevents: Fix cpu_down() race for hrtimer based broadcasting Preeti U Murthy
@ 2015-06-18  8:06 ` Preeti U Murthy
  5 siblings, 0 replies; 9+ messages in thread
From: Preeti U Murthy @ 2015-06-18  8:06 UTC (permalink / raw)
  To: stable; +Cc: mingo, Thomas Gleixner, LKML

A reminder to pick this series up for stable-4.0

On 05/13/2015 05:19 PM, Preeti U Murthy wrote:
> The intention was to backport only PATCH[5/5]: clockevents: Fix
> cpu_down() race for hrtimer based broadcasting,
> 
> but this depends on commits upstream which did cleanup and
> reorganization of code. However these commits cannot be cherry-picked as
> is. There are a few minor changes upstream and hence these commits had
> to be backported too. Reasons for backports are given below:
> 
> 1. PATCH[1/5]: The upstream commit introduced a duplicate function which
> was removed much later by commit:
> 
>         9eed56e889d: clockevents: Clean up clockchips.h
> 
> We do not need to cherry-pick the entire above commit because the backport
> was a simple one.
> 
> 2. PATCH[3/5]: There are newer functions introduced upstream through
> 
>         554ef3876c6: clockevents: Handle tick device's resume separately
> 
> Yet again we did not need to cherry pick the entire above commit,
> firstly because it introduces significant new code, secondly because the
> backport was a simple one.
> 
> 3. PATCH[4/5]: The function clockevent_set_mode() was renamed to
> clockevent_set_state() upstream by commit:
> 
>         77e32c89a7: clockevents: Manage device's state separately for
>                     the core
> 
> We do not need to cherry-pick this commit for the same reason as in (2).
> 
> This series needs to be applied on top of stable-4.0. 
> ---
> 
> Preeti U Murthy (1):
>       clockevents: Fix cpu_down() race for hrtimer based broadcasting
> 
> Thomas Gleixner (4):
>       clockevents: Remove CONFIG_GENERIC_CLOCKEVENTS_BUILD
>       tick: Move clocksource related stuff to timekeeping.h
>       tick: Simplify tick-internal.h
>       tick: Move core only declarations and functions to core
> 
> 
>  include/linux/clockchips.h   |   23 ++----
>  include/linux/tick.h         |  138 ++++++-----------------------------
>  kernel/cpu.c                 |    2 +
>  kernel/time/Kconfig          |    6 --
>  kernel/time/Makefile         |    6 +-
>  kernel/time/clockevents.c    |    3 -
>  kernel/time/hrtimer.c        |    2 -
>  kernel/time/jiffies.c        |    2 -
>  kernel/time/ntp.c            |    1 
>  kernel/time/tick-broadcast.c |   19 +++--
>  kernel/time/tick-internal.h  |  166 ++++++++++++++++--------------------------
>  kernel/time/tick-sched.c     |    7 ++
>  kernel/time/tick-sched.h     |   64 ++++++++++++++++
>  kernel/time/timekeeping.h    |    7 ++
>  kernel/time/timer_list.c     |    2 -
>  15 files changed, 190 insertions(+), 258 deletions(-)
>  create mode 100644 kernel/time/tick-sched.h
> 
> --
> 


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

* Re: [PATCH3/5] tick: Simplify tick-internal.h
  2015-05-13 11:50 ` [PATCH3/5] tick: Simplify tick-internal.h Preeti U Murthy
@ 2015-06-29 22:49   ` Greg KH
  2015-06-30  3:24     ` Preeti U Murthy
  0 siblings, 1 reply; 9+ messages in thread
From: Greg KH @ 2015-06-29 22:49 UTC (permalink / raw)
  To: Preeti U Murthy; +Cc: stable, mingo, linux

On Wed, May 13, 2015 at 05:20:23PM +0530, Preeti U Murthy wrote:
> From: Thomas Gleixner <tglx@linutronix.de>
> 
> commit b7475eb599ddb2e8cab2dc86ff38a9507463ad6b upstream
> 
> tick-internal.h is pretty confusing as a lot of the stub inlines
> are there several times.
> 
> Distangle the maze and make clear functional sections.
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> [ rjw: Subject ]
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Link: http://lkml.kernel.org/r/16068264.vcNp79HLaT@vostro.rjw.lan
> Signed-off-by: Ingo Molnar <mingo@kernel.org>
> Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>

You don't mention that you changed this function from what it is
upstream, which isn't ok to do without a good reason.

I'm really not liking this series, it's very intrusive for almost no
gain.  In other words, you have a very specific platform, with limited
users, and a limited use case, yet are asking for core timer functions
to be made for a kernel that I'm going to stop maintaining after the
next release.

In other words, these patches are going to only have a lifespan of 1
more week, max.  By then, all your users should be on 4.1, so 4.0
doesn't matter anymore.

So I'm just going to drop this whole series, sorry.  If you have a
distro that "has to have these", then please work with them, otherwise,
just use 4.1, as all is good, and most importantly, properly tested,
there.

thanks,

greg k-h

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

* Re: [PATCH3/5] tick: Simplify tick-internal.h
  2015-06-29 22:49   ` Greg KH
@ 2015-06-30  3:24     ` Preeti U Murthy
  0 siblings, 0 replies; 9+ messages in thread
From: Preeti U Murthy @ 2015-06-30  3:24 UTC (permalink / raw)
  To: Greg KH; +Cc: stable, mingo, linux

On 06/30/2015 04:19 AM, Greg KH wrote:
> On Wed, May 13, 2015 at 05:20:23PM +0530, Preeti U Murthy wrote:
>> From: Thomas Gleixner <tglx@linutronix.de>
>>
>> commit b7475eb599ddb2e8cab2dc86ff38a9507463ad6b upstream
>>
>> tick-internal.h is pretty confusing as a lot of the stub inlines
>> are there several times.
>>
>> Distangle the maze and make clear functional sections.
>>
>> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
>> [ rjw: Subject ]
>> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>> Cc: Peter Zijlstra <peterz@infradead.org>
>> Link: http://lkml.kernel.org/r/16068264.vcNp79HLaT@vostro.rjw.lan
>> Signed-off-by: Ingo Molnar <mingo@kernel.org>
>> Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
> 
> You don't mention that you changed this function from what it is
> upstream, which isn't ok to do without a good reason.
> 
> I'm really not liking this series, it's very intrusive for almost no
> gain.  In other words, you have a very specific platform, with limited
> users, and a limited use case, yet are asking for core timer functions
> to be made for a kernel that I'm going to stop maintaining after the
> next release.
> 
> In other words, these patches are going to only have a lifespan of 1
> more week, max.  By then, all your users should be on 4.1, so 4.0
> doesn't matter anymore.
> 
> So I'm just going to drop this whole series, sorry.  If you have a
> distro that "has to have these", then please work with them, otherwise,
> just use 4.1, as all is good, and most importantly, properly tested,
> there.

Fair enough. Thanks.

Regards
Preeti U Murthy
> 
> thanks,
> 
> greg k-h
> 


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

end of thread, other threads:[~2015-06-30  3:24 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-13 11:49 [PATCH 0/5] Fix race in hrtimer broadcast and take care of dependencies Preeti U Murthy
2015-05-13 11:50 ` [PATCH1/5] clockevents: Remove CONFIG_GENERIC_CLOCKEVENTS_BUILD Preeti U Murthy
2015-05-13 11:50 ` [PATCH2/5] tick: Move clocksource related stuff to timekeeping.h Preeti U Murthy
2015-05-13 11:50 ` [PATCH3/5] tick: Simplify tick-internal.h Preeti U Murthy
2015-06-29 22:49   ` Greg KH
2015-06-30  3:24     ` Preeti U Murthy
2015-05-13 11:50 ` [PATCH4/5] tick: Move core only declarations and functions to core Preeti U Murthy
2015-05-13 11:50 ` [PATCH5/5] clockevents: Fix cpu_down() race for hrtimer based broadcasting Preeti U Murthy
2015-06-18  8:06 ` [PATCH 0/5] Fix race in hrtimer broadcast and take care of dependencies Preeti U Murthy

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).