posix-cpu-timers: Create a container struct
authorThomas Gleixner <tglx@linutronix.de>
Wed, 21 Aug 2019 19:09:04 +0000 (21:09 +0200)
committerThomas Gleixner <tglx@linutronix.de>
Wed, 28 Aug 2019 09:50:33 +0000 (11:50 +0200)
Per task/process data of posix CPU timers is all over the place which
makes the code hard to follow and requires ifdeffery.

Create a container to hold all this information in one place, so data is
consolidated and the ifdeffery can be confined to the posix timer header
file and removed from places like fork.

As a first step, move the cpu_timers list head array into the new struct
and clean up the initializers and simplify fork. The remaining #ifdef in
fork will be removed later.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
Link: https://lkml.kernel.org/r/20190821192920.819418976@linutronix.de
include/linux/init_task.h
include/linux/posix-timers.h
include/linux/sched.h
include/linux/sched/signal.h
kernel/fork.c
kernel/time/posix-cpu-timers.c

index 6049baa5b8bcb28ab2ecef121b966f1d25054cc2..2c620d7ac432dd7e94fe45a65a113d75fee6af0b 100644 (file)
@@ -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 */
index 033374b9976707ec75a4295819a866e120582ba6..cdef89750b2cde7a65ba9a79bf98e8ddef890f58 100644 (file)
@@ -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
 
 /**
index 8dc1811487f5212ec89665269302f19db4c497c5..fde844a3b86eae5c0fd52d368ab21727a5df3da2 100644 (file)
@@ -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: */
 
index efd8ce7675ede96262d26138d9d2670fb37cefa3..88fbb3f1c3758530347583938afd0d6d440a4251 100644 (file)
@@ -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];
index d8ae0f1b4148023c8c0d242b799039deb362ca09..b6a135e4275b41f6ac7fc27568b95094fd38314e 100644 (file)
@@ -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) { }
index b1c97664a730447f4c54c05a060b9396e8249170..849e2045fb6e4945e98cab0dad0045bfa3340a20 100644 (file)
@@ -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;