omit POSIX timer stuff from task_struct when disabled

Message ID alpine.LFD.2.20.1701091336370.2671@knanqh.ubzr
State New
Headers show

Commit Message

Nicolas Pitre Jan. 9, 2017, 6:49 p.m.
When CONFIG_POSIX_TIMERS is disabled, it is preferable to remove related
structures from struct task_struct and struct signal_struct as they
won't contain anything useful and shouldn't be relied upon by mistake.
Code still referencing those structures is also disabled here.

Signed-off-by: Nicolas Pitre <nico@linaro.org>

Comments

John Stultz Jan. 20, 2017, 10:32 p.m. | #1
On Mon, Jan 9, 2017 at 10:49 AM, Nicolas Pitre <nicolas.pitre@linaro.org> wrote:
> When CONFIG_POSIX_TIMERS is disabled, it is preferable to remove related

> structures from struct task_struct and struct signal_struct as they

> won't contain anything useful and shouldn't be relied upon by mistake.

> Code still referencing those structures is also disabled here.

>

> Signed-off-by: Nicolas Pitre <nico@linaro.org>

>

[snip]
> diff --git a/kernel/fork.c b/kernel/fork.c

> index 11c5c8ab82..8e333e55a9 100644

> --- a/kernel/fork.c

> +++ b/kernel/fork.c

> @@ -1309,6 +1309,7 @@ void __cleanup_sighand(struct sighand_struct *sighand)

>   */

>  static void posix_cpu_timers_init_group(struct signal_struct *sig)

>  {

> +#ifdef CONFIG_POSIX_TIMERS

>         unsigned long cpu_limit;

>

>         cpu_limit = READ_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur);

> @@ -1321,6 +1322,7 @@ static void posix_cpu_timers_init_group(struct signal_struct *sig)

>         INIT_LIST_HEAD(&sig->cpu_timers[0]);

>         INIT_LIST_HEAD(&sig->cpu_timers[1]);

>         INIT_LIST_HEAD(&sig->cpu_timers[2]);

> +#endif

>  }


So apologies for not catching this earlier. I was just queuing this
up, when I noticed the style issue here.

Aren't in-function ifdefs frowned upon? Wouldn't it be better to do:
#ifdef CONFIG_POSIX_TIMERS
static void posix_cpu_timers_init_group(struct signal_struct *sig)
{
...
}
#else
static void posix_cpu_timers_init_group(struct signal_struct *sig) {}
#endif

And similar for most of the ifdef'ed out functions in this patch?

thanks
-john
Nicolas Pitre Jan. 20, 2017, 10:46 p.m. | #2
On Fri, 20 Jan 2017, John Stultz wrote:

> On Mon, Jan 9, 2017 at 10:49 AM, Nicolas Pitre <nicolas.pitre@linaro.org> wrote:

> > When CONFIG_POSIX_TIMERS is disabled, it is preferable to remove related

> > structures from struct task_struct and struct signal_struct as they

> > won't contain anything useful and shouldn't be relied upon by mistake.

> > Code still referencing those structures is also disabled here.

> >

> > Signed-off-by: Nicolas Pitre <nico@linaro.org>

> >

> [snip]

> > diff --git a/kernel/fork.c b/kernel/fork.c

> > index 11c5c8ab82..8e333e55a9 100644

> > --- a/kernel/fork.c

> > +++ b/kernel/fork.c

> > @@ -1309,6 +1309,7 @@ void __cleanup_sighand(struct sighand_struct *sighand)

> >   */

> >  static void posix_cpu_timers_init_group(struct signal_struct *sig)

> >  {

> > +#ifdef CONFIG_POSIX_TIMERS

> >         unsigned long cpu_limit;

> >

> >         cpu_limit = READ_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur);

> > @@ -1321,6 +1322,7 @@ static void posix_cpu_timers_init_group(struct signal_struct *sig)

> >         INIT_LIST_HEAD(&sig->cpu_timers[0]);

> >         INIT_LIST_HEAD(&sig->cpu_timers[1]);

> >         INIT_LIST_HEAD(&sig->cpu_timers[2]);

> > +#endif

> >  }

> 

> So apologies for not catching this earlier. I was just queuing this

> up, when I noticed the style issue here.

> 

> Aren't in-function ifdefs frowned upon? Wouldn't it be better to do:

> #ifdef CONFIG_POSIX_TIMERS

> static void posix_cpu_timers_init_group(struct signal_struct *sig)

> {

> ...

> }

> #else

> static void posix_cpu_timers_init_group(struct signal_struct *sig) {}

> #endif

> 

> And similar for most of the ifdef'ed out functions in this patch?


Well... I don't mind either ways.  In this case those functions are 
rather small and doing it the way you suggest doubles the number of 
added lines in this hunk. That's why I opted for the current style.

Just tell me if you prefer that I respin the patch and I'll do it.


Nicolas
John Stultz Jan. 20, 2017, 10:48 p.m. | #3
On Fri, Jan 20, 2017 at 2:46 PM, Nicolas Pitre <nicolas.pitre@linaro.org> wrote:
> On Fri, 20 Jan 2017, John Stultz wrote:

>

>> On Mon, Jan 9, 2017 at 10:49 AM, Nicolas Pitre <nicolas.pitre@linaro.org> wrote:

>> > When CONFIG_POSIX_TIMERS is disabled, it is preferable to remove related

>> > structures from struct task_struct and struct signal_struct as they

>> > won't contain anything useful and shouldn't be relied upon by mistake.

>> > Code still referencing those structures is also disabled here.

>> >

>> > Signed-off-by: Nicolas Pitre <nico@linaro.org>

>> >

>> [snip]

>> > diff --git a/kernel/fork.c b/kernel/fork.c

>> > index 11c5c8ab82..8e333e55a9 100644

>> > --- a/kernel/fork.c

>> > +++ b/kernel/fork.c

>> > @@ -1309,6 +1309,7 @@ void __cleanup_sighand(struct sighand_struct *sighand)

>> >   */

>> >  static void posix_cpu_timers_init_group(struct signal_struct *sig)

>> >  {

>> > +#ifdef CONFIG_POSIX_TIMERS

>> >         unsigned long cpu_limit;

>> >

>> >         cpu_limit = READ_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur);

>> > @@ -1321,6 +1322,7 @@ static void posix_cpu_timers_init_group(struct signal_struct *sig)

>> >         INIT_LIST_HEAD(&sig->cpu_timers[0]);

>> >         INIT_LIST_HEAD(&sig->cpu_timers[1]);

>> >         INIT_LIST_HEAD(&sig->cpu_timers[2]);

>> > +#endif

>> >  }

>>

>> So apologies for not catching this earlier. I was just queuing this

>> up, when I noticed the style issue here.

>>

>> Aren't in-function ifdefs frowned upon? Wouldn't it be better to do:

>> #ifdef CONFIG_POSIX_TIMERS

>> static void posix_cpu_timers_init_group(struct signal_struct *sig)

>> {

>> ...

>> }

>> #else

>> static void posix_cpu_timers_init_group(struct signal_struct *sig) {}

>> #endif

>>

>> And similar for most of the ifdef'ed out functions in this patch?

>

> Well... I don't mind either ways.  In this case those functions are

> rather small and doing it the way you suggest doubles the number of

> added lines in this hunk. That's why I opted for the current style.

>

> Just tell me if you prefer that I respin the patch and I'll do it.


Yea. I'm not so finicky but I'm sure I'll probably get yelled at if I
pass it on, so if you don't mind respinning it, I'll get it applied
for testing here quickly :)

thanks
-john
Nicolas Pitre Jan. 21, 2017, 5:09 a.m. | #4
On Fri, 20 Jan 2017, John Stultz wrote:

> On Fri, Jan 20, 2017 at 2:46 PM, Nicolas Pitre <nicolas.pitre@linaro.org> wrote:

> > Just tell me if you prefer that I respin the patch and I'll do it.

> 

> Yea. I'm not so finicky but I'm sure I'll probably get yelled at if I

> pass it on, so if you don't mind respinning it, I'll get it applied

> for testing here quickly :)


There you go.

----- >8
Subject: omit POSIX timer stuff from task_struct when disabled

When CONFIG_POSIX_TIMERS is disabled, it is preferable to remove related
structures from struct task_struct and struct signal_struct as they
won't contain anything useful and shouldn't be relied upon by mistake.
Code still referencing those structures is also disabled here.

Signed-off-by: Nicolas Pitre <nico@linaro.org>diff --git a/fs/proc/base.c b/fs/proc/base.c

index 8e7e61b28f..03deeac1e8 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -2179,7 +2179,7 @@ static const struct file_operations proc_map_files_operations = {
 	.llseek		= generic_file_llseek,
 };
 
-#ifdef CONFIG_CHECKPOINT_RESTORE
+#if defined(CONFIG_CHECKPOINT_RESTORE) && defined(CONFIG_POSIX_TIMERS)
 struct timers_private {
 	struct pid *pid;
 	struct task_struct *task;
@@ -2936,7 +2936,7 @@ static const struct pid_entry tgid_base_stuff[] = {
 	REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations),
 	REG("setgroups",  S_IRUGO|S_IWUSR, proc_setgroups_operations),
 #endif
-#ifdef CONFIG_CHECKPOINT_RESTORE
+#if defined(CONFIG_CHECKPOINT_RESTORE) && defined(CONFIG_POSIX_TIMERS)
 	REG("timers",	  S_IRUGO, proc_timers_operations),
 #endif
 	REG("timerslack_ns", S_IRUGO|S_IWUGO, proc_pid_set_timerslack_ns_operations),
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index 325f649d77..3a85d61f76 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -42,6 +42,27 @@ extern struct fs_struct init_fs;
 #define INIT_PREV_CPUTIME(x)
 #endif
 
+#ifdef CONFIG_POSIX_TIMERS
+#define INIT_POSIX_TIMERS(s)						\
+	.posix_timers = LIST_HEAD_INIT(s.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]),								\
+	},
+#define INIT_CPUTIMER(s)						\
+	.cputimer	= { 						\
+		.cputime_atomic	= INIT_CPUTIME_ATOMIC,			\
+		.running	= false,				\
+		.checking_timer = false,				\
+	},
+#else
+#define INIT_POSIX_TIMERS(s)
+#define INIT_CPU_TIMERS(s)
+#define INIT_CPUTIMER(s)
+#endif
+
 #define INIT_SIGNALS(sig) {						\
 	.nr_threads	= 1,						\
 	.thread_head	= LIST_HEAD_INIT(init_task.thread_node),	\
@@ -49,14 +70,10 @@ extern struct fs_struct init_fs;
 	.shared_pending	= { 						\
 		.list = LIST_HEAD_INIT(sig.shared_pending.list),	\
 		.signal =  {{0}}},					\
-	.posix_timers	 = LIST_HEAD_INIT(sig.posix_timers),		\
-	.cpu_timers	= INIT_CPU_TIMERS(sig.cpu_timers),		\
+	INIT_POSIX_TIMERS(sig)						\
+	INIT_CPU_TIMERS(sig)						\
 	.rlim		= INIT_RLIMITS,					\
-	.cputimer	= { 						\
-		.cputime_atomic	= INIT_CPUTIME_ATOMIC,			\
-		.running	= false,				\
-		.checking_timer = false,				\
-	},								\
+	INIT_CPUTIMER(sig)						\
 	INIT_PREV_CPUTIME(sig)						\
 	.cred_guard_mutex =						\
 		 __MUTEX_INITIALIZER(sig.cred_guard_mutex),		\
@@ -247,7 +264,7 @@ extern struct task_group root_task_group;
 	.blocked	= {{0}},					\
 	.alloc_lock	= __SPIN_LOCK_UNLOCKED(tsk.alloc_lock),		\
 	.journal_info	= NULL,						\
-	.cpu_timers	= INIT_CPU_TIMERS(tsk.cpu_timers),		\
+	INIT_CPU_TIMERS(tsk)						\
 	.pi_lock	= __RAW_SPIN_LOCK_UNLOCKED(tsk.pi_lock),	\
 	.timer_slack_ns = 50000, /* 50 usec default slack */		\
 	.pids = {							\
@@ -274,13 +291,6 @@ extern struct task_group root_task_group;
 }
 
 
-#define INIT_CPU_TIMERS(cpu_timers)					\
-{									\
-	LIST_HEAD_INIT(cpu_timers[0]),					\
-	LIST_HEAD_INIT(cpu_timers[1]),					\
-	LIST_HEAD_INIT(cpu_timers[2]),					\
-}
-
 /* Attach to the init_task data structure for proper alignment */
 #define __init_task_data __attribute__((__section__(".data..init_task")))
 
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 4d1905245c..e8f6af5972 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -734,13 +734,14 @@ struct signal_struct {
 	unsigned int		is_child_subreaper:1;
 	unsigned int		has_child_subreaper:1;
 
+#ifdef CONFIG_POSIX_TIMERS
+
 	/* POSIX.1b Interval Timers */
 	int			posix_timer_id;
 	struct list_head	posix_timers;
 
 	/* ITIMER_REAL timer for the process */
 	struct hrtimer real_timer;
-	struct pid *leader_pid;
 	ktime_t it_real_incr;
 
 	/*
@@ -759,12 +760,16 @@ struct signal_struct {
 	/* Earliest-expiration cache. */
 	struct task_cputime cputime_expires;
 
+	struct list_head cpu_timers[3];
+
+#endif
+
+	struct pid *leader_pid;
+
 #ifdef CONFIG_NO_HZ_FULL
 	atomic_t tick_dep_mask;
 #endif
 
-	struct list_head cpu_timers[3];
-
 	struct pid *tty_old_pgrp;
 
 	/* boolean value for session group leader */
@@ -1681,8 +1686,10 @@ struct task_struct {
 /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */
 	unsigned long min_flt, maj_flt;
 
+#ifdef CONFIG_POSIX_TIMERS
 	struct task_cputime cputime_expires;
 	struct list_head cpu_timers[3];
+#endif
 
 /* process credentials */
 	const struct cred __rcu *ptracer_cred; /* Tracer's credentials at attach */
diff --git a/kernel/fork.c b/kernel/fork.c
index 11c5c8ab82..105c6676d9 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1304,6 +1304,7 @@ void __cleanup_sighand(struct sighand_struct *sighand)
 	}
 }
 
+#ifdef CONFIG_POSIX_TIMERS
 /*
  * Initialize POSIX timer handling for a thread group.
  */
@@ -1322,6 +1323,9 @@ static void posix_cpu_timers_init_group(struct signal_struct *sig)
 	INIT_LIST_HEAD(&sig->cpu_timers[1]);
 	INIT_LIST_HEAD(&sig->cpu_timers[2]);
 }
+#else
+static inline void posix_cpu_timers_init_group(struct signal_struct *sig) { }
+#endif
 
 static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
 {
@@ -1346,11 +1350,11 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
 	init_waitqueue_head(&sig->wait_chldexit);
 	sig->curr_target = tsk;
 	init_sigpending(&sig->shared_pending);
-	INIT_LIST_HEAD(&sig->posix_timers);
 	seqlock_init(&sig->stats_lock);
 	prev_cputime_init(&sig->prev_cputime);
 
 #ifdef CONFIG_POSIX_TIMERS
+	INIT_LIST_HEAD(&sig->posix_timers);
 	hrtimer_init(&sig->real_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
 	sig->real_timer.function = it_real_fn;
 #endif
@@ -1425,6 +1429,7 @@ static void rt_mutex_init_task(struct task_struct *p)
 #endif
 }
 
+#ifdef CONFIG_POSIX_TIMERS
 /*
  * Initialize POSIX timer handling for a single task.
  */
@@ -1437,6 +1442,9 @@ static void posix_cpu_timers_init(struct task_struct *tsk)
 	INIT_LIST_HEAD(&tsk->cpu_timers[1]);
 	INIT_LIST_HEAD(&tsk->cpu_timers[2]);
 }
+#else
+static inline void posix_cpu_timers_init(struct task_struct *tsk) { }
+#endif
 
 static inline void
 init_task_pid(struct task_struct *task, enum pid_type type, struct pid *pid)
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 2516b8df6d..a688a82067 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -2246,6 +2246,7 @@ prio_changed_rt(struct rq *rq, struct task_struct *p, int oldprio)
 	}
 }
 
+#ifdef CONFIG_POSIX_TIMERS
 static void watchdog(struct rq *rq, struct task_struct *p)
 {
 	unsigned long soft, hard;
@@ -2267,6 +2268,9 @@ static void watchdog(struct rq *rq, struct task_struct *p)
 			p->cputime_expires.sched_exp = p->se.sum_exec_runtime;
 	}
 }
+#else
+static inline void watchdog(struct rq *rq, struct task_struct *p) { }
+#endif
 
 static void task_tick_rt(struct rq *rq, struct task_struct *p, int queued)
 {
diff --git a/kernel/sched/stats.h b/kernel/sched/stats.h
index 34659a8535..c69a9870ab 100644
--- a/kernel/sched/stats.h
+++ b/kernel/sched/stats.h
@@ -172,18 +172,19 @@ sched_info_switch(struct rq *rq,
  */
 
 /**
- * cputimer_running - return true if cputimer is running
+ * get_running_cputimer - return &tsk->signal->cputimer if cputimer is running
  *
  * @tsk:	Pointer to target task.
  */
-static inline bool cputimer_running(struct task_struct *tsk)
-
+#ifdef CONFIG_POSIX_TIMERS
+static inline
+struct thread_group_cputimer *get_running_cputimer(struct task_struct *tsk)
 {
 	struct thread_group_cputimer *cputimer = &tsk->signal->cputimer;
 
 	/* Check if cputimer isn't running. This is accessed without locking. */
 	if (!READ_ONCE(cputimer->running))
-		return false;
+		return NULL;
 
 	/*
 	 * After we flush the task's sum_exec_runtime to sig->sum_sched_runtime
@@ -200,10 +201,17 @@ static inline bool cputimer_running(struct task_struct *tsk)
 	 * clock delta is behind the expiring timer value.
 	 */
 	if (unlikely(!tsk->sighand))
-		return false;
+		return NULL;
 
-	return true;
+	return cputimer;
+}
+#else
+static inline
+struct thread_group_cputimer *get_running_cputimer(struct task_struct *tsk)
+{
+	return NULL;
 }
+#endif
 
 /**
  * account_group_user_time - Maintain utime for a thread group.
@@ -218,9 +226,9 @@ static inline bool cputimer_running(struct task_struct *tsk)
 static inline void account_group_user_time(struct task_struct *tsk,
 					   cputime_t cputime)
 {
-	struct thread_group_cputimer *cputimer = &tsk->signal->cputimer;
+	struct thread_group_cputimer *cputimer = get_running_cputimer(tsk);
 
-	if (!cputimer_running(tsk))
+	if (!cputimer)
 		return;
 
 	atomic64_add(cputime, &cputimer->cputime_atomic.utime);
@@ -239,9 +247,9 @@ static inline void account_group_user_time(struct task_struct *tsk,
 static inline void account_group_system_time(struct task_struct *tsk,
 					     cputime_t cputime)
 {
-	struct thread_group_cputimer *cputimer = &tsk->signal->cputimer;
+	struct thread_group_cputimer *cputimer = get_running_cputimer(tsk);
 
-	if (!cputimer_running(tsk))
+	if (!cputimer)
 		return;
 
 	atomic64_add(cputime, &cputimer->cputime_atomic.stime);
@@ -260,9 +268,9 @@ static inline void account_group_system_time(struct task_struct *tsk,
 static inline void account_group_exec_runtime(struct task_struct *tsk,
 					      unsigned long long ns)
 {
-	struct thread_group_cputimer *cputimer = &tsk->signal->cputimer;
+	struct thread_group_cputimer *cputimer = get_running_cputimer(tsk);
 
-	if (!cputimer_running(tsk))
+	if (!cputimer)
 		return;
 
 	atomic64_add(ns, &cputimer->cputime_atomic.sum_exec_runtime);

Patch hide | download patch | download mbox

diff --git a/fs/proc/base.c b/fs/proc/base.c
index 8e7e61b28f..03deeac1e8 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -2179,7 +2179,7 @@  static const struct file_operations proc_map_files_operations = {
 	.llseek		= generic_file_llseek,
 };
 
-#ifdef CONFIG_CHECKPOINT_RESTORE
+#if defined(CONFIG_CHECKPOINT_RESTORE) && defined(CONFIG_POSIX_TIMERS)
 struct timers_private {
 	struct pid *pid;
 	struct task_struct *task;
@@ -2936,7 +2936,7 @@  static const struct pid_entry tgid_base_stuff[] = {
 	REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations),
 	REG("setgroups",  S_IRUGO|S_IWUSR, proc_setgroups_operations),
 #endif
-#ifdef CONFIG_CHECKPOINT_RESTORE
+#if defined(CONFIG_CHECKPOINT_RESTORE) && defined(CONFIG_POSIX_TIMERS)
 	REG("timers",	  S_IRUGO, proc_timers_operations),
 #endif
 	REG("timerslack_ns", S_IRUGO|S_IWUGO, proc_pid_set_timerslack_ns_operations),
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index 325f649d77..3a85d61f76 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -42,6 +42,27 @@  extern struct fs_struct init_fs;
 #define INIT_PREV_CPUTIME(x)
 #endif
 
+#ifdef CONFIG_POSIX_TIMERS
+#define INIT_POSIX_TIMERS(s)						\
+	.posix_timers = LIST_HEAD_INIT(s.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]),								\
+	},
+#define INIT_CPUTIMER(s)						\
+	.cputimer	= { 						\
+		.cputime_atomic	= INIT_CPUTIME_ATOMIC,			\
+		.running	= false,				\
+		.checking_timer = false,				\
+	},
+#else
+#define INIT_POSIX_TIMERS(s)
+#define INIT_CPU_TIMERS(s)
+#define INIT_CPUTIMER(s)
+#endif
+
 #define INIT_SIGNALS(sig) {						\
 	.nr_threads	= 1,						\
 	.thread_head	= LIST_HEAD_INIT(init_task.thread_node),	\
@@ -49,14 +70,10 @@  extern struct fs_struct init_fs;
 	.shared_pending	= { 						\
 		.list = LIST_HEAD_INIT(sig.shared_pending.list),	\
 		.signal =  {{0}}},					\
-	.posix_timers	 = LIST_HEAD_INIT(sig.posix_timers),		\
-	.cpu_timers	= INIT_CPU_TIMERS(sig.cpu_timers),		\
+	INIT_POSIX_TIMERS(sig)						\
+	INIT_CPU_TIMERS(sig)						\
 	.rlim		= INIT_RLIMITS,					\
-	.cputimer	= { 						\
-		.cputime_atomic	= INIT_CPUTIME_ATOMIC,			\
-		.running	= false,				\
-		.checking_timer = false,				\
-	},								\
+	INIT_CPUTIMER(sig)						\
 	INIT_PREV_CPUTIME(sig)						\
 	.cred_guard_mutex =						\
 		 __MUTEX_INITIALIZER(sig.cred_guard_mutex),		\
@@ -247,7 +264,7 @@  extern struct task_group root_task_group;
 	.blocked	= {{0}},					\
 	.alloc_lock	= __SPIN_LOCK_UNLOCKED(tsk.alloc_lock),		\
 	.journal_info	= NULL,						\
-	.cpu_timers	= INIT_CPU_TIMERS(tsk.cpu_timers),		\
+	INIT_CPU_TIMERS(tsk)						\
 	.pi_lock	= __RAW_SPIN_LOCK_UNLOCKED(tsk.pi_lock),	\
 	.timer_slack_ns = 50000, /* 50 usec default slack */		\
 	.pids = {							\
@@ -274,13 +291,6 @@  extern struct task_group root_task_group;
 }
 
 
-#define INIT_CPU_TIMERS(cpu_timers)					\
-{									\
-	LIST_HEAD_INIT(cpu_timers[0]),					\
-	LIST_HEAD_INIT(cpu_timers[1]),					\
-	LIST_HEAD_INIT(cpu_timers[2]),					\
-}
-
 /* Attach to the init_task data structure for proper alignment */
 #define __init_task_data __attribute__((__section__(".data..init_task")))
 
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 4d1905245c..e8f6af5972 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -734,13 +734,14 @@  struct signal_struct {
 	unsigned int		is_child_subreaper:1;
 	unsigned int		has_child_subreaper:1;
 
+#ifdef CONFIG_POSIX_TIMERS
+
 	/* POSIX.1b Interval Timers */
 	int			posix_timer_id;
 	struct list_head	posix_timers;
 
 	/* ITIMER_REAL timer for the process */
 	struct hrtimer real_timer;
-	struct pid *leader_pid;
 	ktime_t it_real_incr;
 
 	/*
@@ -759,12 +760,16 @@  struct signal_struct {
 	/* Earliest-expiration cache. */
 	struct task_cputime cputime_expires;
 
+	struct list_head cpu_timers[3];
+
+#endif
+
+	struct pid *leader_pid;
+
 #ifdef CONFIG_NO_HZ_FULL
 	atomic_t tick_dep_mask;
 #endif
 
-	struct list_head cpu_timers[3];
-
 	struct pid *tty_old_pgrp;
 
 	/* boolean value for session group leader */
@@ -1681,8 +1686,10 @@  struct task_struct {
 /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */
 	unsigned long min_flt, maj_flt;
 
+#ifdef CONFIG_POSIX_TIMERS
 	struct task_cputime cputime_expires;
 	struct list_head cpu_timers[3];
+#endif
 
 /* process credentials */
 	const struct cred __rcu *ptracer_cred; /* Tracer's credentials at attach */
diff --git a/kernel/fork.c b/kernel/fork.c
index 11c5c8ab82..8e333e55a9 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1309,6 +1309,7 @@  void __cleanup_sighand(struct sighand_struct *sighand)
  */
 static void posix_cpu_timers_init_group(struct signal_struct *sig)
 {
+#ifdef CONFIG_POSIX_TIMERS
 	unsigned long cpu_limit;
 
 	cpu_limit = READ_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur);
@@ -1321,6 +1322,7 @@  static void posix_cpu_timers_init_group(struct signal_struct *sig)
 	INIT_LIST_HEAD(&sig->cpu_timers[0]);
 	INIT_LIST_HEAD(&sig->cpu_timers[1]);
 	INIT_LIST_HEAD(&sig->cpu_timers[2]);
+#endif
 }
 
 static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
@@ -1346,11 +1348,11 @@  static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
 	init_waitqueue_head(&sig->wait_chldexit);
 	sig->curr_target = tsk;
 	init_sigpending(&sig->shared_pending);
-	INIT_LIST_HEAD(&sig->posix_timers);
 	seqlock_init(&sig->stats_lock);
 	prev_cputime_init(&sig->prev_cputime);
 
 #ifdef CONFIG_POSIX_TIMERS
+	INIT_LIST_HEAD(&sig->posix_timers);
 	hrtimer_init(&sig->real_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
 	sig->real_timer.function = it_real_fn;
 #endif
@@ -1430,12 +1432,14 @@  static void rt_mutex_init_task(struct task_struct *p)
  */
 static void posix_cpu_timers_init(struct task_struct *tsk)
 {
+#ifdef CONFIG_POSIX_TIMERS
 	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]);
+#endif
 }
 
 static inline void
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 2516b8df6d..f772e0c100 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -2248,6 +2248,7 @@  prio_changed_rt(struct rq *rq, struct task_struct *p, int oldprio)
 
 static void watchdog(struct rq *rq, struct task_struct *p)
 {
+#ifdef CONFIG_POSIX_TIMERS
 	unsigned long soft, hard;
 
 	/* max may change after cur was read, this will be fixed next tick */
@@ -2266,6 +2267,7 @@  static void watchdog(struct rq *rq, struct task_struct *p)
 		if (p->rt.timeout > next)
 			p->cputime_expires.sched_exp = p->se.sum_exec_runtime;
 	}
+#endif
 }
 
 static void task_tick_rt(struct rq *rq, struct task_struct *p, int queued)
diff --git a/kernel/sched/stats.h b/kernel/sched/stats.h
index 34659a8535..32505f71a8 100644
--- a/kernel/sched/stats.h
+++ b/kernel/sched/stats.h
@@ -172,18 +172,19 @@  sched_info_switch(struct rq *rq,
  */
 
 /**
- * cputimer_running - return true if cputimer is running
+ * get_running_cputimer - return &tsk->signal->cputimer if cputimer is running
  *
  * @tsk:	Pointer to target task.
  */
-static inline bool cputimer_running(struct task_struct *tsk)
-
+static inline
+struct thread_group_cputimer *get_running_cputimer(struct task_struct *tsk)
 {
+#ifdef CONFIG_POSIX_TIMERS
 	struct thread_group_cputimer *cputimer = &tsk->signal->cputimer;
 
 	/* Check if cputimer isn't running. This is accessed without locking. */
 	if (!READ_ONCE(cputimer->running))
-		return false;
+		return NULL;
 
 	/*
 	 * After we flush the task's sum_exec_runtime to sig->sum_sched_runtime
@@ -200,9 +201,12 @@  static inline bool cputimer_running(struct task_struct *tsk)
 	 * clock delta is behind the expiring timer value.
 	 */
 	if (unlikely(!tsk->sighand))
-		return false;
+		return NULL;
 
-	return true;
+	return cputimer;
+#else
+	return NULL;
+#endif
 }
 
 /**
@@ -218,9 +222,9 @@  static inline bool cputimer_running(struct task_struct *tsk)
 static inline void account_group_user_time(struct task_struct *tsk,
 					   cputime_t cputime)
 {
-	struct thread_group_cputimer *cputimer = &tsk->signal->cputimer;
+	struct thread_group_cputimer *cputimer = get_running_cputimer(tsk);
 
-	if (!cputimer_running(tsk))
+	if (!cputimer)
 		return;
 
 	atomic64_add(cputime, &cputimer->cputime_atomic.utime);
@@ -239,9 +243,9 @@  static inline void account_group_user_time(struct task_struct *tsk,
 static inline void account_group_system_time(struct task_struct *tsk,
 					     cputime_t cputime)
 {
-	struct thread_group_cputimer *cputimer = &tsk->signal->cputimer;
+	struct thread_group_cputimer *cputimer = get_running_cputimer(tsk);
 
-	if (!cputimer_running(tsk))
+	if (!cputimer)
 		return;
 
 	atomic64_add(cputime, &cputimer->cputime_atomic.stime);
@@ -260,9 +264,9 @@  static inline void account_group_system_time(struct task_struct *tsk,
 static inline void account_group_exec_runtime(struct task_struct *tsk,
 					      unsigned long long ns)
 {
-	struct thread_group_cputimer *cputimer = &tsk->signal->cputimer;
+	struct thread_group_cputimer *cputimer = get_running_cputimer(tsk);
 
-	if (!cputimer_running(tsk))
+	if (!cputimer)
 		return;
 
 	atomic64_add(ns, &cputimer->cputime_atomic.sum_exec_runtime);