mirror of
https://github.com/ipxe/ipxe
synced 2025-12-14 07:50:43 +03:00
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.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 * )
|
||||
|
||||
Reference in New Issue
Block a user