Skip to content

Commit b541315

Browse files
Benjamin SegallKAGA-KOKO
authored andcommitted
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: b787830 ("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
1 parent 42f7652 commit b541315

File tree

2 files changed

+10
-0
lines changed

2 files changed

+10
-0
lines changed

include/linux/tick.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,12 +251,19 @@ static inline void tick_dep_set_task(struct task_struct *tsk,
251251
if (tick_nohz_full_enabled())
252252
tick_nohz_dep_set_task(tsk, bit);
253253
}
254+
254255
static inline void tick_dep_clear_task(struct task_struct *tsk,
255256
enum tick_dep_bits bit)
256257
{
257258
if (tick_nohz_full_enabled())
258259
tick_nohz_dep_clear_task(tsk, bit);
259260
}
261+
262+
static inline void tick_dep_init_task(struct task_struct *tsk)
263+
{
264+
atomic_set(&tsk->tick_dep_mask, 0);
265+
}
266+
260267
static inline void tick_dep_set_signal(struct task_struct *tsk,
261268
enum tick_dep_bits bit)
262269
{
@@ -290,6 +297,7 @@ static inline void tick_dep_set_task(struct task_struct *tsk,
290297
enum tick_dep_bits bit) { }
291298
static inline void tick_dep_clear_task(struct task_struct *tsk,
292299
enum tick_dep_bits bit) { }
300+
static inline void tick_dep_init_task(struct task_struct *tsk) { }
293301
static inline void tick_dep_set_signal(struct task_struct *tsk,
294302
enum tick_dep_bits bit) { }
295303
static inline void tick_dep_clear_signal(struct signal_struct *signal,

kernel/fork.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@
105105
#include <linux/rseq.h>
106106
#include <uapi/linux/pidfd.h>
107107
#include <linux/pidfs.h>
108+
#include <linux/tick.h>
108109

109110
#include <asm/pgalloc.h>
110111
#include <linux/uaccess.h>
@@ -2292,6 +2293,7 @@ __latent_entropy struct task_struct *copy_process(
22922293
acct_clear_integrals(p);
22932294

22942295
posix_cputimers_init(&p->posix_cputimers);
2296+
tick_dep_init_task(p);
22952297

22962298
p->io_context = NULL;
22972299
audit_set_context(p, NULL);

0 commit comments

Comments
 (0)