* [PATCH 00/09] Some kernel/time cleanups (related to timer_suspend/resume)
[not found] <20150216121435.203983131@infradead.org>
@ 2015-03-25 12:04 ` Rafael J. Wysocki
2015-03-25 12:05 ` [PATCH 01/09] clockevents: Remove CONFIG_GENERIC_CLOCKEVENTS_BUILD Rafael J. Wysocki
` (10 more replies)
0 siblings, 11 replies; 19+ messages in thread
From: Rafael J. Wysocki @ 2015-03-25 12:04 UTC (permalink / raw)
To: Peter Zijlstra; +Cc: linux-kernel, mingo, tglx, Linux PM list
Hi,
On Monday, February 16, 2015 01:14:35 PM Peter Zijlstra wrote:
> Hi,
>
> While working with Rafael on the suspend to idle machinery Thomas made these
> cleanups; since one might as well clean code up while you've done the work of
> thinking through it again.
>
> As it stands there's very little overlap between Rafael's series and this one
> aside from a few trivial fixups. So we'll merge them seperately.
Since some of the original Thomas' patches needed to be rebased on top of the
suspend-to-idle material that went in during the 4.0 merge window, I did
that with the patches related to the suspending/resuming of ticks which
follow.
Thanks,
Rafael
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 01/09] clockevents: Remove CONFIG_GENERIC_CLOCKEVENTS_BUILD
2015-03-25 12:04 ` [PATCH 00/09] Some kernel/time cleanups (related to timer_suspend/resume) Rafael J. Wysocki
@ 2015-03-25 12:05 ` Rafael J. Wysocki
2015-03-25 12:06 ` [PATCH 02/09] tick: Move clocksource related stuff to timekeeping.h Rafael J. Wysocki
` (9 subsequent siblings)
10 siblings, 0 replies; 19+ messages in thread
From: Rafael J. Wysocki @ 2015-03-25 12:05 UTC (permalink / raw)
To: Peter Zijlstra; +Cc: linux-kernel, mingo, tglx, Linux PM list
From: Thomas Gleixner <tglx@linutronix.de>
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>
---
include/linux/clockchips.h | 9 +++------
kernel/time/Kconfig | 6 ------
kernel/time/Makefile | 6 ++----
kernel/time/clockevents.c | 3 ---
kernel/time/tick-internal.h | 4 ++--
5 files changed, 7 insertions(+), 21 deletions(-)
Index: linux-pm/include/linux/clockchips.h
===================================================================
--- linux-pm.orig/include/linux/clockchips.h
+++ linux-pm/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_e
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) {}
@@ -208,6 +204,7 @@ static inline void clockevents_resume(vo
static inline int clockevents_notify(unsigned long reason, void *arg) { return 0; }
static inline int tick_check_broadcast_expired(void) { return 0; }
static inline void tick_setup_hrtimer_broadcast(void) {};
+static inline int clockevents_notify(unsigned long reason, void *arg) { return 0; }
#endif
Index: linux-pm/kernel/time/Kconfig
===================================================================
--- linux-pm.orig/kernel/time/Kconfig
+++ linux-pm/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
Index: linux-pm/kernel/time/Makefile
===================================================================
--- linux-pm.orig/kernel/time/Makefile
+++ linux-pm/kernel/time/Makefile
@@ -2,15 +2,13 @@ obj-y += time.o timer.o hrtimer.o itimer
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
Index: linux-pm/kernel/time/clockevents.c
===================================================================
--- linux-pm.orig/kernel/time/clockevents.c
+++ linux-pm/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
}
device_initcall(clockevents_init_sysfs);
#endif /* SYSFS */
-
-#endif /* GENERIC_CLOCK_EVENTS */
Index: linux-pm/kernel/time/tick-internal.h
===================================================================
--- linux-pm.orig/kernel/time/tick-internal.h
+++ linux-pm/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_functio
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 [flat|nested] 19+ messages in thread
* [PATCH 02/09] tick: Move clocksource related stuff to timekeeping.h
2015-03-25 12:04 ` [PATCH 00/09] Some kernel/time cleanups (related to timer_suspend/resume) Rafael J. Wysocki
2015-03-25 12:05 ` [PATCH 01/09] clockevents: Remove CONFIG_GENERIC_CLOCKEVENTS_BUILD Rafael J. Wysocki
@ 2015-03-25 12:06 ` Rafael J. Wysocki
2015-03-25 12:06 ` [PATCH 03/09] tick: Simplify tick-internal.h Rafael J. Wysocki
` (8 subsequent siblings)
10 siblings, 0 replies; 19+ messages in thread
From: Rafael J. Wysocki @ 2015-03-25 12:06 UTC (permalink / raw)
To: Peter Zijlstra; +Cc: linux-kernel, mingo, tglx, Linux PM list
From: Thomas Gleixner <tglx@linutronix.de>
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>
---
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(-)
Index: linux-pm/kernel/time/clocksource.c
===================================================================
--- linux-pm.orig/kernel/time/clocksource.c
+++ linux-pm/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"
/**
Index: linux-pm/kernel/time/jiffies.c
===================================================================
--- linux-pm.orig/kernel/time/jiffies.c
+++ linux-pm/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
Index: linux-pm/kernel/time/ntp.c
===================================================================
--- linux-pm.orig/kernel/time/ntp.c
+++ linux-pm/kernel/time/ntp.c
@@ -17,7 +17,6 @@
#include <linux/module.h>
#include <linux/rtc.h>
-#include "tick-internal.h"
#include "ntp_internal.h"
/*
Index: linux-pm/kernel/time/tick-internal.h
===================================================================
--- linux-pm.orig/kernel/time/tick-internal.h
+++ linux-pm/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 clo
#endif /* GENERIC_CLOCKEVENTS */
-extern void do_timer(unsigned long ticks);
-extern void update_wall_time(void);
Index: linux-pm/kernel/time/timekeeping.h
===================================================================
--- linux-pm.orig/kernel/time/timekeeping.h
+++ linux-pm/kernel/time/timekeeping.h
@@ -19,4 +19,11 @@ extern void timekeeping_clocktai(struct
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 [flat|nested] 19+ messages in thread
* [PATCH 03/09] tick: Simplify tick-internal.h
2015-03-25 12:04 ` [PATCH 00/09] Some kernel/time cleanups (related to timer_suspend/resume) Rafael J. Wysocki
2015-03-25 12:05 ` [PATCH 01/09] clockevents: Remove CONFIG_GENERIC_CLOCKEVENTS_BUILD Rafael J. Wysocki
2015-03-25 12:06 ` [PATCH 02/09] tick: Move clocksource related stuff to timekeeping.h Rafael J. Wysocki
@ 2015-03-25 12:06 ` Rafael J. Wysocki
2015-03-25 12:07 ` [PATCH 04/09] tick: Move core only declarations and functions to core Rafael J. Wysocki
` (7 subsequent siblings)
10 siblings, 0 replies; 19+ messages in thread
From: Rafael J. Wysocki @ 2015-03-25 12:06 UTC (permalink / raw)
To: Peter Zijlstra; +Cc: linux-kernel, mingo, tglx, Linux PM list
From: Thomas Gleixner <tglx@linutronix.de>
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>
---
kernel/time/tick-internal.h | 145 ++++++++++++++------------------------------
1 file changed, 49 insertions(+), 96 deletions(-)
Index: linux-pm/kernel/time/tick-internal.h
===================================================================
--- linux-pm.orig/kernel/time/tick-internal.h
+++ linux-pm/kernel/time/tick-internal.h
@@ -27,13 +27,18 @@ extern bool tick_check_replacement(struc
struct clock_event_device *newdev);
extern void tick_install_replacement(struct clock_event_device *dev);
-extern void clockevents_shutdown(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 ex
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(unsi
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 [flat|nested] 19+ messages in thread
* [PATCH 04/09] tick: Move core only declarations and functions to core
2015-03-25 12:04 ` [PATCH 00/09] Some kernel/time cleanups (related to timer_suspend/resume) Rafael J. Wysocki
` (2 preceding siblings ...)
2015-03-25 12:06 ` [PATCH 03/09] tick: Simplify tick-internal.h Rafael J. Wysocki
@ 2015-03-25 12:07 ` Rafael J. Wysocki
2015-03-25 12:08 ` [PATCH 05/09] clockevents: Remove extra local_irq_save in clockevents_exchange_device() Rafael J. Wysocki
` (6 subsequent siblings)
10 siblings, 0 replies; 19+ messages in thread
From: Rafael J. Wysocki @ 2015-03-25 12:07 UTC (permalink / raw)
To: Peter Zijlstra; +Cc: linux-kernel, mingo, tglx, Linux PM list, Nicolas Pitre
From: Thomas Gleixner <tglx@linutronix.de>
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>
Cc: Nicolas Pitre <nico@linaro.org>
[ rjw: Rebased on top of 4.0-rc5 ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.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(-)
Index: linux-pm/include/linux/clockchips.h
===================================================================
--- linux-pm.orig/include/linux/clockchips.h
+++ linux-pm/include/linux/clockchips.h
@@ -158,15 +158,6 @@ extern void clockevents_config_and_regis
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
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 mode);
+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);
Index: linux-pm/include/linux/tick.h
===================================================================
--- linux-pm.orig/include/linux/tick.h
+++ linux-pm/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_slee
}
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;
Index: linux-pm/kernel/time/clocksource.c
===================================================================
--- linux-pm.orig/kernel/time/clocksource.c
+++ linux-pm/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"
/**
Index: linux-pm/kernel/time/hrtimer.c
===================================================================
--- linux-pm.orig/kernel/time/hrtimer.c
+++ linux-pm/kernel/time/hrtimer.c
@@ -54,7 +54,7 @@
#include <trace/events/timer.h>
-#include "timekeeping.h"
+#include "tick-internal.h"
/*
* The timer bases:
Index: linux-pm/kernel/time/tick-internal.h
===================================================================
--- linux-pm.orig/kernel/time/tick-internal.h
+++ linux-pm/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_functio
}
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(v
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
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; }
Index: linux-pm/kernel/time/tick-sched.c
===================================================================
--- linux-pm.orig/kernel/time/tick-sched.c
+++ linux-pm/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 *
__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
*
Index: linux-pm/kernel/time/tick-sched.h
===================================================================
--- /dev/null
+++ linux-pm/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
Index: linux-pm/kernel/time/timer_list.c
===================================================================
--- linux-pm.orig/kernel/time/timer_list.c
+++ linux-pm/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 [flat|nested] 19+ messages in thread
* [PATCH 05/09] clockevents: Remove extra local_irq_save in clockevents_exchange_device()
2015-03-25 12:04 ` [PATCH 00/09] Some kernel/time cleanups (related to timer_suspend/resume) Rafael J. Wysocki
` (3 preceding siblings ...)
2015-03-25 12:07 ` [PATCH 04/09] tick: Move core only declarations and functions to core Rafael J. Wysocki
@ 2015-03-25 12:08 ` Rafael J. Wysocki
2015-03-25 12:09 ` [PATCH 06/09] clockevents: Make suspend/resume calls explicit Rafael J. Wysocki
` (5 subsequent siblings)
10 siblings, 0 replies; 19+ messages in thread
From: Rafael J. Wysocki @ 2015-03-25 12:08 UTC (permalink / raw)
To: Peter Zijlstra; +Cc: linux-kernel, mingo, tglx, Linux PM list
From: Thomas Gleixner <tglx@linutronix.de>
Called with clockevents_lock held and interrupts disabled already.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
kernel/time/clockevents.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
Index: linux/kernel/time/clockevents.c
===================================================================
--- linux.orig/kernel/time/clockevents.c
+++ linux/kernel/time/clockevents.c
@@ -491,14 +491,12 @@ void clockevents_handle_noop(struct cloc
* @old: device to release (can be NULL)
* @new: device to request (can be NULL)
*
- * Called from the notifier chain. clockevents_lock is held already
+ * Called from various tick functions with clockevents_lock held and
+ * interrupts disabled.
*/
void clockevents_exchange_device(struct clock_event_device *old,
struct clock_event_device *new)
{
- unsigned long flags;
-
- local_irq_save(flags);
/*
* Caller releases a clock event device. We queue it into the
* released list and do a notify add later.
@@ -514,7 +512,6 @@ void clockevents_exchange_device(struct
BUG_ON(new->mode != CLOCK_EVT_MODE_UNUSED);
clockevents_shutdown(new);
}
- local_irq_restore(flags);
}
/**
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 06/09] clockevents: Make suspend/resume calls explicit
2015-03-25 12:04 ` [PATCH 00/09] Some kernel/time cleanups (related to timer_suspend/resume) Rafael J. Wysocki
` (4 preceding siblings ...)
2015-03-25 12:08 ` [PATCH 05/09] clockevents: Remove extra local_irq_save in clockevents_exchange_device() Rafael J. Wysocki
@ 2015-03-25 12:09 ` Rafael J. Wysocki
2015-03-25 12:09 ` [PATCH 07/09] tick: Make tick_resume_broadcast_oneshot static Rafael J. Wysocki
` (4 subsequent siblings)
10 siblings, 0 replies; 19+ messages in thread
From: Rafael J. Wysocki @ 2015-03-25 12:09 UTC (permalink / raw)
To: Peter Zijlstra; +Cc: linux-kernel, mingo, tglx, Linux PM 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 suspend/resume() calls and invoke them
directly from the call sites.
No locking required at this point because these calls happen with
interrupts disabled and a single cpu online.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
[ rjw: Rebased on top of 4.0-rc5 ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
arch/x86/xen/suspend.c | 11 ++++-------
include/linux/clockchips.h | 2 --
include/linux/tick.h | 3 +++
kernel/time/clockevents.c | 9 ---------
kernel/time/tick-common.c | 26 +++++++++++++++++++++++---
kernel/time/tick-internal.h | 3 ++-
kernel/time/timekeeping.c | 6 ++----
7 files changed, 34 insertions(+), 26 deletions(-)
Index: linux-pm/arch/x86/xen/suspend.c
===================================================================
--- linux-pm.orig/arch/x86/xen/suspend.c
+++ linux-pm/arch/x86/xen/suspend.c
@@ -1,5 +1,5 @@
#include <linux/types.h>
-#include <linux/clockchips.h>
+#include <linux/tick.h>
#include <xen/interface/xen.h>
#include <xen/grant_table.h>
@@ -81,17 +81,14 @@ void xen_arch_post_suspend(int cancelled
static void xen_vcpu_notify_restore(void *data)
{
- unsigned long reason = (unsigned long)data;
-
/* Boot processor notified via generic timekeeping_resume() */
- if ( smp_processor_id() == 0)
+ if (smp_processor_id() == 0)
return;
- clockevents_notify(reason, NULL);
+ tick_resume();
}
void xen_arch_resume(void)
{
- on_each_cpu(xen_vcpu_notify_restore,
- (void *)CLOCK_EVT_NOTIFY_RESUME, 1);
+ on_each_cpu(xen_vcpu_notify_restore, NULL, 1);
}
Index: linux-pm/include/linux/clockchips.h
===================================================================
--- linux-pm.orig/include/linux/clockchips.h
+++ linux-pm/include/linux/clockchips.h
@@ -16,8 +16,6 @@ enum clock_event_nofitiers {
CLOCK_EVT_NOTIFY_BROADCAST_FORCE,
CLOCK_EVT_NOTIFY_BROADCAST_ENTER,
CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
- CLOCK_EVT_NOTIFY_SUSPEND,
- CLOCK_EVT_NOTIFY_RESUME,
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
@@ -29,10 +29,13 @@ extern struct tick_device *tick_get_devi
extern void __init tick_init(void);
extern void tick_freeze(void);
extern void tick_unfreeze(void);
+/* Should be core only, but XEN resume magic abuses this interface */
+extern void tick_resume(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_resume(void) { }
#endif /* !CONFIG_GENERIC_CLOCKEVENTS */
#ifdef CONFIG_TICK_ONESHOT
Index: linux-pm/kernel/time/clockevents.c
===================================================================
--- linux-pm.orig/kernel/time/clockevents.c
+++ linux-pm/kernel/time/clockevents.c
@@ -566,15 +566,6 @@ int clockevents_notify(unsigned long rea
tick_handover_do_timer(arg);
break;
- case CLOCK_EVT_NOTIFY_SUSPEND:
- tick_suspend();
- tick_suspend_broadcast();
- break;
-
- case CLOCK_EVT_NOTIFY_RESUME:
- tick_resume();
- break;
-
case CLOCK_EVT_NOTIFY_CPU_DEAD:
tick_shutdown_broadcast_oneshot(arg);
tick_shutdown_broadcast(arg);
Index: linux-pm/kernel/time/tick-common.c
===================================================================
--- linux-pm.orig/kernel/time/tick-common.c
+++ linux-pm/kernel/time/tick-common.c
@@ -372,18 +372,39 @@ void tick_shutdown(unsigned int *cpup)
}
}
+/**
+ * tick_suspend - Suspend the tick and the broadcast device
+ *
+ * Called from syscore_suspend() via timekeeping_suspend with only one
+ * CPU online and interrupts disabled or from tick_unfreeze() under
+ * tick_freeze_lock.
+ *
+ * No locks required. Nothing can change the per cpu device.
+ */
void tick_suspend(void)
{
struct tick_device *td = this_cpu_ptr(&tick_cpu_device);
clockevents_shutdown(td->evtdev);
+ tick_suspend_broadcast();
}
+/**
+ * tick_resume - Resume the tick and the broadcast device
+ *
+ * Called from syscore_resume() via timekeeping_resume with only one
+ * CPU online and interrupts disabled or from tick_unfreeze() under
+ * tick_freeze_lock.
+ *
+ * No locks required. Nothing can change the per cpu device.
+ */
void tick_resume(void)
{
- struct tick_device *td = this_cpu_ptr(&tick_cpu_device);
- int broadcast = tick_resume_broadcast();
+ struct tick_device *td;
+ int broadcast;
+ broadcast = tick_resume_broadcast();
+ td = this_cpu_ptr(&tick_cpu_device);
clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_RESUME);
if (!broadcast) {
@@ -420,7 +441,6 @@ void tick_freeze(void)
timekeeping_suspend_count++;
} else {
tick_suspend();
- tick_suspend_broadcast();
}
raw_spin_unlock(&tick_freeze_lock);
Index: linux-pm/kernel/time/tick-internal.h
===================================================================
--- linux-pm.orig/kernel/time/tick-internal.h
+++ linux-pm/kernel/time/tick-internal.h
@@ -23,7 +23,6 @@ extern void tick_check_new_device(struct
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);
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);
@@ -41,6 +40,8 @@ extern void clockevents_exchange_device(
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);
+#else
+static inline void tick_suspend(void) { }
#endif /* GENERIC_CLOCKEVENTS */
/* Oneshot related functions */
Index: linux-pm/kernel/time/timekeeping.c
===================================================================
--- linux-pm.orig/kernel/time/timekeeping.c
+++ linux-pm/kernel/time/timekeeping.c
@@ -1272,9 +1272,7 @@ void timekeeping_resume(void)
touch_softlockup_watchdog();
- clockevents_notify(CLOCK_EVT_NOTIFY_RESUME, NULL);
-
- /* Resume hrtimers */
+ tick_resume();
hrtimers_resume();
}
@@ -1327,7 +1325,7 @@ int timekeeping_suspend(void)
write_seqcount_end(&tk_core.seq);
raw_spin_unlock_irqrestore(&timekeeper_lock, flags);
- clockevents_notify(CLOCK_EVT_NOTIFY_SUSPEND, NULL);
+ tick_suspend();
clocksource_suspend();
clockevents_suspend();
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 07/09] tick: Make tick_resume_broadcast_oneshot static
2015-03-25 12:04 ` [PATCH 00/09] Some kernel/time cleanups (related to timer_suspend/resume) Rafael J. Wysocki
` (5 preceding siblings ...)
2015-03-25 12:09 ` [PATCH 06/09] clockevents: Make suspend/resume calls explicit Rafael J. Wysocki
@ 2015-03-25 12:09 ` Rafael J. Wysocki
2015-03-25 12:11 ` [PATCH 08/09] tick/xen: Provide and use tick_suspend_local() and tick_resume_local() Rafael J. Wysocki
` (3 subsequent siblings)
10 siblings, 0 replies; 19+ messages in thread
From: Rafael J. Wysocki @ 2015-03-25 12:09 UTC (permalink / raw)
To: Peter Zijlstra; +Cc: linux-kernel, mingo, tglx, Linux PM list
From: Thomas Gleixner <tglx@linutronix.de>
Solely used in tick-broadcast.c and the return value is hardcoded 0.
Make it static and void.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
kernel/time/tick-broadcast.c | 7 ++++---
kernel/time/tick-internal.h | 2 --
2 files changed, 4 insertions(+), 5 deletions(-)
Index: linux-pm/kernel/time/tick-broadcast.c
===================================================================
--- linux-pm.orig/kernel/time/tick-broadcast.c
+++ linux-pm/kernel/time/tick-broadcast.c
@@ -37,8 +37,10 @@ static int tick_broadcast_force;
#ifdef CONFIG_TICK_ONESHOT
static void tick_broadcast_clear_oneshot(int cpu);
+static void tick_resume_broadcast_oneshot(struct clock_event_device *bc);
#else
static inline void tick_broadcast_clear_oneshot(int cpu) { }
+static inline void tick_resume_broadcast_oneshot(struct clock_event_device *bc) { }
#endif
/*
@@ -475,7 +477,7 @@ int tick_resume_broadcast(void)
break;
case TICKDEV_MODE_ONESHOT:
if (!cpumask_empty(tick_broadcast_mask))
- broadcast = tick_resume_broadcast_oneshot(bc);
+ tick_resume_broadcast_oneshot(bc);
break;
}
}
@@ -541,10 +543,9 @@ static int tick_broadcast_set_event(stru
return ret;
}
-int tick_resume_broadcast_oneshot(struct clock_event_device *bc)
+static void tick_resume_broadcast_oneshot(struct clock_event_device *bc)
{
clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT);
- return 0;
}
/*
Index: linux-pm/kernel/time/tick-internal.h
===================================================================
--- linux-pm.orig/kernel/time/tick-internal.h
+++ linux-pm/kernel/time/tick-internal.h
@@ -111,7 +111,6 @@ extern void tick_broadcast_setup_oneshot
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);
@@ -121,7 +120,6 @@ static inline void tick_broadcast_setup_
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(); }
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 08/09] tick/xen: Provide and use tick_suspend_local() and tick_resume_local()
2015-03-25 12:04 ` [PATCH 00/09] Some kernel/time cleanups (related to timer_suspend/resume) Rafael J. Wysocki
` (6 preceding siblings ...)
2015-03-25 12:09 ` [PATCH 07/09] tick: Make tick_resume_broadcast_oneshot static Rafael J. Wysocki
@ 2015-03-25 12:11 ` Rafael J. Wysocki
2015-03-25 20:13 ` Konrad Rzeszutek Wilk
[not found] ` <tip-f46481d0a7cb942b84145acb80ad43bdb1ff8eb4@git.kernel.org>
2015-03-25 12:11 ` [PATCH 09/09] arm: bl_switcher: Kill tick suspend hackery Rafael J. Wysocki
` (2 subsequent siblings)
10 siblings, 2 replies; 19+ messages in thread
From: Rafael J. Wysocki @ 2015-03-25 12:11 UTC (permalink / raw)
To: Peter Zijlstra
Cc: linux-kernel, mingo, tglx, Linux PM list, Konrad Rzeszutek Wilk,
Boris Ostrovsky, David Vrabel
From: Thomas Gleixner <tglx@linutronix.de>
Xen calls on every cpu into tick_resume() which is just wrong.
tick_resume() is for the syscore global suspend/resume invocation.
What XEN really wants is a per cpu local resume function.
Provide a tick_resume_local() function and use it in XEN.
Also provide a complementary tick_suspend_local() and modify
tick_unfreeze() and tick_freeze(), respectively, to use the
new local tick resume/suspend functions.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: David Vrabel <david.vrabel@citrix.com>
[ rjw: Combined two patches, rebased, modified subject/changelog ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
arch/x86/xen/suspend.c | 2 -
include/linux/tick.h | 6 ++--
kernel/time/tick-broadcast.c | 24 ++++++++++++------
kernel/time/tick-common.c | 57 +++++++++++++++++++++++++++++--------------
kernel/time/tick-internal.h | 8 ++++--
5 files changed, 66 insertions(+), 31 deletions(-)
Index: linux-pm/arch/x86/xen/suspend.c
===================================================================
--- linux-pm.orig/arch/x86/xen/suspend.c
+++ linux-pm/arch/x86/xen/suspend.c
@@ -85,7 +85,7 @@ static void xen_vcpu_notify_restore(void
if (smp_processor_id() == 0)
return;
- tick_resume();
+ tick_resume_local();
}
void xen_arch_resume(void)
Index: linux-pm/include/linux/tick.h
===================================================================
--- linux-pm.orig/include/linux/tick.h
+++ linux-pm/include/linux/tick.h
@@ -29,13 +29,13 @@ extern struct tick_device *tick_get_devi
extern void __init tick_init(void);
extern void tick_freeze(void);
extern void tick_unfreeze(void);
-/* Should be core only, but XEN resume magic abuses this interface */
-extern void tick_resume(void);
+/* Should be core only, but XEN resume magic requires this */
+extern void tick_resume_local(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_resume(void) { }
+static inline void tick_resume_local(void) { }
#endif /* !CONFIG_GENERIC_CLOCKEVENTS */
#ifdef CONFIG_TICK_ONESHOT
Index: linux-pm/kernel/time/tick-broadcast.c
===================================================================
--- linux-pm.orig/kernel/time/tick-broadcast.c
+++ linux-pm/kernel/time/tick-broadcast.c
@@ -455,11 +455,26 @@ void tick_suspend_broadcast(void)
raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
}
-int tick_resume_broadcast(void)
+/*
+ * This is called from tick_resume_local() on a resuming CPU. That's
+ * called from the core resume function, tick_unfreeze() and the magic XEN
+ * resume hackery.
+ *
+ * In none of these cases the broadcast device mode can change and the
+ * bit of the resuming CPU in the broadcast mask is safe as well.
+ */
+bool tick_resume_check_broadcast(void)
+{
+ if (tick_broadcast_device.mode == TICKDEV_MODE_ONESHOT)
+ return false;
+ else
+ return cpumask_test_cpu(smp_processor_id(), tick_broadcast_mask);
+}
+
+void tick_resume_broadcast(void)
{
struct clock_event_device *bc;
unsigned long flags;
- int broadcast = 0;
raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
@@ -472,8 +487,6 @@ int tick_resume_broadcast(void)
case TICKDEV_MODE_PERIODIC:
if (!cpumask_empty(tick_broadcast_mask))
tick_broadcast_start_periodic(bc);
- broadcast = cpumask_test_cpu(smp_processor_id(),
- tick_broadcast_mask);
break;
case TICKDEV_MODE_ONESHOT:
if (!cpumask_empty(tick_broadcast_mask))
@@ -482,11 +495,8 @@ int tick_resume_broadcast(void)
}
}
raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
-
- return broadcast;
}
-
#ifdef CONFIG_TICK_ONESHOT
static cpumask_var_t tick_broadcast_oneshot_mask;
Index: linux-pm/kernel/time/tick-common.c
===================================================================
--- linux-pm.orig/kernel/time/tick-common.c
+++ linux-pm/kernel/time/tick-common.c
@@ -373,40 +373,32 @@ void tick_shutdown(unsigned int *cpup)
}
/**
- * tick_suspend - Suspend the tick and the broadcast device
+ * tick_suspend_local - Suspend the local tick device
*
- * Called from syscore_suspend() via timekeeping_suspend with only one
- * CPU online and interrupts disabled or from tick_unfreeze() under
- * tick_freeze_lock.
+ * Called from the local cpu for freeze with interrupts disabled.
*
* No locks required. Nothing can change the per cpu device.
*/
-void tick_suspend(void)
+static void tick_suspend_local(void)
{
struct tick_device *td = this_cpu_ptr(&tick_cpu_device);
clockevents_shutdown(td->evtdev);
- tick_suspend_broadcast();
}
/**
- * tick_resume - Resume the tick and the broadcast device
+ * tick_resume_local - Resume the local tick device
*
- * Called from syscore_resume() via timekeeping_resume with only one
- * CPU online and interrupts disabled or from tick_unfreeze() under
- * tick_freeze_lock.
+ * Called from the local CPU for unfreeze or XEN resume magic.
*
* No locks required. Nothing can change the per cpu device.
*/
-void tick_resume(void)
+void tick_resume_local(void)
{
- struct tick_device *td;
- int broadcast;
+ struct tick_device *td = this_cpu_ptr(&tick_cpu_device);
+ bool broadcast = tick_resume_check_broadcast();
- broadcast = tick_resume_broadcast();
- td = this_cpu_ptr(&tick_cpu_device);
clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_RESUME);
-
if (!broadcast) {
if (td->mode == TICKDEV_MODE_PERIODIC)
tick_setup_periodic(td->evtdev, 0);
@@ -415,6 +407,35 @@ void tick_resume(void)
}
}
+/**
+ * tick_suspend - Suspend the tick and the broadcast device
+ *
+ * Called from syscore_suspend() via timekeeping_suspend with only one
+ * CPU online and interrupts disabled or from tick_unfreeze() under
+ * tick_freeze_lock.
+ *
+ * No locks required. Nothing can change the per cpu device.
+ */
+void tick_suspend(void)
+{
+ tick_suspend_local();
+ tick_suspend_broadcast();
+}
+
+/**
+ * tick_resume - Resume the tick and the broadcast device
+ *
+ * Called from syscore_resume() via timekeeping_resume with only one
+ * CPU online and interrupts disabled.
+ *
+ * No locks required. Nothing can change the per cpu device.
+ */
+void tick_resume(void)
+{
+ tick_resume_broadcast();
+ tick_resume_local();
+}
+
static DEFINE_RAW_SPINLOCK(tick_freeze_lock);
static unsigned int tick_freeze_depth;
@@ -440,7 +461,7 @@ void tick_freeze(void)
timekeeping_suspend();
timekeeping_suspend_count++;
} else {
- tick_suspend();
+ tick_suspend_local();
}
raw_spin_unlock(&tick_freeze_lock);
@@ -465,7 +486,7 @@ void tick_unfreeze(void)
smp_processor_id(), tick_freeze_depth,
timekeeping_suspend_count);
} else {
- tick_resume();
+ tick_resume_local();
}
tick_freeze_depth--;
Index: linux-pm/kernel/time/tick-internal.h
===================================================================
--- linux-pm.orig/kernel/time/tick-internal.h
+++ linux-pm/kernel/time/tick-internal.h
@@ -23,6 +23,7 @@ extern void tick_check_new_device(struct
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);
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);
@@ -42,6 +43,7 @@ extern int __clockevents_update_freq(str
extern ssize_t sysfs_get_uname(const char *buf, char *dst, size_t cnt);
#else
static inline void tick_suspend(void) { }
+static inline void tick_resume(void) { }
#endif /* GENERIC_CLOCKEVENTS */
/* Oneshot related functions */
@@ -80,7 +82,8 @@ extern int tick_is_broadcast_device(stru
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 int tick_resume_broadcast(void);
+extern void tick_resume_broadcast(void);
+extern bool tick_resume_check_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);
@@ -94,7 +97,8 @@ static inline void tick_do_periodic_broa
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_resume_broadcast(void) { }
+static inline bool tick_resume_check_broadcast(void) { return false; }
static inline void tick_broadcast_init(void) { }
static inline int tick_broadcast_update_freq(struct clock_event_device *dev, u32 freq) { return -ENODEV; }
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 09/09] arm: bl_switcher: Kill tick suspend hackery
2015-03-25 12:04 ` [PATCH 00/09] Some kernel/time cleanups (related to timer_suspend/resume) Rafael J. Wysocki
` (7 preceding siblings ...)
2015-03-25 12:11 ` [PATCH 08/09] tick/xen: Provide and use tick_suspend_local() and tick_resume_local() Rafael J. Wysocki
@ 2015-03-25 12:11 ` Rafael J. Wysocki
2015-03-25 12:34 ` Nicolas Pitre
2015-03-25 12:13 ` [PATCH 00/09] Some kernel/time cleanups (related to timer_suspend/resume) Rafael J. Wysocki
2015-03-31 22:45 ` [GIT PULL] kernel/time cleanups (related to tick_suspend/resume) Rafael J. Wysocki
10 siblings, 1 reply; 19+ messages in thread
From: Rafael J. Wysocki @ 2015-03-25 12:11 UTC (permalink / raw)
To: Peter Zijlstra
Cc: linux-kernel, mingo, tglx, Linux PM list, Nicolas Pitre,
Russell King
From: Thomas Gleixner <tglx@linutronix.de>
Use the new tick_suspend/resume_local() and get rid of the homebrewn
implementation of these in the ARM bL switcher. The check for the
cpumask is completely pointless. There is no harm to suspend a per
cpu tick device unconditionally. If that's a real issue then we fix
it proper at the core level and not with some completely undocumented
hacks in some random core code.
Move the tick internals to the core code, now that this nuisance is
gone.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Nicolas Pitre <nicolas.pitre@linaro.org>
Cc: Russell King <rmk+kernel@arm.linux.org.uk>
[ rjw: Rebase, changelog ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
arch/arm/common/bL_switcher.c | 16 ++--------------
include/linux/clockchips.h | 6 ------
include/linux/tick.h | 19 ++++---------------
kernel/time/tick-common.c | 2 +-
kernel/time/tick-internal.h | 5 +++++
kernel/time/tick-sched.h | 10 ++++++++++
6 files changed, 22 insertions(+), 36 deletions(-)
Index: linux-pm/include/linux/tick.h
===================================================================
--- linux-pm.orig/include/linux/tick.h
+++ linux-pm/include/linux/tick.h
@@ -11,30 +11,19 @@
#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,
-};
-
-struct tick_device {
- struct clock_event_device *evtdev;
- enum tick_device_mode mode;
-};
-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);
-/* Should be core only, but XEN resume magic requires this */
+/* Should be core only, but ARM BL switcher requires it */
+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);
#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) { }
#endif /* !CONFIG_GENERIC_CLOCKEVENTS */
Index: linux-pm/arch/arm/common/bL_switcher.c
===================================================================
--- linux-pm.orig/arch/arm/common/bL_switcher.c
+++ linux-pm/arch/arm/common/bL_switcher.c
@@ -151,8 +151,6 @@ static int bL_switch_to(unsigned int new
unsigned int mpidr, this_cpu, that_cpu;
unsigned int ob_mpidr, ob_cpu, ob_cluster, ib_mpidr, ib_cpu, ib_cluster;
struct completion inbound_alive;
- struct tick_device *tdev;
- enum clock_event_mode tdev_mode;
long volatile *handshake_ptr;
int ipi_nr, ret;
@@ -219,13 +217,7 @@ static int bL_switch_to(unsigned int new
/* redirect GIC's SGIs to our counterpart */
gic_migrate_target(bL_gic_id[ib_cpu][ib_cluster]);
- tdev = tick_get_device(this_cpu);
- if (tdev && !cpumask_equal(tdev->evtdev->cpumask, cpumask_of(this_cpu)))
- tdev = NULL;
- if (tdev) {
- tdev_mode = tdev->evtdev->mode;
- clockevents_set_mode(tdev->evtdev, CLOCK_EVT_MODE_SHUTDOWN);
- }
+ tick_suspend_local();
ret = cpu_pm_enter();
@@ -251,11 +243,7 @@ static int bL_switch_to(unsigned int new
ret = cpu_pm_exit();
- if (tdev) {
- clockevents_set_mode(tdev->evtdev, tdev_mode);
- clockevents_program_event(tdev->evtdev,
- tdev->evtdev->next_event, 1);
- }
+ tick_resume_local();
trace_cpu_migrate_finish(ktime_get_real_ns(), ib_mpidr);
local_fiq_enable();
Index: linux-pm/include/linux/clockchips.h
===================================================================
--- linux-pm.orig/include/linux/clockchips.h
+++ linux-pm/include/linux/clockchips.h
@@ -163,12 +163,6 @@ clockevents_calc_mult_shift(struct clock
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 mode);
-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);
Index: linux-pm/kernel/time/tick-internal.h
===================================================================
--- linux-pm.orig/kernel/time/tick-internal.h
+++ linux-pm/kernel/time/tick-internal.h
@@ -28,6 +28,7 @@ extern bool tick_check_replacement(struc
struct clock_event_device *newdev);
extern void tick_install_replacement(struct clock_event_device *dev);
extern int tick_is_oneshot_available(void);
+extern struct tick_device *tick_get_device(int cpu);
/* Check, if the device is functional or a dummy for broadcast */
static inline int tick_device_is_functional(struct clock_event_device *dev)
@@ -38,6 +39,10 @@ static inline int tick_device_is_functio
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_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);
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);
Index: linux-pm/kernel/time/tick-sched.h
===================================================================
--- linux-pm.orig/kernel/time/tick-sched.h
+++ linux-pm/kernel/time/tick-sched.h
@@ -3,6 +3,16 @@
#include <linux/hrtimer.h>
+enum tick_device_mode {
+ TICKDEV_MODE_PERIODIC,
+ TICKDEV_MODE_ONESHOT,
+};
+
+struct tick_device {
+ struct clock_event_device *evtdev;
+ enum tick_device_mode mode;
+};
+
enum tick_nohz_mode {
NOHZ_MODE_INACTIVE,
NOHZ_MODE_LOWRES,
Index: linux-pm/kernel/time/tick-common.c
===================================================================
--- linux-pm.orig/kernel/time/tick-common.c
+++ linux-pm/kernel/time/tick-common.c
@@ -379,7 +379,7 @@ void tick_shutdown(unsigned int *cpup)
*
* No locks required. Nothing can change the per cpu device.
*/
-static void tick_suspend_local(void)
+void tick_suspend_local(void)
{
struct tick_device *td = this_cpu_ptr(&tick_cpu_device);
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 00/09] Some kernel/time cleanups (related to timer_suspend/resume)
2015-03-25 12:04 ` [PATCH 00/09] Some kernel/time cleanups (related to timer_suspend/resume) Rafael J. Wysocki
` (8 preceding siblings ...)
2015-03-25 12:11 ` [PATCH 09/09] arm: bl_switcher: Kill tick suspend hackery Rafael J. Wysocki
@ 2015-03-25 12:13 ` Rafael J. Wysocki
2015-03-31 22:45 ` [GIT PULL] kernel/time cleanups (related to tick_suspend/resume) Rafael J. Wysocki
10 siblings, 0 replies; 19+ messages in thread
From: Rafael J. Wysocki @ 2015-03-25 12:13 UTC (permalink / raw)
To: Peter Zijlstra; +Cc: linux-kernel, mingo, tglx, Linux PM list
On Wednesday, March 25, 2015 01:04:23 PM Rafael J. Wysocki wrote:
> Hi,
>
> On Monday, February 16, 2015 01:14:35 PM Peter Zijlstra wrote:
> > Hi,
> >
> > While working with Rafael on the suspend to idle machinery Thomas made these
> > cleanups; since one might as well clean code up while you've done the work of
> > thinking through it again.
> >
> > As it stands there's very little overlap between Rafael's series and this one
> > aside from a few trivial fixups. So we'll merge them seperately.
>
> Since some of the original Thomas' patches needed to be rebased on top of the
> suspend-to-idle material that went in during the 4.0 merge window, I did
> that with the patches related to the suspending/resuming of ticks which
> follow.
I forgot to mention that I'd tested these vs suspend-to-idle and suspend-to-RAM
on a couple of different systems and they don't seem to break anything for me.
Also I have a plan to make the compilation of some PM-related stuff conditional
on CONFIG_PM_SLEEP etc. on top of these.
Rafael
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 09/09] arm: bl_switcher: Kill tick suspend hackery
2015-03-25 12:11 ` [PATCH 09/09] arm: bl_switcher: Kill tick suspend hackery Rafael J. Wysocki
@ 2015-03-25 12:34 ` Nicolas Pitre
0 siblings, 0 replies; 19+ messages in thread
From: Nicolas Pitre @ 2015-03-25 12:34 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Peter Zijlstra, linux-kernel, mingo, tglx, Linux PM list,
Russell King
On Wed, 25 Mar 2015, Rafael J. Wysocki wrote:
> From: Thomas Gleixner <tglx@linutronix.de>
>
> Use the new tick_suspend/resume_local() and get rid of the homebrewn
> implementation of these in the ARM bL switcher. The check for the
> cpumask is completely pointless. There is no harm to suspend a per
> cpu tick device unconditionally. If that's a real issue then we fix
> it proper at the core level and not with some completely undocumented
> hacks in some random core code.
>
> Move the tick internals to the core code, now that this nuisance is
> gone.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Cc: Nicolas Pitre <nicolas.pitre@linaro.org>
> Cc: Russell King <rmk+kernel@arm.linux.org.uk>
> [ rjw: Rebase, changelog ]
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Nicolas Pitre <nicolas.pitre@linaro.org>
> ---
> arch/arm/common/bL_switcher.c | 16 ++--------------
> include/linux/clockchips.h | 6 ------
> include/linux/tick.h | 19 ++++---------------
> kernel/time/tick-common.c | 2 +-
> kernel/time/tick-internal.h | 5 +++++
> kernel/time/tick-sched.h | 10 ++++++++++
> 6 files changed, 22 insertions(+), 36 deletions(-)
>
> Index: linux-pm/include/linux/tick.h
> ===================================================================
> --- linux-pm.orig/include/linux/tick.h
> +++ linux-pm/include/linux/tick.h
> @@ -11,30 +11,19 @@
> #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,
> -};
> -
> -struct tick_device {
> - struct clock_event_device *evtdev;
> - enum tick_device_mode mode;
> -};
> -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);
> -/* Should be core only, but XEN resume magic requires this */
> +/* Should be core only, but ARM BL switcher requires it */
> +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);
> #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) { }
> #endif /* !CONFIG_GENERIC_CLOCKEVENTS */
>
> Index: linux-pm/arch/arm/common/bL_switcher.c
> ===================================================================
> --- linux-pm.orig/arch/arm/common/bL_switcher.c
> +++ linux-pm/arch/arm/common/bL_switcher.c
> @@ -151,8 +151,6 @@ static int bL_switch_to(unsigned int new
> unsigned int mpidr, this_cpu, that_cpu;
> unsigned int ob_mpidr, ob_cpu, ob_cluster, ib_mpidr, ib_cpu, ib_cluster;
> struct completion inbound_alive;
> - struct tick_device *tdev;
> - enum clock_event_mode tdev_mode;
> long volatile *handshake_ptr;
> int ipi_nr, ret;
>
> @@ -219,13 +217,7 @@ static int bL_switch_to(unsigned int new
> /* redirect GIC's SGIs to our counterpart */
> gic_migrate_target(bL_gic_id[ib_cpu][ib_cluster]);
>
> - tdev = tick_get_device(this_cpu);
> - if (tdev && !cpumask_equal(tdev->evtdev->cpumask, cpumask_of(this_cpu)))
> - tdev = NULL;
> - if (tdev) {
> - tdev_mode = tdev->evtdev->mode;
> - clockevents_set_mode(tdev->evtdev, CLOCK_EVT_MODE_SHUTDOWN);
> - }
> + tick_suspend_local();
>
> ret = cpu_pm_enter();
>
> @@ -251,11 +243,7 @@ static int bL_switch_to(unsigned int new
>
> ret = cpu_pm_exit();
>
> - if (tdev) {
> - clockevents_set_mode(tdev->evtdev, tdev_mode);
> - clockevents_program_event(tdev->evtdev,
> - tdev->evtdev->next_event, 1);
> - }
> + tick_resume_local();
>
> trace_cpu_migrate_finish(ktime_get_real_ns(), ib_mpidr);
> local_fiq_enable();
> Index: linux-pm/include/linux/clockchips.h
> ===================================================================
> --- linux-pm.orig/include/linux/clockchips.h
> +++ linux-pm/include/linux/clockchips.h
> @@ -163,12 +163,6 @@ clockevents_calc_mult_shift(struct clock
> 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 mode);
> -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);
>
> Index: linux-pm/kernel/time/tick-internal.h
> ===================================================================
> --- linux-pm.orig/kernel/time/tick-internal.h
> +++ linux-pm/kernel/time/tick-internal.h
> @@ -28,6 +28,7 @@ extern bool tick_check_replacement(struc
> struct clock_event_device *newdev);
> extern void tick_install_replacement(struct clock_event_device *dev);
> extern int tick_is_oneshot_available(void);
> +extern struct tick_device *tick_get_device(int cpu);
>
> /* Check, if the device is functional or a dummy for broadcast */
> static inline int tick_device_is_functional(struct clock_event_device *dev)
> @@ -38,6 +39,10 @@ static inline int tick_device_is_functio
> 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_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);
> 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);
> Index: linux-pm/kernel/time/tick-sched.h
> ===================================================================
> --- linux-pm.orig/kernel/time/tick-sched.h
> +++ linux-pm/kernel/time/tick-sched.h
> @@ -3,6 +3,16 @@
>
> #include <linux/hrtimer.h>
>
> +enum tick_device_mode {
> + TICKDEV_MODE_PERIODIC,
> + TICKDEV_MODE_ONESHOT,
> +};
> +
> +struct tick_device {
> + struct clock_event_device *evtdev;
> + enum tick_device_mode mode;
> +};
> +
> enum tick_nohz_mode {
> NOHZ_MODE_INACTIVE,
> NOHZ_MODE_LOWRES,
> Index: linux-pm/kernel/time/tick-common.c
> ===================================================================
> --- linux-pm.orig/kernel/time/tick-common.c
> +++ linux-pm/kernel/time/tick-common.c
> @@ -379,7 +379,7 @@ void tick_shutdown(unsigned int *cpup)
> *
> * No locks required. Nothing can change the per cpu device.
> */
> -static void tick_suspend_local(void)
> +void tick_suspend_local(void)
> {
> struct tick_device *td = this_cpu_ptr(&tick_cpu_device);
>
>
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 08/09] tick/xen: Provide and use tick_suspend_local() and tick_resume_local()
2015-03-25 12:11 ` [PATCH 08/09] tick/xen: Provide and use tick_suspend_local() and tick_resume_local() Rafael J. Wysocki
@ 2015-03-25 20:13 ` Konrad Rzeszutek Wilk
2015-03-25 20:57 ` Rafael J. Wysocki
[not found] ` <tip-f46481d0a7cb942b84145acb80ad43bdb1ff8eb4@git.kernel.org>
1 sibling, 1 reply; 19+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-03-25 20:13 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Peter Zijlstra, linux-kernel, mingo, tglx, Linux PM list,
Boris Ostrovsky, David Vrabel
On Wed, Mar 25, 2015 at 01:11:04PM +0100, Rafael J. Wysocki wrote:
> From: Thomas Gleixner <tglx@linutronix.de>
>
> Xen calls on every cpu into tick_resume() which is just wrong.
> tick_resume() is for the syscore global suspend/resume invocation.
> What XEN really wants is a per cpu local resume function.
>
> Provide a tick_resume_local() function and use it in XEN.
>
> Also provide a complementary tick_suspend_local() and modify
> tick_unfreeze() and tick_freeze(), respectively, to use the
> new local tick resume/suspend functions.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
> Cc: David Vrabel <david.vrabel@citrix.com>
> [ rjw: Combined two patches, rebased, modified subject/changelog ]
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
> arch/x86/xen/suspend.c | 2 -
> include/linux/tick.h | 6 ++--
> kernel/time/tick-broadcast.c | 24 ++++++++++++------
> kernel/time/tick-common.c | 57 +++++++++++++++++++++++++++++--------------
> kernel/time/tick-internal.h | 8 ++++--
> 5 files changed, 66 insertions(+), 31 deletions(-)
>
> Index: linux-pm/arch/x86/xen/suspend.c
> ===================================================================
> --- linux-pm.orig/arch/x86/xen/suspend.c
> +++ linux-pm/arch/x86/xen/suspend.c
> @@ -85,7 +85,7 @@ static void xen_vcpu_notify_restore(void
> if (smp_processor_id() == 0)
> return;
>
> - tick_resume();
> + tick_resume_local();
I am looking at Linus's tree and I see:
82 static void xen_vcpu_notify_restore(void *data)
83 {
84 unsigned long reason = (unsigned long)data;
85
86 /* Boot processor notified via generic timekeeping_resume() */
87 if ( smp_processor_id() == 0)
88 return;
89
90 clockevents_notify(reason, NULL);
91 }
So there must be another patch that altered the clockevents_notify?
Is there an git tree with all of these patches?
> }
>
> void xen_arch_resume(void)
> Index: linux-pm/include/linux/tick.h
> ===================================================================
> --- linux-pm.orig/include/linux/tick.h
> +++ linux-pm/include/linux/tick.h
> @@ -29,13 +29,13 @@ extern struct tick_device *tick_get_devi
> extern void __init tick_init(void);
> extern void tick_freeze(void);
> extern void tick_unfreeze(void);
> -/* Should be core only, but XEN resume magic abuses this interface */
> -extern void tick_resume(void);
> +/* Should be core only, but XEN resume magic requires this */
> +extern void tick_resume_local(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_resume(void) { }
> +static inline void tick_resume_local(void) { }
> #endif /* !CONFIG_GENERIC_CLOCKEVENTS */
>
> #ifdef CONFIG_TICK_ONESHOT
> Index: linux-pm/kernel/time/tick-broadcast.c
> ===================================================================
> --- linux-pm.orig/kernel/time/tick-broadcast.c
> +++ linux-pm/kernel/time/tick-broadcast.c
> @@ -455,11 +455,26 @@ void tick_suspend_broadcast(void)
> raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
> }
>
> -int tick_resume_broadcast(void)
> +/*
> + * This is called from tick_resume_local() on a resuming CPU. That's
> + * called from the core resume function, tick_unfreeze() and the magic XEN
> + * resume hackery.
> + *
> + * In none of these cases the broadcast device mode can change and the
> + * bit of the resuming CPU in the broadcast mask is safe as well.
> + */
> +bool tick_resume_check_broadcast(void)
> +{
> + if (tick_broadcast_device.mode == TICKDEV_MODE_ONESHOT)
> + return false;
> + else
> + return cpumask_test_cpu(smp_processor_id(), tick_broadcast_mask);
> +}
> +
> +void tick_resume_broadcast(void)
> {
> struct clock_event_device *bc;
> unsigned long flags;
> - int broadcast = 0;
>
> raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
>
> @@ -472,8 +487,6 @@ int tick_resume_broadcast(void)
> case TICKDEV_MODE_PERIODIC:
> if (!cpumask_empty(tick_broadcast_mask))
> tick_broadcast_start_periodic(bc);
> - broadcast = cpumask_test_cpu(smp_processor_id(),
> - tick_broadcast_mask);
> break;
> case TICKDEV_MODE_ONESHOT:
> if (!cpumask_empty(tick_broadcast_mask))
> @@ -482,11 +495,8 @@ int tick_resume_broadcast(void)
> }
> }
> raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
> -
> - return broadcast;
> }
>
> -
> #ifdef CONFIG_TICK_ONESHOT
>
> static cpumask_var_t tick_broadcast_oneshot_mask;
> Index: linux-pm/kernel/time/tick-common.c
> ===================================================================
> --- linux-pm.orig/kernel/time/tick-common.c
> +++ linux-pm/kernel/time/tick-common.c
> @@ -373,40 +373,32 @@ void tick_shutdown(unsigned int *cpup)
> }
>
> /**
> - * tick_suspend - Suspend the tick and the broadcast device
> + * tick_suspend_local - Suspend the local tick device
> *
> - * Called from syscore_suspend() via timekeeping_suspend with only one
> - * CPU online and interrupts disabled or from tick_unfreeze() under
> - * tick_freeze_lock.
> + * Called from the local cpu for freeze with interrupts disabled.
> *
> * No locks required. Nothing can change the per cpu device.
> */
> -void tick_suspend(void)
> +static void tick_suspend_local(void)
> {
> struct tick_device *td = this_cpu_ptr(&tick_cpu_device);
>
> clockevents_shutdown(td->evtdev);
> - tick_suspend_broadcast();
> }
>
> /**
> - * tick_resume - Resume the tick and the broadcast device
> + * tick_resume_local - Resume the local tick device
> *
> - * Called from syscore_resume() via timekeeping_resume with only one
> - * CPU online and interrupts disabled or from tick_unfreeze() under
> - * tick_freeze_lock.
> + * Called from the local CPU for unfreeze or XEN resume magic.
> *
> * No locks required. Nothing can change the per cpu device.
> */
> -void tick_resume(void)
> +void tick_resume_local(void)
> {
> - struct tick_device *td;
> - int broadcast;
> + struct tick_device *td = this_cpu_ptr(&tick_cpu_device);
> + bool broadcast = tick_resume_check_broadcast();
>
> - broadcast = tick_resume_broadcast();
> - td = this_cpu_ptr(&tick_cpu_device);
> clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_RESUME);
> -
> if (!broadcast) {
> if (td->mode == TICKDEV_MODE_PERIODIC)
> tick_setup_periodic(td->evtdev, 0);
> @@ -415,6 +407,35 @@ void tick_resume(void)
> }
> }
>
> +/**
> + * tick_suspend - Suspend the tick and the broadcast device
> + *
> + * Called from syscore_suspend() via timekeeping_suspend with only one
> + * CPU online and interrupts disabled or from tick_unfreeze() under
> + * tick_freeze_lock.
> + *
> + * No locks required. Nothing can change the per cpu device.
> + */
> +void tick_suspend(void)
> +{
> + tick_suspend_local();
> + tick_suspend_broadcast();
> +}
> +
> +/**
> + * tick_resume - Resume the tick and the broadcast device
> + *
> + * Called from syscore_resume() via timekeeping_resume with only one
> + * CPU online and interrupts disabled.
> + *
> + * No locks required. Nothing can change the per cpu device.
> + */
> +void tick_resume(void)
> +{
> + tick_resume_broadcast();
> + tick_resume_local();
> +}
> +
> static DEFINE_RAW_SPINLOCK(tick_freeze_lock);
> static unsigned int tick_freeze_depth;
>
> @@ -440,7 +461,7 @@ void tick_freeze(void)
> timekeeping_suspend();
> timekeeping_suspend_count++;
> } else {
> - tick_suspend();
> + tick_suspend_local();
> }
>
> raw_spin_unlock(&tick_freeze_lock);
> @@ -465,7 +486,7 @@ void tick_unfreeze(void)
> smp_processor_id(), tick_freeze_depth,
> timekeeping_suspend_count);
> } else {
> - tick_resume();
> + tick_resume_local();
> }
> tick_freeze_depth--;
>
> Index: linux-pm/kernel/time/tick-internal.h
> ===================================================================
> --- linux-pm.orig/kernel/time/tick-internal.h
> +++ linux-pm/kernel/time/tick-internal.h
> @@ -23,6 +23,7 @@ extern void tick_check_new_device(struct
> 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);
> 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);
> @@ -42,6 +43,7 @@ extern int __clockevents_update_freq(str
> extern ssize_t sysfs_get_uname(const char *buf, char *dst, size_t cnt);
> #else
> static inline void tick_suspend(void) { }
> +static inline void tick_resume(void) { }
> #endif /* GENERIC_CLOCKEVENTS */
>
> /* Oneshot related functions */
> @@ -80,7 +82,8 @@ extern int tick_is_broadcast_device(stru
> 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 int tick_resume_broadcast(void);
> +extern void tick_resume_broadcast(void);
> +extern bool tick_resume_check_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);
> @@ -94,7 +97,8 @@ static inline void tick_do_periodic_broa
> 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_resume_broadcast(void) { }
> +static inline bool tick_resume_check_broadcast(void) { return false; }
> static inline void tick_broadcast_init(void) { }
> static inline int tick_broadcast_update_freq(struct clock_event_device *dev, u32 freq) { return -ENODEV; }
>
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 08/09] tick/xen: Provide and use tick_suspend_local() and tick_resume_local()
2015-03-25 20:57 ` Rafael J. Wysocki
@ 2015-03-25 20:44 ` Konrad Rzeszutek Wilk
2015-03-25 21:36 ` Rafael J. Wysocki
0 siblings, 1 reply; 19+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-03-25 20:44 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Peter Zijlstra, linux-kernel, mingo, tglx, Linux PM list,
Boris Ostrovsky, David Vrabel
On Wed, Mar 25, 2015 at 09:57:18PM +0100, Rafael J. Wysocki wrote:
> On Wednesday, March 25, 2015 04:13:09 PM Konrad Rzeszutek Wilk wrote:
> > On Wed, Mar 25, 2015 at 01:11:04PM +0100, Rafael J. Wysocki wrote:
> > > From: Thomas Gleixner <tglx@linutronix.de>
> > >
> > > Xen calls on every cpu into tick_resume() which is just wrong.
> > > tick_resume() is for the syscore global suspend/resume invocation.
> > > What XEN really wants is a per cpu local resume function.
> > >
> > > Provide a tick_resume_local() function and use it in XEN.
> > >
> > > Also provide a complementary tick_suspend_local() and modify
> > > tick_unfreeze() and tick_freeze(), respectively, to use the
> > > new local tick resume/suspend functions.
> > >
> > > Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> > > Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> > > Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
> > > Cc: David Vrabel <david.vrabel@citrix.com>
> > > [ rjw: Combined two patches, rebased, modified subject/changelog ]
> > > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > > ---
> > > arch/x86/xen/suspend.c | 2 -
> > > include/linux/tick.h | 6 ++--
> > > kernel/time/tick-broadcast.c | 24 ++++++++++++------
> > > kernel/time/tick-common.c | 57 +++++++++++++++++++++++++++++--------------
> > > kernel/time/tick-internal.h | 8 ++++--
> > > 5 files changed, 66 insertions(+), 31 deletions(-)
> > >
> > > Index: linux-pm/arch/x86/xen/suspend.c
> > > ===================================================================
> > > --- linux-pm.orig/arch/x86/xen/suspend.c
> > > +++ linux-pm/arch/x86/xen/suspend.c
> > > @@ -85,7 +85,7 @@ static void xen_vcpu_notify_restore(void
> > > if (smp_processor_id() == 0)
> > > return;
> > >
> > > - tick_resume();
> > > + tick_resume_local();
> >
> > I am looking at Linus's tree and I see:
> >
> > 82 static void xen_vcpu_notify_restore(void *data)
> > 83 {
> > 84 unsigned long reason = (unsigned long)data;
> > 85
> > 86 /* Boot processor notified via generic timekeeping_resume() */
> > 87 if ( smp_processor_id() == 0)
> > 88 return;
> > 89
> > 90 clockevents_notify(reason, NULL);
> > 91 }
> >
> > So there must be another patch that altered the clockevents_notify?
>
> Yes, there is. It is the [06/09] in this series
> (https://patchwork.kernel.org/patch/6090631/).
>
> I should have CCed it to you too, sorry about that.
That is alright.
>
> > Is there an git tree with all of these patches?
>
> Not yet, but they all are in the linux-pm patchwork at
>
> https://patchwork.kernel.org/project/linux-pm/list/
>
> I can create a branch in the linux-pm.git tree for them if that helps,
> please let me know.
If it is not too much trouble..
Thank you.
>
>
> --
> I speak only for myself.
> Rafael J. Wysocki, Intel Open Source Technology Center.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 08/09] tick/xen: Provide and use tick_suspend_local() and tick_resume_local()
2015-03-25 20:13 ` Konrad Rzeszutek Wilk
@ 2015-03-25 20:57 ` Rafael J. Wysocki
2015-03-25 20:44 ` Konrad Rzeszutek Wilk
0 siblings, 1 reply; 19+ messages in thread
From: Rafael J. Wysocki @ 2015-03-25 20:57 UTC (permalink / raw)
To: Konrad Rzeszutek Wilk
Cc: Peter Zijlstra, linux-kernel, mingo, tglx, Linux PM list,
Boris Ostrovsky, David Vrabel
On Wednesday, March 25, 2015 04:13:09 PM Konrad Rzeszutek Wilk wrote:
> On Wed, Mar 25, 2015 at 01:11:04PM +0100, Rafael J. Wysocki wrote:
> > From: Thomas Gleixner <tglx@linutronix.de>
> >
> > Xen calls on every cpu into tick_resume() which is just wrong.
> > tick_resume() is for the syscore global suspend/resume invocation.
> > What XEN really wants is a per cpu local resume function.
> >
> > Provide a tick_resume_local() function and use it in XEN.
> >
> > Also provide a complementary tick_suspend_local() and modify
> > tick_unfreeze() and tick_freeze(), respectively, to use the
> > new local tick resume/suspend functions.
> >
> > Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> > Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> > Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
> > Cc: David Vrabel <david.vrabel@citrix.com>
> > [ rjw: Combined two patches, rebased, modified subject/changelog ]
> > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > ---
> > arch/x86/xen/suspend.c | 2 -
> > include/linux/tick.h | 6 ++--
> > kernel/time/tick-broadcast.c | 24 ++++++++++++------
> > kernel/time/tick-common.c | 57 +++++++++++++++++++++++++++++--------------
> > kernel/time/tick-internal.h | 8 ++++--
> > 5 files changed, 66 insertions(+), 31 deletions(-)
> >
> > Index: linux-pm/arch/x86/xen/suspend.c
> > ===================================================================
> > --- linux-pm.orig/arch/x86/xen/suspend.c
> > +++ linux-pm/arch/x86/xen/suspend.c
> > @@ -85,7 +85,7 @@ static void xen_vcpu_notify_restore(void
> > if (smp_processor_id() == 0)
> > return;
> >
> > - tick_resume();
> > + tick_resume_local();
>
> I am looking at Linus's tree and I see:
>
> 82 static void xen_vcpu_notify_restore(void *data)
> 83 {
> 84 unsigned long reason = (unsigned long)data;
> 85
> 86 /* Boot processor notified via generic timekeeping_resume() */
> 87 if ( smp_processor_id() == 0)
> 88 return;
> 89
> 90 clockevents_notify(reason, NULL);
> 91 }
>
> So there must be another patch that altered the clockevents_notify?
Yes, there is. It is the [06/09] in this series
(https://patchwork.kernel.org/patch/6090631/).
I should have CCed it to you too, sorry about that.
> Is there an git tree with all of these patches?
Not yet, but they all are in the linux-pm patchwork at
https://patchwork.kernel.org/project/linux-pm/list/
I can create a branch in the linux-pm.git tree for them if that helps,
please let me know.
--
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 08/09] tick/xen: Provide and use tick_suspend_local() and tick_resume_local()
2015-03-25 20:44 ` Konrad Rzeszutek Wilk
@ 2015-03-25 21:36 ` Rafael J. Wysocki
0 siblings, 0 replies; 19+ messages in thread
From: Rafael J. Wysocki @ 2015-03-25 21:36 UTC (permalink / raw)
To: Konrad Rzeszutek Wilk
Cc: Peter Zijlstra, linux-kernel, mingo, tglx, Linux PM list,
Boris Ostrovsky, David Vrabel
On Wednesday, March 25, 2015 04:44:45 PM Konrad Rzeszutek Wilk wrote:
> On Wed, Mar 25, 2015 at 09:57:18PM +0100, Rafael J. Wysocki wrote:
> > On Wednesday, March 25, 2015 04:13:09 PM Konrad Rzeszutek Wilk wrote:
> > > On Wed, Mar 25, 2015 at 01:11:04PM +0100, Rafael J. Wysocki wrote:
> > > > From: Thomas Gleixner <tglx@linutronix.de>
> > > >
> > > > Xen calls on every cpu into tick_resume() which is just wrong.
> > > > tick_resume() is for the syscore global suspend/resume invocation.
> > > > What XEN really wants is a per cpu local resume function.
> > > >
> > > > Provide a tick_resume_local() function and use it in XEN.
> > > >
> > > > Also provide a complementary tick_suspend_local() and modify
> > > > tick_unfreeze() and tick_freeze(), respectively, to use the
> > > > new local tick resume/suspend functions.
> > > >
> > > > Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> > > > Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> > > > Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
> > > > Cc: David Vrabel <david.vrabel@citrix.com>
> > > > [ rjw: Combined two patches, rebased, modified subject/changelog ]
> > > > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > > > ---
> > > > arch/x86/xen/suspend.c | 2 -
> > > > include/linux/tick.h | 6 ++--
> > > > kernel/time/tick-broadcast.c | 24 ++++++++++++------
> > > > kernel/time/tick-common.c | 57 +++++++++++++++++++++++++++++--------------
> > > > kernel/time/tick-internal.h | 8 ++++--
> > > > 5 files changed, 66 insertions(+), 31 deletions(-)
> > > >
> > > > Index: linux-pm/arch/x86/xen/suspend.c
> > > > ===================================================================
> > > > --- linux-pm.orig/arch/x86/xen/suspend.c
> > > > +++ linux-pm/arch/x86/xen/suspend.c
> > > > @@ -85,7 +85,7 @@ static void xen_vcpu_notify_restore(void
> > > > if (smp_processor_id() == 0)
> > > > return;
> > > >
> > > > - tick_resume();
> > > > + tick_resume_local();
> > >
> > > I am looking at Linus's tree and I see:
> > >
> > > 82 static void xen_vcpu_notify_restore(void *data)
> > > 83 {
> > > 84 unsigned long reason = (unsigned long)data;
> > > 85
> > > 86 /* Boot processor notified via generic timekeeping_resume() */
> > > 87 if ( smp_processor_id() == 0)
> > > 88 return;
> > > 89
> > > 90 clockevents_notify(reason, NULL);
> > > 91 }
> > >
> > > So there must be another patch that altered the clockevents_notify?
> >
> > Yes, there is. It is the [06/09] in this series
> > (https://patchwork.kernel.org/patch/6090631/).
> >
> > I should have CCed it to you too, sorry about that.
>
> That is alright.
> >
> > > Is there an git tree with all of these patches?
> >
> > Not yet, but they all are in the linux-pm patchwork at
> >
> > https://patchwork.kernel.org/project/linux-pm/list/
> >
> > I can create a branch in the linux-pm.git tree for them if that helps,
> > please let me know.
>
> If it is not too much trouble..
Done:
git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git tick-pm
Also turns out that the $subject patch was actually on top of some debug stuff
I have in tick_freeze()/tick_unfreeze(), so here goes a cleaned-up updated.
---
From: Thomas Gleixner <tglx@linutronix.de>
Subject: tick/xen: Provide and use tick_suspend_local() and tick_resume_local()
Xen calls on every cpu into tick_resume() which is just wrong.
tick_resume() is for the syscore global suspend/resume invocation.
What XEN really wants is a per cpu local resume function.
Provide a tick_resume_local() function and use it in XEN.
Also provide a complementary tick_suspend_local() and modify
tick_unfreeze() and tick_freeze(), respectively, to use the
new local tick resume/suspend functions.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: David Vrabel <david.vrabel@citrix.com>
[ rjw: Combined two patches, rebased, modified subject/changelog ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
arch/x86/xen/suspend.c | 2 -
include/linux/tick.h | 6 ++--
kernel/time/tick-broadcast.c | 24 +++++++++++-----
kernel/time/tick-common.c | 62 ++++++++++++++++++++++++++++---------------
kernel/time/tick-internal.h | 8 ++++-
5 files changed, 68 insertions(+), 34 deletions(-)
Index: linux-pm/arch/x86/xen/suspend.c
===================================================================
--- linux-pm.orig/arch/x86/xen/suspend.c
+++ linux-pm/arch/x86/xen/suspend.c
@@ -85,7 +85,7 @@ static void xen_vcpu_notify_restore(void
if (smp_processor_id() == 0)
return;
- tick_resume();
+ tick_resume_local();
}
void xen_arch_resume(void)
Index: linux-pm/include/linux/tick.h
===================================================================
--- linux-pm.orig/include/linux/tick.h
+++ linux-pm/include/linux/tick.h
@@ -29,13 +29,13 @@ extern struct tick_device *tick_get_devi
extern void __init tick_init(void);
extern void tick_freeze(void);
extern void tick_unfreeze(void);
-/* Should be core only, but XEN resume magic abuses this interface */
-extern void tick_resume(void);
+/* Should be core only, but XEN resume magic requires this */
+extern void tick_resume_local(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_resume(void) { }
+static inline void tick_resume_local(void) { }
#endif /* !CONFIG_GENERIC_CLOCKEVENTS */
#ifdef CONFIG_TICK_ONESHOT
Index: linux-pm/kernel/time/tick-broadcast.c
===================================================================
--- linux-pm.orig/kernel/time/tick-broadcast.c
+++ linux-pm/kernel/time/tick-broadcast.c
@@ -455,11 +455,26 @@ void tick_suspend_broadcast(void)
raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
}
-int tick_resume_broadcast(void)
+/*
+ * This is called from tick_resume_local() on a resuming CPU. That's
+ * called from the core resume function, tick_unfreeze() and the magic XEN
+ * resume hackery.
+ *
+ * In none of these cases the broadcast device mode can change and the
+ * bit of the resuming CPU in the broadcast mask is safe as well.
+ */
+bool tick_resume_check_broadcast(void)
+{
+ if (tick_broadcast_device.mode == TICKDEV_MODE_ONESHOT)
+ return false;
+ else
+ return cpumask_test_cpu(smp_processor_id(), tick_broadcast_mask);
+}
+
+void tick_resume_broadcast(void)
{
struct clock_event_device *bc;
unsigned long flags;
- int broadcast = 0;
raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
@@ -472,8 +487,6 @@ int tick_resume_broadcast(void)
case TICKDEV_MODE_PERIODIC:
if (!cpumask_empty(tick_broadcast_mask))
tick_broadcast_start_periodic(bc);
- broadcast = cpumask_test_cpu(smp_processor_id(),
- tick_broadcast_mask);
break;
case TICKDEV_MODE_ONESHOT:
if (!cpumask_empty(tick_broadcast_mask))
@@ -482,11 +495,8 @@ int tick_resume_broadcast(void)
}
}
raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
-
- return broadcast;
}
-
#ifdef CONFIG_TICK_ONESHOT
static cpumask_var_t tick_broadcast_oneshot_mask;
Index: linux-pm/kernel/time/tick-common.c
===================================================================
--- linux-pm.orig/kernel/time/tick-common.c
+++ linux-pm/kernel/time/tick-common.c
@@ -373,40 +373,32 @@ void tick_shutdown(unsigned int *cpup)
}
/**
- * tick_suspend - Suspend the tick and the broadcast device
+ * tick_suspend_local - Suspend the local tick device
*
- * Called from syscore_suspend() via timekeeping_suspend with only one
- * CPU online and interrupts disabled or from tick_unfreeze() under
- * tick_freeze_lock.
+ * Called from the local cpu for freeze with interrupts disabled.
*
* No locks required. Nothing can change the per cpu device.
*/
-void tick_suspend(void)
+static void tick_suspend_local(void)
{
struct tick_device *td = this_cpu_ptr(&tick_cpu_device);
clockevents_shutdown(td->evtdev);
- tick_suspend_broadcast();
}
/**
- * tick_resume - Resume the tick and the broadcast device
+ * tick_resume_local - Resume the local tick device
*
- * Called from syscore_resume() via timekeeping_resume with only one
- * CPU online and interrupts disabled or from tick_unfreeze() under
- * tick_freeze_lock.
+ * Called from the local CPU for unfreeze or XEN resume magic.
*
* No locks required. Nothing can change the per cpu device.
*/
-void tick_resume(void)
+void tick_resume_local(void)
{
- struct tick_device *td;
- int broadcast;
+ struct tick_device *td = this_cpu_ptr(&tick_cpu_device);
+ bool broadcast = tick_resume_check_broadcast();
- broadcast = tick_resume_broadcast();
- td = this_cpu_ptr(&tick_cpu_device);
clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_RESUME);
-
if (!broadcast) {
if (td->mode == TICKDEV_MODE_PERIODIC)
tick_setup_periodic(td->evtdev, 0);
@@ -415,6 +407,35 @@ void tick_resume(void)
}
}
+/**
+ * tick_suspend - Suspend the tick and the broadcast device
+ *
+ * Called from syscore_suspend() via timekeeping_suspend with only one
+ * CPU online and interrupts disabled or from tick_unfreeze() under
+ * tick_freeze_lock.
+ *
+ * No locks required. Nothing can change the per cpu device.
+ */
+void tick_suspend(void)
+{
+ tick_suspend_local();
+ tick_suspend_broadcast();
+}
+
+/**
+ * tick_resume - Resume the tick and the broadcast device
+ *
+ * Called from syscore_resume() via timekeeping_resume with only one
+ * CPU online and interrupts disabled.
+ *
+ * No locks required. Nothing can change the per cpu device.
+ */
+void tick_resume(void)
+{
+ tick_resume_broadcast();
+ tick_resume_local();
+}
+
static DEFINE_RAW_SPINLOCK(tick_freeze_lock);
static unsigned int tick_freeze_depth;
@@ -432,11 +453,10 @@ void tick_freeze(void)
raw_spin_lock(&tick_freeze_lock);
tick_freeze_depth++;
- if (tick_freeze_depth == num_online_cpus()) {
+ if (tick_freeze_depth == num_online_cpus())
timekeeping_suspend();
- } else {
- tick_suspend();
- }
+ else
+ tick_suspend_local();
raw_spin_unlock(&tick_freeze_lock);
}
@@ -457,7 +477,7 @@ void tick_unfreeze(void)
if (tick_freeze_depth == num_online_cpus())
timekeeping_resume();
else
- tick_resume();
+ tick_resume_local();
tick_freeze_depth--;
Index: linux-pm/kernel/time/tick-internal.h
===================================================================
--- linux-pm.orig/kernel/time/tick-internal.h
+++ linux-pm/kernel/time/tick-internal.h
@@ -23,6 +23,7 @@ extern void tick_check_new_device(struct
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);
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);
@@ -42,6 +43,7 @@ extern int __clockevents_update_freq(str
extern ssize_t sysfs_get_uname(const char *buf, char *dst, size_t cnt);
#else
static inline void tick_suspend(void) { }
+static inline void tick_resume(void) { }
#endif /* GENERIC_CLOCKEVENTS */
/* Oneshot related functions */
@@ -80,7 +82,8 @@ extern int tick_is_broadcast_device(stru
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 int tick_resume_broadcast(void);
+extern void tick_resume_broadcast(void);
+extern bool tick_resume_check_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);
@@ -94,7 +97,8 @@ static inline void tick_do_periodic_broa
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_resume_broadcast(void) { }
+static inline bool tick_resume_check_broadcast(void) { return false; }
static inline void tick_broadcast_init(void) { }
static inline int tick_broadcast_update_freq(struct clock_event_device *dev, u32 freq) { return -ENODEV; }
^ permalink raw reply [flat|nested] 19+ messages in thread
* [GIT PULL] kernel/time cleanups (related to tick_suspend/resume)
2015-03-25 12:04 ` [PATCH 00/09] Some kernel/time cleanups (related to timer_suspend/resume) Rafael J. Wysocki
` (9 preceding siblings ...)
2015-03-25 12:13 ` [PATCH 00/09] Some kernel/time cleanups (related to timer_suspend/resume) Rafael J. Wysocki
@ 2015-03-31 22:45 ` Rafael J. Wysocki
10 siblings, 0 replies; 19+ messages in thread
From: Rafael J. Wysocki @ 2015-03-31 22:45 UTC (permalink / raw)
To: Ingo Molnar
Cc: Peter Zijlstra, linux-kernel, tglx, Linux PM list,
Stephen Rothwell
Hi Ingo,
Please pull from
git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git tick-pm
to receive kernel/time cleanups related to tick_suspend/resume from Thomas Gleixner
that I've rebased on top of the Linus' tree and reworked slightly.
There will be a conflict between this branch and tip that can be resolved with
the help of the patch from Stephen Rothwell available at:
http://marc.info/?l=linux-kernel&m=142778874014355&w=4
Kind regards,
Rafael
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH][fix for tip/timers/core] timers / PM: Fix up tick_unfreeze()
[not found] ` <tip-f46481d0a7cb942b84145acb80ad43bdb1ff8eb4@git.kernel.org>
@ 2015-04-03 13:21 ` Rafael J. Wysocki
2015-04-03 13:31 ` [PATCH][cleanup for tip/timers/core] timers / PM: Drop unnecessary braces from tick_freeze() Rafael J. Wysocki
0 siblings, 1 reply; 19+ messages in thread
From: Rafael J. Wysocki @ 2015-04-03 13:21 UTC (permalink / raw)
To: peterz, mingo
Cc: rafael.j.wysocki, konrad.wilk, boris.ostrovsky, tglx,
david.vrabel, linux-kernel, hpa, Linux PM list
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
A recent conflict resolution has left tick_resume() in
tick_unfreeze() which leads to an unbalanced execution of
tick_resume_broadcast() every time that function runs.
Fix that by replacing the tick_resume() in tick_unfreeze()
with tick_resume_local() as appropriate.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
kernel/time/tick-common.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: linux-pm/kernel/time/tick-common.c
===================================================================
--- linux-pm.orig/kernel/time/tick-common.c
+++ linux-pm/kernel/time/tick-common.c
@@ -482,7 +482,7 @@ void tick_unfreeze(void)
if (tick_freeze_depth == num_online_cpus())
timekeeping_resume();
else
- tick_resume();
+ tick_resume_local();
tick_freeze_depth--;
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH][cleanup for tip/timers/core] timers / PM: Drop unnecessary braces from tick_freeze()
2015-04-03 13:21 ` [PATCH][fix for tip/timers/core] timers / PM: Fix up tick_unfreeze() Rafael J. Wysocki
@ 2015-04-03 13:31 ` Rafael J. Wysocki
0 siblings, 0 replies; 19+ messages in thread
From: Rafael J. Wysocki @ 2015-04-03 13:31 UTC (permalink / raw)
To: peterz, mingo; +Cc: rafael.j.wysocki, tglx, linux-kernel, hpa, Linux PM list
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Some braces in tick_freeze() are not necessary, so drop them.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
kernel/time/tick-common.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
Index: linux-pm/kernel/time/tick-common.c
===================================================================
--- linux-pm.orig/kernel/time/tick-common.c
+++ linux-pm/kernel/time/tick-common.c
@@ -457,11 +457,10 @@ void tick_freeze(void)
raw_spin_lock(&tick_freeze_lock);
tick_freeze_depth++;
- if (tick_freeze_depth == num_online_cpus()) {
+ if (tick_freeze_depth == num_online_cpus())
timekeeping_suspend();
- } else {
+ else
tick_suspend_local();
- }
raw_spin_unlock(&tick_freeze_lock);
}
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2015-04-03 13:31 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20150216121435.203983131@infradead.org>
2015-03-25 12:04 ` [PATCH 00/09] Some kernel/time cleanups (related to timer_suspend/resume) Rafael J. Wysocki
2015-03-25 12:05 ` [PATCH 01/09] clockevents: Remove CONFIG_GENERIC_CLOCKEVENTS_BUILD Rafael J. Wysocki
2015-03-25 12:06 ` [PATCH 02/09] tick: Move clocksource related stuff to timekeeping.h Rafael J. Wysocki
2015-03-25 12:06 ` [PATCH 03/09] tick: Simplify tick-internal.h Rafael J. Wysocki
2015-03-25 12:07 ` [PATCH 04/09] tick: Move core only declarations and functions to core Rafael J. Wysocki
2015-03-25 12:08 ` [PATCH 05/09] clockevents: Remove extra local_irq_save in clockevents_exchange_device() Rafael J. Wysocki
2015-03-25 12:09 ` [PATCH 06/09] clockevents: Make suspend/resume calls explicit Rafael J. Wysocki
2015-03-25 12:09 ` [PATCH 07/09] tick: Make tick_resume_broadcast_oneshot static Rafael J. Wysocki
2015-03-25 12:11 ` [PATCH 08/09] tick/xen: Provide and use tick_suspend_local() and tick_resume_local() Rafael J. Wysocki
2015-03-25 20:13 ` Konrad Rzeszutek Wilk
2015-03-25 20:57 ` Rafael J. Wysocki
2015-03-25 20:44 ` Konrad Rzeszutek Wilk
2015-03-25 21:36 ` Rafael J. Wysocki
[not found] ` <tip-f46481d0a7cb942b84145acb80ad43bdb1ff8eb4@git.kernel.org>
2015-04-03 13:21 ` [PATCH][fix for tip/timers/core] timers / PM: Fix up tick_unfreeze() Rafael J. Wysocki
2015-04-03 13:31 ` [PATCH][cleanup for tip/timers/core] timers / PM: Drop unnecessary braces from tick_freeze() Rafael J. Wysocki
2015-03-25 12:11 ` [PATCH 09/09] arm: bl_switcher: Kill tick suspend hackery Rafael J. Wysocki
2015-03-25 12:34 ` Nicolas Pitre
2015-03-25 12:13 ` [PATCH 00/09] Some kernel/time cleanups (related to timer_suspend/resume) Rafael J. Wysocki
2015-03-31 22:45 ` [GIT PULL] kernel/time cleanups (related to tick_suspend/resume) Rafael J. Wysocki
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox