* sis900: eth0: NULL pointer encountered in Rx ring, skipping @ 2005-01-18 10:13 Lennert Buytenhek 2005-01-18 10:21 ` Lennert Buytenhek 0 siblings, 1 reply; 4+ messages in thread From: Lennert Buytenhek @ 2005-01-18 10:13 UTC (permalink / raw) To: netdev Hi, I can make one of my machines, which has an on-board sis900 NIC, lose network connectivity within seconds by doing something like "nc -l -p 6666 > /dev/null" and then blasting some data towards it. When this happens, syslog fills up with these messages: eth0: NULL pointer encountered in Rx ring, skipping It seems like the driver+NIC combo doesn't handle any kind of load very well in general -- whenever it receives more than just a few tens of packets per second, the machine's ping time turns rather awful: (Two machines on 100Mb/s with an el-cheapo 8-port 100Mb/s switch between them. Other machines on the same switch don't show any of the same problems.) 64 bytes from 10.0.0.4: icmp_seq=212 ttl=64 time=128 ms 64 bytes from 10.0.0.4: icmp_seq=213 ttl=64 time=124 ms 64 bytes from 10.0.0.4: icmp_seq=214 ttl=64 time=119 ms 64 bytes from 10.0.0.4: icmp_seq=215 ttl=64 time=124 ms When it locks up, 'ifconfig eth0 down up' suffices to make it come back to life. I haven't checked whether it's just RX that stops working or whether it's both RX and TX. Any ideas? This is on the Fedora Core 3 update kernel, 2.6.10-based. cheers, Lennert ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: sis900: eth0: NULL pointer encountered in Rx ring, skipping 2005-01-18 10:13 sis900: eth0: NULL pointer encountered in Rx ring, skipping Lennert Buytenhek @ 2005-01-18 10:21 ` Lennert Buytenhek 2005-01-19 20:52 ` Eric Lemoine 0 siblings, 1 reply; 4+ messages in thread From: Lennert Buytenhek @ 2005-01-18 10:21 UTC (permalink / raw) To: netdev On Tue, Jan 18, 2005 at 11:13:58AM +0100, Lennert Buytenhek wrote: > I can make one of my machines, which has an on-board sis900 NIC, lose > network connectivity within seconds by doing something like > "nc -l -p 6666 > /dev/null" and then blasting some data towards it. When > this happens, syslog fills up with these messages: > > eth0: NULL pointer encountered in Rx ring, skipping Just before it starts spewing these it says: eth0: Memory squeeze,deferring packet. So apparently it just doesn't deal with OOM very well. --L ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: sis900: eth0: NULL pointer encountered in Rx ring, skipping 2005-01-18 10:21 ` Lennert Buytenhek @ 2005-01-19 20:52 ` Eric Lemoine 2005-01-19 21:49 ` Francois Romieu 0 siblings, 1 reply; 4+ messages in thread From: Eric Lemoine @ 2005-01-19 20:52 UTC (permalink / raw) To: Lennert Buytenhek; +Cc: netdev [-- Attachment #1: Type: text/plain, Size: 1064 bytes --] On Tue, 18 Jan 2005 11:21:39 +0100, Lennert Buytenhek <buytenh@wantstofly.org> wrote: > On Tue, Jan 18, 2005 at 11:13:58AM +0100, Lennert Buytenhek wrote: > > > I can make one of my machines, which has an on-board sis900 NIC, lose > > network connectivity within seconds by doing something like > > "nc -l -p 6666 > /dev/null" and then blasting some data towards it. When > > this happens, syslog fills up with these messages: > > > > eth0: NULL pointer encountered in Rx ring, skipping > > Just before it starts spewing these it says: > > eth0: Memory squeeze,deferring packet. > > So apparently it just doesn't deal with OOM very well. There are dev_alloc_skb()'s failing due to memory shortage. I think anyhow that the sis9000 driver doesnt handle "memory squeeze" situations right. Why not throwing current rx packet away and reuse ring entry instead of leaving holes (null skb's) in the ring. I would suggest a patch to the sis900 driver around that attached. Warning: patch compiling but untested - dont have hardware handy. -- Eric [-- Attachment #2: sis900.patch --] [-- Type: application/octet-stream, Size: 3038 bytes --] ===== drivers/net/sis900.c 1.56 vs edited ===== --- 1.56/drivers/net/sis900.c 2004-08-25 09:15:20 +02:00 +++ edited/drivers/net/sis900.c 2005-01-19 21:48:27 +01:00 @@ -1650,7 +1650,7 @@ /* reset buffer descriptor state */ sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE; } else { - struct sk_buff * skb; + struct sk_buff * skb, *new_skb; /* This situation should never happen, but due to some unknow bugs, it is possible that @@ -1662,11 +1662,30 @@ break; } + skb = sis_priv->rx_skbuff[entry]; + + if ((new_skb = dev_alloc_skb(RX_BUF_SIZE)) == NULL) { + printk(KERN_INFO "%s: memory shortage, rx packet dropped\n", + net_dev->name); + + sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE; + sis_priv->stats.rx_dropped++; + sis_priv->dirty_rx++; /* dirty no longer needed? */ + break; /* next */ + } + pci_unmap_single(sis_priv->pci_dev, sis_priv->rx_ring[entry].bufptr, RX_BUF_SIZE, PCI_DMA_FROMDEVICE); + + new_skb->dev = net_dev; + sis_priv->rx_skbuff[entry] = new_skb; + sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE; + sis_priv->rx_ring[entry].bufptr = + pci_map_single(sis_priv->pci_dev, new_skb->tail, + RX_BUF_SIZE, PCI_DMA_FROMDEVICE); + /* give the socket buffer to upper layers */ - skb = sis_priv->rx_skbuff[entry]; skb_put(skb, rx_size); skb->protocol = eth_type_trans(skb, net_dev); netif_rx(skb); @@ -1678,29 +1697,6 @@ sis_priv->stats.rx_bytes += rx_size; sis_priv->stats.rx_packets++; - /* refill the Rx buffer, what if there is not enought memory for - new socket buffer ?? */ - if ((skb = dev_alloc_skb(RX_BUF_SIZE)) == NULL) { - /* not enough memory for skbuff, this makes a "hole" - on the buffer ring, it is not clear how the - hardware will react to this kind of degenerated - buffer */ - printk(KERN_INFO "%s: Memory squeeze," - "deferring packet.\n", - net_dev->name); - sis_priv->rx_skbuff[entry] = NULL; - /* reset buffer descriptor state */ - sis_priv->rx_ring[entry].cmdsts = 0; - sis_priv->rx_ring[entry].bufptr = 0; - sis_priv->stats.rx_dropped++; - break; - } - skb->dev = net_dev; - sis_priv->rx_skbuff[entry] = skb; - sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE; - sis_priv->rx_ring[entry].bufptr = - pci_map_single(sis_priv->pci_dev, skb->tail, - RX_BUF_SIZE, PCI_DMA_FROMDEVICE); sis_priv->dirty_rx++; } sis_priv->cur_rx++; @@ -1708,6 +1704,7 @@ rx_status = sis_priv->rx_ring[entry].cmdsts; } // while +#if 0 /* no need to refill skbs are added to the rx ring as packets are received */ /* 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++) { @@ -1735,6 +1732,7 @@ RX_BUF_SIZE, PCI_DMA_FROMDEVICE); } } +#endif /* re-enable the potentially idle receive state matchine */ outl(RxENA | inl(ioaddr + cr), ioaddr + cr ); ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: sis900: eth0: NULL pointer encountered in Rx ring, skipping 2005-01-19 20:52 ` Eric Lemoine @ 2005-01-19 21:49 ` Francois Romieu 0 siblings, 0 replies; 4+ messages in thread From: Francois Romieu @ 2005-01-19 21:49 UTC (permalink / raw) To: Eric Lemoine; +Cc: Lennert Buytenhek, netdev Eric Lemoine <eric.lemoine@gmail.com> : [...] > There are dev_alloc_skb()'s failing due to memory shortage. I think > anyhow that the sis9000 driver doesnt handle "memory squeeze" > situations right. Why not throwing current rx packet away and reuse > ring entry instead of leaving holes (null skb's) in the ring. I would > suggest a patch to the sis900 driver around that attached. Imho it should not be necessary as long as the hardware is not completely b0rken. I'd rather see how the driver behaves when it is really short of memory (i.e. no entry is available for DMA in the ring). Patch below. Make the driver own a Rx descriptor entry as long as it is not refilled. Signed-off-by: Francois Romieu <romieu@fr.zoreil.com> diff -puN drivers/net/sis900.c~sis900-000 drivers/net/sis900.c --- linux-2.6.11-rc1-bk6/drivers/net/sis900.c~sis900-000 2005-01-19 22:28:38.633282552 +0100 +++ linux-2.6.11-rc1-bk6-fr/drivers/net/sis900.c 2005-01-19 22:34:16.362996145 +0100 @@ -1643,13 +1643,15 @@ 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_left; if (sis900_debug > 3) printk(KERN_INFO "sis900_rx, cur_rx:%4.4d, dirty_rx:%4.4d " "status:0x%8.8x\n", sis_priv->cur_rx, sis_priv->dirty_rx, rx_status); - while (rx_status & OWN) { + rx_left = NUM_RX_DESC + sis_priv->dirty_rx - sis_priv->cur_rx; + while ((rx_left > 0) && (rx_status & OWN)) { unsigned int rx_size; rx_size = (rx_status & DSIZE) - CRC_SIZE; @@ -1712,7 +1714,7 @@ static int sis900_rx(struct net_device * net_dev->name); sis_priv->rx_skbuff[entry] = NULL; /* reset buffer descriptor state */ - sis_priv->rx_ring[entry].cmdsts = 0; + sis_priv->rx_ring[entry].cmdsts = OWN; sis_priv->rx_ring[entry].bufptr = 0; sis_priv->stats.rx_dropped++; break; @@ -1728,6 +1730,8 @@ static int sis900_rx(struct net_device * sis_priv->cur_rx++; entry = sis_priv->cur_rx % NUM_RX_DESC; + rmb(); rx_status = sis_priv->rx_ring[entry].cmdsts; + rx_left--; } // while /* refill the Rx buffer, what if the rate of refilling is slower _ ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2005-01-19 21:49 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2005-01-18 10:13 sis900: eth0: NULL pointer encountered in Rx ring, skipping Lennert Buytenhek 2005-01-18 10:21 ` Lennert Buytenhek 2005-01-19 20:52 ` Eric Lemoine 2005-01-19 21:49 ` Francois Romieu
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).