Eric Lemoine wrote:
> On 8/27/05, Eric Lemoine <[EMAIL PROTECTED]> wrote:
> 
>>On 8/27/05, Eric Lemoine <[EMAIL PROTECTED]> wrote:
>>
>>>On 8/26/05, Geoff Levand <[EMAIL PROTECTED]> wrote:
>>>
>>>>This fixes a major bug in the Sun GEM Ether
>>>>driver's netpoll implementation.  When both polled
>>>>and interrupt driven i/o are used simultaneously,
>>>>for example when using kgdb over Ether with active
>>>>NFS mounts, a condition easily arises where the bug
>>>>is hit.
>>>>
>>>>The problem is that gem_poll() expects an rx softnet_data
>>>>structure to have been allocated (via __netif_rx_schedule())
>>>>prior to its being called.  The existing gem driver code
>>>>uses gem_interrupt() to set things up for gem_poll(),
>>>>but unfortunately, gem_interrupt() doesn't know about
>>>>this, and so doesn't allocate the required structure
>>>>when it finds no bits set in the interrupt status
>>>>register.  gem_poll() then move on its way and tries to
>>>>delete the non-existent softnet_data structure.
>>>
>>>I may be missing something here but I don't see how gem_poll() can
>>>move on its way if __netif_rx_schedule() hasen't been called.
> 
> Wait...
> 
>>>in netpoll.c:poll_napi()  because bit __LINK_STATE_RX_SCHED  is set,
>>>correct?
>>>
>>>To me the bug is that __LINK_STATE_RX_SCHED can be set while
>>>__netif_rx_schedule() hasen't be called. Why don't fix it in the
>>>simplest way ? See attached patch (absolutely untested).
>>
>>It doesn't even compile :-)
>>
>>[new patch attached]
> 
> 
> I just realized that my previous patch isn't correct: gem_interrupt()
> cannot read from
> GREG_STAT without making sure gem_poll() isn't currently running -
> gem_poll() must have exclusive access to GREG_STAT. One solution would
> be to clear __LINK_STATE_RX_SCHED (i.e. reenable polling) before
> returning IRQ_NONE. See attached patch.
> 

Sure, your fix works, and seems to be the best way to do it.

-Geoff

Signed-off-by: Geoff Levand <[EMAIL PROTECTED]>


Index: linux-2.6.12/drivers/net/sungem.c
===================================================================
--- linux-2.6.12.orig/drivers/net/sungem.c      2005-08-29 14:28:17.000000000 
-0700
+++ linux-2.6.12/drivers/net/sungem.c   2005-08-29 14:50:51.000000000 -0700
@@ -947,6 +947,7 @@
                u32 gem_status = readl(gp->regs + GREG_STAT);
 
                if (gem_status == 0) {
+                       netif_poll_enable(dev);
                        spin_unlock_irqrestore(&gp->lock, flags);
                        return IRQ_NONE;
                }
Index: linux-2.6.12/drivers/net/sungem.h
===================================================================
--- linux-2.6.12.orig/drivers/net/sungem.h      2005-08-29 14:28:17.000000000 
-0700
+++ linux-2.6.12/drivers/net/sungem.h   2005-08-29 15:00:10.000000000 -0700
@@ -1020,7 +1020,7 @@
                
        struct gem_init_block   *init_block;
        struct sk_buff          *rx_skbs[RX_RING_SIZE];
-       struct sk_buff          *tx_skbs[RX_RING_SIZE];
+       struct sk_buff          *tx_skbs[TX_RING_SIZE];
        dma_addr_t              gblock_dvma;
 
        struct pci_dev          *pdev;




-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to