linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Frederic Weisbecker <fweisbec@gmail.com>
To: LKML <linux-kernel@vger.kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	Eric Dumazet <eric.dumazet@gmail.com>,
	Ingo Molnar <mingo@kernel.org>, Kevin Hilman <khilman@linaro.org>,
	"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Viresh Kumar <viresh.kumar@linaro.org>
Subject: [PATCH 2/6] irq_work: Implement remote queueing
Date: Tue, 10 Jun 2014 17:15:05 +0200	[thread overview]
Message-ID: <1402413309-3415-3-git-send-email-fweisbec@gmail.com> (raw)
In-Reply-To: <1402413309-3415-1-git-send-email-fweisbec@gmail.com>

irq work currently only supports local callbacks. However its code
is mostly ready to run remote callbacks and we have some potential user.

The full nohz subsystem currently open codes its own remote irq work
on top of the scheduler ipi when it wants a CPU to reevaluate its next
tick. However this ad hoc solution bloats the scheduler IPI.

Lets just extend the irq work subsystem to support remote queuing on top
of the generic SMP IPI to handle this kind of user. This shouldn't add
noticeable overhead.

Suggested-by: Peter Zijlstra <peterz@infradead.org>
Acked-by: Peter Zijlstra <peterz@infradead.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Kevin Hilman <khilman@linaro.org>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
---
 include/linux/irq_work.h |  5 +++++
 kernel/irq_work.c        | 25 ++++++++++++++++++++++++-
 kernel/smp.c             |  9 +++++++++
 3 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/include/linux/irq_work.h b/include/linux/irq_work.h
index 19ae05d..bf9422c 100644
--- a/include/linux/irq_work.h
+++ b/include/linux/irq_work.h
@@ -33,6 +33,11 @@ void init_irq_work(struct irq_work *work, void (*func)(struct irq_work *))
 #define DEFINE_IRQ_WORK(name, _f) struct irq_work name = { .func = (_f), }
 
 bool irq_work_queue(struct irq_work *work);
+
+#ifdef CONFIG_SMP
+bool irq_work_queue_on(struct irq_work *work, int cpu);
+#endif
+
 void irq_work_run(void);
 void irq_work_sync(struct irq_work *work);
 
diff --git a/kernel/irq_work.c b/kernel/irq_work.c
index 126f254..4b0a890 100644
--- a/kernel/irq_work.c
+++ b/kernel/irq_work.c
@@ -16,6 +16,7 @@
 #include <linux/tick.h>
 #include <linux/cpu.h>
 #include <linux/notifier.h>
+#include <linux/smp.h>
 #include <asm/processor.h>
 
 
@@ -55,12 +56,34 @@ void __weak arch_irq_work_raise(void)
 	 */
 }
 
+#ifdef CONFIG_SMP
 /*
- * Enqueue the irq_work @entry unless it's already pending
+ * Enqueue the irq_work @work on @cpu unless it's already pending
  * somewhere.
  *
  * Can be re-enqueued while the callback is still in progress.
  */
+bool irq_work_queue_on(struct irq_work *work, int cpu)
+{
+	/* All work should have been flushed before going offline */
+	WARN_ON_ONCE(cpu_is_offline(cpu));
+
+	/* Arch remote IPI send/receive backend aren't NMI safe */
+	WARN_ON_ONCE(in_nmi());
+
+	/* Only queue if not already pending */
+	if (!irq_work_claim(work))
+		return false;
+
+	if (llist_add(&work->llnode, &per_cpu(raised_list, cpu)))
+		arch_send_call_function_single_ipi(cpu);
+
+	return true;
+}
+EXPORT_SYMBOL_GPL(irq_work_queue_on);
+#endif
+
+/* Enqueue the irq work @work on the current CPU */
 bool irq_work_queue(struct irq_work *work)
 {
 	/* Only queue if not already pending */
diff --git a/kernel/smp.c b/kernel/smp.c
index 06d574e..6e9ff62 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -3,6 +3,7 @@
  *
  * (C) Jens Axboe <jens.axboe@oracle.com> 2008
  */
+#include <linux/irq_work.h>
 #include <linux/rcupdate.h>
 #include <linux/rculist.h>
 #include <linux/kernel.h>
@@ -198,6 +199,14 @@ void generic_smp_call_function_single_interrupt(void)
 		csd->func(csd->info);
 		csd_unlock(csd);
 	}
+
+	/*
+	 * Handle irq works queued remotely by irq_work_queue_on().
+	 * Smp functions above are typically synchronous so they
+	 * better run first since some other CPUs may be busy waiting
+	 * for them.
+	 */
+	irq_work_run();
 }
 
 /*
-- 
1.8.3.1


  parent reply	other threads:[~2014-06-10 15:16 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-06-10 15:15 [PATCH 0/6] nohz: Move nohz kick out of scheduler IPI, v8 Frederic Weisbecker
2014-06-10 15:15 ` [PATCH 1/6] irq_work: Split raised and lazy lists Frederic Weisbecker
2014-06-10 15:15 ` Frederic Weisbecker [this message]
2014-06-24 20:33   ` [PATCH 2/6] irq_work: Implement remote queueing Stephen Warren
2014-06-24 20:35     ` Stephen Warren
2014-06-25  5:12     ` Peter Zijlstra
2014-06-25  5:17       ` Peter Zijlstra
2014-06-25  6:37         ` Srivatsa S. Bhat
2014-06-25  9:36           ` Peter Zijlstra
2014-06-25  9:39             ` Peter Zijlstra
2014-06-25  9:50               ` Srivatsa S. Bhat
2014-06-25  9:54                 ` Srivatsa S. Bhat
2014-06-25 10:19                   ` Peter Zijlstra
2014-06-25 10:57                     ` Srivatsa S. Bhat
2014-06-25 16:23                     ` Stephen Warren
2014-06-25 16:38                       ` Peter Zijlstra
2014-06-25 16:57                         ` Srivatsa S. Bhat
2014-06-28 18:19                           ` Borislav Petkov
2014-07-03 14:52                         ` Frederic Weisbecker
2014-07-04  5:10                         ` Sachin Kamat
2014-07-01 19:13                       ` Stephen Warren
2014-06-10 15:15 ` [PATCH 3/6] nohz: Support nohz full remote kick Frederic Weisbecker
2014-06-10 15:15 ` [PATCH 4/6] nohz: Switch to nohz full remote kick on timer enqueue Frederic Weisbecker
2014-06-10 15:15 ` [PATCH 5/6] nohz: Use nohz own full kick on 2nd task enqueue Frederic Weisbecker
2014-06-10 15:15 ` [PATCH 6/6] nohz: Use IPI implicit full barrier against rq->nr_running r/w Frederic Weisbecker
2014-06-10 15:48   ` Peter Zijlstra
2014-06-10 16:24     ` Frederic Weisbecker
2014-06-10 15:48 ` [PATCH 0/6] nohz: Move nohz kick out of scheduler IPI, v8 Peter Zijlstra
2014-06-10 16:18   ` Frederic Weisbecker

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=1402413309-3415-3-git-send-email-fweisbec@gmail.com \
    --to=fweisbec@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=eric.dumazet@gmail.com \
    --cc=khilman@linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=paulmck@linux.vnet.ibm.com \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    --cc=viresh.kumar@linaro.org \
    /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).