diff options
author | Michael Brown <mcb30@etherboot.org> | 2007-01-09 21:47:01 +0000 |
---|---|---|
committer | Michael Brown <mcb30@etherboot.org> | 2007-01-09 21:47:01 +0000 |
commit | c65fae2475ca652ef7948f286881b0c06bce861b (patch) | |
tree | 5588ec4b947ecc79201ee613d1cd0a0a7ca6d1d8 /src/drivers/net | |
parent | e822bc2a90016f206b051cce1287a655e66b6b9b (diff) | |
download | ipxe-c65fae2475ca652ef7948f286881b0c06bce861b.tar.gz |
Add RX quotas to the net device poll() method. This avoids the problem
of alloc_pkb() exhaustion when e.g. an iSCSI-booted DOS session is left
idle for a long time at the C:\ prompt and builds up a huge packet
backlog.
Diffstat (limited to 'src/drivers/net')
-rw-r--r-- | src/drivers/net/legacy.c | 5 | ||||
-rw-r--r-- | src/drivers/net/pnic.c | 5 | ||||
-rw-r--r-- | src/drivers/net/rtl8139.c | 5 |
3 files changed, 10 insertions, 5 deletions
diff --git a/src/drivers/net/legacy.c b/src/drivers/net/legacy.c index 2d952aac0..091cdcc20 100644 --- a/src/drivers/net/legacy.c +++ b/src/drivers/net/legacy.c @@ -38,10 +38,13 @@ static int legacy_transmit ( struct net_device *netdev, struct pk_buff *pkb ) { return 0; } -static void legacy_poll ( struct net_device *netdev ) { +static void legacy_poll ( struct net_device *netdev, unsigned int rx_quota ) { struct nic *nic = netdev->priv; struct pk_buff *pkb; + if ( ! rx_quota ) + return; + pkb = alloc_pkb ( ETH_FRAME_LEN ); if ( ! pkb ) return; diff --git a/src/drivers/net/pnic.c b/src/drivers/net/pnic.c index 09ac92a47..c74e7b508 100644 --- a/src/drivers/net/pnic.c +++ b/src/drivers/net/pnic.c @@ -112,14 +112,14 @@ static int pnic_api_check ( uint16_t api_version ) { /************************************************************************** POLL - Wait for a frame ***************************************************************************/ -static void pnic_poll ( struct net_device *netdev ) { +static void pnic_poll ( struct net_device *netdev, unsigned int rx_quota ) { struct pnic *pnic = netdev->priv; struct pk_buff *pkb; uint16_t length; uint16_t qlen; /* Fetch all available packets */ - while ( 1 ) { + while ( rx_quota ) { if ( pnic_command ( pnic, PNIC_CMD_RECV_QLEN, NULL, 0, &qlen, sizeof ( qlen ), NULL ) != PNIC_STATUS_OK ) @@ -139,6 +139,7 @@ static void pnic_poll ( struct net_device *netdev ) { } pkb_put ( pkb, length ); netdev_rx ( netdev, pkb ); + --rx_quota; } } diff --git a/src/drivers/net/rtl8139.c b/src/drivers/net/rtl8139.c index 4981329c3..a25755c2d 100644 --- a/src/drivers/net/rtl8139.c +++ b/src/drivers/net/rtl8139.c @@ -413,8 +413,9 @@ static int rtl_transmit ( struct net_device *netdev, struct pk_buff *pkb ) { * Poll for received packets * * @v netdev Network device + * @v rx_quota Maximum number of packets to receive */ -static void rtl_poll ( struct net_device *netdev ) { +static void rtl_poll ( struct net_device *netdev, unsigned int rx_quota ) { struct rtl8139_nic *rtl = netdev->priv; unsigned int status; unsigned int tsad; @@ -441,7 +442,7 @@ static void rtl_poll ( struct net_device *netdev ) { } /* Handle received packets */ - while ( ! ( inw ( rtl->ioaddr + ChipCmd ) & RxBufEmpty ) ) { + while ( rx_quota && ! ( inw ( rtl->ioaddr + ChipCmd ) & RxBufEmpty ) ){ rx_status = * ( ( uint16_t * ) ( rtl->rx.ring + rtl->rx.offset ) ); rx_len = * ( ( uint16_t * ) |