Skip to content

Instantly share code, notes, and snippets.

@mato
Created December 3, 2014 18:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mato/512eb70f39565b030f73 to your computer and use it in GitHub Desktop.
Save mato/512eb70f39565b030f73 to your computer and use it in GitHub Desktop.
Cleaned up implementation of netfront.c:network_rx()
void network_rx(struct netfront_dev *dev)
{
RING_IDX i, resp_prod, req_prod;
int more_to_do, nr_consumed, notify;
nr_consumed = 0;
again:
resp_prod = dev->rx.sring->rsp_prod;
rmb(); /* Ensure we see queued responses up to 'resp_prod'. */
for (i = dev->rx.rsp_cons; i != resp_prod; i++, nr_consumed++)
{
struct netif_rx_response *rx = RING_GET_RESPONSE(&dev->rx, i);
struct net_buffer* buf;
unsigned char* page;
BUG_ON(rx->id >= NET_RX_RING_SIZE);
buf = &dev->rx_buffers[rx->id];
page = (unsigned char*)buf->page;
gnttab_end_access(buf->gref);
if (rx->status > 0)
dev->netif_rx(dev, page + rx->offset, rx->status);
}
rmb();
dev->rx.rsp_cons = i;
RING_FINAL_CHECK_FOR_RESPONSES(&dev->rx, more_to_do);
if (more_to_do)
goto again;
/* We must push the same amount of request slots onto the ring as we
* consumed in this run, otherwise they will eventually run out. */
req_prod = dev->rx.req_prod_pvt;
for(i=0; i < nr_consumed; i++)
{
int id = xennet_rxidx(req_prod + i);
netif_rx_request_t *req = RING_GET_REQUEST(&dev->rx, req_prod + i);
struct net_buffer* buf = &dev->rx_buffers[id];
void* page = buf->page;
req->id = id;
/* We are sure to have free gnttab entries since they got released above */
buf->gref = req->gref =
gnttab_grant_access(dev->dom, virt_to_mfn(page),0);
}
wmb();
dev->rx.req_prod_pvt = req_prod + i;
RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&dev->rx, notify);
if (notify)
notify_remote_via_evtchn(dev->evtchn);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment