aboutsummaryrefslogtreecommitdiffstats
path: root/src/drivers/net
diff options
context:
space:
mode:
authorMichael Brown <mcb30@etherboot.org>2007-01-09 21:47:01 +0000
committerMichael Brown <mcb30@etherboot.org>2007-01-09 21:47:01 +0000
commitc65fae2475ca652ef7948f286881b0c06bce861b (patch)
tree5588ec4b947ecc79201ee613d1cd0a0a7ca6d1d8 /src/drivers/net
parente822bc2a90016f206b051cce1287a655e66b6b9b (diff)
downloadipxe-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.c5
-rw-r--r--src/drivers/net/pnic.c5
-rw-r--r--src/drivers/net/rtl8139.c5
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 * )