All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sabrina Dubroca <sd@queasysnail.net>
To: David Miller <davem@davemloft.net>
Cc: netdev@vger.kernel.org, peterz@infradead.org, tglx@linutronix.de
Subject: Re: [RFC PATCH net-next 00/11] net: remove disable_irq() from ->ndo_poll_controller
Date: Thu, 11 Dec 2014 22:45:37 +0100	[thread overview]
Message-ID: <20141211214537.GA4159@kria> (raw)
In-Reply-To: <20141209.214433.7463087833083181.davem@davemloft.net>

2014-12-09, 21:44:33 -0500, David Miller wrote:
> 
> Adding a new spinlock to every interrupt service routine is
> simply a non-starter.
> 
> You will certainly have to find a way to fix this in a way
> that doesn't involve adding any new overhead to the normal
> operational paths of these drivers.
> 
> Thanks.

Okay. Here is another idea.

Since the issue is with the wait_event() part of synchronize_irq(),
and it only takes care of threaded handlers, maybe we could try not
waiting for threaded handlers.

Introduce disable_irq_nosleep() that returns true if it successfully
synchronized against all handlers (there was no threaded handler
running), false if it left some threads running.  And in
->ndo_poll_controller, only call the interrupt handler if
synchronization was successful.

Both users of the poll controllers retry their action (alloc/xmit an
skb) several times, with calls to the device's poll controller between
attempts.  And hopefully, if the first attempt fails, we will still
manage to get through?



diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c
index 83140cbb5f01..d967937aca3c 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_main.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_main.c
@@ -5216,8 +5216,8 @@ static void e1000_netpoll(struct net_device *netdev)
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 
-	disable_irq(adapter->pdev->irq);
-	e1000_intr(adapter->pdev->irq, netdev);
+	if (disable_irq_nosleep(adapter->pdev->irq))
+		e1000_intr(adapter->pdev->irq, netdev);
 	enable_irq(adapter->pdev->irq);
 }
 #endif
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 69517a24bc50..f2e4125ac963 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -184,6 +184,7 @@ extern void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id);
 #endif
 
 extern void disable_irq_nosync(unsigned int irq);
+extern bool disable_irq_nosleep(unsigned int irq);
 extern void disable_irq(unsigned int irq);
 extern void disable_percpu_irq(unsigned int irq);
 extern void enable_irq(unsigned int irq);
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 0a9104b4608b..58199b023845 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -106,6 +106,23 @@ void synchronize_irq(unsigned int irq)
 }
 EXPORT_SYMBOL(synchronize_irq);
 
+static bool synchronize_irq_nosleep(unsigned int irq)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+
+	if (desc) {
+		__synchronize_hardirq(desc);
+		/*
+		 * We made sure that no hardirq handler is
+		 * running. Now check if some threaded handlers are
+		 * active.
+		 */
+		return !atomic_read(&desc->threads_active);
+	}
+
+	return true;
+}
+
 #ifdef CONFIG_SMP
 cpumask_var_t irq_default_affinity;
 
@@ -418,6 +435,31 @@ void disable_irq_nosync(unsigned int irq)
 EXPORT_SYMBOL(disable_irq_nosync);
 
 /**
+ *	disable_irq_nosleep - disable an irq and wait for completion of hard IRQ handlers
+ *	@irq: Interrupt to disable
+ *
+ *	Disable the selected interrupt line.  Enables and Disables are
+ *	nested.
+ *	This function waits for any pending hard IRQ handlers for this
+ *	interrupt to complete before returning. If you use this
+ *	function while holding a resource the IRQ handler may need you
+ *	will deadlock.
+ *	This function does not wait for threaded IRQ handlers.
+ *
+ *      Returns true if synchronized, false if there are threaded
+ *      handlers pending.
+ *
+ *	This function may be called - with care - from IRQ context.
+ */
+bool disable_irq_nosleep(unsigned int irq)
+{
+	if (!__disable_irq_nosync(irq))
+		return synchronize_irq_nosleep(irq);
+	return true;
+}
+EXPORT_SYMBOL(disable_irq_nosleep);
+
+/**
  *	disable_irq - disable an irq and wait for completion
  *	@irq: Interrupt to disable
  *


-- 
Sabrina

  reply	other threads:[~2014-12-11 21:45 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-12-09 14:37 [RFC PATCH net-next 00/11] net: remove disable_irq() from ->ndo_poll_controller Sabrina Dubroca
2014-12-09 14:37 ` [RFC PATCH net-next 01/11] netpoll: introduce netpoll_irq_lock to protect netpoll controller against interrupts Sabrina Dubroca
2014-12-09 14:37 ` [RFC PATCH net-next 02/11] e1000: remove disable_irq from netpoll controller, use netpoll_irq_lock Sabrina Dubroca
2014-12-09 14:37 ` [RFC PATCH net-next 03/11] 8139cp/too: remove disable_irq from netpoll controller Sabrina Dubroca
2014-12-09 14:37 ` [RFC PATCH net-next 04/11] atl1c: remove disable_irq from netpoll controller, use netpoll_irq_lock Sabrina Dubroca
     [not found]   ` <CAMXMK6t5NfPQFBxK1Qny45LCS6rwX4Ys1n4C7fsTPHXu=x_vuQ@mail.gmail.com>
2014-12-09 17:23     ` Sabrina Dubroca
2014-12-09 21:17       ` Chris Snook
2014-12-09 14:37 ` [RFC PATCH net-next 05/11] bnx2: " Sabrina Dubroca
2014-12-09 14:37 ` [RFC PATCH net-next 06/11] s2io: " Sabrina Dubroca
2014-12-09 14:37 ` [RFC PATCH net-next 07/11] pasemi: " Sabrina Dubroca
2014-12-09 14:37 ` [RFC PATCH net-next 08/11] ll_temac: " Sabrina Dubroca
2014-12-09 14:37 ` [RFC PATCH net-next 09/11] xilinx/axienet: " Sabrina Dubroca
2014-12-09 14:37 ` [RFC PATCH net-next 10/11] gianfar: " Sabrina Dubroca
2014-12-09 14:37 ` [RFC PATCH net-next 11/11] net: fec: " Sabrina Dubroca
2014-12-10  2:44 ` [RFC PATCH net-next 00/11] net: remove disable_irq() from ->ndo_poll_controller David Miller
2014-12-11 21:45   ` Sabrina Dubroca [this message]
2014-12-12  2:14     ` David Miller
2014-12-12 22:01     ` Thomas Gleixner
2015-01-05 14:31       ` Sabrina Dubroca
2015-02-05  0:20         ` Sabrina Dubroca
2015-02-05 13:06           ` Peter Zijlstra
2015-02-05 15:33             ` Sabrina Dubroca
2015-02-18 17:08             ` [tip:irq/core] genirq: Provide disable_hardirq() tip-bot for Peter Zijlstra

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=20141211214537.GA4159@kria \
    --to=sd@queasysnail.net \
    --cc=davem@davemloft.net \
    --cc=netdev@vger.kernel.org \
    --cc=peterz@infradead.org \
    --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.