linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Frederic Weisbecker <frederic@kernel.org>
To: Thomas Gleixner <tglx@linutronix.de>, Ingo Molnar <mingo@kernel.org>
Cc: LKML <linux-kernel@vger.kernel.org>,
	Marcelo Tosatti <mtosatti@redhat.com>,
	"Rafael J . Wysocki" <rafael.j.wysocki@intel.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Yunfeng Ye <yeyunfeng@huawei.com>,
	Frederic Weisbecker <frederic@kernel.org>
Subject: [PATCH 08/10] tick/nohz: Kick only _queued_ task whose tick dependency is updated
Date: Thu, 13 May 2021 01:29:22 +0200	[thread overview]
Message-ID: <20210512232924.150322-9-frederic@kernel.org> (raw)
In-Reply-To: <20210512232924.150322-1-frederic@kernel.org>

From: Marcelo Tosatti <mtosatti@redhat.com>

When the tick dependency of a task is updated, we want it to aknowledge
the new state and restart the tick if needed. If the task is not
running, we don't need to kick it because it will observe the new
dependency upon scheduling in. But if the task is running, we may need
to send an IPI to it so that it gets notified.

Unfortunately we don't have the means to check if a task is running
in a race free way. Checking p->on_cpu in a synchronized way against
p->tick_dep_mask would imply adding a full barrier between
prepare_task_switch() and tick_nohz_task_switch(), which we want to
avoid in this fast-path.

Therefore we blindly fire an IPI to the task's CPU.

Meanwhile we can check if the task is queued on the CPU rq because
p->on_rq is always set to TASK_ON_RQ_QUEUED _before_ schedule() and its
full barrier that precedes tick_nohz_task_switch(). And if the task is
queued on a nohz_full CPU, it also has fair chances to be running as the
isolation constraints prescribe running single tasks on full dynticks
CPUs.

So use this as a trick to check if we can spare an IPI toward a
non-running task.

NOTE: For the ordering to be correct, it is assumed that we never
deactivate a task while it is running, the only exception being the task
deactivating itself while scheduling out.

Suggested-by: Peter Zijlstra <peterz@infradead.org>
Acked-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Yunfeng Ye <yeyunfeng@huawei.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 include/linux/sched.h    |  2 ++
 kernel/sched/core.c      |  5 +++++
 kernel/time/tick-sched.c | 19 +++++++++++++++++--
 3 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index d2c881384517..3341ae2e8231 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -2011,6 +2011,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.
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 5226cc26a095..78e480f7881a 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -1590,6 +1590,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))
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 800719ea4045..d370a04deaa8 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -324,14 +324,28 @@ void tick_nohz_full_kick_cpu(int cpu)
 
 static void tick_nohz_kick_task(struct task_struct *tsk)
 {
-	int cpu = task_cpu(tsk);
+	int cpu;
+
+	/*
+	 * If the task is not running, run_posix_cpu_timers
+	 * has nothing to elapse, IPI can then be spared.
+	 *
+	 * activate_task()                      STORE p->tick_dep_mask
+	 *   STORE p->on_rq
+	 * __schedule() (switch to task 'p')    smp_mb() (atomic_fetch_or())
+	 *   LOCK rq->lock                      LOAD p->on_rq
+	 *   smp_mb__after_spin_lock()
+	 *   tick_nohz_task_switch()
+	 *     LOAD p->tick_dep_mask
+	 */
+	if (!sched_task_on_rq(tsk))
+		return;
 
 	/*
 	 * If the task concurrently migrates to another cpu,
 	 * we guarantee it sees the new tick dependency upon
 	 * schedule.
 	 *
-	 *
 	 * set_task_cpu(p, cpu);
 	 *   STORE p->cpu = @cpu
 	 * __schedule() (switch to task 'p')
@@ -340,6 +354,7 @@ static void tick_nohz_kick_task(struct task_struct *tsk)
 	 *   tick_nohz_task_switch()            smp_mb() (atomic_fetch_or())
 	 *      LOAD p->tick_dep_mask           LOAD p->cpu
 	 */
+	cpu = task_cpu(tsk);
 
 	preempt_disable();
 	if (cpu_online(cpu))
-- 
2.25.1


  parent reply	other threads:[~2021-05-12 23:43 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-12 23:29 [GIT PULL] tick/nohz updates v3 Frederic Weisbecker
2021-05-12 23:29 ` [PATCH 01/10] tick/nohz: Evaluate the CPU expression after the static key Frederic Weisbecker
2021-05-13 13:17   ` [tip: timers/nohz] " tip-bot2 for Peter Zijlstra
2021-05-12 23:29 ` [PATCH 02/10] tick/nohz: Conditionally restart tick on idle exit Frederic Weisbecker
2021-05-13 13:17   ` [tip: timers/nohz] " tip-bot2 for Yunfeng Ye
2021-05-12 23:29 ` [PATCH 03/10] tick/nohz: Remove superflous check for CONFIG_VIRT_CPU_ACCOUNTING_NATIVE Frederic Weisbecker
2021-05-13 13:17   ` [tip: timers/nohz] " tip-bot2 for Frederic Weisbecker
2021-05-12 23:29 ` [PATCH 04/10] tick/nohz: Update idle_exittime on actual idle exit Frederic Weisbecker
2021-05-13 13:17   ` [tip: timers/nohz] " tip-bot2 for Yunfeng Ye
2021-05-12 23:29 ` [PATCH 05/10] tick/nohz: Update nohz_full Kconfig help Frederic Weisbecker
2021-05-13 13:17   ` [tip: timers/nohz] " tip-bot2 for Frederic Weisbecker
2021-05-12 23:29 ` [PATCH 06/10] tick/nohz: Only wakeup a single target cpu when kicking a task Frederic Weisbecker
2021-05-13 13:17   ` [tip: timers/nohz] tick/nohz: Only wake up " tip-bot2 for Frederic Weisbecker
2021-05-12 23:29 ` [PATCH 07/10] tick/nohz: Change signal tick dependency to wakeup CPUs of member tasks Frederic Weisbecker
2021-05-13 13:17   ` [tip: timers/nohz] tick/nohz: Change signal tick dependency to wake up " tip-bot2 for Marcelo Tosatti
2021-05-12 23:29 ` Frederic Weisbecker [this message]
2021-05-13 13:17   ` [tip: timers/nohz] tick/nohz: Kick only _queued_ task whose tick dependency is updated tip-bot2 for Marcelo Tosatti
2021-05-12 23:29 ` [PATCH 09/10] tick/nohz: Call tick_nohz_task_switch() with interrupts disabled Frederic Weisbecker
2021-05-13 13:17   ` [tip: timers/nohz] " tip-bot2 for Peter Zijlstra
2021-05-12 23:29 ` [PATCH 10/10] MAINTAINERS: Add myself as context tracking maintainer Frederic Weisbecker
2021-05-19  9:21   ` [tip: timers/nohz] " tip-bot2 for Frederic Weisbecker
2021-05-13 12:23 ` [GIT PULL] tick/nohz updates v3 Ingo Molnar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210512232924.150322-9-frederic@kernel.org \
    --to=frederic@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=mtosatti@redhat.com \
    --cc=peterz@infradead.org \
    --cc=rafael.j.wysocki@intel.com \
    --cc=tglx@linutronix.de \
    --cc=yeyunfeng@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).