netdev
[Top] [All Lists]

[PATCH] sis900: come alive after temporary memory shortage

To: Jeff Garzik <jgarzik@xxxxxxxxx>
Subject: [PATCH] sis900: come alive after temporary memory shortage
From: Daniele Venzano <venza@xxxxxxxxxxxx>
Date: Thu, 6 Oct 2005 12:40:05 +0200
Cc: NetDev <netdev@xxxxxxxxxxx>, Jeff Garzik <jgarzik@xxxxxxxxx>, Stanislav Protassov <st@xxxxxxxxx>, Vasily Averin <vvs@xxxxx>
In-reply-to: <4337FF9D.70200@sw.ru>
Mail-followup-to: Jeff Garzik <jgarzik@xxxxxxxxx>, NetDev <netdev@xxxxxxxxxxx>, Stanislav Protassov <st@xxxxxxxxx>, Vasily Averin <vvs@xxxxx>
References: <4337E76B.1090003@sw.ru> <8204E0D1-F30D-494F-8E97-CDCC26A82807@libero.it> <4337FF9D.70200@sw.ru>
Sender: netdev-bounce@xxxxxxxxxxx
User-agent: Mutt/1.5.9i
This patch is good and fixes some corner cases. Please consider for
inclusion.

On Mon, Sep 26, 2005 at 06:03:09PM +0400, Konstantin Khorenko wrote:
> 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 <khorenko@xxxxx>
> Signed-off-by: Vasily Averin <vvs@xxxxx>
Signed-off-by: Daniele Venzano <venza@xxxxxxxxxxxx>

--- main-2.6.13.1/drivers/net/sis900.c.sis900   2005-08-29 03:41:01.000000000 
+0400
+++ main-2.6.13.1/drivers/net/sis900.c  2005-09-19 14:34:42.000000000 +0400
@@ -1696,6 +1696,8 @@ 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;
+       int rx_work_limit =
+               (sis_priv->dirty_rx - sis_priv->cur_rx) % NUM_RX_DESC;
 
        if (netif_msg_rx_status(sis_priv))
                printk(KERN_DEBUG "sis900_rx, cur_rx:%4.4d, dirty_rx:%4.4d "
@@ -1705,6 +1713,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)) {
@@ -1770,6 +1780,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;
@@ -1787,7 +1798,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;


-- 
------------------------------
Daniele Venzano
Web: http://teg.homeunix.org

<Prev in Thread] Current Thread [Next in Thread>