mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
Mini-OS: netfront: Fix rx ring starvation in network_rx
In network_rx() we must push the same amount of requests back onto the ring in the second loop that we consumed in the first loop. Otherwise the ring will eventually starve itself of free request slots and no packets will be delivered. Further, we make the HAVE_LIBC codepath clearer to follow by removing the "some" variable from the for loop initialisation and conditions. Signed-off-by: Martin Lucina <martin@lucina.net> Acked-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
This commit is contained in:
1 parent
762c08496e
commit
eed8d774ce
1 file changed
+17
-19
+17
-19
@@ -96,42 +96,35 @@ static inline int xennet_rxidx(RING_IDX idx)
|
||||
void network_rx(struct netfront_dev *dev)
|
||||
{
|
||||
RING_IDX rp,cons,req_prod;
|
||||
struct netif_rx_response *rx;
|
||||
int nr_consumed, some, more, i, notify;
|
||||
|
||||
int nr_consumed, more, i, notify;
|
||||
#ifdef HAVE_LIBC
|
||||
int some;
|
||||
#endif
|
||||
|
||||
nr_consumed = 0;
|
||||
moretodo:
|
||||
rp = dev->rx.sring->rsp_prod;
|
||||
rmb(); /* Ensure we see queued responses up to 'rp'. */
|
||||
cons = dev->rx.rsp_cons;
|
||||
|
||||
for (nr_consumed = 0, some = 0;
|
||||
(cons != rp) && !some;
|
||||
nr_consumed++, cons++)
|
||||
#ifdef HAVE_LIBC
|
||||
some = 0;
|
||||
#endif
|
||||
for (cons = dev->rx.rsp_cons; cons != rp; nr_consumed++, cons++)
|
||||
{
|
||||
struct net_buffer* buf;
|
||||
unsigned char* page;
|
||||
int id;
|
||||
|
||||
rx = RING_GET_RESPONSE(&dev->rx, cons);
|
||||
|
||||
if (rx->flags & NETRXF_extra_info)
|
||||
{
|
||||
printk("+++++++++++++++++++++ we have extras!\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (rx->status == NETIF_RSP_NULL) continue;
|
||||
struct netif_rx_response *rx = RING_GET_RESPONSE(&dev->rx, cons);
|
||||
|
||||
id = rx->id;
|
||||
BUG_ON(id >= NET_TX_RING_SIZE);
|
||||
BUG_ON(id >= NET_RX_RING_SIZE);
|
||||
|
||||
buf = &dev->rx_buffers[id];
|
||||
page = (unsigned char*)buf->page;
|
||||
gnttab_end_access(buf->gref);
|
||||
|
||||
if(rx->status>0)
|
||||
if (rx->status > NETIF_RSP_NULL)
|
||||
{
|
||||
#ifdef HAVE_LIBC
|
||||
if (dev->netif_rx == NETIF_SELECT_RX) {
|
||||
@@ -142,6 +135,7 @@ moretodo:
|
||||
memcpy(dev->data, page+rx->offset, len);
|
||||
dev->rlen = len;
|
||||
some = 1;
|
||||
break;
|
||||
} else
|
||||
#endif
|
||||
dev->netif_rx(page+rx->offset,rx->status);
|
||||
@@ -150,7 +144,11 @@ moretodo:
|
||||
dev->rx.rsp_cons=cons;
|
||||
|
||||
RING_FINAL_CHECK_FOR_RESPONSES(&dev->rx,more);
|
||||
#ifdef HAVE_LIBC
|
||||
if(more && !some) goto moretodo;
|
||||
#else
|
||||
if(more) goto moretodo;
|
||||
#endif
|
||||
|
||||
req_prod = dev->rx.req_prod_pvt;
|
||||
|
||||
|
||||