--- ./drivers/net/sis900.c.sis900 2004-08-08 03:26:05.000000000 +0400 +++ ./drivers/net/sis900.c 2005-09-16 17:17:27.000000000 +0400 @@ -1613,6 +1613,14 @@ static int sis900_rx(struct net_device * long ioaddr = net_dev->base_addr; unsigned int entry = sis_priv->cur_rx % NUM_RX_DESC; u32 rx_status = sis_priv->rx_ring[entry].cmdsts; + /* + * If cur > dirty, then limit = NUM_RX_DESC - cur + dirty = + * NUM_RX_DESC + (dirty - cur) + * If cur < dirty (cur overflowed, dirty - not), then + * limit = dirty - cur + */ + int rx_work_limit = + (sis_priv->dirty_rx - sis_priv->cur_rx) % NUM_RX_DESC; if (sis900_debug > 3) printk(KERN_INFO "sis900_rx, cur_rx:%4.4d, dirty_rx:%4.4d " @@ -1622,6 +1630,8 @@ static int sis900_rx(struct net_device * while (rx_status & OWN) { unsigned int rx_size; + if (--rx_work_limit < 0) + break; rx_size = (rx_status & DSIZE) - CRC_SIZE; if (rx_status & (ABORT|OVERRUN|TOOLONG|RUNT|RXISERR|CRCERR|FAERR)) { @@ -1688,6 +1698,7 @@ static int sis900_rx(struct net_device * sis_priv->rx_ring[entry].cmdsts = 0; sis_priv->rx_ring[entry].bufptr = 0; sis_priv->stats.rx_dropped++; + sis_priv->cur_rx++; break; } skb->dev = net_dev; @@ -1705,7 +1716,7 @@ static int sis900_rx(struct net_device * /* refill the Rx buffer, what if the rate of refilling is slower than consuming ?? */ - for (;sis_priv->cur_rx - sis_priv->dirty_rx > 0; sis_priv->dirty_rx++) { + for (; sis_priv->cur_rx != sis_priv->dirty_rx; sis_priv->dirty_rx++) { struct sk_buff *skb; entry = sis_priv->dirty_rx % NUM_RX_DESC; # # Patch solves following problems: # 1) Forgotten counter incrementation in sis900_rx() in case # it doesn't get memory for skb, that leads to whole interface failure. # Problem is accompanied with messages: # eth0: Memory squeeze,deferring packet. # eth0: NULL pointer encountered in Rx ring, skipping # 2) If counter cur_rx overflows and there'll be temporary memory problems # buffer can't be recreated later, when memory IS avaliable. # 3) Limit the work in handler to prevent the endless packets processing if # new packets are generated faster then handled. # # Signed-off-by: Konstantin Khorenko # Signed-off-by: Vasily Averin