aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/posix-timers.h
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-09-17 15:35:15 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-09-17 15:35:15 -0400
commit7f2444d38f6bbfa12bc15e2533d8f9daa85ca02b (patch)
tree6506ec79036890edfd9797b001391a350b5ac10f /include/linux/posix-timers.h
parentc5f12fdb8bd873aa3ffdb79512e6bdac92b257b0 (diff)
parent77b4b5420422fc037d00b8f3f0e89b2262e4ae29 (diff)
Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull core timer updates from Thomas Gleixner: "Timers and timekeeping updates: - A large overhaul of the posix CPU timer code which is a preparation for moving the CPU timer expiry out into task work so it can be properly accounted on the task/process. An update to the bogus permission checks will come later during the merge window as feedback was not complete before heading of for travel. - Switch the timerqueue code to use cached rbtrees and get rid of the homebrewn caching of the leftmost node. - Consolidate hrtimer_init() + hrtimer_init_sleeper() calls into a single function - Implement the separation of hrtimers to be forced to expire in hard interrupt context even when PREEMPT_RT is enabled and mark the affected timers accordingly. - Implement a mechanism for hrtimers and the timer wheel to protect RT against priority inversion and live lock issues when a (hr)timer which should be canceled is currently executing the callback. Instead of infinitely spinning, the task which tries to cancel the timer blocks on a per cpu base expiry lock which is held and released by the (hr)timer expiry code. - Enable the Hyper-V TSC page based sched_clock for Hyper-V guests resulting in faster access to timekeeping functions. - Updates to various clocksource/clockevent drivers and their device tree bindings. - The usual small improvements all over the place" * 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (101 commits) posix-cpu-timers: Fix permission check regression posix-cpu-timers: Always clear head pointer on dequeue hrtimer: Add a missing bracket and hide `migration_base' on !SMP posix-cpu-timers: Make expiry_active check actually work correctly posix-timers: Unbreak CONFIG_POSIX_TIMERS=n build tick: Mark sched_timer to expire in hard interrupt context hrtimer: Add kernel doc annotation for HRTIMER_MODE_HARD x86/hyperv: Hide pv_ops access for CONFIG_PARAVIRT=n posix-cpu-timers: Utilize timerqueue for storage posix-cpu-timers: Move state tracking to struct posix_cputimers posix-cpu-timers: Deduplicate rlimit handling posix-cpu-timers: Remove pointless comparisons posix-cpu-timers: Get rid of 64bit divisions posix-cpu-timers: Consolidate timer expiry further posix-cpu-timers: Get rid of zero checks rlimit: Rewrite non-sensical RLIMIT_CPU comment posix-cpu-timers: Respect INFINITY for hard RTTIME limit posix-cpu-timers: Switch thread group sampling to array posix-cpu-timers: Restructure expiry array posix-cpu-timers: Remove cputime_expires ...
Diffstat (limited to 'include/linux/posix-timers.h')
-rw-r--r--include/linux/posix-timers.h131
1 files changed, 117 insertions, 14 deletions
diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h
index b20798fc5191..3d10c84a97a9 100644
--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -4,18 +4,11 @@
4 4
5#include <linux/spinlock.h> 5#include <linux/spinlock.h>
6#include <linux/list.h> 6#include <linux/list.h>
7#include <linux/sched.h>
8#include <linux/timex.h>
9#include <linux/alarmtimer.h> 7#include <linux/alarmtimer.h>
8#include <linux/timerqueue.h>
10 9
11struct siginfo; 10struct kernel_siginfo;
12 11struct task_struct;
13struct cpu_timer_list {
14 struct list_head entry;
15 u64 expires;
16 struct task_struct *task;
17 int firing;
18};
19 12
20/* 13/*
21 * Bit fields within a clockid: 14 * Bit fields within a clockid:
@@ -63,6 +56,115 @@ static inline int clockid_to_fd(const clockid_t clk)
63 return ~(clk >> 3); 56 return ~(clk >> 3);
64} 57}
65 58
59#ifdef CONFIG_POSIX_TIMERS
60
61/**
62 * cpu_timer - Posix CPU timer representation for k_itimer
63 * @node: timerqueue node to queue in the task/sig
64 * @head: timerqueue head on which this timer is queued
65 * @task: Pointer to target task
66 * @elist: List head for the expiry list
67 * @firing: Timer is currently firing
68 */
69struct cpu_timer {
70 struct timerqueue_node node;
71 struct timerqueue_head *head;
72 struct task_struct *task;
73 struct list_head elist;
74 int firing;
75};
76
77static inline bool cpu_timer_enqueue(struct timerqueue_head *head,
78 struct cpu_timer *ctmr)
79{
80 ctmr->head = head;
81 return timerqueue_add(head, &ctmr->node);
82}
83
84static inline void cpu_timer_dequeue(struct cpu_timer *ctmr)
85{
86 if (ctmr->head) {
87 timerqueue_del(ctmr->head, &ctmr->node);
88 ctmr->head = NULL;
89 }
90}
91
92static inline u64 cpu_timer_getexpires(struct cpu_timer *ctmr)
93{
94 return ctmr->node.expires;
95}
96
97static inline void cpu_timer_setexpires(struct cpu_timer *ctmr, u64 exp)
98{
99 ctmr->node.expires = exp;
100}
101
102/**
103 * posix_cputimer_base - Container per posix CPU clock
104 * @nextevt: Earliest-expiration cache
105 * @tqhead: timerqueue head for cpu_timers
106 */
107struct posix_cputimer_base {
108 u64 nextevt;
109 struct timerqueue_head tqhead;
110};
111
112/**
113 * posix_cputimers - Container for posix CPU timer related data
114 * @bases: Base container for posix CPU clocks
115 * @timers_active: Timers are queued.
116 * @expiry_active: Timer expiry is active. Used for
117 * process wide timers to avoid multiple
118 * task trying to handle expiry concurrently
119 *
120 * Used in task_struct and signal_struct
121 */
122struct posix_cputimers {
123 struct posix_cputimer_base bases[CPUCLOCK_MAX];
124 unsigned int timers_active;
125 unsigned int expiry_active;
126};
127
128static inline void posix_cputimers_init(struct posix_cputimers *pct)
129{
130 memset(pct, 0, sizeof(*pct));
131 pct->bases[0].nextevt = U64_MAX;
132 pct->bases[1].nextevt = U64_MAX;
133 pct->bases[2].nextevt = U64_MAX;
134}
135
136void posix_cputimers_group_init(struct posix_cputimers *pct, u64 cpu_limit);
137
138static inline void posix_cputimers_rt_watchdog(struct posix_cputimers *pct,
139 u64 runtime)
140{
141 pct->bases[CPUCLOCK_SCHED].nextevt = runtime;
142}
143
144/* Init task static initializer */
145#define INIT_CPU_TIMERBASE(b) { \
146 .nextevt = U64_MAX, \
147}
148
149#define INIT_CPU_TIMERBASES(b) { \
150 INIT_CPU_TIMERBASE(b[0]), \
151 INIT_CPU_TIMERBASE(b[1]), \
152 INIT_CPU_TIMERBASE(b[2]), \
153}
154
155#define INIT_CPU_TIMERS(s) \
156 .posix_cputimers = { \
157 .bases = INIT_CPU_TIMERBASES(s.posix_cputimers.bases), \
158 },
159#else
160struct posix_cputimers { };
161struct cpu_timer { };
162#define INIT_CPU_TIMERS(s)
163static inline void posix_cputimers_init(struct posix_cputimers *pct) { }
164static inline void posix_cputimers_group_init(struct posix_cputimers *pct,
165 u64 cpu_limit) { }
166#endif
167
66#define REQUEUE_PENDING 1 168#define REQUEUE_PENDING 1
67 169
68/** 170/**
@@ -85,7 +187,8 @@ static inline int clockid_to_fd(const clockid_t clk)
85 * @it_process: The task to wakeup on clock_nanosleep (CPU timers) 187 * @it_process: The task to wakeup on clock_nanosleep (CPU timers)
86 * @sigq: Pointer to preallocated sigqueue 188 * @sigq: Pointer to preallocated sigqueue
87 * @it: Union representing the various posix timer type 189 * @it: Union representing the various posix timer type
88 * internals. Also used for rcu freeing the timer. 190 * internals.
191 * @rcu: RCU head for freeing the timer.
89 */ 192 */
90struct k_itimer { 193struct k_itimer {
91 struct list_head list; 194 struct list_head list;
@@ -110,15 +213,15 @@ struct k_itimer {
110 struct { 213 struct {
111 struct hrtimer timer; 214 struct hrtimer timer;
112 } real; 215 } real;
113 struct cpu_timer_list cpu; 216 struct cpu_timer cpu;
114 struct { 217 struct {
115 struct alarm alarmtimer; 218 struct alarm alarmtimer;
116 } alarm; 219 } alarm;
117 struct rcu_head rcu;
118 } it; 220 } it;
221 struct rcu_head rcu;
119}; 222};
120 223
121void run_posix_cpu_timers(struct task_struct *task); 224void run_posix_cpu_timers(void);
122void posix_cpu_timers_exit(struct task_struct *task); 225void posix_cpu_timers_exit(struct task_struct *task);
123void posix_cpu_timers_exit_group(struct task_struct *task); 226void posix_cpu_timers_exit_group(struct task_struct *task);
124void set_process_cpu_timer(struct task_struct *task, unsigned int clock_idx, 227void set_process_cpu_timer(struct task_struct *task, unsigned int clock_idx,