Hi,

first post. Please yell if something is awkward.

Acked-by: Andreas Mohr <a...@lisas.de>

--- /dev/null   2009-05-14 19:20:59.000000000 +0200
+++ 
target/linux/generic-2.6/patches-2.6.30/695-b44_netconsole_poll_bogus-irq-enable_fix.patch
  2009-11-24 22:27:52.000000000 +0100
@@ -0,0 +1,67 @@
+From patchwork Thu Sep 17 02:10:47 2009
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: d44: the poll handler b44_poll must not enable IRQ unconditionally
+Date: Wed, 16 Sep 2009 16:10:47 -0000
+From: Dongdong Deng <dongdong.d...@windriver.com>
+X-Patchwork-Id: 33753
+Message-Id: <1253153447.24160.12.ca...@dengdd-desktop>
+To: da...@davemloft.net, m...@selenic.com, rom...@fr.zoreil.com
+Cc: net...@vger.kernel.org
+
+net/core/netpoll.c::netpoll_send_skb() calls the poll handler when
+it is available. As netconsole can be used from almost any context,
+IRQ must not be enabled blindly in the NAPI handler of the driver
+which supports netpoll.
+
+Call trace:
+netpoll_send_skb()
+{
+local_irq_save(flags)
+  -> netpoll_poll()
+    -> poll_napi()
+      -> poll_one_napi()
+        -> napi->poll()
+            -> b44_poll()
+local_irq_restore(flags)
+}
+
+Signed-off-by: Dongdong Deng <dongdong.d...@windriver.com>
+Acked-by: Matt Mackall <m...@selenic.com>
+
+---
+drivers/net/b44.c |    7 +++----
+ 1 files changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/b44.c b/drivers/net/b44.c
+index 0189dcd..e046943 100644
+--- a/drivers/net/b44.c
++++ b/drivers/net/b44.c
+@@ -847,23 +847,22 @@ static int b44_poll(struct napi_struct *napi, int budget)
+ {
+       struct b44 *bp = container_of(napi, struct b44, napi);
+       int work_done;
++      unsigned long flags;
+ 
+-      spin_lock_irq(&bp->lock);
++      spin_lock_irqsave(&bp->lock, flags);
+ 
+       if (bp->istat & (ISTAT_TX | ISTAT_TO)) {
+               /* spin_lock(&bp->tx_lock); */
+               b44_tx(bp);
+               /* spin_unlock(&bp->tx_lock); */
+       }
+-      spin_unlock_irq(&bp->lock);
++      spin_unlock_irqrestore(&bp->lock, flags);
+ 
+       work_done = 0;
+       if (bp->istat & ISTAT_RX)
+               work_done += b44_rx(bp, budget);
+ 
+       if (bp->istat & ISTAT_ERRORS) {
+-              unsigned long flags;
+-
+               spin_lock_irqsave(&bp->lock, flags);
+               b44_halt(bp);
+               b44_init_rings(bp);
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to