Commit 9269d27e authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'timers-nohz-2021-06-28' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull timers/nohz updates from Ingo Molnar:

 - Micro-optimize tick_nohz_full_cpu()

 - Optimize idle exit tick restarts to be less eager

 - Optimize tick_nohz_dep_set_task() to only wake up a single CPU.
   This reduces IPIs and interruptions on nohz_full CPUs.

 - Optimize tick_nohz_dep_set_signal() in a similar fashion.

 - Skip IPIs in tick_nohz_kick_task() when trying to kick a
   non-running task.

 - Micro-optimize tick_nohz_task_switch() IRQ flags handling to
   reduce context switching costs.

 - Misc cleanups and fixes

* tag 'timers-nohz-2021-06-28' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  MAINTAINERS: Add myself as context tracking maintainer
  tick/nohz: Call tick_nohz_task_switch() with interrupts disabled
  tick/nohz: Kick only _queued_ task whose tick dependency is updated
  tick/nohz: Change signal tick dependency to wake up CPUs of member tasks
  tick/nohz: Only wake up a single target cpu when kicking a task
  tick/nohz: Update nohz_full Kconfig help
  tick/nohz: Update idle_exittime on actual idle exit
  tick/nohz: Remove superflous check for CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
  tick/nohz: Conditionally restart tick on idle exit
  tick/nohz: Evaluate the CPU expression after the static key
parents 54a728dc 09fe880e
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -4610,6 +4610,12 @@ S: Supported
F:	drivers/video/console/
F:	include/linux/console*
CONTEXT TRACKING
M:	Frederic Weisbecker <frederic@kernel.org>
S:	Maintained
F:	kernel/context_tracking.c
F:	include/linux/context_tracking*
CONTROL GROUP (CGROUP)
M:	Tejun Heo <tj@kernel.org>
M:	Zefan Li <lizefan.x@bytedance.com>
+2 −0
Original line number Diff line number Diff line
@@ -2028,6 +2028,8 @@ static inline void set_task_cpu(struct task_struct *p, unsigned int cpu)

#endif /* CONFIG_SMP */

extern bool sched_task_on_rq(struct task_struct *p);

/*
 * In order to reduce various lock holder preemption latencies provide an
 * interface to see if a vCPU is currently running or not.
+15 −11
Original line number Diff line number Diff line
@@ -186,13 +186,17 @@ static inline bool tick_nohz_full_enabled(void)
	return tick_nohz_full_running;
}

static inline bool tick_nohz_full_cpu(int cpu)
{
	if (!tick_nohz_full_enabled())
		return false;

	return cpumask_test_cpu(cpu, tick_nohz_full_mask);
}
/*
 * Check if a CPU is part of the nohz_full subset. Arrange for evaluating
 * the cpu expression (typically smp_processor_id()) _after_ the static
 * key.
 */
#define tick_nohz_full_cpu(_cpu) ({					\
	bool __ret = false;						\
	if (tick_nohz_full_enabled())					\
		__ret = cpumask_test_cpu((_cpu), tick_nohz_full_mask);	\
	__ret;								\
})

static inline void tick_nohz_full_add_cpus_to(struct cpumask *mask)
{
@@ -208,7 +212,7 @@ extern void tick_nohz_dep_set_task(struct task_struct *tsk,
				   enum tick_dep_bits bit);
extern void tick_nohz_dep_clear_task(struct task_struct *tsk,
				     enum tick_dep_bits bit);
extern void tick_nohz_dep_set_signal(struct signal_struct *signal,
extern void tick_nohz_dep_set_signal(struct task_struct *tsk,
				     enum tick_dep_bits bit);
extern void tick_nohz_dep_clear_signal(struct signal_struct *signal,
				       enum tick_dep_bits bit);
@@ -253,11 +257,11 @@ static inline void tick_dep_clear_task(struct task_struct *tsk,
	if (tick_nohz_full_enabled())
		tick_nohz_dep_clear_task(tsk, bit);
}
static inline void tick_dep_set_signal(struct signal_struct *signal,
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(signal, bit);
		tick_nohz_dep_set_signal(tsk, bit);
}
static inline void tick_dep_clear_signal(struct signal_struct *signal,
					 enum tick_dep_bits bit)
@@ -285,7 +289,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_set_signal(struct signal_struct *signal,
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) { }
+6 −1
Original line number Diff line number Diff line
@@ -1928,6 +1928,11 @@ static inline void uclamp_post_fork(struct task_struct *p) { }
static inline void init_uclamp(void) { }
#endif /* CONFIG_UCLAMP_TASK */

bool sched_task_on_rq(struct task_struct *p)
{
	return task_on_rq_queued(p);
}

static inline void enqueue_task(struct rq *rq, struct task_struct *p, int flags)
{
	if (!(flags & ENQUEUE_NOCLOCK))
@@ -4546,6 +4551,7 @@ static struct rq *finish_task_switch(struct task_struct *prev)
	vtime_task_switch(prev);
	perf_event_task_sched_in(prev, current);
	finish_task(prev);
	tick_nohz_task_switch();
	finish_lock_switch(rq);
	finish_arch_post_lock_switch();
	kcov_finish_switch(current);
@@ -4591,7 +4597,6 @@ static struct rq *finish_task_switch(struct task_struct *prev)
		put_task_struct_rcu_user(prev);
	}

	tick_nohz_task_switch();
	return rq;
}

+6 −5
Original line number Diff line number Diff line
@@ -117,13 +117,14 @@ config NO_HZ_FULL
	 the task mostly runs in userspace and has few kernel activity.

	 You need to fill up the nohz_full boot parameter with the
	 desired range of dynticks CPUs.
	 desired range of dynticks CPUs to use it. This is implemented at
	 the expense of some overhead in user <-> kernel transitions:
	 syscalls, exceptions and interrupts.

	 This is implemented at the expense of some overhead in user <-> kernel
	 transitions: syscalls, exceptions and interrupts. Even when it's
	 dynamically off.
	 By default, without passing the nohz_full parameter, this behaves just
	 like NO_HZ_IDLE.

	 Say N.
	 If you're a distro say Y.

endchoice

Loading