All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3] posix-cpu-timers: clear TICK_DEP_BIT_POSIX_TIMER on clone
@ 2024-10-26  1:35 Benjamin Segall
  2024-10-26 15:29 ` Frederic Weisbecker
  2024-10-27  9:45 ` [tip: timers/urgent] posix-cpu-timers: Clear " tip-bot2 for Benjamin Segall
  0 siblings, 2 replies; 3+ messages in thread
From: Benjamin Segall @ 2024-10-26  1:35 UTC (permalink / raw)
  To: linux-kernel, Anna-Maria Behnsen, Thomas Gleixner,
	Frederic Weisbecker

When cloning a new thread, its posix_cputimers are not inherited, and
are cleared by posix_cputimers_init(). However, this does not clear the
tick dependency it creates in tsk->tick_dep_mask, and the handler does
not reach the code to clear the dependency if there were no timers to
begin with.

Thus if a thread has a cputimer running before clone/fork, all
descendants will prevent nohz_full unless they create a cputimer of
their own.

Fix this by entirely clearing the tick_dep_mask in copy_process().
(There is currently no inherited state that needs a tick dependency)

Process-wide timers do not have this problem because fork does not copy
signal_struct as a baseline, it creates one from scratch.

Fixes: b78783000d5c ("posix-cpu-timers: Migrate to use new tick dependency mask model")
Signed-off-by: Ben Segall <bsegall@google.com>
Cc: stable@vger.kernel.org
---
 include/linux/tick.h | 8 ++++++++
 kernel/fork.c        | 2 ++
 2 files changed, 10 insertions(+)

diff --git a/include/linux/tick.h b/include/linux/tick.h
index 72744638c5b0..99c9c5a7252a 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -249,16 +249,23 @@ static inline void tick_dep_set_task(struct task_struct *tsk,
 				     enum tick_dep_bits bit)
 {
 	if (tick_nohz_full_enabled())
 		tick_nohz_dep_set_task(tsk, bit);
 }
+
 static inline void tick_dep_clear_task(struct task_struct *tsk,
 				       enum tick_dep_bits bit)
 {
 	if (tick_nohz_full_enabled())
 		tick_nohz_dep_clear_task(tsk, bit);
 }
+
+static inline void tick_dep_init_task(struct task_struct *tsk)
+{
+	atomic_set(&tsk->tick_dep_mask, 0);
+}
+
 static inline void tick_dep_set_signal(struct task_struct *tsk,
 				       enum tick_dep_bits bit)
 {
 	if (tick_nohz_full_enabled())
 		tick_nohz_dep_set_signal(tsk, bit);
@@ -288,10 +295,11 @@ static inline void tick_dep_set_cpu(int cpu, enum tick_dep_bits bit) { }
 static inline void tick_dep_clear_cpu(int cpu, enum tick_dep_bits bit) { }
 static inline void tick_dep_set_task(struct task_struct *tsk,
 				     enum tick_dep_bits bit) { }
 static inline void tick_dep_clear_task(struct task_struct *tsk,
 				       enum tick_dep_bits bit) { }
+static inline void tick_dep_init_task(struct task_struct *tsk) { }
 static inline void tick_dep_set_signal(struct task_struct *tsk,
 				       enum tick_dep_bits bit) { }
 static inline void tick_dep_clear_signal(struct signal_struct *signal,
 					 enum tick_dep_bits bit) { }
 
diff --git a/kernel/fork.c b/kernel/fork.c
index df8e4575ff01..9adad1ad202e 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -103,10 +103,11 @@
 #include <linux/user_events.h>
 #include <linux/iommu.h>
 #include <linux/rseq.h>
 #include <uapi/linux/pidfd.h>
 #include <linux/pidfs.h>
+#include <linux/tick.h>
 
 #include <asm/pgalloc.h>
 #include <linux/uaccess.h>
 #include <asm/mmu_context.h>
 #include <asm/cacheflush.h>
@@ -2290,10 +2291,11 @@ __latent_entropy struct task_struct *copy_process(
 
 	task_io_accounting_init(&p->ioac);
 	acct_clear_integrals(p);
 
 	posix_cputimers_init(&p->posix_cputimers);
+	tick_dep_init_task(p);
 
 	p->io_context = NULL;
 	audit_set_context(p, NULL);
 	cgroup_fork(p);
 	if (args->kthread) {
-- 
2.47.0.163.g1226f6d8fa-goog


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v3] posix-cpu-timers: clear TICK_DEP_BIT_POSIX_TIMER on clone
  2024-10-26  1:35 [PATCH v3] posix-cpu-timers: clear TICK_DEP_BIT_POSIX_TIMER on clone Benjamin Segall
@ 2024-10-26 15:29 ` Frederic Weisbecker
  2024-10-27  9:45 ` [tip: timers/urgent] posix-cpu-timers: Clear " tip-bot2 for Benjamin Segall
  1 sibling, 0 replies; 3+ messages in thread
From: Frederic Weisbecker @ 2024-10-26 15:29 UTC (permalink / raw)
  To: Benjamin Segall; +Cc: linux-kernel, Anna-Maria Behnsen, Thomas Gleixner

Le Fri, Oct 25, 2024 at 06:35:35PM -0700, Benjamin Segall a écrit :
> When cloning a new thread, its posix_cputimers are not inherited, and
> are cleared by posix_cputimers_init(). However, this does not clear the
> tick dependency it creates in tsk->tick_dep_mask, and the handler does
> not reach the code to clear the dependency if there were no timers to
> begin with.
> 
> Thus if a thread has a cputimer running before clone/fork, all
> descendants will prevent nohz_full unless they create a cputimer of
> their own.
> 
> Fix this by entirely clearing the tick_dep_mask in copy_process().
> (There is currently no inherited state that needs a tick dependency)
> 
> Process-wide timers do not have this problem because fork does not copy
> signal_struct as a baseline, it creates one from scratch.
> 
> Fixes: b78783000d5c ("posix-cpu-timers: Migrate to use new tick dependency mask model")
> Signed-off-by: Ben Segall <bsegall@google.com>
> Cc: stable@vger.kernel.org

Reviewed-by: Frederic Weisbecker <frederic@kernel.org>

Thanks!

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [tip: timers/urgent] posix-cpu-timers: Clear TICK_DEP_BIT_POSIX_TIMER on clone
  2024-10-26  1:35 [PATCH v3] posix-cpu-timers: clear TICK_DEP_BIT_POSIX_TIMER on clone Benjamin Segall
  2024-10-26 15:29 ` Frederic Weisbecker
@ 2024-10-27  9:45 ` tip-bot2 for Benjamin Segall
  1 sibling, 0 replies; 3+ messages in thread
From: tip-bot2 for Benjamin Segall @ 2024-10-27  9:45 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Ben Segall, Thomas Gleixner, Frederic Weisbecker, stable, x86,
	linux-kernel

The following commit has been merged into the timers/urgent branch of tip:

Commit-ID:     b5413156bad91dc2995a5c4eab1b05e56914638a
Gitweb:        https://git.kernel.org/tip/b5413156bad91dc2995a5c4eab1b05e56914638a
Author:        Benjamin Segall <bsegall@google.com>
AuthorDate:    Fri, 25 Oct 2024 18:35:35 -07:00
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Sun, 27 Oct 2024 10:36:04 +01:00

posix-cpu-timers: Clear TICK_DEP_BIT_POSIX_TIMER on clone

When cloning a new thread, its posix_cputimers are not inherited, and
are cleared by posix_cputimers_init(). However, this does not clear the
tick dependency it creates in tsk->tick_dep_mask, and the handler does
not reach the code to clear the dependency if there were no timers to
begin with.

Thus if a thread has a cputimer running before clone/fork, all
descendants will prevent nohz_full unless they create a cputimer of
their own.

Fix this by entirely clearing the tick_dep_mask in copy_process().
(There is currently no inherited state that needs a tick dependency)

Process-wide timers do not have this problem because fork does not copy
signal_struct as a baseline, it creates one from scratch.

Fixes: b78783000d5c ("posix-cpu-timers: Migrate to use new tick dependency mask model")
Signed-off-by: Ben Segall <bsegall@google.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/all/xm26o737bq8o.fsf@google.com

---
 include/linux/tick.h | 8 ++++++++
 kernel/fork.c        | 2 ++
 2 files changed, 10 insertions(+)

diff --git a/include/linux/tick.h b/include/linux/tick.h
index 7274463..99c9c5a 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -251,12 +251,19 @@ static inline void tick_dep_set_task(struct task_struct *tsk,
 	if (tick_nohz_full_enabled())
 		tick_nohz_dep_set_task(tsk, bit);
 }
+
 static inline void tick_dep_clear_task(struct task_struct *tsk,
 				       enum tick_dep_bits bit)
 {
 	if (tick_nohz_full_enabled())
 		tick_nohz_dep_clear_task(tsk, bit);
 }
+
+static inline void tick_dep_init_task(struct task_struct *tsk)
+{
+	atomic_set(&tsk->tick_dep_mask, 0);
+}
+
 static inline void tick_dep_set_signal(struct task_struct *tsk,
 				       enum tick_dep_bits bit)
 {
@@ -290,6 +297,7 @@ static inline void tick_dep_set_task(struct task_struct *tsk,
 				     enum tick_dep_bits bit) { }
 static inline void tick_dep_clear_task(struct task_struct *tsk,
 				       enum tick_dep_bits bit) { }
+static inline void tick_dep_init_task(struct task_struct *tsk) { }
 static inline void tick_dep_set_signal(struct task_struct *tsk,
 				       enum tick_dep_bits bit) { }
 static inline void tick_dep_clear_signal(struct signal_struct *signal,
diff --git a/kernel/fork.c b/kernel/fork.c
index 89ceb4a..6fa9fe6 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -105,6 +105,7 @@
 #include <linux/rseq.h>
 #include <uapi/linux/pidfd.h>
 #include <linux/pidfs.h>
+#include <linux/tick.h>
 
 #include <asm/pgalloc.h>
 #include <linux/uaccess.h>
@@ -2292,6 +2293,7 @@ __latent_entropy struct task_struct *copy_process(
 	acct_clear_integrals(p);
 
 	posix_cputimers_init(&p->posix_cputimers);
+	tick_dep_init_task(p);
 
 	p->io_context = NULL;
 	audit_set_context(p, NULL);

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-10-27  9:45 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-26  1:35 [PATCH v3] posix-cpu-timers: clear TICK_DEP_BIT_POSIX_TIMER on clone Benjamin Segall
2024-10-26 15:29 ` Frederic Weisbecker
2024-10-27  9:45 ` [tip: timers/urgent] posix-cpu-timers: Clear " tip-bot2 for Benjamin Segall

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.