diff options
author | Michael Brown | 2017-05-19 03:50:21 +0200 |
---|---|---|
committer | Michael Brown | 2017-05-19 03:56:53 +0200 |
commit | 7457bfc5b29cee677ab9a49efcea4a476a648a1a (patch) | |
tree | 23148bddb4899aecadbe0ce2d9d5089fb1981d7b /src/drivers/net/netfront.c | |
parent | [iscsi] Fix iBFT when no explicit initiator name setting exists (diff) | |
download | ipxe-7457bfc5b29cee677ab9a49efcea4a476a648a1a.tar.gz ipxe-7457bfc5b29cee677ab9a49efcea4a476a648a1a.tar.xz ipxe-7457bfc5b29cee677ab9a49efcea4a476a648a1a.zip |
[xen] Provide 18 4kB receive buffers to work around xen-netback bug
The Xen network backend (xen-netback) suffered from a regression
between upstream Linux kernels 3.18 and 4.2 inclusive, which would
cause packet reception to fail unless at least 18 receive buffers were
available. This bug was fixed in kernel commit 1d5d485 ("xen-netback:
require fewer guest Rx slots when not using GSO").
Work around this bug in affected versions of xen-netback by providing
the requisite 18 receive buffers.
Reported-by: Taylor Schneider <tschneider@live.com>
Tested-by: Taylor Schneider <tschneider@live.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/drivers/net/netfront.c')
-rw-r--r-- | src/drivers/net/netfront.c | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/src/drivers/net/netfront.c b/src/drivers/net/netfront.c index 2f4bbf2a..b6205542 100644 --- a/src/drivers/net/netfront.c +++ b/src/drivers/net/netfront.c @@ -511,15 +511,12 @@ static void netfront_refill_rx ( struct net_device *netdev ) { struct xen_device *xendev = netfront->xendev; struct io_buffer *iobuf; struct netif_rx_request *request; + unsigned int refilled = 0; int notify; int rc; - /* Do nothing if ring is already full */ - if ( netfront_ring_is_full ( &netfront->rx ) ) - return; - /* Refill ring */ - do { + while ( netfront_ring_fill ( &netfront->rx ) < NETFRONT_RX_FILL ) { /* Allocate I/O buffer */ iobuf = alloc_iob ( PAGE_SIZE ); @@ -543,13 +540,17 @@ static void netfront_refill_rx ( struct net_device *netdev ) { /* Move to next descriptor */ netfront->rx_fring.req_prod_pvt++; + refilled++; - } while ( ! netfront_ring_is_full ( &netfront->rx ) ); + } /* Push new descriptors and notify backend if applicable */ - RING_PUSH_REQUESTS_AND_CHECK_NOTIFY ( &netfront->rx_fring, notify ); - if ( notify ) - netfront_send_event ( netfront ); + if ( refilled ) { + RING_PUSH_REQUESTS_AND_CHECK_NOTIFY ( &netfront->rx_fring, + notify ); + if ( notify ) + netfront_send_event ( netfront ); + } } /** |