xref: /OK3568_Linux_fs/kernel/include/linux/posix-timers.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun #ifndef _linux_POSIX_TIMERS_H
3*4882a593Smuzhiyun #define _linux_POSIX_TIMERS_H
4*4882a593Smuzhiyun 
5*4882a593Smuzhiyun #include <linux/spinlock.h>
6*4882a593Smuzhiyun #include <linux/list.h>
7*4882a593Smuzhiyun #include <linux/alarmtimer.h>
8*4882a593Smuzhiyun #include <linux/timerqueue.h>
9*4882a593Smuzhiyun #include <linux/task_work.h>
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun struct kernel_siginfo;
12*4882a593Smuzhiyun struct task_struct;
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun /*
15*4882a593Smuzhiyun  * Bit fields within a clockid:
16*4882a593Smuzhiyun  *
17*4882a593Smuzhiyun  * The most significant 29 bits hold either a pid or a file descriptor.
18*4882a593Smuzhiyun  *
19*4882a593Smuzhiyun  * Bit 2 indicates whether a cpu clock refers to a thread or a process.
20*4882a593Smuzhiyun  *
21*4882a593Smuzhiyun  * Bits 1 and 0 give the type: PROF=0, VIRT=1, SCHED=2, or FD=3.
22*4882a593Smuzhiyun  *
23*4882a593Smuzhiyun  * A clockid is invalid if bits 2, 1, and 0 are all set.
24*4882a593Smuzhiyun  */
25*4882a593Smuzhiyun #define CPUCLOCK_PID(clock)		((pid_t) ~((clock) >> 3))
26*4882a593Smuzhiyun #define CPUCLOCK_PERTHREAD(clock) \
27*4882a593Smuzhiyun 	(((clock) & (clockid_t) CPUCLOCK_PERTHREAD_MASK) != 0)
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun #define CPUCLOCK_PERTHREAD_MASK	4
30*4882a593Smuzhiyun #define CPUCLOCK_WHICH(clock)	((clock) & (clockid_t) CPUCLOCK_CLOCK_MASK)
31*4882a593Smuzhiyun #define CPUCLOCK_CLOCK_MASK	3
32*4882a593Smuzhiyun #define CPUCLOCK_PROF		0
33*4882a593Smuzhiyun #define CPUCLOCK_VIRT		1
34*4882a593Smuzhiyun #define CPUCLOCK_SCHED		2
35*4882a593Smuzhiyun #define CPUCLOCK_MAX		3
36*4882a593Smuzhiyun #define CLOCKFD			CPUCLOCK_MAX
37*4882a593Smuzhiyun #define CLOCKFD_MASK		(CPUCLOCK_PERTHREAD_MASK|CPUCLOCK_CLOCK_MASK)
38*4882a593Smuzhiyun 
make_process_cpuclock(const unsigned int pid,const clockid_t clock)39*4882a593Smuzhiyun static inline clockid_t make_process_cpuclock(const unsigned int pid,
40*4882a593Smuzhiyun 		const clockid_t clock)
41*4882a593Smuzhiyun {
42*4882a593Smuzhiyun 	return ((~pid) << 3) | clock;
43*4882a593Smuzhiyun }
make_thread_cpuclock(const unsigned int tid,const clockid_t clock)44*4882a593Smuzhiyun static inline clockid_t make_thread_cpuclock(const unsigned int tid,
45*4882a593Smuzhiyun 		const clockid_t clock)
46*4882a593Smuzhiyun {
47*4882a593Smuzhiyun 	return make_process_cpuclock(tid, clock | CPUCLOCK_PERTHREAD_MASK);
48*4882a593Smuzhiyun }
49*4882a593Smuzhiyun 
fd_to_clockid(const int fd)50*4882a593Smuzhiyun static inline clockid_t fd_to_clockid(const int fd)
51*4882a593Smuzhiyun {
52*4882a593Smuzhiyun 	return make_process_cpuclock((unsigned int) fd, CLOCKFD);
53*4882a593Smuzhiyun }
54*4882a593Smuzhiyun 
clockid_to_fd(const clockid_t clk)55*4882a593Smuzhiyun static inline int clockid_to_fd(const clockid_t clk)
56*4882a593Smuzhiyun {
57*4882a593Smuzhiyun 	return ~(clk >> 3);
58*4882a593Smuzhiyun }
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun #ifdef CONFIG_POSIX_TIMERS
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun /**
63*4882a593Smuzhiyun  * cpu_timer - Posix CPU timer representation for k_itimer
64*4882a593Smuzhiyun  * @node:	timerqueue node to queue in the task/sig
65*4882a593Smuzhiyun  * @head:	timerqueue head on which this timer is queued
66*4882a593Smuzhiyun  * @task:	Pointer to target task
67*4882a593Smuzhiyun  * @elist:	List head for the expiry list
68*4882a593Smuzhiyun  * @firing:	Timer is currently firing
69*4882a593Smuzhiyun  */
70*4882a593Smuzhiyun struct cpu_timer {
71*4882a593Smuzhiyun 	struct timerqueue_node	node;
72*4882a593Smuzhiyun 	struct timerqueue_head	*head;
73*4882a593Smuzhiyun 	struct pid		*pid;
74*4882a593Smuzhiyun 	struct list_head	elist;
75*4882a593Smuzhiyun 	int			firing;
76*4882a593Smuzhiyun };
77*4882a593Smuzhiyun 
cpu_timer_enqueue(struct timerqueue_head * head,struct cpu_timer * ctmr)78*4882a593Smuzhiyun static inline bool cpu_timer_enqueue(struct timerqueue_head *head,
79*4882a593Smuzhiyun 				     struct cpu_timer *ctmr)
80*4882a593Smuzhiyun {
81*4882a593Smuzhiyun 	ctmr->head = head;
82*4882a593Smuzhiyun 	return timerqueue_add(head, &ctmr->node);
83*4882a593Smuzhiyun }
84*4882a593Smuzhiyun 
cpu_timer_dequeue(struct cpu_timer * ctmr)85*4882a593Smuzhiyun static inline void cpu_timer_dequeue(struct cpu_timer *ctmr)
86*4882a593Smuzhiyun {
87*4882a593Smuzhiyun 	if (ctmr->head) {
88*4882a593Smuzhiyun 		timerqueue_del(ctmr->head, &ctmr->node);
89*4882a593Smuzhiyun 		ctmr->head = NULL;
90*4882a593Smuzhiyun 	}
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun 
cpu_timer_getexpires(struct cpu_timer * ctmr)93*4882a593Smuzhiyun static inline u64 cpu_timer_getexpires(struct cpu_timer *ctmr)
94*4882a593Smuzhiyun {
95*4882a593Smuzhiyun 	return ctmr->node.expires;
96*4882a593Smuzhiyun }
97*4882a593Smuzhiyun 
cpu_timer_setexpires(struct cpu_timer * ctmr,u64 exp)98*4882a593Smuzhiyun static inline void cpu_timer_setexpires(struct cpu_timer *ctmr, u64 exp)
99*4882a593Smuzhiyun {
100*4882a593Smuzhiyun 	ctmr->node.expires = exp;
101*4882a593Smuzhiyun }
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun /**
104*4882a593Smuzhiyun  * posix_cputimer_base - Container per posix CPU clock
105*4882a593Smuzhiyun  * @nextevt:		Earliest-expiration cache
106*4882a593Smuzhiyun  * @tqhead:		timerqueue head for cpu_timers
107*4882a593Smuzhiyun  */
108*4882a593Smuzhiyun struct posix_cputimer_base {
109*4882a593Smuzhiyun 	u64			nextevt;
110*4882a593Smuzhiyun 	struct timerqueue_head	tqhead;
111*4882a593Smuzhiyun };
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun /**
114*4882a593Smuzhiyun  * posix_cputimers - Container for posix CPU timer related data
115*4882a593Smuzhiyun  * @bases:		Base container for posix CPU clocks
116*4882a593Smuzhiyun  * @timers_active:	Timers are queued.
117*4882a593Smuzhiyun  * @expiry_active:	Timer expiry is active. Used for
118*4882a593Smuzhiyun  *			process wide timers to avoid multiple
119*4882a593Smuzhiyun  *			task trying to handle expiry concurrently
120*4882a593Smuzhiyun  *
121*4882a593Smuzhiyun  * Used in task_struct and signal_struct
122*4882a593Smuzhiyun  */
123*4882a593Smuzhiyun struct posix_cputimers {
124*4882a593Smuzhiyun 	struct posix_cputimer_base	bases[CPUCLOCK_MAX];
125*4882a593Smuzhiyun 	unsigned int			timers_active;
126*4882a593Smuzhiyun 	unsigned int			expiry_active;
127*4882a593Smuzhiyun };
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun /**
130*4882a593Smuzhiyun  * posix_cputimers_work - Container for task work based posix CPU timer expiry
131*4882a593Smuzhiyun  * @work:	The task work to be scheduled
132*4882a593Smuzhiyun  * @scheduled:  @work has been scheduled already, no further processing
133*4882a593Smuzhiyun  */
134*4882a593Smuzhiyun struct posix_cputimers_work {
135*4882a593Smuzhiyun 	struct callback_head	work;
136*4882a593Smuzhiyun 	unsigned int		scheduled;
137*4882a593Smuzhiyun };
138*4882a593Smuzhiyun 
posix_cputimers_init(struct posix_cputimers * pct)139*4882a593Smuzhiyun static inline void posix_cputimers_init(struct posix_cputimers *pct)
140*4882a593Smuzhiyun {
141*4882a593Smuzhiyun 	memset(pct, 0, sizeof(*pct));
142*4882a593Smuzhiyun 	pct->bases[0].nextevt = U64_MAX;
143*4882a593Smuzhiyun 	pct->bases[1].nextevt = U64_MAX;
144*4882a593Smuzhiyun 	pct->bases[2].nextevt = U64_MAX;
145*4882a593Smuzhiyun }
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun void posix_cputimers_group_init(struct posix_cputimers *pct, u64 cpu_limit);
148*4882a593Smuzhiyun 
posix_cputimers_rt_watchdog(struct posix_cputimers * pct,u64 runtime)149*4882a593Smuzhiyun static inline void posix_cputimers_rt_watchdog(struct posix_cputimers *pct,
150*4882a593Smuzhiyun 					       u64 runtime)
151*4882a593Smuzhiyun {
152*4882a593Smuzhiyun 	pct->bases[CPUCLOCK_SCHED].nextevt = runtime;
153*4882a593Smuzhiyun }
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun /* Init task static initializer */
156*4882a593Smuzhiyun #define INIT_CPU_TIMERBASE(b) {						\
157*4882a593Smuzhiyun 	.nextevt	= U64_MAX,					\
158*4882a593Smuzhiyun }
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun #define INIT_CPU_TIMERBASES(b) {					\
161*4882a593Smuzhiyun 	INIT_CPU_TIMERBASE(b[0]),					\
162*4882a593Smuzhiyun 	INIT_CPU_TIMERBASE(b[1]),					\
163*4882a593Smuzhiyun 	INIT_CPU_TIMERBASE(b[2]),					\
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun #define INIT_CPU_TIMERS(s)						\
167*4882a593Smuzhiyun 	.posix_cputimers = {						\
168*4882a593Smuzhiyun 		.bases = INIT_CPU_TIMERBASES(s.posix_cputimers.bases),	\
169*4882a593Smuzhiyun 	},
170*4882a593Smuzhiyun #else
171*4882a593Smuzhiyun struct posix_cputimers { };
172*4882a593Smuzhiyun struct cpu_timer { };
173*4882a593Smuzhiyun #define INIT_CPU_TIMERS(s)
posix_cputimers_init(struct posix_cputimers * pct)174*4882a593Smuzhiyun static inline void posix_cputimers_init(struct posix_cputimers *pct) { }
posix_cputimers_group_init(struct posix_cputimers * pct,u64 cpu_limit)175*4882a593Smuzhiyun static inline void posix_cputimers_group_init(struct posix_cputimers *pct,
176*4882a593Smuzhiyun 					      u64 cpu_limit) { }
177*4882a593Smuzhiyun #endif
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun #ifdef CONFIG_POSIX_CPU_TIMERS_TASK_WORK
180*4882a593Smuzhiyun void clear_posix_cputimers_work(struct task_struct *p);
181*4882a593Smuzhiyun void posix_cputimers_init_work(void);
182*4882a593Smuzhiyun #else
clear_posix_cputimers_work(struct task_struct * p)183*4882a593Smuzhiyun static inline void clear_posix_cputimers_work(struct task_struct *p) { }
posix_cputimers_init_work(void)184*4882a593Smuzhiyun static inline void posix_cputimers_init_work(void) { }
185*4882a593Smuzhiyun #endif
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun #define REQUEUE_PENDING 1
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun /**
190*4882a593Smuzhiyun  * struct k_itimer - POSIX.1b interval timer structure.
191*4882a593Smuzhiyun  * @list:		List head for binding the timer to signals->posix_timers
192*4882a593Smuzhiyun  * @t_hash:		Entry in the posix timer hash table
193*4882a593Smuzhiyun  * @it_lock:		Lock protecting the timer
194*4882a593Smuzhiyun  * @kclock:		Pointer to the k_clock struct handling this timer
195*4882a593Smuzhiyun  * @it_clock:		The posix timer clock id
196*4882a593Smuzhiyun  * @it_id:		The posix timer id for identifying the timer
197*4882a593Smuzhiyun  * @it_active:		Marker that timer is active
198*4882a593Smuzhiyun  * @it_overrun:		The overrun counter for pending signals
199*4882a593Smuzhiyun  * @it_overrun_last:	The overrun at the time of the last delivered signal
200*4882a593Smuzhiyun  * @it_requeue_pending:	Indicator that timer waits for being requeued on
201*4882a593Smuzhiyun  *			signal delivery
202*4882a593Smuzhiyun  * @it_sigev_notify:	The notify word of sigevent struct for signal delivery
203*4882a593Smuzhiyun  * @it_interval:	The interval for periodic timers
204*4882a593Smuzhiyun  * @it_signal:		Pointer to the creators signal struct
205*4882a593Smuzhiyun  * @it_pid:		The pid of the process/task targeted by the signal
206*4882a593Smuzhiyun  * @it_process:		The task to wakeup on clock_nanosleep (CPU timers)
207*4882a593Smuzhiyun  * @sigq:		Pointer to preallocated sigqueue
208*4882a593Smuzhiyun  * @it:			Union representing the various posix timer type
209*4882a593Smuzhiyun  *			internals.
210*4882a593Smuzhiyun  * @rcu:		RCU head for freeing the timer.
211*4882a593Smuzhiyun  */
212*4882a593Smuzhiyun struct k_itimer {
213*4882a593Smuzhiyun 	struct list_head	list;
214*4882a593Smuzhiyun 	struct hlist_node	t_hash;
215*4882a593Smuzhiyun 	spinlock_t		it_lock;
216*4882a593Smuzhiyun 	const struct k_clock	*kclock;
217*4882a593Smuzhiyun 	clockid_t		it_clock;
218*4882a593Smuzhiyun 	timer_t			it_id;
219*4882a593Smuzhiyun 	int			it_active;
220*4882a593Smuzhiyun 	s64			it_overrun;
221*4882a593Smuzhiyun 	s64			it_overrun_last;
222*4882a593Smuzhiyun 	int			it_requeue_pending;
223*4882a593Smuzhiyun 	int			it_sigev_notify;
224*4882a593Smuzhiyun 	ktime_t			it_interval;
225*4882a593Smuzhiyun 	struct signal_struct	*it_signal;
226*4882a593Smuzhiyun 	union {
227*4882a593Smuzhiyun 		struct pid		*it_pid;
228*4882a593Smuzhiyun 		struct task_struct	*it_process;
229*4882a593Smuzhiyun 	};
230*4882a593Smuzhiyun 	struct sigqueue		*sigq;
231*4882a593Smuzhiyun 	union {
232*4882a593Smuzhiyun 		struct {
233*4882a593Smuzhiyun 			struct hrtimer	timer;
234*4882a593Smuzhiyun 		} real;
235*4882a593Smuzhiyun 		struct cpu_timer	cpu;
236*4882a593Smuzhiyun 		struct {
237*4882a593Smuzhiyun 			struct alarm	alarmtimer;
238*4882a593Smuzhiyun 		} alarm;
239*4882a593Smuzhiyun 	} it;
240*4882a593Smuzhiyun 	struct rcu_head		rcu;
241*4882a593Smuzhiyun };
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun void run_posix_cpu_timers(void);
244*4882a593Smuzhiyun void posix_cpu_timers_exit(struct task_struct *task);
245*4882a593Smuzhiyun void posix_cpu_timers_exit_group(struct task_struct *task);
246*4882a593Smuzhiyun void set_process_cpu_timer(struct task_struct *task, unsigned int clock_idx,
247*4882a593Smuzhiyun 			   u64 *newval, u64 *oldval);
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun void update_rlimit_cpu(struct task_struct *task, unsigned long rlim_new);
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun void posixtimer_rearm(struct kernel_siginfo *info);
252*4882a593Smuzhiyun #endif
253