All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jakub Kicinski <kuba@kernel.org>
To: davem@davemloft.net, tglx@linutronix.de
Cc: netdev@vger.kernel.org, eric.dumazet@gmail.com,
	simon.horman@netronome.com, oss-drivers@netronome.com,
	bigeasy@linutronix.de, Jakub Kicinski <kuba@kernel.org>
Subject: [PATCH net-next 1/2] net: add a napi variant for RT-well-behaved drivers
Date: Fri, 14 May 2021 15:24:01 -0700	[thread overview]
Message-ID: <20210514222402.295157-1-kuba@kernel.org> (raw)

Most networking drivers use napi_schedule_irqoff() to schedule
NAPI from hardware IRQ handler. Unfortunately, as explained in
commit 8380c81d5c4f ("net: Treat __napi_schedule_irqoff() as
__napi_schedule() on PREEMPT_RT") the current implementation
is problematic for RT.

The best solution seems to be to mark the irq handler with
IRQF_NO_THREAD, to avoid going through an irq thread just
to schedule NAPI and therefore wake up ksoftirqd.

Since analyzing the 40 callers of napi_schedule_irqoff()
to figure out which handlers are light-weight enough to
warrant IRQF_NO_THREAD seems like a larger effort add
a new helper for drivers which set IRQF_NO_THREAD.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 include/linux/netdevice.h | 21 ++++++++++++++++-----
 net/core/dev.c            | 13 +++++++++++--
 2 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 5cbc950b34df..457e2e3ef5a5 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -436,7 +436,8 @@ typedef enum rx_handler_result rx_handler_result_t;
 typedef rx_handler_result_t rx_handler_func_t(struct sk_buff **pskb);
 
 void __napi_schedule(struct napi_struct *n);
-void __napi_schedule_irqoff(struct napi_struct *n);
+void __napi_schedule_irqoff(struct napi_struct *n); /* deprecated */
+void __napi_schedule_irq(struct napi_struct *n);
 
 static inline bool napi_disable_pending(struct napi_struct *n)
 {
@@ -463,16 +464,26 @@ static inline void napi_schedule(struct napi_struct *n)
 		__napi_schedule(n);
 }
 
+/* Deprecated, use napi_schedule_irq(). */
+static inline void napi_schedule_irqoff(struct napi_struct *n)
+{
+	if (napi_schedule_prep(n))
+		__napi_schedule_irqoff(n);
+}
+
 /**
- *	napi_schedule_irqoff - schedule NAPI poll
- *	@n: NAPI context
+ * napi_schedule_irq() - schedule NAPI poll from hardware IRQ
+ * @n: NAPI context
  *
  * Variant of napi_schedule(), assuming hard irqs are masked.
+ * Hardware interrupt handler must be marked with IRQF_NO_THREAD
+ * to safely invoke this function on CONFIG_RT=y kernels (unless
+ * it manually masks the interrupts already).
  */
-static inline void napi_schedule_irqoff(struct napi_struct *n)
+static inline void napi_schedule_irq(struct napi_struct *n)
 {
 	if (napi_schedule_prep(n))
-		__napi_schedule_irqoff(n);
+		__napi_schedule_irq(n);
 }
 
 /* Try to reschedule poll. Called by dev->poll() after napi_complete().  */
diff --git a/net/core/dev.c b/net/core/dev.c
index febb23708184..2e20858b5df6 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6497,20 +6497,29 @@ bool napi_schedule_prep(struct napi_struct *n)
 }
 EXPORT_SYMBOL(napi_schedule_prep);
 
+void __napi_schedule_irq(struct napi_struct *n)
+{
+	____napi_schedule(this_cpu_ptr(&softnet_data), n);
+}
+EXPORT_SYMBOL(__napi_schedule_irq);
+
 /**
  * __napi_schedule_irqoff - schedule for receive
  * @n: entry to schedule
  *
- * Variant of __napi_schedule() assuming hard irqs are masked.
+ * Legacy variant of __napi_schedule() assuming hard irqs are masked.
  *
  * On PREEMPT_RT enabled kernels this maps to __napi_schedule()
  * because the interrupt disabled assumption might not be true
  * due to force-threaded interrupts and spinlock substitution.
+ *
+ * For light weight IRQ handlers prefer use of napi_schedule_irq(),
+ * and marking IRQ handler with IRQF_NO_THREAD.
  */
 void __napi_schedule_irqoff(struct napi_struct *n)
 {
 	if (!IS_ENABLED(CONFIG_PREEMPT_RT))
-		____napi_schedule(this_cpu_ptr(&softnet_data), n);
+		__napi_schedule_irq(n);
 	else
 		__napi_schedule(n);
 }
-- 
2.31.1


             reply	other threads:[~2021-05-14 22:24 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-14 22:24 Jakub Kicinski [this message]
2021-05-14 22:24 ` [PATCH net-next 2/2] nfp: use napi_schedule_irq() Jakub Kicinski
2021-05-17  9:48   ` Simon Horman
2021-05-15  0:17 ` [PATCH net-next 1/2] net: add a napi variant for RT-well-behaved drivers Thomas Gleixner
2021-05-15  0:21   ` Jakub Kicinski
2021-05-15  0:29     ` Thomas Gleixner
2021-05-15  9:49 ` Thomas Gleixner
2021-05-15 20:38   ` Jakub Kicinski
2021-05-15 11:07 ` Sebastian Andrzej Siewior
2021-05-15 20:31   ` Jakub Kicinski
2021-05-15 20:53     ` Thomas Gleixner
2021-05-21 14:11       ` Juri Lelli

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=20210514222402.295157-1-kuba@kernel.org \
    --to=kuba@kernel.org \
    --cc=bigeasy@linutronix.de \
    --cc=davem@davemloft.net \
    --cc=eric.dumazet@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=oss-drivers@netronome.com \
    --cc=simon.horman@netronome.com \
    --cc=tglx@linutronix.de \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.