Skip to content

Commit 1e4ca26

Browse files
matosattiingomolnar
authored andcommitted
tick/nohz: Change signal tick dependency to wake up CPUs of member tasks
Rather than waking up all nohz_full CPUs on the system, only wake up the target CPUs of member threads of the signal. Reduces interruptions to nohz_full CPUs. Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Frederic Weisbecker <frederic@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Acked-by: Peter Zijlstra <peterz@infradead.org> Link: https://lore.kernel.org/r/20210512232924.150322-8-frederic@kernel.org
1 parent 29721b8 commit 1e4ca26

3 files changed

Lines changed: 19 additions & 8 deletions

File tree

include/linux/tick.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ extern void tick_nohz_dep_set_task(struct task_struct *tsk,
211211
enum tick_dep_bits bit);
212212
extern void tick_nohz_dep_clear_task(struct task_struct *tsk,
213213
enum tick_dep_bits bit);
214-
extern void tick_nohz_dep_set_signal(struct signal_struct *signal,
214+
extern void tick_nohz_dep_set_signal(struct task_struct *tsk,
215215
enum tick_dep_bits bit);
216216
extern void tick_nohz_dep_clear_signal(struct signal_struct *signal,
217217
enum tick_dep_bits bit);
@@ -256,11 +256,11 @@ static inline void tick_dep_clear_task(struct task_struct *tsk,
256256
if (tick_nohz_full_enabled())
257257
tick_nohz_dep_clear_task(tsk, bit);
258258
}
259-
static inline void tick_dep_set_signal(struct signal_struct *signal,
259+
static inline void tick_dep_set_signal(struct task_struct *tsk,
260260
enum tick_dep_bits bit)
261261
{
262262
if (tick_nohz_full_enabled())
263-
tick_nohz_dep_set_signal(signal, bit);
263+
tick_nohz_dep_set_signal(tsk, bit);
264264
}
265265
static inline void tick_dep_clear_signal(struct signal_struct *signal,
266266
enum tick_dep_bits bit)
@@ -288,7 +288,7 @@ static inline void tick_dep_set_task(struct task_struct *tsk,
288288
enum tick_dep_bits bit) { }
289289
static inline void tick_dep_clear_task(struct task_struct *tsk,
290290
enum tick_dep_bits bit) { }
291-
static inline void tick_dep_set_signal(struct signal_struct *signal,
291+
static inline void tick_dep_set_signal(struct task_struct *tsk,
292292
enum tick_dep_bits bit) { }
293293
static inline void tick_dep_clear_signal(struct signal_struct *signal,
294294
enum tick_dep_bits bit) { }

kernel/time/posix-cpu-timers.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,7 @@ static void arm_timer(struct k_itimer *timer, struct task_struct *p)
523523
if (CPUCLOCK_PERTHREAD(timer->it_clock))
524524
tick_dep_set_task(p, TICK_DEP_BIT_POSIX_TIMER);
525525
else
526-
tick_dep_set_signal(p->signal, TICK_DEP_BIT_POSIX_TIMER);
526+
tick_dep_set_signal(p, TICK_DEP_BIT_POSIX_TIMER);
527527
}
528528

529529
/*
@@ -1358,7 +1358,7 @@ void set_process_cpu_timer(struct task_struct *tsk, unsigned int clkid,
13581358
if (*newval < *nextevt)
13591359
*nextevt = *newval;
13601360

1361-
tick_dep_set_signal(tsk->signal, TICK_DEP_BIT_POSIX_TIMER);
1361+
tick_dep_set_signal(tsk, TICK_DEP_BIT_POSIX_TIMER);
13621362
}
13631363

13641364
static int do_cpu_nanosleep(const clockid_t which_clock, int flags,

kernel/time/tick-sched.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -444,9 +444,20 @@ EXPORT_SYMBOL_GPL(tick_nohz_dep_clear_task);
444444
* Set a per-taskgroup tick dependency. Posix CPU timers need this in order to elapse
445445
* per process timers.
446446
*/
447-
void tick_nohz_dep_set_signal(struct signal_struct *sig, enum tick_dep_bits bit)
447+
void tick_nohz_dep_set_signal(struct task_struct *tsk,
448+
enum tick_dep_bits bit)
448449
{
449-
tick_nohz_dep_set_all(&sig->tick_dep_mask, bit);
450+
int prev;
451+
struct signal_struct *sig = tsk->signal;
452+
453+
prev = atomic_fetch_or(BIT(bit), &sig->tick_dep_mask);
454+
if (!prev) {
455+
struct task_struct *t;
456+
457+
lockdep_assert_held(&tsk->sighand->siglock);
458+
__for_each_thread(sig, t)
459+
tick_nohz_kick_task(t);
460+
}
450461
}
451462

452463
void tick_nohz_dep_clear_signal(struct signal_struct *sig, enum tick_dep_bits bit)

0 commit comments

Comments
 (0)