hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/include/linux/posix-timers.h
....@@ -4,19 +4,12 @@
44
55 #include <linux/spinlock.h>
66 #include <linux/list.h>
7
-#include <linux/sched.h>
8
-#include <linux/timex.h>
97 #include <linux/alarmtimer.h>
8
+#include <linux/timerqueue.h>
9
+#include <linux/task_work.h>
1010
11
-struct siginfo;
12
-
13
-struct cpu_timer_list {
14
- struct list_head entry;
15
- u64 expires, incr;
16
- struct task_struct *task;
17
- int firing;
18
- int firing_cpu;
19
-};
11
+struct kernel_siginfo;
12
+struct task_struct;
2013
2114 /*
2215 * Bit fields within a clockid:
....@@ -64,6 +57,133 @@
6457 return ~(clk >> 3);
6558 }
6659
60
+#ifdef CONFIG_POSIX_TIMERS
61
+
62
+/**
63
+ * cpu_timer - Posix CPU timer representation for k_itimer
64
+ * @node: timerqueue node to queue in the task/sig
65
+ * @head: timerqueue head on which this timer is queued
66
+ * @task: Pointer to target task
67
+ * @elist: List head for the expiry list
68
+ * @firing: Timer is currently firing
69
+ */
70
+struct cpu_timer {
71
+ struct timerqueue_node node;
72
+ struct timerqueue_head *head;
73
+ struct pid *pid;
74
+ struct list_head elist;
75
+ int firing;
76
+};
77
+
78
+static inline bool cpu_timer_enqueue(struct timerqueue_head *head,
79
+ struct cpu_timer *ctmr)
80
+{
81
+ ctmr->head = head;
82
+ return timerqueue_add(head, &ctmr->node);
83
+}
84
+
85
+static inline void cpu_timer_dequeue(struct cpu_timer *ctmr)
86
+{
87
+ if (ctmr->head) {
88
+ timerqueue_del(ctmr->head, &ctmr->node);
89
+ ctmr->head = NULL;
90
+ }
91
+}
92
+
93
+static inline u64 cpu_timer_getexpires(struct cpu_timer *ctmr)
94
+{
95
+ return ctmr->node.expires;
96
+}
97
+
98
+static inline void cpu_timer_setexpires(struct cpu_timer *ctmr, u64 exp)
99
+{
100
+ ctmr->node.expires = exp;
101
+}
102
+
103
+/**
104
+ * posix_cputimer_base - Container per posix CPU clock
105
+ * @nextevt: Earliest-expiration cache
106
+ * @tqhead: timerqueue head for cpu_timers
107
+ */
108
+struct posix_cputimer_base {
109
+ u64 nextevt;
110
+ struct timerqueue_head tqhead;
111
+};
112
+
113
+/**
114
+ * posix_cputimers - Container for posix CPU timer related data
115
+ * @bases: Base container for posix CPU clocks
116
+ * @timers_active: Timers are queued.
117
+ * @expiry_active: Timer expiry is active. Used for
118
+ * process wide timers to avoid multiple
119
+ * task trying to handle expiry concurrently
120
+ *
121
+ * Used in task_struct and signal_struct
122
+ */
123
+struct posix_cputimers {
124
+ struct posix_cputimer_base bases[CPUCLOCK_MAX];
125
+ unsigned int timers_active;
126
+ unsigned int expiry_active;
127
+};
128
+
129
+/**
130
+ * posix_cputimers_work - Container for task work based posix CPU timer expiry
131
+ * @work: The task work to be scheduled
132
+ * @scheduled: @work has been scheduled already, no further processing
133
+ */
134
+struct posix_cputimers_work {
135
+ struct callback_head work;
136
+ unsigned int scheduled;
137
+};
138
+
139
+static inline void posix_cputimers_init(struct posix_cputimers *pct)
140
+{
141
+ memset(pct, 0, sizeof(*pct));
142
+ pct->bases[0].nextevt = U64_MAX;
143
+ pct->bases[1].nextevt = U64_MAX;
144
+ pct->bases[2].nextevt = U64_MAX;
145
+}
146
+
147
+void posix_cputimers_group_init(struct posix_cputimers *pct, u64 cpu_limit);
148
+
149
+static inline void posix_cputimers_rt_watchdog(struct posix_cputimers *pct,
150
+ u64 runtime)
151
+{
152
+ pct->bases[CPUCLOCK_SCHED].nextevt = runtime;
153
+}
154
+
155
+/* Init task static initializer */
156
+#define INIT_CPU_TIMERBASE(b) { \
157
+ .nextevt = U64_MAX, \
158
+}
159
+
160
+#define INIT_CPU_TIMERBASES(b) { \
161
+ INIT_CPU_TIMERBASE(b[0]), \
162
+ INIT_CPU_TIMERBASE(b[1]), \
163
+ INIT_CPU_TIMERBASE(b[2]), \
164
+}
165
+
166
+#define INIT_CPU_TIMERS(s) \
167
+ .posix_cputimers = { \
168
+ .bases = INIT_CPU_TIMERBASES(s.posix_cputimers.bases), \
169
+ },
170
+#else
171
+struct posix_cputimers { };
172
+struct cpu_timer { };
173
+#define INIT_CPU_TIMERS(s)
174
+static inline void posix_cputimers_init(struct posix_cputimers *pct) { }
175
+static inline void posix_cputimers_group_init(struct posix_cputimers *pct,
176
+ u64 cpu_limit) { }
177
+#endif
178
+
179
+#ifdef CONFIG_POSIX_CPU_TIMERS_TASK_WORK
180
+void clear_posix_cputimers_work(struct task_struct *p);
181
+void posix_cputimers_init_work(void);
182
+#else
183
+static inline void clear_posix_cputimers_work(struct task_struct *p) { }
184
+static inline void posix_cputimers_init_work(void) { }
185
+#endif
186
+
67187 #define REQUEUE_PENDING 1
68188
69189 /**
....@@ -86,7 +206,8 @@
86206 * @it_process: The task to wakeup on clock_nanosleep (CPU timers)
87207 * @sigq: Pointer to preallocated sigqueue
88208 * @it: Union representing the various posix timer type
89
- * internals. Also used for rcu freeing the timer.
209
+ * internals.
210
+ * @rcu: RCU head for freeing the timer.
90211 */
91212 struct k_itimer {
92213 struct list_head list;
....@@ -111,7 +232,7 @@
111232 struct {
112233 struct hrtimer timer;
113234 } real;
114
- struct cpu_timer_list cpu;
235
+ struct cpu_timer cpu;
115236 struct {
116237 struct alarm alarmtimer;
117238 } alarm;
....@@ -119,7 +240,7 @@
119240 struct rcu_head rcu;
120241 };
121242
122
-void run_posix_cpu_timers(struct task_struct *task);
243
+void run_posix_cpu_timers(void);
123244 void posix_cpu_timers_exit(struct task_struct *task);
124245 void posix_cpu_timers_exit_group(struct task_struct *task);
125246 void set_process_cpu_timer(struct task_struct *task, unsigned int clock_idx,
....@@ -127,5 +248,5 @@
127248
128249 void update_rlimit_cpu(struct task_struct *task, unsigned long rlim_new);
129250
130
-void posixtimer_rearm(struct siginfo *info);
251
+void posixtimer_rearm(struct kernel_siginfo *info);
131252 #endif