hc
2024-05-10 37f49e37ab4cb5d0bc4c60eb5c6d4dd57db767bb
kernel/include/linux/posix-timers.h
....@@ -4,19 +4,13 @@
44
55 #include <linux/spinlock.h>
66 #include <linux/list.h>
7
-#include <linux/sched.h>
8
-#include <linux/timex.h>
7
+#include <linux/mutex.h>
98 #include <linux/alarmtimer.h>
9
+#include <linux/timerqueue.h>
10
+#include <linux/task_work.h>
1011
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
-};
12
+struct kernel_siginfo;
13
+struct task_struct;
2014
2115 /*
2216 * Bit fields within a clockid:
....@@ -64,6 +58,137 @@
6458 return ~(clk >> 3);
6559 }
6660
61
+#ifdef CONFIG_POSIX_TIMERS
62
+
63
+/**
64
+ * cpu_timer - Posix CPU timer representation for k_itimer
65
+ * @node: timerqueue node to queue in the task/sig
66
+ * @head: timerqueue head on which this timer is queued
67
+ * @pid: Pointer to target task PID
68
+ * @elist: List head for the expiry list
69
+ * @firing: Timer is currently firing
70
+ * @handling: Pointer to the task which handles expiry
71
+ */
72
+struct cpu_timer {
73
+ struct timerqueue_node node;
74
+ struct timerqueue_head *head;
75
+ struct pid *pid;
76
+ struct list_head elist;
77
+ int firing;
78
+ struct task_struct __rcu *handling;
79
+};
80
+
81
+static inline bool cpu_timer_enqueue(struct timerqueue_head *head,
82
+ struct cpu_timer *ctmr)
83
+{
84
+ ctmr->head = head;
85
+ return timerqueue_add(head, &ctmr->node);
86
+}
87
+
88
+static inline void cpu_timer_dequeue(struct cpu_timer *ctmr)
89
+{
90
+ if (ctmr->head) {
91
+ timerqueue_del(ctmr->head, &ctmr->node);
92
+ ctmr->head = NULL;
93
+ }
94
+}
95
+
96
+static inline u64 cpu_timer_getexpires(struct cpu_timer *ctmr)
97
+{
98
+ return ctmr->node.expires;
99
+}
100
+
101
+static inline void cpu_timer_setexpires(struct cpu_timer *ctmr, u64 exp)
102
+{
103
+ ctmr->node.expires = exp;
104
+}
105
+
106
+/**
107
+ * posix_cputimer_base - Container per posix CPU clock
108
+ * @nextevt: Earliest-expiration cache
109
+ * @tqhead: timerqueue head for cpu_timers
110
+ */
111
+struct posix_cputimer_base {
112
+ u64 nextevt;
113
+ struct timerqueue_head tqhead;
114
+};
115
+
116
+/**
117
+ * posix_cputimers - Container for posix CPU timer related data
118
+ * @bases: Base container for posix CPU clocks
119
+ * @timers_active: Timers are queued.
120
+ * @expiry_active: Timer expiry is active. Used for
121
+ * process wide timers to avoid multiple
122
+ * task trying to handle expiry concurrently
123
+ *
124
+ * Used in task_struct and signal_struct
125
+ */
126
+struct posix_cputimers {
127
+ struct posix_cputimer_base bases[CPUCLOCK_MAX];
128
+ unsigned int timers_active;
129
+ unsigned int expiry_active;
130
+};
131
+
132
+/**
133
+ * posix_cputimers_work - Container for task work based posix CPU timer expiry
134
+ * @work: The task work to be scheduled
135
+ * @mutex: Mutex held around expiry in context of this task work
136
+ * @scheduled: @work has been scheduled already, no further processing
137
+ */
138
+struct posix_cputimers_work {
139
+ struct callback_head work;
140
+ struct mutex mutex;
141
+ unsigned int scheduled;
142
+};
143
+
144
+static inline void posix_cputimers_init(struct posix_cputimers *pct)
145
+{
146
+ memset(pct, 0, sizeof(*pct));
147
+ pct->bases[0].nextevt = U64_MAX;
148
+ pct->bases[1].nextevt = U64_MAX;
149
+ pct->bases[2].nextevt = U64_MAX;
150
+}
151
+
152
+void posix_cputimers_group_init(struct posix_cputimers *pct, u64 cpu_limit);
153
+
154
+static inline void posix_cputimers_rt_watchdog(struct posix_cputimers *pct,
155
+ u64 runtime)
156
+{
157
+ pct->bases[CPUCLOCK_SCHED].nextevt = runtime;
158
+}
159
+
160
+/* Init task static initializer */
161
+#define INIT_CPU_TIMERBASE(b) { \
162
+ .nextevt = U64_MAX, \
163
+}
164
+
165
+#define INIT_CPU_TIMERBASES(b) { \
166
+ INIT_CPU_TIMERBASE(b[0]), \
167
+ INIT_CPU_TIMERBASE(b[1]), \
168
+ INIT_CPU_TIMERBASE(b[2]), \
169
+}
170
+
171
+#define INIT_CPU_TIMERS(s) \
172
+ .posix_cputimers = { \
173
+ .bases = INIT_CPU_TIMERBASES(s.posix_cputimers.bases), \
174
+ },
175
+#else
176
+struct posix_cputimers { };
177
+struct cpu_timer { };
178
+#define INIT_CPU_TIMERS(s)
179
+static inline void posix_cputimers_init(struct posix_cputimers *pct) { }
180
+static inline void posix_cputimers_group_init(struct posix_cputimers *pct,
181
+ u64 cpu_limit) { }
182
+#endif
183
+
184
+#ifdef CONFIG_POSIX_CPU_TIMERS_TASK_WORK
185
+void clear_posix_cputimers_work(struct task_struct *p);
186
+void posix_cputimers_init_work(void);
187
+#else
188
+static inline void clear_posix_cputimers_work(struct task_struct *p) { }
189
+static inline void posix_cputimers_init_work(void) { }
190
+#endif
191
+
67192 #define REQUEUE_PENDING 1
68193
69194 /**
....@@ -86,7 +211,8 @@
86211 * @it_process: The task to wakeup on clock_nanosleep (CPU timers)
87212 * @sigq: Pointer to preallocated sigqueue
88213 * @it: Union representing the various posix timer type
89
- * internals. Also used for rcu freeing the timer.
214
+ * internals.
215
+ * @rcu: RCU head for freeing the timer.
90216 */
91217 struct k_itimer {
92218 struct list_head list;
....@@ -111,7 +237,7 @@
111237 struct {
112238 struct hrtimer timer;
113239 } real;
114
- struct cpu_timer_list cpu;
240
+ struct cpu_timer cpu;
115241 struct {
116242 struct alarm alarmtimer;
117243 } alarm;
....@@ -119,7 +245,7 @@
119245 struct rcu_head rcu;
120246 };
121247
122
-void run_posix_cpu_timers(struct task_struct *task);
248
+void run_posix_cpu_timers(void);
123249 void posix_cpu_timers_exit(struct task_struct *task);
124250 void posix_cpu_timers_exit_group(struct task_struct *task);
125251 void set_process_cpu_timer(struct task_struct *task, unsigned int clock_idx,
....@@ -127,5 +253,5 @@
127253
128254 void update_rlimit_cpu(struct task_struct *task, unsigned long rlim_new);
129255
130
-void posixtimer_rearm(struct siginfo *info);
256
+void posixtimer_rearm(struct kernel_siginfo *info);
131257 #endif