forked from Minki/linux
500462a9de
The current timer wheel has some drawbacks: 1) Cascading: Cascading can be an unbound operation and is completely pointless in most cases because the vast majority of the timer wheel timers are canceled or rearmed before expiration. (They are used as timeout safeguards, not as real timers to measure time.) 2) No fast lookup of the next expiring timer: In NOHZ scenarios the first timer soft interrupt after a long NOHZ period must fast forward the base time to the current value of jiffies. As we have no way to find the next expiring timer fast, the code loops linearly and increments the base time one by one and checks for expired timers in each step. This causes unbound overhead spikes exactly in the moment when we should wake up as fast as possible. After a thorough analysis of real world data gathered on laptops, workstations, webservers and other machines (thanks Chris!) I came to the conclusion that the current 'classic' timer wheel implementation can be modified to address the above issues. The vast majority of timer wheel timers is canceled or rearmed before expiry. Most of them are timeouts for networking and other I/O tasks. The nature of timeouts is to catch the exception from normal operation (TCP ack timed out, disk does not respond, etc.). For these kinds of timeouts the accuracy of the timeout is not really a concern. Timeouts are very often approximate worst-case values and in case the timeout fires, we already waited for a long time and performance is down the drain already. The few timers which actually expire can be split into two categories: 1) Short expiry times which expect halfways accurate expiry 2) Long term expiry times are inaccurate today already due to the batching which is done for NOHZ automatically and also via the set_timer_slack() API. So for long term expiry timers we can avoid the cascading property and just leave them in the less granular outer wheels until expiry or cancelation. Timers which are armed with a timeout larger than the wheel capacity are no longer cascaded. We expire them with the longest possible timeout (6+ days). We have not observed such timeouts in our data collection, but at least we handle them, applying the rule of the least surprise. To avoid extending the wheel levels for HZ=1000 so we can accomodate the longest observed timeouts (5 days in the network conntrack code) we reduce the first level granularity on HZ=1000 to 4ms, which effectively is the same as the HZ=250 behaviour. From our data analysis there is nothing which relies on that 1ms granularity and as a side effect we get better batching and timer locality for the networking code as well. Contrary to the classic wheel the granularity of the next wheel is not the capacity of the first wheel. The granularities of the wheels are in the currently chosen setting 8 times the granularity of the previous wheel. So for HZ=250 we end up with the following granularity levels: Level Offset Granularity Range 0 0 4 ms 0 ms - 252 ms 1 64 32 ms 256 ms - 2044 ms (256ms - ~2s) 2 128 256 ms 2048 ms - 16380 ms (~2s - ~16s) 3 192 2048 ms (~2s) 16384 ms - 131068 ms (~16s - ~2m) 4 256 16384 ms (~16s) 131072 ms - 1048572 ms (~2m - ~17m) 5 320 131072 ms (~2m) 1048576 ms - 8388604 ms (~17m - ~2h) 6 384 1048576 ms (~17m) 8388608 ms - 67108863 ms (~2h - ~18h) 7 448 8388608 ms (~2h) 67108864 ms - 536870911 ms (~18h - ~6d) That's a worst case inaccuracy of 12.5% for the timers which are queued at the beginning of a level. So the new wheel concept addresses the old issues: 1) Cascading is avoided completely 2) By keeping the timers in the bucket until expiry/cancelation we can track the buckets which have timers enqueued in a bucket bitmap and therefore can look up the next expiring timer very fast and O(1). A further benefit of the concept is that the slack calculation which is done on every timer start is no longer necessary because the granularity levels provide natural batching already. Our extensive testing with various loads did not show any performance degradation vs. the current wheel implementation. This patch does not address the 'fast lookup' issue as we wanted to make sure that there is no regression introduced by the wheel redesign. The optimizations are in follow up patches. This patch contains fixes from Anna-Maria Gleixner and Richard Cochran. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Arjan van de Ven <arjan@infradead.org> Cc: Chris Mason <clm@fb.com> Cc: Eric Dumazet <edumazet@google.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: George Spelvin <linux@sciencehorizons.net> Cc: Josh Triplett <josh@joshtriplett.org> Cc: Len Brown <lenb@kernel.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Rik van Riel <riel@redhat.com> Cc: rt@linutronix.de Link: http://lkml.kernel.org/r/20160704094342.108621834@linutronix.de Signed-off-by: Ingo Molnar <mingo@kernel.org>
1791 lines
51 KiB
C
1791 lines
51 KiB
C
/*
|
|
* linux/kernel/timer.c
|
|
*
|
|
* Kernel internal timers
|
|
*
|
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
|
*
|
|
* 1997-01-28 Modified by Finn Arne Gangstad to make timers scale better.
|
|
*
|
|
* 1997-09-10 Updated NTP code according to technical memorandum Jan '96
|
|
* "A Kernel Model for Precision Timekeeping" by Dave Mills
|
|
* 1998-12-24 Fixed a xtime SMP race (we need the xtime_lock rw spinlock to
|
|
* serialize accesses to xtime/lost_ticks).
|
|
* Copyright (C) 1998 Andrea Arcangeli
|
|
* 1999-03-10 Improved NTP compatibility by Ulrich Windl
|
|
* 2002-05-31 Move sys_sysinfo here and make its locking sane, Robert Love
|
|
* 2000-10-05 Implemented scalable SMP per-CPU timer handling.
|
|
* Copyright (C) 2000, 2001, 2002 Ingo Molnar
|
|
* Designed by David S. Miller, Alexey Kuznetsov and Ingo Molnar
|
|
*/
|
|
|
|
#include <linux/kernel_stat.h>
|
|
#include <linux/export.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/percpu.h>
|
|
#include <linux/init.h>
|
|
#include <linux/mm.h>
|
|
#include <linux/swap.h>
|
|
#include <linux/pid_namespace.h>
|
|
#include <linux/notifier.h>
|
|
#include <linux/thread_info.h>
|
|
#include <linux/time.h>
|
|
#include <linux/jiffies.h>
|
|
#include <linux/posix-timers.h>
|
|
#include <linux/cpu.h>
|
|
#include <linux/syscalls.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/tick.h>
|
|
#include <linux/kallsyms.h>
|
|
#include <linux/irq_work.h>
|
|
#include <linux/sched.h>
|
|
#include <linux/sched/sysctl.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/compat.h>
|
|
|
|
#include <asm/uaccess.h>
|
|
#include <asm/unistd.h>
|
|
#include <asm/div64.h>
|
|
#include <asm/timex.h>
|
|
#include <asm/io.h>
|
|
|
|
#include "tick-internal.h"
|
|
|
|
#define CREATE_TRACE_POINTS
|
|
#include <trace/events/timer.h>
|
|
|
|
__visible u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;
|
|
|
|
EXPORT_SYMBOL(jiffies_64);
|
|
|
|
/*
|
|
* The timer wheel has LVL_DEPTH array levels. Each level provides an array of
|
|
* LVL_SIZE buckets. Each level is driven by its own clock and therefor each
|
|
* level has a different granularity.
|
|
*
|
|
* The level granularity is: LVL_CLK_DIV ^ lvl
|
|
* The level clock frequency is: HZ / (LVL_CLK_DIV ^ level)
|
|
*
|
|
* The array level of a newly armed timer depends on the relative expiry
|
|
* time. The farther the expiry time is away the higher the array level and
|
|
* therefor the granularity becomes.
|
|
*
|
|
* Contrary to the original timer wheel implementation, which aims for 'exact'
|
|
* expiry of the timers, this implementation removes the need for recascading
|
|
* the timers into the lower array levels. The previous 'classic' timer wheel
|
|
* implementation of the kernel already violated the 'exact' expiry by adding
|
|
* slack to the expiry time to provide batched expiration. The granularity
|
|
* levels provide implicit batching.
|
|
*
|
|
* This is an optimization of the original timer wheel implementation for the
|
|
* majority of the timer wheel use cases: timeouts. The vast majority of
|
|
* timeout timers (networking, disk I/O ...) are canceled before expiry. If
|
|
* the timeout expires it indicates that normal operation is disturbed, so it
|
|
* does not matter much whether the timeout comes with a slight delay.
|
|
*
|
|
* The only exception to this are networking timers with a small expiry
|
|
* time. They rely on the granularity. Those fit into the first wheel level,
|
|
* which has HZ granularity.
|
|
*
|
|
* We don't have cascading anymore. timers with a expiry time above the
|
|
* capacity of the last wheel level are force expired at the maximum timeout
|
|
* value of the last wheel level. From data sampling we know that the maximum
|
|
* value observed is 5 days (network connection tracking), so this should not
|
|
* be an issue.
|
|
*
|
|
* The currently chosen array constants values are a good compromise between
|
|
* array size and granularity.
|
|
*
|
|
* This results in the following granularity and range levels:
|
|
*
|
|
* HZ 1000 steps
|
|
* Level Offset Granularity Range
|
|
* 0 0 1 ms 0 ms - 63 ms
|
|
* 1 64 8 ms 64 ms - 511 ms
|
|
* 2 128 64 ms 512 ms - 4095 ms (512ms - ~4s)
|
|
* 3 192 512 ms 4096 ms - 32767 ms (~4s - ~32s)
|
|
* 4 256 4096 ms (~4s) 32768 ms - 262143 ms (~32s - ~4m)
|
|
* 5 320 32768 ms (~32s) 262144 ms - 2097151 ms (~4m - ~34m)
|
|
* 6 384 262144 ms (~4m) 2097152 ms - 16777215 ms (~34m - ~4h)
|
|
* 7 448 2097152 ms (~34m) 16777216 ms - 134217727 ms (~4h - ~1d)
|
|
* 8 512 16777216 ms (~4h) 134217728 ms - 1073741822 ms (~1d - ~12d)
|
|
*
|
|
* HZ 300
|
|
* Level Offset Granularity Range
|
|
* 0 0 3 ms 0 ms - 210 ms
|
|
* 1 64 26 ms 213 ms - 1703 ms (213ms - ~1s)
|
|
* 2 128 213 ms 1706 ms - 13650 ms (~1s - ~13s)
|
|
* 3 192 1706 ms (~1s) 13653 ms - 109223 ms (~13s - ~1m)
|
|
* 4 256 13653 ms (~13s) 109226 ms - 873810 ms (~1m - ~14m)
|
|
* 5 320 109226 ms (~1m) 873813 ms - 6990503 ms (~14m - ~1h)
|
|
* 6 384 873813 ms (~14m) 6990506 ms - 55924050 ms (~1h - ~15h)
|
|
* 7 448 6990506 ms (~1h) 55924053 ms - 447392423 ms (~15h - ~5d)
|
|
* 8 512 55924053 ms (~15h) 447392426 ms - 3579139406 ms (~5d - ~41d)
|
|
*
|
|
* HZ 250
|
|
* Level Offset Granularity Range
|
|
* 0 0 4 ms 0 ms - 255 ms
|
|
* 1 64 32 ms 256 ms - 2047 ms (256ms - ~2s)
|
|
* 2 128 256 ms 2048 ms - 16383 ms (~2s - ~16s)
|
|
* 3 192 2048 ms (~2s) 16384 ms - 131071 ms (~16s - ~2m)
|
|
* 4 256 16384 ms (~16s) 131072 ms - 1048575 ms (~2m - ~17m)
|
|
* 5 320 131072 ms (~2m) 1048576 ms - 8388607 ms (~17m - ~2h)
|
|
* 6 384 1048576 ms (~17m) 8388608 ms - 67108863 ms (~2h - ~18h)
|
|
* 7 448 8388608 ms (~2h) 67108864 ms - 536870911 ms (~18h - ~6d)
|
|
* 8 512 67108864 ms (~18h) 536870912 ms - 4294967288 ms (~6d - ~49d)
|
|
*
|
|
* HZ 100
|
|
* Level Offset Granularity Range
|
|
* 0 0 10 ms 0 ms - 630 ms
|
|
* 1 64 80 ms 640 ms - 5110 ms (640ms - ~5s)
|
|
* 2 128 640 ms 5120 ms - 40950 ms (~5s - ~40s)
|
|
* 3 192 5120 ms (~5s) 40960 ms - 327670 ms (~40s - ~5m)
|
|
* 4 256 40960 ms (~40s) 327680 ms - 2621430 ms (~5m - ~43m)
|
|
* 5 320 327680 ms (~5m) 2621440 ms - 20971510 ms (~43m - ~5h)
|
|
* 6 384 2621440 ms (~43m) 20971520 ms - 167772150 ms (~5h - ~1d)
|
|
* 7 448 20971520 ms (~5h) 167772160 ms - 1342177270 ms (~1d - ~15d)
|
|
*/
|
|
|
|
/* Clock divisor for the next level */
|
|
#define LVL_CLK_SHIFT 3
|
|
#define LVL_CLK_DIV (1UL << LVL_CLK_SHIFT)
|
|
#define LVL_CLK_MASK (LVL_CLK_DIV - 1)
|
|
#define LVL_SHIFT(n) ((n) * LVL_CLK_SHIFT)
|
|
#define LVL_GRAN(n) (1UL << LVL_SHIFT(n))
|
|
|
|
/*
|
|
* The time start value for each level to select the bucket at enqueue
|
|
* time.
|
|
*/
|
|
#define LVL_START(n) ((LVL_SIZE - 1) << (((n) - 1) * LVL_CLK_SHIFT))
|
|
|
|
/* Size of each clock level */
|
|
#define LVL_BITS 6
|
|
#define LVL_SIZE (1UL << LVL_BITS)
|
|
#define LVL_MASK (LVL_SIZE - 1)
|
|
#define LVL_OFFS(n) ((n) * LVL_SIZE)
|
|
|
|
/* Level depth */
|
|
#if HZ > 100
|
|
# define LVL_DEPTH 9
|
|
# else
|
|
# define LVL_DEPTH 8
|
|
#endif
|
|
|
|
/* The cutoff (max. capacity of the wheel) */
|
|
#define WHEEL_TIMEOUT_CUTOFF (LVL_START(LVL_DEPTH))
|
|
#define WHEEL_TIMEOUT_MAX (WHEEL_TIMEOUT_CUTOFF - LVL_GRAN(LVL_DEPTH - 1))
|
|
|
|
/*
|
|
* The resulting wheel size. If NOHZ is configured we allocate two
|
|
* wheels so we have a separate storage for the deferrable timers.
|
|
*/
|
|
#define WHEEL_SIZE (LVL_SIZE * LVL_DEPTH)
|
|
|
|
#ifdef CONFIG_NO_HZ_COMMON
|
|
# define NR_BASES 2
|
|
# define BASE_STD 0
|
|
# define BASE_DEF 1
|
|
#else
|
|
# define NR_BASES 1
|
|
# define BASE_STD 0
|
|
# define BASE_DEF 0
|
|
#endif
|
|
|
|
struct timer_base {
|
|
spinlock_t lock;
|
|
struct timer_list *running_timer;
|
|
unsigned long clk;
|
|
unsigned int cpu;
|
|
bool migration_enabled;
|
|
bool nohz_active;
|
|
DECLARE_BITMAP(pending_map, WHEEL_SIZE);
|
|
struct hlist_head vectors[WHEEL_SIZE];
|
|
} ____cacheline_aligned;
|
|
|
|
static DEFINE_PER_CPU(struct timer_base, timer_bases[NR_BASES]);
|
|
|
|
#if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ_COMMON)
|
|
unsigned int sysctl_timer_migration = 1;
|
|
|
|
void timers_update_migration(bool update_nohz)
|
|
{
|
|
bool on = sysctl_timer_migration && tick_nohz_active;
|
|
unsigned int cpu;
|
|
|
|
/* Avoid the loop, if nothing to update */
|
|
if (this_cpu_read(timer_bases[BASE_STD].migration_enabled) == on)
|
|
return;
|
|
|
|
for_each_possible_cpu(cpu) {
|
|
per_cpu(timer_bases[BASE_STD].migration_enabled, cpu) = on;
|
|
per_cpu(timer_bases[BASE_DEF].migration_enabled, cpu) = on;
|
|
per_cpu(hrtimer_bases.migration_enabled, cpu) = on;
|
|
if (!update_nohz)
|
|
continue;
|
|
per_cpu(timer_bases[BASE_STD].nohz_active, cpu) = true;
|
|
per_cpu(timer_bases[BASE_DEF].nohz_active, cpu) = true;
|
|
per_cpu(hrtimer_bases.nohz_active, cpu) = true;
|
|
}
|
|
}
|
|
|
|
int timer_migration_handler(struct ctl_table *table, int write,
|
|
void __user *buffer, size_t *lenp,
|
|
loff_t *ppos)
|
|
{
|
|
static DEFINE_MUTEX(mutex);
|
|
int ret;
|
|
|
|
mutex_lock(&mutex);
|
|
ret = proc_dointvec(table, write, buffer, lenp, ppos);
|
|
if (!ret && write)
|
|
timers_update_migration(false);
|
|
mutex_unlock(&mutex);
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
static unsigned long round_jiffies_common(unsigned long j, int cpu,
|
|
bool force_up)
|
|
{
|
|
int rem;
|
|
unsigned long original = j;
|
|
|
|
/*
|
|
* We don't want all cpus firing their timers at once hitting the
|
|
* same lock or cachelines, so we skew each extra cpu with an extra
|
|
* 3 jiffies. This 3 jiffies came originally from the mm/ code which
|
|
* already did this.
|
|
* The skew is done by adding 3*cpunr, then round, then subtract this
|
|
* extra offset again.
|
|
*/
|
|
j += cpu * 3;
|
|
|
|
rem = j % HZ;
|
|
|
|
/*
|
|
* If the target jiffie is just after a whole second (which can happen
|
|
* due to delays of the timer irq, long irq off times etc etc) then
|
|
* we should round down to the whole second, not up. Use 1/4th second
|
|
* as cutoff for this rounding as an extreme upper bound for this.
|
|
* But never round down if @force_up is set.
|
|
*/
|
|
if (rem < HZ/4 && !force_up) /* round down */
|
|
j = j - rem;
|
|
else /* round up */
|
|
j = j - rem + HZ;
|
|
|
|
/* now that we have rounded, subtract the extra skew again */
|
|
j -= cpu * 3;
|
|
|
|
/*
|
|
* Make sure j is still in the future. Otherwise return the
|
|
* unmodified value.
|
|
*/
|
|
return time_is_after_jiffies(j) ? j : original;
|
|
}
|
|
|
|
/**
|
|
* __round_jiffies - function to round jiffies to a full second
|
|
* @j: the time in (absolute) jiffies that should be rounded
|
|
* @cpu: the processor number on which the timeout will happen
|
|
*
|
|
* __round_jiffies() rounds an absolute time in the future (in jiffies)
|
|
* up or down to (approximately) full seconds. This is useful for timers
|
|
* for which the exact time they fire does not matter too much, as long as
|
|
* they fire approximately every X seconds.
|
|
*
|
|
* By rounding these timers to whole seconds, all such timers will fire
|
|
* at the same time, rather than at various times spread out. The goal
|
|
* of this is to have the CPU wake up less, which saves power.
|
|
*
|
|
* The exact rounding is skewed for each processor to avoid all
|
|
* processors firing at the exact same time, which could lead
|
|
* to lock contention or spurious cache line bouncing.
|
|
*
|
|
* The return value is the rounded version of the @j parameter.
|
|
*/
|
|
unsigned long __round_jiffies(unsigned long j, int cpu)
|
|
{
|
|
return round_jiffies_common(j, cpu, false);
|
|
}
|
|
EXPORT_SYMBOL_GPL(__round_jiffies);
|
|
|
|
/**
|
|
* __round_jiffies_relative - function to round jiffies to a full second
|
|
* @j: the time in (relative) jiffies that should be rounded
|
|
* @cpu: the processor number on which the timeout will happen
|
|
*
|
|
* __round_jiffies_relative() rounds a time delta in the future (in jiffies)
|
|
* up or down to (approximately) full seconds. This is useful for timers
|
|
* for which the exact time they fire does not matter too much, as long as
|
|
* they fire approximately every X seconds.
|
|
*
|
|
* By rounding these timers to whole seconds, all such timers will fire
|
|
* at the same time, rather than at various times spread out. The goal
|
|
* of this is to have the CPU wake up less, which saves power.
|
|
*
|
|
* The exact rounding is skewed for each processor to avoid all
|
|
* processors firing at the exact same time, which could lead
|
|
* to lock contention or spurious cache line bouncing.
|
|
*
|
|
* The return value is the rounded version of the @j parameter.
|
|
*/
|
|
unsigned long __round_jiffies_relative(unsigned long j, int cpu)
|
|
{
|
|
unsigned long j0 = jiffies;
|
|
|
|
/* Use j0 because jiffies might change while we run */
|
|
return round_jiffies_common(j + j0, cpu, false) - j0;
|
|
}
|
|
EXPORT_SYMBOL_GPL(__round_jiffies_relative);
|
|
|
|
/**
|
|
* round_jiffies - function to round jiffies to a full second
|
|
* @j: the time in (absolute) jiffies that should be rounded
|
|
*
|
|
* round_jiffies() rounds an absolute time in the future (in jiffies)
|
|
* up or down to (approximately) full seconds. This is useful for timers
|
|
* for which the exact time they fire does not matter too much, as long as
|
|
* they fire approximately every X seconds.
|
|
*
|
|
* By rounding these timers to whole seconds, all such timers will fire
|
|
* at the same time, rather than at various times spread out. The goal
|
|
* of this is to have the CPU wake up less, which saves power.
|
|
*
|
|
* The return value is the rounded version of the @j parameter.
|
|
*/
|
|
unsigned long round_jiffies(unsigned long j)
|
|
{
|
|
return round_jiffies_common(j, raw_smp_processor_id(), false);
|
|
}
|
|
EXPORT_SYMBOL_GPL(round_jiffies);
|
|
|
|
/**
|
|
* round_jiffies_relative - function to round jiffies to a full second
|
|
* @j: the time in (relative) jiffies that should be rounded
|
|
*
|
|
* round_jiffies_relative() rounds a time delta in the future (in jiffies)
|
|
* up or down to (approximately) full seconds. This is useful for timers
|
|
* for which the exact time they fire does not matter too much, as long as
|
|
* they fire approximately every X seconds.
|
|
*
|
|
* By rounding these timers to whole seconds, all such timers will fire
|
|
* at the same time, rather than at various times spread out. The goal
|
|
* of this is to have the CPU wake up less, which saves power.
|
|
*
|
|
* The return value is the rounded version of the @j parameter.
|
|
*/
|
|
unsigned long round_jiffies_relative(unsigned long j)
|
|
{
|
|
return __round_jiffies_relative(j, raw_smp_processor_id());
|
|
}
|
|
EXPORT_SYMBOL_GPL(round_jiffies_relative);
|
|
|
|
/**
|
|
* __round_jiffies_up - function to round jiffies up to a full second
|
|
* @j: the time in (absolute) jiffies that should be rounded
|
|
* @cpu: the processor number on which the timeout will happen
|
|
*
|
|
* This is the same as __round_jiffies() except that it will never
|
|
* round down. This is useful for timeouts for which the exact time
|
|
* of firing does not matter too much, as long as they don't fire too
|
|
* early.
|
|
*/
|
|
unsigned long __round_jiffies_up(unsigned long j, int cpu)
|
|
{
|
|
return round_jiffies_common(j, cpu, true);
|
|
}
|
|
EXPORT_SYMBOL_GPL(__round_jiffies_up);
|
|
|
|
/**
|
|
* __round_jiffies_up_relative - function to round jiffies up to a full second
|
|
* @j: the time in (relative) jiffies that should be rounded
|
|
* @cpu: the processor number on which the timeout will happen
|
|
*
|
|
* This is the same as __round_jiffies_relative() except that it will never
|
|
* round down. This is useful for timeouts for which the exact time
|
|
* of firing does not matter too much, as long as they don't fire too
|
|
* early.
|
|
*/
|
|
unsigned long __round_jiffies_up_relative(unsigned long j, int cpu)
|
|
{
|
|
unsigned long j0 = jiffies;
|
|
|
|
/* Use j0 because jiffies might change while we run */
|
|
return round_jiffies_common(j + j0, cpu, true) - j0;
|
|
}
|
|
EXPORT_SYMBOL_GPL(__round_jiffies_up_relative);
|
|
|
|
/**
|
|
* round_jiffies_up - function to round jiffies up to a full second
|
|
* @j: the time in (absolute) jiffies that should be rounded
|
|
*
|
|
* This is the same as round_jiffies() except that it will never
|
|
* round down. This is useful for timeouts for which the exact time
|
|
* of firing does not matter too much, as long as they don't fire too
|
|
* early.
|
|
*/
|
|
unsigned long round_jiffies_up(unsigned long j)
|
|
{
|
|
return round_jiffies_common(j, raw_smp_processor_id(), true);
|
|
}
|
|
EXPORT_SYMBOL_GPL(round_jiffies_up);
|
|
|
|
/**
|
|
* round_jiffies_up_relative - function to round jiffies up to a full second
|
|
* @j: the time in (relative) jiffies that should be rounded
|
|
*
|
|
* This is the same as round_jiffies_relative() except that it will never
|
|
* round down. This is useful for timeouts for which the exact time
|
|
* of firing does not matter too much, as long as they don't fire too
|
|
* early.
|
|
*/
|
|
unsigned long round_jiffies_up_relative(unsigned long j)
|
|
{
|
|
return __round_jiffies_up_relative(j, raw_smp_processor_id());
|
|
}
|
|
EXPORT_SYMBOL_GPL(round_jiffies_up_relative);
|
|
|
|
/**
|
|
* set_timer_slack - set the allowed slack for a timer
|
|
* @timer: the timer to be modified
|
|
* @slack_hz: the amount of time (in jiffies) allowed for rounding
|
|
*
|
|
* Set the amount of time, in jiffies, that a certain timer has
|
|
* in terms of slack. By setting this value, the timer subsystem
|
|
* will schedule the actual timer somewhere between
|
|
* the time mod_timer() asks for, and that time plus the slack.
|
|
*
|
|
* By setting the slack to -1, a percentage of the delay is used
|
|
* instead.
|
|
*/
|
|
void set_timer_slack(struct timer_list *timer, int slack_hz)
|
|
{
|
|
timer->slack = slack_hz;
|
|
}
|
|
EXPORT_SYMBOL_GPL(set_timer_slack);
|
|
|
|
static inline unsigned int timer_get_idx(struct timer_list *timer)
|
|
{
|
|
return (timer->flags & TIMER_ARRAYMASK) >> TIMER_ARRAYSHIFT;
|
|
}
|
|
|
|
static inline void timer_set_idx(struct timer_list *timer, unsigned int idx)
|
|
{
|
|
timer->flags = (timer->flags & ~TIMER_ARRAYMASK) |
|
|
idx << TIMER_ARRAYSHIFT;
|
|
}
|
|
|
|
/*
|
|
* Helper function to calculate the array index for a given expiry
|
|
* time.
|
|
*/
|
|
static inline unsigned calc_index(unsigned expires, unsigned lvl)
|
|
{
|
|
expires = (expires + LVL_GRAN(lvl)) >> LVL_SHIFT(lvl);
|
|
return LVL_OFFS(lvl) + (expires & LVL_MASK);
|
|
}
|
|
|
|
static void
|
|
__internal_add_timer(struct timer_base *base, struct timer_list *timer)
|
|
{
|
|
unsigned long expires = timer->expires;
|
|
unsigned long delta = expires - base->clk;
|
|
struct hlist_head *vec;
|
|
unsigned int idx;
|
|
|
|
if (delta < LVL_START(1)) {
|
|
idx = calc_index(expires, 0);
|
|
} else if (delta < LVL_START(2)) {
|
|
idx = calc_index(expires, 1);
|
|
} else if (delta < LVL_START(3)) {
|
|
idx = calc_index(expires, 2);
|
|
} else if (delta < LVL_START(4)) {
|
|
idx = calc_index(expires, 3);
|
|
} else if (delta < LVL_START(5)) {
|
|
idx = calc_index(expires, 4);
|
|
} else if (delta < LVL_START(6)) {
|
|
idx = calc_index(expires, 5);
|
|
} else if (delta < LVL_START(7)) {
|
|
idx = calc_index(expires, 6);
|
|
} else if (LVL_DEPTH > 8 && delta < LVL_START(8)) {
|
|
idx = calc_index(expires, 7);
|
|
} else if ((long) delta < 0) {
|
|
idx = base->clk & LVL_MASK;
|
|
} else {
|
|
/*
|
|
* Force expire obscene large timeouts to expire at the
|
|
* capacity limit of the wheel.
|
|
*/
|
|
if (expires >= WHEEL_TIMEOUT_CUTOFF)
|
|
expires = WHEEL_TIMEOUT_MAX;
|
|
|
|
idx = calc_index(expires, LVL_DEPTH - 1);
|
|
}
|
|
/*
|
|
* Enqueue the timer into the array bucket, mark it pending in
|
|
* the bitmap and store the index in the timer flags.
|
|
*/
|
|
vec = base->vectors + idx;
|
|
hlist_add_head(&timer->entry, vec);
|
|
__set_bit(idx, base->pending_map);
|
|
timer_set_idx(timer, idx);
|
|
}
|
|
|
|
static void internal_add_timer(struct timer_base *base, struct timer_list *timer)
|
|
{
|
|
__internal_add_timer(base, timer);
|
|
|
|
/*
|
|
* Check whether the other CPU is in dynticks mode and needs
|
|
* to be triggered to reevaluate the timer wheel. We are
|
|
* protected against the other CPU fiddling with the timer by
|
|
* holding the timer base lock. This also makes sure that a
|
|
* CPU on the way to stop its tick can not evaluate the timer
|
|
* wheel.
|
|
*
|
|
* Spare the IPI for deferrable timers on idle targets though.
|
|
* The next busy ticks will take care of it. Except full dynticks
|
|
* require special care against races with idle_cpu(), lets deal
|
|
* with that later.
|
|
*/
|
|
if (IS_ENABLED(CONFIG_NO_HZ_COMMON) && base->nohz_active) {
|
|
if (!(timer->flags & TIMER_DEFERRABLE) ||
|
|
tick_nohz_full_cpu(base->cpu))
|
|
wake_up_nohz_cpu(base->cpu);
|
|
}
|
|
}
|
|
|
|
#ifdef CONFIG_TIMER_STATS
|
|
void __timer_stats_timer_set_start_info(struct timer_list *timer, void *addr)
|
|
{
|
|
if (timer->start_site)
|
|
return;
|
|
|
|
timer->start_site = addr;
|
|
memcpy(timer->start_comm, current->comm, TASK_COMM_LEN);
|
|
timer->start_pid = current->pid;
|
|
}
|
|
|
|
static void timer_stats_account_timer(struct timer_list *timer)
|
|
{
|
|
void *site;
|
|
|
|
/*
|
|
* start_site can be concurrently reset by
|
|
* timer_stats_timer_clear_start_info()
|
|
*/
|
|
site = READ_ONCE(timer->start_site);
|
|
if (likely(!site))
|
|
return;
|
|
|
|
timer_stats_update_stats(timer, timer->start_pid, site,
|
|
timer->function, timer->start_comm,
|
|
timer->flags);
|
|
}
|
|
|
|
#else
|
|
static void timer_stats_account_timer(struct timer_list *timer) {}
|
|
#endif
|
|
|
|
#ifdef CONFIG_DEBUG_OBJECTS_TIMERS
|
|
|
|
static struct debug_obj_descr timer_debug_descr;
|
|
|
|
static void *timer_debug_hint(void *addr)
|
|
{
|
|
return ((struct timer_list *) addr)->function;
|
|
}
|
|
|
|
static bool timer_is_static_object(void *addr)
|
|
{
|
|
struct timer_list *timer = addr;
|
|
|
|
return (timer->entry.pprev == NULL &&
|
|
timer->entry.next == TIMER_ENTRY_STATIC);
|
|
}
|
|
|
|
/*
|
|
* fixup_init is called when:
|
|
* - an active object is initialized
|
|
*/
|
|
static bool timer_fixup_init(void *addr, enum debug_obj_state state)
|
|
{
|
|
struct timer_list *timer = addr;
|
|
|
|
switch (state) {
|
|
case ODEBUG_STATE_ACTIVE:
|
|
del_timer_sync(timer);
|
|
debug_object_init(timer, &timer_debug_descr);
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/* Stub timer callback for improperly used timers. */
|
|
static void stub_timer(unsigned long data)
|
|
{
|
|
WARN_ON(1);
|
|
}
|
|
|
|
/*
|
|
* fixup_activate is called when:
|
|
* - an active object is activated
|
|
* - an unknown non-static object is activated
|
|
*/
|
|
static bool timer_fixup_activate(void *addr, enum debug_obj_state state)
|
|
{
|
|
struct timer_list *timer = addr;
|
|
|
|
switch (state) {
|
|
case ODEBUG_STATE_NOTAVAILABLE:
|
|
setup_timer(timer, stub_timer, 0);
|
|
return true;
|
|
|
|
case ODEBUG_STATE_ACTIVE:
|
|
WARN_ON(1);
|
|
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* fixup_free is called when:
|
|
* - an active object is freed
|
|
*/
|
|
static bool timer_fixup_free(void *addr, enum debug_obj_state state)
|
|
{
|
|
struct timer_list *timer = addr;
|
|
|
|
switch (state) {
|
|
case ODEBUG_STATE_ACTIVE:
|
|
del_timer_sync(timer);
|
|
debug_object_free(timer, &timer_debug_descr);
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* fixup_assert_init is called when:
|
|
* - an untracked/uninit-ed object is found
|
|
*/
|
|
static bool timer_fixup_assert_init(void *addr, enum debug_obj_state state)
|
|
{
|
|
struct timer_list *timer = addr;
|
|
|
|
switch (state) {
|
|
case ODEBUG_STATE_NOTAVAILABLE:
|
|
setup_timer(timer, stub_timer, 0);
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
static struct debug_obj_descr timer_debug_descr = {
|
|
.name = "timer_list",
|
|
.debug_hint = timer_debug_hint,
|
|
.is_static_object = timer_is_static_object,
|
|
.fixup_init = timer_fixup_init,
|
|
.fixup_activate = timer_fixup_activate,
|
|
.fixup_free = timer_fixup_free,
|
|
.fixup_assert_init = timer_fixup_assert_init,
|
|
};
|
|
|
|
static inline void debug_timer_init(struct timer_list *timer)
|
|
{
|
|
debug_object_init(timer, &timer_debug_descr);
|
|
}
|
|
|
|
static inline void debug_timer_activate(struct timer_list *timer)
|
|
{
|
|
debug_object_activate(timer, &timer_debug_descr);
|
|
}
|
|
|
|
static inline void debug_timer_deactivate(struct timer_list *timer)
|
|
{
|
|
debug_object_deactivate(timer, &timer_debug_descr);
|
|
}
|
|
|
|
static inline void debug_timer_free(struct timer_list *timer)
|
|
{
|
|
debug_object_free(timer, &timer_debug_descr);
|
|
}
|
|
|
|
static inline void debug_timer_assert_init(struct timer_list *timer)
|
|
{
|
|
debug_object_assert_init(timer, &timer_debug_descr);
|
|
}
|
|
|
|
static void do_init_timer(struct timer_list *timer, unsigned int flags,
|
|
const char *name, struct lock_class_key *key);
|
|
|
|
void init_timer_on_stack_key(struct timer_list *timer, unsigned int flags,
|
|
const char *name, struct lock_class_key *key)
|
|
{
|
|
debug_object_init_on_stack(timer, &timer_debug_descr);
|
|
do_init_timer(timer, flags, name, key);
|
|
}
|
|
EXPORT_SYMBOL_GPL(init_timer_on_stack_key);
|
|
|
|
void destroy_timer_on_stack(struct timer_list *timer)
|
|
{
|
|
debug_object_free(timer, &timer_debug_descr);
|
|
}
|
|
EXPORT_SYMBOL_GPL(destroy_timer_on_stack);
|
|
|
|
#else
|
|
static inline void debug_timer_init(struct timer_list *timer) { }
|
|
static inline void debug_timer_activate(struct timer_list *timer) { }
|
|
static inline void debug_timer_deactivate(struct timer_list *timer) { }
|
|
static inline void debug_timer_assert_init(struct timer_list *timer) { }
|
|
#endif
|
|
|
|
static inline void debug_init(struct timer_list *timer)
|
|
{
|
|
debug_timer_init(timer);
|
|
trace_timer_init(timer);
|
|
}
|
|
|
|
static inline void
|
|
debug_activate(struct timer_list *timer, unsigned long expires)
|
|
{
|
|
debug_timer_activate(timer);
|
|
trace_timer_start(timer, expires, timer->flags);
|
|
}
|
|
|
|
static inline void debug_deactivate(struct timer_list *timer)
|
|
{
|
|
debug_timer_deactivate(timer);
|
|
trace_timer_cancel(timer);
|
|
}
|
|
|
|
static inline void debug_assert_init(struct timer_list *timer)
|
|
{
|
|
debug_timer_assert_init(timer);
|
|
}
|
|
|
|
static void do_init_timer(struct timer_list *timer, unsigned int flags,
|
|
const char *name, struct lock_class_key *key)
|
|
{
|
|
timer->entry.pprev = NULL;
|
|
timer->flags = flags | raw_smp_processor_id();
|
|
timer->slack = -1;
|
|
#ifdef CONFIG_TIMER_STATS
|
|
timer->start_site = NULL;
|
|
timer->start_pid = -1;
|
|
memset(timer->start_comm, 0, TASK_COMM_LEN);
|
|
#endif
|
|
lockdep_init_map(&timer->lockdep_map, name, key, 0);
|
|
}
|
|
|
|
/**
|
|
* init_timer_key - initialize a timer
|
|
* @timer: the timer to be initialized
|
|
* @flags: timer flags
|
|
* @name: name of the timer
|
|
* @key: lockdep class key of the fake lock used for tracking timer
|
|
* sync lock dependencies
|
|
*
|
|
* init_timer_key() must be done to a timer prior calling *any* of the
|
|
* other timer functions.
|
|
*/
|
|
void init_timer_key(struct timer_list *timer, unsigned int flags,
|
|
const char *name, struct lock_class_key *key)
|
|
{
|
|
debug_init(timer);
|
|
do_init_timer(timer, flags, name, key);
|
|
}
|
|
EXPORT_SYMBOL(init_timer_key);
|
|
|
|
static inline void detach_timer(struct timer_list *timer, bool clear_pending)
|
|
{
|
|
struct hlist_node *entry = &timer->entry;
|
|
|
|
debug_deactivate(timer);
|
|
|
|
__hlist_del(entry);
|
|
if (clear_pending)
|
|
entry->pprev = NULL;
|
|
entry->next = LIST_POISON2;
|
|
}
|
|
|
|
static int detach_if_pending(struct timer_list *timer, struct timer_base *base,
|
|
bool clear_pending)
|
|
{
|
|
unsigned idx = timer_get_idx(timer);
|
|
|
|
if (!timer_pending(timer))
|
|
return 0;
|
|
|
|
if (hlist_is_singular_node(&timer->entry, base->vectors + idx))
|
|
__clear_bit(idx, base->pending_map);
|
|
|
|
detach_timer(timer, clear_pending);
|
|
return 1;
|
|
}
|
|
|
|
static inline struct timer_base *get_timer_cpu_base(u32 tflags, u32 cpu)
|
|
{
|
|
struct timer_base *base = per_cpu_ptr(&timer_bases[BASE_STD], cpu);
|
|
|
|
/*
|
|
* If the timer is deferrable and nohz is active then we need to use
|
|
* the deferrable base.
|
|
*/
|
|
if (IS_ENABLED(CONFIG_NO_HZ_COMMON) && base->nohz_active &&
|
|
(tflags & TIMER_DEFERRABLE))
|
|
base = per_cpu_ptr(&timer_bases[BASE_DEF], cpu);
|
|
return base;
|
|
}
|
|
|
|
static inline struct timer_base *get_timer_this_cpu_base(u32 tflags)
|
|
{
|
|
struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]);
|
|
|
|
/*
|
|
* If the timer is deferrable and nohz is active then we need to use
|
|
* the deferrable base.
|
|
*/
|
|
if (IS_ENABLED(CONFIG_NO_HZ_COMMON) && base->nohz_active &&
|
|
(tflags & TIMER_DEFERRABLE))
|
|
base = this_cpu_ptr(&timer_bases[BASE_DEF]);
|
|
return base;
|
|
}
|
|
|
|
static inline struct timer_base *get_timer_base(u32 tflags)
|
|
{
|
|
return get_timer_cpu_base(tflags, tflags & TIMER_CPUMASK);
|
|
}
|
|
|
|
static inline struct timer_base *get_target_base(struct timer_base *base,
|
|
unsigned tflags)
|
|
{
|
|
#if defined(CONFIG_NO_HZ_COMMON) && defined(CONFIG_SMP)
|
|
if ((tflags & TIMER_PINNED) || !base->migration_enabled)
|
|
return get_timer_this_cpu_base(tflags);
|
|
return get_timer_cpu_base(tflags, get_nohz_timer_target());
|
|
#else
|
|
return get_timer_this_cpu_base(tflags);
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* We are using hashed locking: Holding per_cpu(timer_bases[x]).lock means
|
|
* that all timers which are tied to this base are locked, and the base itself
|
|
* is locked too.
|
|
*
|
|
* So __run_timers/migrate_timers can safely modify all timers which could
|
|
* be found in the base->vectors array.
|
|
*
|
|
* When a timer is migrating then the TIMER_MIGRATING flag is set and we need
|
|
* to wait until the migration is done.
|
|
*/
|
|
static struct timer_base *lock_timer_base(struct timer_list *timer,
|
|
unsigned long *flags)
|
|
__acquires(timer->base->lock)
|
|
{
|
|
for (;;) {
|
|
struct timer_base *base;
|
|
u32 tf = timer->flags;
|
|
|
|
if (!(tf & TIMER_MIGRATING)) {
|
|
base = get_timer_base(tf);
|
|
spin_lock_irqsave(&base->lock, *flags);
|
|
if (timer->flags == tf)
|
|
return base;
|
|
spin_unlock_irqrestore(&base->lock, *flags);
|
|
}
|
|
cpu_relax();
|
|
}
|
|
}
|
|
|
|
static inline int
|
|
__mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only)
|
|
{
|
|
struct timer_base *base, *new_base;
|
|
unsigned long flags;
|
|
int ret = 0;
|
|
|
|
/*
|
|
* TODO: Calculate the array bucket of the timer right here w/o
|
|
* holding the base lock. This allows to check not only
|
|
* timer->expires == expires below, but also whether the timer
|
|
* ends up in the same bucket. If we really need to requeue
|
|
* the timer then we check whether base->clk have
|
|
* advanced between here and locking the timer base. If
|
|
* jiffies advanced we have to recalc the array bucket with the
|
|
* lock held.
|
|
*/
|
|
|
|
/*
|
|
* This is a common optimization triggered by the
|
|
* networking code - if the timer is re-modified
|
|
* to be the same thing then just return:
|
|
*/
|
|
if (timer_pending(timer)) {
|
|
if (timer->expires == expires)
|
|
return 1;
|
|
}
|
|
|
|
timer_stats_timer_set_start_info(timer);
|
|
BUG_ON(!timer->function);
|
|
|
|
base = lock_timer_base(timer, &flags);
|
|
|
|
ret = detach_if_pending(timer, base, false);
|
|
if (!ret && pending_only)
|
|
goto out_unlock;
|
|
|
|
debug_activate(timer, expires);
|
|
|
|
new_base = get_target_base(base, timer->flags);
|
|
|
|
if (base != new_base) {
|
|
/*
|
|
* We are trying to schedule the timer on the new base.
|
|
* However we can't change timer's base while it is running,
|
|
* otherwise del_timer_sync() can't detect that the timer's
|
|
* handler yet has not finished. This also guarantees that the
|
|
* timer is serialized wrt itself.
|
|
*/
|
|
if (likely(base->running_timer != timer)) {
|
|
/* See the comment in lock_timer_base() */
|
|
timer->flags |= TIMER_MIGRATING;
|
|
|
|
spin_unlock(&base->lock);
|
|
base = new_base;
|
|
spin_lock(&base->lock);
|
|
WRITE_ONCE(timer->flags,
|
|
(timer->flags & ~TIMER_BASEMASK) | base->cpu);
|
|
}
|
|
}
|
|
|
|
timer->expires = expires;
|
|
internal_add_timer(base, timer);
|
|
|
|
out_unlock:
|
|
spin_unlock_irqrestore(&base->lock, flags);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* mod_timer_pending - modify a pending timer's timeout
|
|
* @timer: the pending timer to be modified
|
|
* @expires: new timeout in jiffies
|
|
*
|
|
* mod_timer_pending() is the same for pending timers as mod_timer(),
|
|
* but will not re-activate and modify already deleted timers.
|
|
*
|
|
* It is useful for unserialized use of timers.
|
|
*/
|
|
int mod_timer_pending(struct timer_list *timer, unsigned long expires)
|
|
{
|
|
return __mod_timer(timer, expires, true);
|
|
}
|
|
EXPORT_SYMBOL(mod_timer_pending);
|
|
|
|
/**
|
|
* mod_timer - modify a timer's timeout
|
|
* @timer: the timer to be modified
|
|
* @expires: new timeout in jiffies
|
|
*
|
|
* mod_timer() is a more efficient way to update the expire field of an
|
|
* active timer (if the timer is inactive it will be activated)
|
|
*
|
|
* mod_timer(timer, expires) is equivalent to:
|
|
*
|
|
* del_timer(timer); timer->expires = expires; add_timer(timer);
|
|
*
|
|
* Note that if there are multiple unserialized concurrent users of the
|
|
* same timer, then mod_timer() is the only safe way to modify the timeout,
|
|
* since add_timer() cannot modify an already running timer.
|
|
*
|
|
* The function returns whether it has modified a pending timer or not.
|
|
* (ie. mod_timer() of an inactive timer returns 0, mod_timer() of an
|
|
* active timer returns 1.)
|
|
*/
|
|
int mod_timer(struct timer_list *timer, unsigned long expires)
|
|
{
|
|
return __mod_timer(timer, expires, false);
|
|
}
|
|
EXPORT_SYMBOL(mod_timer);
|
|
|
|
/**
|
|
* add_timer - start a timer
|
|
* @timer: the timer to be added
|
|
*
|
|
* The kernel will do a ->function(->data) callback from the
|
|
* timer interrupt at the ->expires point in the future. The
|
|
* current time is 'jiffies'.
|
|
*
|
|
* The timer's ->expires, ->function (and if the handler uses it, ->data)
|
|
* fields must be set prior calling this function.
|
|
*
|
|
* Timers with an ->expires field in the past will be executed in the next
|
|
* timer tick.
|
|
*/
|
|
void add_timer(struct timer_list *timer)
|
|
{
|
|
BUG_ON(timer_pending(timer));
|
|
mod_timer(timer, timer->expires);
|
|
}
|
|
EXPORT_SYMBOL(add_timer);
|
|
|
|
/**
|
|
* add_timer_on - start a timer on a particular CPU
|
|
* @timer: the timer to be added
|
|
* @cpu: the CPU to start it on
|
|
*
|
|
* This is not very scalable on SMP. Double adds are not possible.
|
|
*/
|
|
void add_timer_on(struct timer_list *timer, int cpu)
|
|
{
|
|
struct timer_base *new_base, *base;
|
|
unsigned long flags;
|
|
|
|
timer_stats_timer_set_start_info(timer);
|
|
BUG_ON(timer_pending(timer) || !timer->function);
|
|
|
|
new_base = get_timer_cpu_base(timer->flags, cpu);
|
|
|
|
/*
|
|
* If @timer was on a different CPU, it should be migrated with the
|
|
* old base locked to prevent other operations proceeding with the
|
|
* wrong base locked. See lock_timer_base().
|
|
*/
|
|
base = lock_timer_base(timer, &flags);
|
|
if (base != new_base) {
|
|
timer->flags |= TIMER_MIGRATING;
|
|
|
|
spin_unlock(&base->lock);
|
|
base = new_base;
|
|
spin_lock(&base->lock);
|
|
WRITE_ONCE(timer->flags,
|
|
(timer->flags & ~TIMER_BASEMASK) | cpu);
|
|
}
|
|
|
|
debug_activate(timer, timer->expires);
|
|
internal_add_timer(base, timer);
|
|
spin_unlock_irqrestore(&base->lock, flags);
|
|
}
|
|
EXPORT_SYMBOL_GPL(add_timer_on);
|
|
|
|
/**
|
|
* del_timer - deactive a timer.
|
|
* @timer: the timer to be deactivated
|
|
*
|
|
* del_timer() deactivates a timer - this works on both active and inactive
|
|
* timers.
|
|
*
|
|
* The function returns whether it has deactivated a pending timer or not.
|
|
* (ie. del_timer() of an inactive timer returns 0, del_timer() of an
|
|
* active timer returns 1.)
|
|
*/
|
|
int del_timer(struct timer_list *timer)
|
|
{
|
|
struct timer_base *base;
|
|
unsigned long flags;
|
|
int ret = 0;
|
|
|
|
debug_assert_init(timer);
|
|
|
|
timer_stats_timer_clear_start_info(timer);
|
|
if (timer_pending(timer)) {
|
|
base = lock_timer_base(timer, &flags);
|
|
ret = detach_if_pending(timer, base, true);
|
|
spin_unlock_irqrestore(&base->lock, flags);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
EXPORT_SYMBOL(del_timer);
|
|
|
|
/**
|
|
* try_to_del_timer_sync - Try to deactivate a timer
|
|
* @timer: timer do del
|
|
*
|
|
* This function tries to deactivate a timer. Upon successful (ret >= 0)
|
|
* exit the timer is not queued and the handler is not running on any CPU.
|
|
*/
|
|
int try_to_del_timer_sync(struct timer_list *timer)
|
|
{
|
|
struct timer_base *base;
|
|
unsigned long flags;
|
|
int ret = -1;
|
|
|
|
debug_assert_init(timer);
|
|
|
|
base = lock_timer_base(timer, &flags);
|
|
|
|
if (base->running_timer != timer) {
|
|
timer_stats_timer_clear_start_info(timer);
|
|
ret = detach_if_pending(timer, base, true);
|
|
}
|
|
spin_unlock_irqrestore(&base->lock, flags);
|
|
|
|
return ret;
|
|
}
|
|
EXPORT_SYMBOL(try_to_del_timer_sync);
|
|
|
|
#ifdef CONFIG_SMP
|
|
/**
|
|
* del_timer_sync - deactivate a timer and wait for the handler to finish.
|
|
* @timer: the timer to be deactivated
|
|
*
|
|
* This function only differs from del_timer() on SMP: besides deactivating
|
|
* the timer it also makes sure the handler has finished executing on other
|
|
* CPUs.
|
|
*
|
|
* Synchronization rules: Callers must prevent restarting of the timer,
|
|
* otherwise this function is meaningless. It must not be called from
|
|
* interrupt contexts unless the timer is an irqsafe one. The caller must
|
|
* not hold locks which would prevent completion of the timer's
|
|
* handler. The timer's handler must not call add_timer_on(). Upon exit the
|
|
* timer is not queued and the handler is not running on any CPU.
|
|
*
|
|
* Note: For !irqsafe timers, you must not hold locks that are held in
|
|
* interrupt context while calling this function. Even if the lock has
|
|
* nothing to do with the timer in question. Here's why:
|
|
*
|
|
* CPU0 CPU1
|
|
* ---- ----
|
|
* <SOFTIRQ>
|
|
* call_timer_fn();
|
|
* base->running_timer = mytimer;
|
|
* spin_lock_irq(somelock);
|
|
* <IRQ>
|
|
* spin_lock(somelock);
|
|
* del_timer_sync(mytimer);
|
|
* while (base->running_timer == mytimer);
|
|
*
|
|
* Now del_timer_sync() will never return and never release somelock.
|
|
* The interrupt on the other CPU is waiting to grab somelock but
|
|
* it has interrupted the softirq that CPU0 is waiting to finish.
|
|
*
|
|
* The function returns whether it has deactivated a pending timer or not.
|
|
*/
|
|
int del_timer_sync(struct timer_list *timer)
|
|
{
|
|
#ifdef CONFIG_LOCKDEP
|
|
unsigned long flags;
|
|
|
|
/*
|
|
* If lockdep gives a backtrace here, please reference
|
|
* the synchronization rules above.
|
|
*/
|
|
local_irq_save(flags);
|
|
lock_map_acquire(&timer->lockdep_map);
|
|
lock_map_release(&timer->lockdep_map);
|
|
local_irq_restore(flags);
|
|
#endif
|
|
/*
|
|
* don't use it in hardirq context, because it
|
|
* could lead to deadlock.
|
|
*/
|
|
WARN_ON(in_irq() && !(timer->flags & TIMER_IRQSAFE));
|
|
for (;;) {
|
|
int ret = try_to_del_timer_sync(timer);
|
|
if (ret >= 0)
|
|
return ret;
|
|
cpu_relax();
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(del_timer_sync);
|
|
#endif
|
|
|
|
static void call_timer_fn(struct timer_list *timer, void (*fn)(unsigned long),
|
|
unsigned long data)
|
|
{
|
|
int count = preempt_count();
|
|
|
|
#ifdef CONFIG_LOCKDEP
|
|
/*
|
|
* It is permissible to free the timer from inside the
|
|
* function that is called from it, this we need to take into
|
|
* account for lockdep too. To avoid bogus "held lock freed"
|
|
* warnings as well as problems when looking into
|
|
* timer->lockdep_map, make a copy and use that here.
|
|
*/
|
|
struct lockdep_map lockdep_map;
|
|
|
|
lockdep_copy_map(&lockdep_map, &timer->lockdep_map);
|
|
#endif
|
|
/*
|
|
* Couple the lock chain with the lock chain at
|
|
* del_timer_sync() by acquiring the lock_map around the fn()
|
|
* call here and in del_timer_sync().
|
|
*/
|
|
lock_map_acquire(&lockdep_map);
|
|
|
|
trace_timer_expire_entry(timer);
|
|
fn(data);
|
|
trace_timer_expire_exit(timer);
|
|
|
|
lock_map_release(&lockdep_map);
|
|
|
|
if (count != preempt_count()) {
|
|
WARN_ONCE(1, "timer: %pF preempt leak: %08x -> %08x\n",
|
|
fn, count, preempt_count());
|
|
/*
|
|
* Restore the preempt count. That gives us a decent
|
|
* chance to survive and extract information. If the
|
|
* callback kept a lock held, bad luck, but not worse
|
|
* than the BUG() we had.
|
|
*/
|
|
preempt_count_set(count);
|
|
}
|
|
}
|
|
|
|
static void expire_timers(struct timer_base *base, struct hlist_head *head)
|
|
{
|
|
while (!hlist_empty(head)) {
|
|
struct timer_list *timer;
|
|
void (*fn)(unsigned long);
|
|
unsigned long data;
|
|
|
|
timer = hlist_entry(head->first, struct timer_list, entry);
|
|
timer_stats_account_timer(timer);
|
|
|
|
base->running_timer = timer;
|
|
detach_timer(timer, true);
|
|
|
|
fn = timer->function;
|
|
data = timer->data;
|
|
|
|
if (timer->flags & TIMER_IRQSAFE) {
|
|
spin_unlock(&base->lock);
|
|
call_timer_fn(timer, fn, data);
|
|
spin_lock(&base->lock);
|
|
} else {
|
|
spin_unlock_irq(&base->lock);
|
|
call_timer_fn(timer, fn, data);
|
|
spin_lock_irq(&base->lock);
|
|
}
|
|
}
|
|
}
|
|
|
|
static int collect_expired_timers(struct timer_base *base,
|
|
struct hlist_head *heads)
|
|
{
|
|
unsigned long clk = base->clk;
|
|
struct hlist_head *vec;
|
|
int i, levels = 0;
|
|
unsigned int idx;
|
|
|
|
for (i = 0; i < LVL_DEPTH; i++) {
|
|
idx = (clk & LVL_MASK) + i * LVL_SIZE;
|
|
|
|
if (__test_and_clear_bit(idx, base->pending_map)) {
|
|
vec = base->vectors + idx;
|
|
hlist_move_list(vec, heads++);
|
|
levels++;
|
|
}
|
|
/* Is it time to look at the next level? */
|
|
if (clk & LVL_CLK_MASK)
|
|
break;
|
|
/* Shift clock for the next level granularity */
|
|
clk >>= LVL_CLK_SHIFT;
|
|
}
|
|
return levels;
|
|
}
|
|
|
|
/**
|
|
* __run_timers - run all expired timers (if any) on this CPU.
|
|
* @base: the timer vector to be processed.
|
|
*/
|
|
static inline void __run_timers(struct timer_base *base)
|
|
{
|
|
struct hlist_head heads[LVL_DEPTH];
|
|
int levels;
|
|
|
|
if (!time_after_eq(jiffies, base->clk))
|
|
return;
|
|
|
|
spin_lock_irq(&base->lock);
|
|
|
|
while (time_after_eq(jiffies, base->clk)) {
|
|
|
|
levels = collect_expired_timers(base, heads);
|
|
base->clk++;
|
|
|
|
while (levels--)
|
|
expire_timers(base, heads + levels);
|
|
}
|
|
base->running_timer = NULL;
|
|
spin_unlock_irq(&base->lock);
|
|
}
|
|
|
|
#ifdef CONFIG_NO_HZ_COMMON
|
|
/*
|
|
* Find the next pending bucket of a level. Search from @offset + @clk upwards
|
|
* and if nothing there, search from start of the level (@offset) up to
|
|
* @offset + clk.
|
|
*/
|
|
static int next_pending_bucket(struct timer_base *base, unsigned offset,
|
|
unsigned clk)
|
|
{
|
|
unsigned pos, start = offset + clk;
|
|
unsigned end = offset + LVL_SIZE;
|
|
|
|
pos = find_next_bit(base->pending_map, end, start);
|
|
if (pos < end)
|
|
return pos - start;
|
|
|
|
pos = find_next_bit(base->pending_map, start, offset);
|
|
return pos < start ? pos + LVL_SIZE - start : -1;
|
|
}
|
|
|
|
/*
|
|
* Search the first expiring timer in the various clock levels.
|
|
*/
|
|
static unsigned long __next_timer_interrupt(struct timer_base *base)
|
|
{
|
|
unsigned long clk, next, adj;
|
|
unsigned lvl, offset = 0;
|
|
|
|
spin_lock(&base->lock);
|
|
next = base->clk + NEXT_TIMER_MAX_DELTA;
|
|
clk = base->clk;
|
|
for (lvl = 0; lvl < LVL_DEPTH; lvl++, offset += LVL_SIZE) {
|
|
int pos = next_pending_bucket(base, offset, clk & LVL_MASK);
|
|
|
|
if (pos >= 0) {
|
|
unsigned long tmp = clk + (unsigned long) pos;
|
|
|
|
tmp <<= LVL_SHIFT(lvl);
|
|
if (time_before(tmp, next))
|
|
next = tmp;
|
|
}
|
|
/*
|
|
* Clock for the next level. If the current level clock lower
|
|
* bits are zero, we look at the next level as is. If not we
|
|
* need to advance it by one because that's going to be the
|
|
* next expiring bucket in that level. base->clk is the next
|
|
* expiring jiffie. So in case of:
|
|
*
|
|
* LVL5 LVL4 LVL3 LVL2 LVL1 LVL0
|
|
* 0 0 0 0 0 0
|
|
*
|
|
* we have to look at all levels @index 0. With
|
|
*
|
|
* LVL5 LVL4 LVL3 LVL2 LVL1 LVL0
|
|
* 0 0 0 0 0 2
|
|
*
|
|
* LVL0 has the next expiring bucket @index 2. The upper
|
|
* levels have the next expiring bucket @index 1.
|
|
*
|
|
* In case that the propagation wraps the next level the same
|
|
* rules apply:
|
|
*
|
|
* LVL5 LVL4 LVL3 LVL2 LVL1 LVL0
|
|
* 0 0 0 0 F 2
|
|
*
|
|
* So after looking at LVL0 we get:
|
|
*
|
|
* LVL5 LVL4 LVL3 LVL2 LVL1
|
|
* 0 0 0 1 0
|
|
*
|
|
* So no propagation from LVL1 to LVL2 because that happened
|
|
* with the add already, but then we need to propagate further
|
|
* from LVL2 to LVL3.
|
|
*
|
|
* So the simple check whether the lower bits of the current
|
|
* level are 0 or not is sufficient for all cases.
|
|
*/
|
|
adj = clk & LVL_CLK_MASK ? 1 : 0;
|
|
clk >>= LVL_CLK_SHIFT;
|
|
clk += adj;
|
|
}
|
|
spin_unlock(&base->lock);
|
|
return next;
|
|
}
|
|
|
|
/*
|
|
* Check, if the next hrtimer event is before the next timer wheel
|
|
* event:
|
|
*/
|
|
static u64 cmp_next_hrtimer_event(u64 basem, u64 expires)
|
|
{
|
|
u64 nextevt = hrtimer_get_next_event();
|
|
|
|
/*
|
|
* If high resolution timers are enabled
|
|
* hrtimer_get_next_event() returns KTIME_MAX.
|
|
*/
|
|
if (expires <= nextevt)
|
|
return expires;
|
|
|
|
/*
|
|
* If the next timer is already expired, return the tick base
|
|
* time so the tick is fired immediately.
|
|
*/
|
|
if (nextevt <= basem)
|
|
return basem;
|
|
|
|
/*
|
|
* Round up to the next jiffie. High resolution timers are
|
|
* off, so the hrtimers are expired in the tick and we need to
|
|
* make sure that this tick really expires the timer to avoid
|
|
* a ping pong of the nohz stop code.
|
|
*
|
|
* Use DIV_ROUND_UP_ULL to prevent gcc calling __divdi3
|
|
*/
|
|
return DIV_ROUND_UP_ULL(nextevt, TICK_NSEC) * TICK_NSEC;
|
|
}
|
|
|
|
/**
|
|
* get_next_timer_interrupt - return the time (clock mono) of the next timer
|
|
* @basej: base time jiffies
|
|
* @basem: base time clock monotonic
|
|
*
|
|
* Returns the tick aligned clock monotonic time of the next pending
|
|
* timer or KTIME_MAX if no timer is pending.
|
|
*/
|
|
u64 get_next_timer_interrupt(unsigned long basej, u64 basem)
|
|
{
|
|
struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]);
|
|
u64 expires = KTIME_MAX;
|
|
unsigned long nextevt;
|
|
|
|
/*
|
|
* Pretend that there is no timer pending if the cpu is offline.
|
|
* Possible pending timers will be migrated later to an active cpu.
|
|
*/
|
|
if (cpu_is_offline(smp_processor_id()))
|
|
return expires;
|
|
|
|
nextevt = __next_timer_interrupt(base);
|
|
if (time_before_eq(nextevt, basej))
|
|
expires = basem;
|
|
else
|
|
expires = basem + (nextevt - basej) * TICK_NSEC;
|
|
|
|
return cmp_next_hrtimer_event(basem, expires);
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* Called from the timer interrupt handler to charge one tick to the current
|
|
* process. user_tick is 1 if the tick is user time, 0 for system.
|
|
*/
|
|
void update_process_times(int user_tick)
|
|
{
|
|
struct task_struct *p = current;
|
|
|
|
/* Note: this timer irq context must be accounted for as well. */
|
|
account_process_tick(p, user_tick);
|
|
run_local_timers();
|
|
rcu_check_callbacks(user_tick);
|
|
#ifdef CONFIG_IRQ_WORK
|
|
if (in_irq())
|
|
irq_work_tick();
|
|
#endif
|
|
scheduler_tick();
|
|
run_posix_cpu_timers(p);
|
|
}
|
|
|
|
/*
|
|
* This function runs timers and the timer-tq in bottom half context.
|
|
*/
|
|
static void run_timer_softirq(struct softirq_action *h)
|
|
{
|
|
struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]);
|
|
|
|
__run_timers(base);
|
|
if (IS_ENABLED(CONFIG_NO_HZ_COMMON) && base->nohz_active)
|
|
__run_timers(this_cpu_ptr(&timer_bases[BASE_DEF]));
|
|
}
|
|
|
|
/*
|
|
* Called by the local, per-CPU timer interrupt on SMP.
|
|
*/
|
|
void run_local_timers(void)
|
|
{
|
|
hrtimer_run_queues();
|
|
raise_softirq(TIMER_SOFTIRQ);
|
|
}
|
|
|
|
#ifdef __ARCH_WANT_SYS_ALARM
|
|
|
|
/*
|
|
* For backwards compatibility? This can be done in libc so Alpha
|
|
* and all newer ports shouldn't need it.
|
|
*/
|
|
SYSCALL_DEFINE1(alarm, unsigned int, seconds)
|
|
{
|
|
return alarm_setitimer(seconds);
|
|
}
|
|
|
|
#endif
|
|
|
|
static void process_timeout(unsigned long __data)
|
|
{
|
|
wake_up_process((struct task_struct *)__data);
|
|
}
|
|
|
|
/**
|
|
* schedule_timeout - sleep until timeout
|
|
* @timeout: timeout value in jiffies
|
|
*
|
|
* Make the current task sleep until @timeout jiffies have
|
|
* elapsed. The routine will return immediately unless
|
|
* the current task state has been set (see set_current_state()).
|
|
*
|
|
* You can set the task state as follows -
|
|
*
|
|
* %TASK_UNINTERRUPTIBLE - at least @timeout jiffies are guaranteed to
|
|
* pass before the routine returns. The routine will return 0
|
|
*
|
|
* %TASK_INTERRUPTIBLE - the routine may return early if a signal is
|
|
* delivered to the current task. In this case the remaining time
|
|
* in jiffies will be returned, or 0 if the timer expired in time
|
|
*
|
|
* The current task state is guaranteed to be TASK_RUNNING when this
|
|
* routine returns.
|
|
*
|
|
* Specifying a @timeout value of %MAX_SCHEDULE_TIMEOUT will schedule
|
|
* the CPU away without a bound on the timeout. In this case the return
|
|
* value will be %MAX_SCHEDULE_TIMEOUT.
|
|
*
|
|
* In all cases the return value is guaranteed to be non-negative.
|
|
*/
|
|
signed long __sched schedule_timeout(signed long timeout)
|
|
{
|
|
struct timer_list timer;
|
|
unsigned long expire;
|
|
|
|
switch (timeout)
|
|
{
|
|
case MAX_SCHEDULE_TIMEOUT:
|
|
/*
|
|
* These two special cases are useful to be comfortable
|
|
* in the caller. Nothing more. We could take
|
|
* MAX_SCHEDULE_TIMEOUT from one of the negative value
|
|
* but I' d like to return a valid offset (>=0) to allow
|
|
* the caller to do everything it want with the retval.
|
|
*/
|
|
schedule();
|
|
goto out;
|
|
default:
|
|
/*
|
|
* Another bit of PARANOID. Note that the retval will be
|
|
* 0 since no piece of kernel is supposed to do a check
|
|
* for a negative retval of schedule_timeout() (since it
|
|
* should never happens anyway). You just have the printk()
|
|
* that will tell you if something is gone wrong and where.
|
|
*/
|
|
if (timeout < 0) {
|
|
printk(KERN_ERR "schedule_timeout: wrong timeout "
|
|
"value %lx\n", timeout);
|
|
dump_stack();
|
|
current->state = TASK_RUNNING;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
expire = timeout + jiffies;
|
|
|
|
setup_timer_on_stack(&timer, process_timeout, (unsigned long)current);
|
|
__mod_timer(&timer, expire, false);
|
|
schedule();
|
|
del_singleshot_timer_sync(&timer);
|
|
|
|
/* Remove the timer from the object tracker */
|
|
destroy_timer_on_stack(&timer);
|
|
|
|
timeout = expire - jiffies;
|
|
|
|
out:
|
|
return timeout < 0 ? 0 : timeout;
|
|
}
|
|
EXPORT_SYMBOL(schedule_timeout);
|
|
|
|
/*
|
|
* We can use __set_current_state() here because schedule_timeout() calls
|
|
* schedule() unconditionally.
|
|
*/
|
|
signed long __sched schedule_timeout_interruptible(signed long timeout)
|
|
{
|
|
__set_current_state(TASK_INTERRUPTIBLE);
|
|
return schedule_timeout(timeout);
|
|
}
|
|
EXPORT_SYMBOL(schedule_timeout_interruptible);
|
|
|
|
signed long __sched schedule_timeout_killable(signed long timeout)
|
|
{
|
|
__set_current_state(TASK_KILLABLE);
|
|
return schedule_timeout(timeout);
|
|
}
|
|
EXPORT_SYMBOL(schedule_timeout_killable);
|
|
|
|
signed long __sched schedule_timeout_uninterruptible(signed long timeout)
|
|
{
|
|
__set_current_state(TASK_UNINTERRUPTIBLE);
|
|
return schedule_timeout(timeout);
|
|
}
|
|
EXPORT_SYMBOL(schedule_timeout_uninterruptible);
|
|
|
|
/*
|
|
* Like schedule_timeout_uninterruptible(), except this task will not contribute
|
|
* to load average.
|
|
*/
|
|
signed long __sched schedule_timeout_idle(signed long timeout)
|
|
{
|
|
__set_current_state(TASK_IDLE);
|
|
return schedule_timeout(timeout);
|
|
}
|
|
EXPORT_SYMBOL(schedule_timeout_idle);
|
|
|
|
#ifdef CONFIG_HOTPLUG_CPU
|
|
static void migrate_timer_list(struct timer_base *new_base, struct hlist_head *head)
|
|
{
|
|
struct timer_list *timer;
|
|
int cpu = new_base->cpu;
|
|
|
|
while (!hlist_empty(head)) {
|
|
timer = hlist_entry(head->first, struct timer_list, entry);
|
|
detach_timer(timer, false);
|
|
timer->flags = (timer->flags & ~TIMER_BASEMASK) | cpu;
|
|
internal_add_timer(new_base, timer);
|
|
}
|
|
}
|
|
|
|
static void migrate_timers(int cpu)
|
|
{
|
|
struct timer_base *old_base;
|
|
struct timer_base *new_base;
|
|
int b, i;
|
|
|
|
BUG_ON(cpu_online(cpu));
|
|
|
|
for (b = 0; b < NR_BASES; b++) {
|
|
old_base = per_cpu_ptr(&timer_bases[b], cpu);
|
|
new_base = get_cpu_ptr(&timer_bases[b]);
|
|
/*
|
|
* The caller is globally serialized and nobody else
|
|
* takes two locks at once, deadlock is not possible.
|
|
*/
|
|
spin_lock_irq(&new_base->lock);
|
|
spin_lock_nested(&old_base->lock, SINGLE_DEPTH_NESTING);
|
|
|
|
BUG_ON(old_base->running_timer);
|
|
|
|
for (i = 0; i < WHEEL_SIZE; i++)
|
|
migrate_timer_list(new_base, old_base->vectors + i);
|
|
|
|
spin_unlock(&old_base->lock);
|
|
spin_unlock_irq(&new_base->lock);
|
|
put_cpu_ptr(&timer_bases);
|
|
}
|
|
}
|
|
|
|
static int timer_cpu_notify(struct notifier_block *self,
|
|
unsigned long action, void *hcpu)
|
|
{
|
|
switch (action) {
|
|
case CPU_DEAD:
|
|
case CPU_DEAD_FROZEN:
|
|
migrate_timers((long)hcpu);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return NOTIFY_OK;
|
|
}
|
|
|
|
static inline void timer_register_cpu_notifier(void)
|
|
{
|
|
cpu_notifier(timer_cpu_notify, 0);
|
|
}
|
|
#else
|
|
static inline void timer_register_cpu_notifier(void) { }
|
|
#endif /* CONFIG_HOTPLUG_CPU */
|
|
|
|
static void __init init_timer_cpu(int cpu)
|
|
{
|
|
struct timer_base *base;
|
|
int i;
|
|
|
|
for (i = 0; i < NR_BASES; i++) {
|
|
base = per_cpu_ptr(&timer_bases[i], cpu);
|
|
base->cpu = cpu;
|
|
spin_lock_init(&base->lock);
|
|
base->clk = jiffies;
|
|
}
|
|
}
|
|
|
|
static void __init init_timer_cpus(void)
|
|
{
|
|
int cpu;
|
|
|
|
for_each_possible_cpu(cpu)
|
|
init_timer_cpu(cpu);
|
|
}
|
|
|
|
void __init init_timers(void)
|
|
{
|
|
init_timer_cpus();
|
|
init_timer_stats();
|
|
timer_register_cpu_notifier();
|
|
open_softirq(TIMER_SOFTIRQ, run_timer_softirq);
|
|
}
|
|
|
|
/**
|
|
* msleep - sleep safely even with waitqueue interruptions
|
|
* @msecs: Time in milliseconds to sleep for
|
|
*/
|
|
void msleep(unsigned int msecs)
|
|
{
|
|
unsigned long timeout = msecs_to_jiffies(msecs) + 1;
|
|
|
|
while (timeout)
|
|
timeout = schedule_timeout_uninterruptible(timeout);
|
|
}
|
|
|
|
EXPORT_SYMBOL(msleep);
|
|
|
|
/**
|
|
* msleep_interruptible - sleep waiting for signals
|
|
* @msecs: Time in milliseconds to sleep for
|
|
*/
|
|
unsigned long msleep_interruptible(unsigned int msecs)
|
|
{
|
|
unsigned long timeout = msecs_to_jiffies(msecs) + 1;
|
|
|
|
while (timeout && !signal_pending(current))
|
|
timeout = schedule_timeout_interruptible(timeout);
|
|
return jiffies_to_msecs(timeout);
|
|
}
|
|
|
|
EXPORT_SYMBOL(msleep_interruptible);
|
|
|
|
static void __sched do_usleep_range(unsigned long min, unsigned long max)
|
|
{
|
|
ktime_t kmin;
|
|
u64 delta;
|
|
|
|
kmin = ktime_set(0, min * NSEC_PER_USEC);
|
|
delta = (u64)(max - min) * NSEC_PER_USEC;
|
|
schedule_hrtimeout_range(&kmin, delta, HRTIMER_MODE_REL);
|
|
}
|
|
|
|
/**
|
|
* usleep_range - Drop in replacement for udelay where wakeup is flexible
|
|
* @min: Minimum time in usecs to sleep
|
|
* @max: Maximum time in usecs to sleep
|
|
*/
|
|
void __sched usleep_range(unsigned long min, unsigned long max)
|
|
{
|
|
__set_current_state(TASK_UNINTERRUPTIBLE);
|
|
do_usleep_range(min, max);
|
|
}
|
|
EXPORT_SYMBOL(usleep_range);
|