Ignore:
Timestamp:
2014-02-28T00:02:37+01:00 (4 years ago)
Author:
nbd
Message:

cns3xxx: ethernet - resolve SMP issue

The combination of r35942 and r35952 causes an issue where eth_schedule_poll()
can be called from a different CPU between the call to napi_complete() and the
setting of cur_index which can break the rx ring accounting and cause ethernet
latency and/or ethernet stalls. The issue can be easilly created by adding
a couple of artificial delays such as:

@@ -715,6 +715,7 @@ static int eth_poll(struct napi_struct *napi, int budget)

if (!received) {

napi_complete(napi);

+udelay(1000);

enable_irq(IRQ_CNS3XXX_SW_R0RXC);

}

@@ -727,6 +728,7 @@ static int eth_poll(struct napi_struct *napi, int budget)

rx_ring->cur_index = i;

wmb();

+udelay(1000);

enable_rx_dma(sw);

return received;

This patch moves the setting of cur_index back up where it needs to be and
addresses the original corner case that r35942 was trying to catch in an
improved fashion by checking to see if the rx descriptor ring has become
full before interrupts were re-enabled so that a poll can be scheduled again
and avoid an rx stall caused by rx interrupts ceasing to fire again.

Signed-off-by: Tim Harvey <tharvey@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/target/linux/cns3xxx/files/drivers/net/ethernet/cavium/cns3xxx_eth.c

    r35953 r39761  
    714714        } 
    715715 
     716        rx_ring->cur_index = i; 
    716717        if (!received) { 
    717718                napi_complete(napi); 
    718719                enable_irq(IRQ_CNS3XXX_SW_R0RXC); 
     720 
     721                /* if rx descriptors are full schedule another poll */ 
     722                if (rx_ring->desc[(i-1) & (RX_DESCS-1)].cown) 
     723                        eth_schedule_poll(sw); 
    719724        } 
    720725 
     
    724729 
    725730        cns3xxx_alloc_rx_buf(sw, received); 
    726  
    727         rx_ring->cur_index = i; 
    728731 
    729732        wmb(); 
Note: See TracChangeset for help on using the changeset viewer.