1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _linux_POSIX_TIMERS_H
3 #define _linux_POSIX_TIMERS_H
5 #include <linux/alarmtimer.h>
6 #include <linux/list.h>
7 #include <linux/mutex.h>
9 #include <linux/posix-timers_types.h>
10 #include <linux/rcuref.h>
11 #include <linux/spinlock.h>
12 #include <linux/timerqueue.h>
14 struct kernel_siginfo
;
19 static inline clockid_t
make_process_cpuclock(const unsigned int pid
,
20 const clockid_t clock
)
22 return ((~pid
) << 3) | clock
;
24 static inline clockid_t
make_thread_cpuclock(const unsigned int tid
,
25 const clockid_t clock
)
27 return make_process_cpuclock(tid
, clock
| CPUCLOCK_PERTHREAD_MASK
);
30 static inline clockid_t
fd_to_clockid(const int fd
)
32 return make_process_cpuclock((unsigned int) fd
, CLOCKFD
);
35 static inline int clockid_to_fd(const clockid_t clk
)
40 #ifdef CONFIG_POSIX_TIMERS
42 #include <linux/signal_types.h>
45 * cpu_timer - Posix CPU timer representation for k_itimer
46 * @node: timerqueue node to queue in the task/sig
47 * @head: timerqueue head on which this timer is queued
48 * @pid: Pointer to target task PID
49 * @elist: List head for the expiry list
50 * @firing: Timer is currently firing
51 * @nanosleep: Timer is used for nanosleep and is not a regular posix-timer
52 * @handling: Pointer to the task which handles expiry
55 struct timerqueue_node node
;
56 struct timerqueue_head
*head
;
58 struct list_head elist
;
61 struct task_struct __rcu
*handling
;
64 static inline bool cpu_timer_enqueue(struct timerqueue_head
*head
,
65 struct cpu_timer
*ctmr
)
68 return timerqueue_add(head
, &ctmr
->node
);
71 static inline bool cpu_timer_queued(struct cpu_timer
*ctmr
)
76 static inline bool cpu_timer_dequeue(struct cpu_timer
*ctmr
)
78 if (cpu_timer_queued(ctmr
)) {
79 timerqueue_del(ctmr
->head
, &ctmr
->node
);
86 static inline u64
cpu_timer_getexpires(struct cpu_timer
*ctmr
)
88 return ctmr
->node
.expires
;
91 static inline void cpu_timer_setexpires(struct cpu_timer
*ctmr
, u64 exp
)
93 ctmr
->node
.expires
= exp
;
96 static inline void posix_cputimers_init(struct posix_cputimers
*pct
)
98 memset(pct
, 0, sizeof(*pct
));
99 pct
->bases
[0].nextevt
= U64_MAX
;
100 pct
->bases
[1].nextevt
= U64_MAX
;
101 pct
->bases
[2].nextevt
= U64_MAX
;
104 void posix_cputimers_group_init(struct posix_cputimers
*pct
, u64 cpu_limit
);
106 static inline void posix_cputimers_rt_watchdog(struct posix_cputimers
*pct
,
109 pct
->bases
[CPUCLOCK_SCHED
].nextevt
= runtime
;
112 void posixtimer_rearm_itimer(struct task_struct
*p
);
113 bool posixtimer_init_sigqueue(struct sigqueue
*q
);
114 void posixtimer_send_sigqueue(struct k_itimer
*tmr
);
115 bool posixtimer_deliver_signal(struct kernel_siginfo
*info
, struct sigqueue
*timer_sigq
);
116 void posixtimer_free_timer(struct k_itimer
*timer
);
118 /* Init task static initializer */
119 #define INIT_CPU_TIMERBASE(b) { \
120 .nextevt = U64_MAX, \
123 #define INIT_CPU_TIMERBASES(b) { \
124 INIT_CPU_TIMERBASE(b[0]), \
125 INIT_CPU_TIMERBASE(b[1]), \
126 INIT_CPU_TIMERBASE(b[2]), \
129 #define INIT_CPU_TIMERS(s) \
130 .posix_cputimers = { \
131 .bases = INIT_CPU_TIMERBASES(s.posix_cputimers.bases), \
134 struct cpu_timer
{ };
135 #define INIT_CPU_TIMERS(s)
136 static inline void posix_cputimers_init(struct posix_cputimers
*pct
) { }
137 static inline void posix_cputimers_group_init(struct posix_cputimers
*pct
,
139 static inline void posixtimer_rearm_itimer(struct task_struct
*p
) { }
140 static inline bool posixtimer_deliver_signal(struct kernel_siginfo
*info
,
141 struct sigqueue
*timer_sigq
) { return false; }
142 static inline void posixtimer_free_timer(struct k_itimer
*timer
) { }
145 #ifdef CONFIG_POSIX_CPU_TIMERS_TASK_WORK
146 void clear_posix_cputimers_work(struct task_struct
*p
);
147 void posix_cputimers_init_work(void);
149 static inline void clear_posix_cputimers_work(struct task_struct
*p
) { }
150 static inline void posix_cputimers_init_work(void) { }
154 * struct k_itimer - POSIX.1b interval timer structure.
155 * @list: List node for binding the timer to tsk::signal::posix_timers
156 * @ignored_list: List node for tracking ignored timers in tsk::signal::ignored_posix_timers
157 * @t_hash: Entry in the posix timer hash table
158 * @it_lock: Lock protecting the timer
159 * @kclock: Pointer to the k_clock struct handling this timer
160 * @it_clock: The posix timer clock id
161 * @it_id: The posix timer id for identifying the timer
162 * @it_status: The status of the timer
163 * @it_sig_periodic: The periodic status at signal delivery
164 * @it_overrun: The overrun counter for pending signals
165 * @it_overrun_last: The overrun at the time of the last delivered signal
166 * @it_signal_seq: Sequence count to control signal delivery
167 * @it_sigqueue_seq: The sequence count at the point where the signal was queued
168 * @it_sigev_notify: The notify word of sigevent struct for signal delivery
169 * @it_interval: The interval for periodic timers
170 * @it_signal: Pointer to the creators signal struct
171 * @it_pid: The pid of the process/task targeted by the signal
172 * @it_process: The task to wakeup on clock_nanosleep (CPU timers)
173 * @rcuref: Reference count for life time management
174 * @sigq: Embedded sigqueue
175 * @it: Union representing the various posix timer type
177 * @rcu: RCU head for freeing the timer.
180 struct hlist_node list
;
181 struct hlist_node ignored_list
;
182 struct hlist_node t_hash
;
184 const struct k_clock
*kclock
;
188 bool it_sig_periodic
;
191 unsigned int it_signal_seq
;
192 unsigned int it_sigqueue_seq
;
194 enum pid_type it_pid_type
;
196 struct signal_struct
*it_signal
;
199 struct task_struct
*it_process
;
201 struct sigqueue sigq
;
205 struct hrtimer timer
;
207 struct cpu_timer cpu
;
209 struct alarm alarmtimer
;
215 void run_posix_cpu_timers(void);
216 void posix_cpu_timers_exit(struct task_struct
*task
);
217 void posix_cpu_timers_exit_group(struct task_struct
*task
);
218 void set_process_cpu_timer(struct task_struct
*task
, unsigned int clock_idx
,
219 u64
*newval
, u64
*oldval
);
221 int update_rlimit_cpu(struct task_struct
*task
, unsigned long rlim_new
);
223 #ifdef CONFIG_POSIX_TIMERS
224 static inline void posixtimer_putref(struct k_itimer
*tmr
)
226 if (rcuref_put(&tmr
->rcuref
))
227 posixtimer_free_timer(tmr
);
230 static inline void posixtimer_sigqueue_getref(struct sigqueue
*q
)
232 struct k_itimer
*tmr
= container_of(q
, struct k_itimer
, sigq
);
234 WARN_ON_ONCE(!rcuref_get(&tmr
->rcuref
));
237 static inline void posixtimer_sigqueue_putref(struct sigqueue
*q
)
239 struct k_itimer
*tmr
= container_of(q
, struct k_itimer
, sigq
);
241 posixtimer_putref(tmr
);
243 #else /* CONFIG_POSIX_TIMERS */
244 static inline void posixtimer_sigqueue_getref(struct sigqueue
*q
) { }
245 static inline void posixtimer_sigqueue_putref(struct sigqueue
*q
) { }
246 #endif /* !CONFIG_POSIX_TIMERS */