summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/init_task.h11
-rw-r--r--include/linux/posix-timers.h34
-rw-r--r--include/linux/sched.h4
-rw-r--r--include/linux/sched/signal.h5
-rw-r--r--kernel/fork.c11
-rw-r--r--kernel/time/posix-cpu-timers.c20
6 files changed, 54 insertions, 31 deletions
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index 6049baa5b8bc..2c620d7ac432 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -36,17 +36,6 @@ extern struct cred init_cred;
#define INIT_PREV_CPUTIME(x)
#endif
-#ifdef CONFIG_POSIX_TIMERS
-#define INIT_CPU_TIMERS(s) \
- .cpu_timers = { \
- LIST_HEAD_INIT(s.cpu_timers[0]), \
- LIST_HEAD_INIT(s.cpu_timers[1]), \
- LIST_HEAD_INIT(s.cpu_timers[2]), \
- },
-#else
-#define INIT_CPU_TIMERS(s)
-#endif
-
#define INIT_TASK_COMM "swapper"
/* Attach to the init_task data structure for proper alignment */
diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h
index 033374b99767..cdef89750b2c 100644
--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -62,6 +62,40 @@ static inline int clockid_to_fd(const clockid_t clk)
return ~(clk >> 3);
}
+#ifdef CONFIG_POSIX_TIMERS
+/**
+ * posix_cputimers - Container for posix CPU timer related data
+ * @cpu_timers: List heads to queue posix CPU timers
+ *
+ * Used in task_struct and signal_struct
+ */
+struct posix_cputimers {
+ struct list_head cpu_timers[CPUCLOCK_MAX];
+};
+
+static inline void posix_cputimers_init(struct posix_cputimers *pct)
+{
+ INIT_LIST_HEAD(&pct->cpu_timers[0]);
+ INIT_LIST_HEAD(&pct->cpu_timers[1]);
+ INIT_LIST_HEAD(&pct->cpu_timers[2]);
+}
+
+/* Init task static initializer */
+#define INIT_CPU_TIMERLISTS(c) { \
+ LIST_HEAD_INIT(c.cpu_timers[0]), \
+ LIST_HEAD_INIT(c.cpu_timers[1]), \
+ LIST_HEAD_INIT(c.cpu_timers[2]), \
+}
+
+#define INIT_CPU_TIMERS(s) \
+ .posix_cputimers = { \
+ .cpu_timers = INIT_CPU_TIMERLISTS(s.posix_cputimers), \
+ },
+#else
+struct posix_cputimers { };
+#define INIT_CPU_TIMERS(s)
+#endif
+
#define REQUEUE_PENDING 1
/**
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 8dc1811487f5..fde844a3b86e 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -28,6 +28,7 @@
#include <linux/signal_types.h>
#include <linux/mm_types_task.h>
#include <linux/task_io_accounting.h>
+#include <linux/posix-timers.h>
#include <linux/rseq.h>
/* task_struct member predeclarations (sorted alphabetically): */
@@ -878,8 +879,9 @@ struct task_struct {
#ifdef CONFIG_POSIX_TIMERS
struct task_cputime cputime_expires;
- struct list_head cpu_timers[3];
#endif
+ /* Empty if CONFIG_POSIX_CPUTIMERS=n */
+ struct posix_cputimers posix_cputimers;
/* Process credentials: */
diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h
index efd8ce7675ed..88fbb3f1c375 100644
--- a/include/linux/sched/signal.h
+++ b/include/linux/sched/signal.h
@@ -9,6 +9,7 @@
#include <linux/sched/task.h>
#include <linux/cred.h>
#include <linux/refcount.h>
+#include <linux/posix-timers.h>
/*
* Types defining task->signal and task->sighand and APIs using them:
@@ -151,9 +152,9 @@ struct signal_struct {
/* Earliest-expiration cache. */
struct task_cputime cputime_expires;
- struct list_head cpu_timers[3];
-
#endif
+ /* Empty if CONFIG_POSIX_TIMERS=n */
+ struct posix_cputimers posix_cputimers;
/* PID/PID hash table linkage. */
struct pid *pids[PIDTYPE_MAX];
diff --git a/kernel/fork.c b/kernel/fork.c
index d8ae0f1b4148..b6a135e4275b 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1523,6 +1523,7 @@ void __cleanup_sighand(struct sighand_struct *sighand)
*/
static void posix_cpu_timers_init_group(struct signal_struct *sig)
{
+ struct posix_cputimers *pct = &sig->posix_cputimers;
unsigned long cpu_limit;
cpu_limit = READ_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur);
@@ -1531,10 +1532,7 @@ static void posix_cpu_timers_init_group(struct signal_struct *sig)
sig->cputimer.running = true;
}
- /* The timer lists. */
- INIT_LIST_HEAD(&sig->cpu_timers[0]);
- INIT_LIST_HEAD(&sig->cpu_timers[1]);
- INIT_LIST_HEAD(&sig->cpu_timers[2]);
+ posix_cputimers_init(pct);
}
#else
static inline void posix_cpu_timers_init_group(struct signal_struct *sig) { }
@@ -1649,9 +1647,8 @@ static void posix_cpu_timers_init(struct task_struct *tsk)
tsk->cputime_expires.prof_exp = 0;
tsk->cputime_expires.virt_exp = 0;
tsk->cputime_expires.sched_exp = 0;
- INIT_LIST_HEAD(&tsk->cpu_timers[0]);
- INIT_LIST_HEAD(&tsk->cpu_timers[1]);
- INIT_LIST_HEAD(&tsk->cpu_timers[2]);
+
+ posix_cputimers_init(&tsk->posix_cputimers);
}
#else
static inline void posix_cpu_timers_init(struct task_struct *tsk) { }
diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c
index b1c97664a730..849e2045fb6e 100644
--- a/kernel/time/posix-cpu-timers.c
+++ b/kernel/time/posix-cpu-timers.c
@@ -407,11 +407,11 @@ static void cleanup_timers_list(struct list_head *head)
*
* This must be called with the siglock held.
*/
-static void cleanup_timers(struct list_head *head)
+static void cleanup_timers(struct posix_cputimers *pct)
{
- cleanup_timers_list(head);
- cleanup_timers_list(++head);
- cleanup_timers_list(++head);
+ cleanup_timers_list(&pct->cpu_timers[CPUCLOCK_PROF]);
+ cleanup_timers_list(&pct->cpu_timers[CPUCLOCK_VIRT]);
+ cleanup_timers_list(&pct->cpu_timers[CPUCLOCK_SCHED]);
}
/*
@@ -421,11 +421,11 @@ static void cleanup_timers(struct list_head *head)
*/
void posix_cpu_timers_exit(struct task_struct *tsk)
{
- cleanup_timers(tsk->cpu_timers);
+ cleanup_timers(&tsk->posix_cputimers);
}
void posix_cpu_timers_exit_group(struct task_struct *tsk)
{
- cleanup_timers(tsk->signal->cpu_timers);
+ cleanup_timers(&tsk->signal->posix_cputimers);
}
static inline int expires_gt(u64 expires, u64 new_exp)
@@ -446,10 +446,10 @@ static void arm_timer(struct k_itimer *timer)
struct cpu_timer_list *next;
if (CPUCLOCK_PERTHREAD(timer->it_clock)) {
- head = p->cpu_timers;
+ head = p->posix_cputimers.cpu_timers;
cputime_expires = &p->cputime_expires;
} else {
- head = p->signal->cpu_timers;
+ head = p->signal->posix_cputimers.cpu_timers;
cputime_expires = &p->signal->cputime_expires;
}
head += CPUCLOCK_WHICH(timer->it_clock);
@@ -773,8 +773,8 @@ static inline void check_dl_overrun(struct task_struct *tsk)
static void check_thread_timers(struct task_struct *tsk,
struct list_head *firing)
{
+ struct list_head *timers = tsk->posix_cputimers.cpu_timers;
struct task_cputime *tsk_expires = &tsk->cputime_expires;
- struct list_head *timers = tsk->cpu_timers;
u64 expires, stime, utime;
unsigned long soft;
@@ -879,9 +879,9 @@ static void check_process_timers(struct task_struct *tsk,
struct list_head *firing)
{
struct signal_struct *const sig = tsk->signal;
+ struct list_head *timers = sig->posix_cputimers.cpu_timers;
u64 utime, ptime, virt_expires, prof_expires;
u64 sum_sched_runtime, sched_expires;
- struct list_head *timers = sig->cpu_timers;
struct task_cputime cputime;
unsigned long soft;