timer changes for v3.2
Subsystems (13)
Linus,
Please pull the latest timers-core-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-core-for-linus
Thanks,
Ingo
------------------>
Heiko Carstens (2):
nohz: Remove "Switched to NOHz mode" debugging messages time, s390: Get rid of compile warning
Jamie Iles (1):
dw_apb_timer: constify clocksource name
John Stultz (9):
alarmtimers: Change alarmtimer functions to return alarmtimer_restart values
alarmtimers: Push rearming peroidic timers down into alamrtimer handler
alarmtimers: Add alarm_forward functionality
alarmtimers: Remove interval cap limit hack
alarmtimers: Remove period from alarm structure
alarmtimers: Add more refined alarm state tracking
alarmtimers: Add try_to_cancel functionality
alarmtimers: Rework RTC device selection using class interface
time: Cleanup old CONFIG_GENERIC_TIME references that snuck in
Martin Schwidefsky (3):
clockevents: Make minimum delay adjustments configurable
clockevents: Add direct ktime programming function
s390: Use direct ktime path for s390 clockevent device
Michal Hocko (4):
cputime: Clean up cputime_to_usecs and usecs_to_cputime macros
nohz: Fix update_ts_time_stat idle accounting
nohz: Make idle/iowait counter update conditional
proc: Consider NO_HZ when printing idle and iowait times
Peter Zijlstra (1):
posix-cpu-timers: Cure SMP accounting oddities
Thomas Gleixner (2):
clocksource: Make watchdog reset lockless
alarmtimers: Fix error handling
hank (1):
time: Change jiffies_to_clock_t() argument type to unsigned long
arch/arm/Kconfig | 4 - arch/mn10300/Kconfig | 3 - arch/s390/kernel/time.c | 13 +- arch/tile/Kconfig | 3 - arch/tile/configs/tilegx_defconfig | 1 - arch/tile/configs/tilepro_defconfig | 1 - arch/um/defconfig | 1 - arch/x86/Kconfig | 1 + arch/xtensa/configs/iss_defconfig | 1 - arch/xtensa/configs/s6105_defconfig | 1 - drivers/clocksource/dw_apb_timer.c | 2 +- drivers/cpufreq/cpufreq_conservative.c | 4 +- drivers/cpufreq/cpufreq_ondemand.c | 4 +- fs/proc/stat.c | 41 ++++- include/asm-generic/cputime.h | 4 +- include/linux/alarmtimer.h | 51 ++++++- include/linux/clockchips.h | 12 +- include/linux/dw_apb_timer.h | 2 +- include/linux/jiffies.h | 2 +- include/linux/posix-timers.h | 5 +- include/linux/sched.h | 1 - kernel/posix-cpu-timers.c | 5 +- kernel/sched.c | 24 --- kernel/time.c | 2 +- kernel/time/Kconfig | 2 + kernel/time/alarmtimer.c | 266 ++++++++++++++++++++++---------- kernel/time/clockevents.c | 129 ++++++++++++++-- kernel/time/clocksource.c | 38 ++--- kernel/time/tick-broadcast.c | 4 +- kernel/time/tick-common.c | 4 +- kernel/time/tick-internal.h | 2 - kernel/time/tick-oneshot.c | 77 +--------- kernel/time/tick-sched.c | 55 +++++-- 33 files changed, 480 insertions(+), 285 deletions(-)
arch/arm/Kconfig +0 -4
@@ -347,7 +347,6 @@ config ARCH_GEMINI config ARCH_PRIMA2 bool "CSR SiRFSoC PRIMA2 ARM Cortex A9 Platform" select CPU_V7 - select GENERIC_TIME select NO_IOPORT select GENERIC_CLOCKEVENTS select CLKDEV_LOOKUP
@@ -520,7 +519,6 @@ config ARCH_LPC32XX select ARM_AMBA select USB_ARCH_HAS_OHCI select CLKDEV_LOOKUP - select GENERIC_TIME select GENERIC_CLOCKEVENTS help Support for the NXP LPC32XX family of processors
@@ -599,7 +597,6 @@ config ARCH_TEGRA bool "NVIDIA Tegra" select CLKDEV_LOOKUP select CLKSRC_MMIO - select GENERIC_TIME select GENERIC_CLOCKEVENTS select GENERIC_GPIO select HAVE_CLK
@@ -911,7 +908,6 @@ config ARCH_VT8500 config ARCH_ZYNQ bool "Xilinx Zynq ARM Cortex A9 Platform" select CPU_V7 - select GENERIC_TIME select GENERIC_CLOCKEVENTS select CLKDEV_LOOKUP select ARM_GIC
arch/mn10300/Kconfig +0 -3
@@ -47,9 +47,6 @@ config GENERIC_CMOS_UPDATE config GENERIC_HWEIGHT def_bool y -config GENERIC_TIME - def_bool y - config GENERIC_CLOCKEVENTS def_bool y
arch/s390/kernel/time.c +9 -4
@@ -109,10 +109,14 @@ static void fixup_clock_comparator(unsigned long long delta)set_clock_comparator (S390_lowcore.clock_comparator); } -static int s390_next_event (unsigned long delta, +static int s390_next_ktime (ktime_t expires,struct clock_event_device *evt) { - S390_lowcore.clock_comparator =get_clock () + delta; +u64 nsecs; + + nsecs =ktime_to_ns (ktime_sub (expires,ktime_get_monotonic_offset ())); +do_div (nsecs,125 ); + S390_lowcore.clock_comparator =TOD_UNIX_EPOCH + (nsecs <<9 );set_clock_comparator (S390_lowcore.clock_comparator);return 0 ; }
@@ -137,14 +141,15 @@ void init_cpu_timer(void) cpu =smp_processor_id (); cd = &per_cpu (comparators, cpu); cd->name ="comparator" ; - cd->features =CLOCK_EVT_FEAT_ONESHOT ; + cd->features =CLOCK_EVT_FEAT_ONESHOT | +CLOCK_EVT_FEAT_KTIME ; cd->mult =16777 ; cd->shift =12 ; cd->min_delta_ns =1 ; cd->max_delta_ns =LONG_MAX ; cd->rating =400 ; cd->cpumask =cpumask_of (cpu); - cd->set_next_event = s390_next_event; + cd->set_next_ktime = s390_next_ktime; cd->set_mode = s390_set_mode;clockevents_register_device (cd);
arch/tile/Kconfig +0 -3
@@ -46,9 +46,6 @@ config NEED_PER_CPU_PAGE_FIRST_CHUNK config SYS_SUPPORTS_HUGETLBFS def_bool y -config GENERIC_TIME - def_bool y - config GENERIC_CLOCKEVENTS def_bool y
arch/tile/configs/tilegx_defconfig +0 -1
@@ -11,7 +11,6 @@ CONFIG_HAVE_ARCH_ALLOC_REMAP=y CONFIG_HAVE_SETUP_PER_CPU_AREA=y CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y CONFIG_SYS_SUPPORTS_HUGETLBFS=y -CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_DEFAULT_MIGRATION_COST=10000000
arch/tile/configs/tilepro_defconfig +0 -1
@@ -11,7 +11,6 @@ CONFIG_HAVE_ARCH_ALLOC_REMAP=y CONFIG_HAVE_SETUP_PER_CPU_AREA=y CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y CONFIG_SYS_SUPPORTS_HUGETLBFS=y -CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_DEFAULT_MIGRATION_COST=10000000
arch/um/defconfig +0 -1
@@ -13,7 +13,6 @@ CONFIG_LOCKDEP_SUPPORT=y # CONFIG_STACKTRACE_SUPPORT is not set CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_IRQ_RELEASE_METHOD=y CONFIG_HZ=100
arch/x86/Kconfig +1 -0
@@ -68,6 +68,7 @@ config X86 select GENERIC_IRQ_PROBE select GENERIC_PENDING_IRQ if SMP select GENERIC_IRQ_SHOW + select GENERIC_CLOCKEVENTS_MIN_ADJUST select IRQ_FORCED_THREADING select USE_GENERIC_SMP_HELPERS if SMP select HAVE_BPF_JIT if (X86_64 && NET)
arch/xtensa/configs/iss_defconfig +0 -1
@@ -15,7 +15,6 @@ CONFIG_GENERIC_GPIO=y # CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_NO_IOPORT=y CONFIG_HZ=100 -CONFIG_GENERIC_TIME=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y
arch/xtensa/configs/s6105_defconfig +0 -1
@@ -15,7 +15,6 @@ CONFIG_GENERIC_GPIO=y # CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_NO_IOPORT=y CONFIG_HZ=100 -CONFIG_GENERIC_TIME=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" #
drivers/clocksource/dw_apb_timer.c +1 -1
@@ -348,7 +348,7 @@ static void apbt_restart_clocksource(struct clocksource *cs)* dw_apb_clocksource_register() as the next step. */ struct dw_apb_clocksource * -dw_apb_clocksource_init (unsigned rating,char *name,void __iomem *base, +dw_apb_clocksource_init (unsigned rating,const char *name,void __iomem *base,unsigned long freq) {struct dw_apb_clocksource *dw_cs =kzalloc (sizeof (*dw_cs),GFP_KERNEL );
drivers/cpufreq/cpufreq_conservative.c +3 -1
@@ -120,10 +120,12 @@ static inline cputime64_t get_cpu_idle_time_jiffy(unsigned int cpu,static inline cputime64_t get_cpu_idle_time (unsigned int cpu,cputime64_t *wall) { -u64 idle_time =get_cpu_idle_time_us (cpu, wall); +u64 idle_time =get_cpu_idle_time_us (cpu,NULL );if (idle_time ==-1ULL )return get_cpu_idle_time_jiffy (cpu, wall); +else + idle_time +=get_cpu_iowait_time_us (cpu, wall);return idle_time; }
drivers/cpufreq/cpufreq_ondemand.c +3 -1
@@ -144,10 +144,12 @@ static inline cputime64_t get_cpu_idle_time_jiffy(unsigned int cpu,static inline cputime64_t get_cpu_idle_time (unsigned int cpu,cputime64_t *wall) { -u64 idle_time =get_cpu_idle_time_us (cpu, wall); +u64 idle_time =get_cpu_idle_time_us (cpu,NULL );if (idle_time ==-1ULL )return get_cpu_idle_time_jiffy (cpu, wall); +else + idle_time +=get_cpu_iowait_time_us (cpu, wall);return idle_time; }
fs/proc/stat.c +34 -7
69 lines not on this page · raw message
include/asm-generic/cputime.h +2 -2
@@ -38,8 +38,8 @@ typedef u64 cputime64_t;/* * Convert cputime to microseconds and back. */ -#define cputime_to_usecs (__ct) jiffies_to_usecs(__ct); -#define usecs_to_cputime (__msecs) usecs_to_jiffies(__msecs); +#define cputime_to_usecs (__ct) jiffies_to_usecs(__ct) +#define usecs_to_cputime (__msecs) usecs_to_jiffies(__msecs)/* * Convert cputime to seconds and back.
include/linux/alarmtimer.h +45 -6
67 lines not on this page · raw message
include/linux/clockchips.h +8 -4
@@ -45,20 +45,22 @@ enum clock_event_nofitiers {*/ #define CLOCK_EVT_FEAT_PERIODIC 0x000001#define CLOCK_EVT_FEAT_ONESHOT 0x000002 +#define CLOCK_EVT_FEAT_KTIME 0x000004/* * x86(64) specific misfeatures: * * - Clockevent source stops in C3 State and needs broadcast support. * - Local APIC timer is used as a dummy device. */ -#define CLOCK_EVT_FEAT_C3STOP 0x000004 -#define CLOCK_EVT_FEAT_DUMMY 0x000008 +#define CLOCK_EVT_FEAT_C3STOP 0x000008 +#define CLOCK_EVT_FEAT_DUMMY 0x000010/** * struct clock_event_device - clock event device descriptor * @event_handler: Assigned by the framework to be called by the low * level handler of the event source -* @set_next_event: set next event function +* @set_next_event: set next event function using a clocksource delta +* @set_next_ktime: set next event function using a direct ktime value * @next_event: local storage for the next event in oneshot mode * @max_delta_ns: maximum delta value in ns * @min_delta_ns: minimum delta value in ns
@@ -81,6 +83,8 @@ struct clock_event_device {void (*event_handler)(struct clock_event_device *);int (*set_next_event)(unsigned long evt,struct clock_event_device *); +int (*set_next_ktime)(ktime_t expires, +struct clock_event_device *);ktime_t next_event;u64 max_delta_ns;u64 min_delta_ns;
@@ -140,7 +144,7 @@ extern void clockevents_set_mode(struct clock_event_device *dev, enum clock_event_mode mode);extern int clockevents_register_notifier (struct notifier_block *nb);extern int clockevents_program_event (struct clock_event_device *dev, -ktime_t expires,ktime_t now); +ktime_t expires,bool force);extern void clockevents_handle_noop (struct clock_event_device *dev);
include/linux/dw_apb_timer.h +1 -1
@@ -46,7 +46,7 @@ struct dw_apb_clock_event_device * dw_apb_clockevent_init(int cpu, const char *name, unsigned rating, void __iomem *base, int irq, unsigned long freq);struct dw_apb_clocksource * -dw_apb_clocksource_init (unsigned rating,char *name,void __iomem *base, +dw_apb_clocksource_init (unsigned rating,const char *name,void __iomem *base,unsigned long freq);void dw_apb_clocksource_register (struct dw_apb_clocksource *dw_cs);void dw_apb_clocksource_start (struct dw_apb_clocksource *dw_cs);
include/linux/jiffies.h +1 -1
@@ -303,7 +303,7 @@ extern void jiffies_to_timespec(const unsigned long jiffies,extern unsigned long timeval_to_jiffies (const struct timeval *value);extern void jiffies_to_timeval (const unsigned long jiffies,struct timeval *value); -extern clock_t jiffies_to_clock_t (long x); +extern clock_t jiffies_to_clock_t (unsigned long x);extern unsigned long clock_t_to_jiffies (unsigned long x);extern u64 jiffies_64_to_clock_t (u64 x);extern u64 nsec_to_clock_t (u64 x);
include/linux/posix-timers.h +4 -1
@@ -81,7 +81,10 @@ struct k_itimer {unsigned long incr;unsigned long expires; } mmtimer; -struct alarm alarmtimer; +struct { +struct alarm alarmtimer; +ktime_t interval; + } alarm;struct rcu_head rcu; } it; };
include/linux/sched.h +0 -1
@@ -1955,7 +1955,6 @@ static inline void disable_sched_clock_irqtime(void) {}extern unsigned long long task_sched_runtime (struct task_struct *task); -extern unsigned long long thread_group_sched_runtime (struct task_struct *task);/* sched_exec is called by processes performing an exec */ #ifdef CONFIG_SMP
kernel/posix-cpu-timers.c +3 -2
@@ -250,7 +250,7 @@ void thread_group_cputime(struct task_struct *tsk, struct task_cputime *times) do { times->utime = cputime_add(times->utime, t->utime); times->stime = cputime_add(times->stime, t->stime); - times->sum_exec_runtime += t->se.sum_exec_runtime; + times->sum_exec_runtime += task_sched_runtime(t); } while_each_thread(tsk, t); out: rcu_read_unlock();
@@ -312,7 +312,8 @@ static int cpu_clock_sample_group(const clockid_t which_clock, cpu->cpu = cputime.utime;break ;case CPUCLOCK_SCHED : - cpu->sched =thread_group_sched_runtime (p); +thread_group_cputime (p, &cputime); + cpu->sched = cputime.sum_exec_runtime;break ; }return 0 ;
kernel/sched.c +0 -24
@@ -3725,30 +3725,6 @@ unsigned long long task_sched_runtime(struct task_struct *p) }/* -* Return sum_exec_runtime for the thread group. -* In case the task is currently running, return the sum plus current's -* pending runtime that have not been accounted yet. -* -* Note that the thread group might have other running tasks as well, -* so the return value not includes other pending runtime that other -* running tasks might have. -*/ -unsigned long long thread_group_sched_runtime (struct task_struct *p) -{ -struct task_cputime totals; -unsigned long flags; -struct rq *rq; -u64 ns; - - rq =task_rq_lock (p, &flags); -thread_group_cputime (p, &totals); - ns = totals.sum_exec_runtime +do_task_delta_exec (p, rq); -task_rq_unlock (rq, p, &flags); - -return ns; -} - -/* * Account user cpu time to a process. * @p: the process that the cpu time gets accounted to * @cputime: the cpu time spent in user space since the last update
kernel/time.c +1 -1
@@ -575,7 +575,7 @@ EXPORT_SYMBOL(jiffies_to_timeval);/* * Convert jiffies/jiffies_64 to clock_t and back. */ -clock_t jiffies_to_clock_t (long x) +clock_t jiffies_to_clock_t (unsigned long x) {#if (TICK_NSEC % (NSEC_PER_SEC /USER_HZ )) ==0 # if HZ <USER_HZ
kernel/time/Kconfig +2 -0
@@ -27,3 +27,5 @@ config GENERIC_CLOCKEVENTS_BUILD default y depends on GENERIC_CLOCKEVENTS || GENERIC_CLOCKEVENTS_MIGR +config GENERIC_CLOCKEVENTS_MIN_ADJUST + bool
kernel/time/alarmtimer.c +181 -85
437 lines not on this page · raw message
kernel/time/clockevents.c +115 -14
164 lines not on this page · raw message
kernel/time/clocksource.c +18 -20
@@ -186,6 +186,7 @@ static struct timer_list watchdog_timer; static DECLARE_WORK(watchdog_work, clocksource_watchdog_work);static DEFINE_SPINLOCK (watchdog_lock);static int watchdog_running; +static atomic_t watchdog_reset_pending;static int clocksource_watchdog_kthread (void *data);static void __clocksource_change_rating (struct clocksource *cs,int rating);
@@ -247,12 +248,14 @@ static void clocksource_watchdog(unsigned long data)struct clocksource *cs;cycle_t csnow, wdnow;int64_t wd_nsec, cs_nsec; -int next_cpu; +int next_cpu, reset_pending;spin_lock (&watchdog_lock);if (!watchdog_running) goto out; + reset_pending =atomic_read (&watchdog_reset_pending); +list_for_each_entry (cs, &watchdog_list, wd_list) {/* Clocksource already marked unstable? */
@@ -268,7 +271,8 @@ static void clocksource_watchdog(unsigned long data)local_irq_enable ();/* Clocksource initialized ? */ -if (!(cs->flags &CLOCK_SOURCE_WATCHDOG )) { +if (!(cs->flags &CLOCK_SOURCE_WATCHDOG ) || +atomic_read (&watchdog_reset_pending)) { cs->flags |=CLOCK_SOURCE_WATCHDOG ; cs->wd_last = wdnow; cs->cs_last = csnow;
@@ -283,8 +287,11 @@ static void clocksource_watchdog(unsigned long data) cs->cs_last = csnow; cs->wd_last = wdnow; +if (atomic_read (&watchdog_reset_pending)) +continue ; +/* Check the deviation from the watchdog clocksource. */ -if (abs (cs_nsec - wd_nsec) >WATCHDOG_THRESHOLD ) { +if ((abs (cs_nsec - wd_nsec) >WATCHDOG_THRESHOLD )) {clocksource_unstable (cs, cs_nsec - wd_nsec);continue ; }
@@ -303,6 +310,13 @@ static void clocksource_watchdog(unsigned long data) }/* +* We only clear the watchdog_reset_pending, when we did a +* full cycle through all clocksources. +*/ +if (reset_pending) +atomic_dec (&watchdog_reset_pending); + +/* * Cycle through CPUs to check if the CPUs stay synchronized * to each other. */
@@ -344,23 +358,7 @@ static inline void clocksource_reset_watchdog(void)static void clocksource_resume_watchdog (void ) { -unsigned long flags; - -/* -* We use trylock here to avoid a potential dead lock when -* kgdb calls this code after the kernel has been stopped with -* watchdog_lock held. When watchdog_lock is held we just -* return and accept, that the watchdog might trigger and mark -* the monitored clock source (usually TSC) unstable. -* -* This does not affect the other caller clocksource_resume() -* because at this point the kernel is UP, interrupts are -* disabled and nothing can hold watchdog_lock. -*/ -if (!spin_trylock_irqsave (&watchdog_lock, flags)) -return ; -clocksource_reset_watchdog (); -spin_unlock_irqrestore (&watchdog_lock, flags); +atomic_inc (&watchdog_reset_pending); }static void clocksource_enqueue_watchdog (struct clocksource *cs)
kernel/time/tick-broadcast.c +2 -2
@@ -194,7 +194,7 @@ static void tick_handle_periodic_broadcast(struct clock_event_device *dev)for (next = dev->next_event; ;) { next =ktime_add (next, tick_period); -if (!clockevents_program_event (dev, next,ktime_get ())) +if (!clockevents_program_event (dev, next, false))return ;tick_do_periodic_broadcast (); }
@@ -373,7 +373,7 @@ static int tick_broadcast_set_event(ktime_t expires, int force) {struct clock_event_device *bc = tick_broadcast_device.evtdev; -return tick_dev_program_event (bc, expires, force); +return clockevents_program_event (bc, expires, force); }int tick_resume_broadcast_oneshot (struct clock_event_device *bc)
kernel/time/tick-common.c +2 -2
@@ -94,7 +94,7 @@ void tick_handle_periodic(struct clock_event_device *dev)*/ next =ktime_add (dev->next_event, tick_period);for (;;) { -if (!clockevents_program_event (dev, next,ktime_get ())) +if (!clockevents_program_event (dev, next, false))return ;/* * Have to be careful here. If we're in oneshot mode,
@@ -137,7 +137,7 @@ void tick_setup_periodic(struct clock_event_device *dev, int broadcast)clockevents_set_mode (dev,CLOCK_EVT_MODE_ONESHOT );for (;;) { -if (!clockevents_program_event (dev, next,ktime_get ())) +if (!clockevents_program_event (dev, next, false))return ; next =ktime_add (next, tick_period); }
kernel/time/tick-internal.h +0 -2
@@ -26,8 +26,6 @@ extern void clockevents_shutdown(struct clock_event_device *dev);extern void tick_setup_oneshot (struct clock_event_device *newdev,void (*handler)(struct clock_event_device *),ktime_t nextevt); -extern int tick_dev_program_event (struct clock_event_device *dev, -ktime_t expires,int force);extern int tick_program_event (ktime_t expires,int force);extern void tick_oneshot_notify (void );extern int tick_switch_to_oneshot (void (*handler)(struct clock_event_device *));
kernel/time/tick-oneshot.c +4 -73
103 lines not on this page · raw message
kernel/time/tick-sched.c +40 -15
111 lines not on this page · raw message