Commit 2b69942f authored by Thomas Gleixner's avatar Thomas Gleixner
Browse files

posix-cpu-timers: Create a container struct



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: default avatarThomas Gleixner <tglx@linutronix.de>
Reviewed-by: default avatarFrederic Weisbecker <frederic@kernel.org>
Link: https://lkml.kernel.org/r/20190821192920.819418976@linutronix.de
parent ab693c5a
Loading
Loading
Loading
Loading
+0 −11
Original line number Diff line number Diff line
@@ -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 */
+34 −0
Original line number Diff line number Diff line
@@ -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

/**
+3 −1
Original line number Diff line number Diff line
@@ -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: */

+3 −2
Original line number Diff line number Diff line
@@ -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];
+4 −7
Original line number Diff line number Diff line
@@ -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) { }
Loading