From 8a29d4a78a581fc2a17114c497568a211aecd806 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Fri, 7 Nov 2014 13:26:12 +0200 Subject: [PATCH] xen: replenish rx ring entries Keep recycling free ring entries back into the receive ring so we can receive more than 256 packets. The code is a little lame at the moment since it writes the index and notifies the host for every frame, but that can be adjusted later. --- net/xenfront.cc | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/net/xenfront.cc b/net/xenfront.cc index ecb153ca4e..2351a3ca81 100644 --- a/net/xenfront.cc +++ b/net/xenfront.cc @@ -62,7 +62,7 @@ private: int bind_tx_evtchn(); int bind_rx_evtchn(); - future<> alloc_rx_references(unsigned refs); + future<> alloc_rx_references(); future<> handle_tx_completions(); future<> queue_rx_packet(); @@ -193,18 +193,12 @@ future<> xenfront_net_device::queue_rx_packet() { packet p(static_cast(entry.page) + rsp.offset, rsp_size); _rx_stream.produce(std::move(p)); - auto req_prod = _rx_ring._sring->req_prod; - if (req_prod >= _rx_ring.req_prod_pvt) { - printf("Allocate more\n"); // FIXME: This is futurized as well, - } - _rx_ring._sring->rsp_event = rsp_cons + 1; rsp_prod = _rx_ring._sring->rsp_prod; _rx_refs->free_ref(entry); _rx_ring.entries.free_index(rsp.id); - alloc_one_rx_reference(rsp.id); } // FIXME: Queue_rx maybe should not be a future then @@ -221,21 +215,17 @@ void xenfront_net_device::alloc_one_rx_reference(unsigned index) { req->gref = _rx_ring.entries[index].xen_id; } -future<> xenfront_net_device::alloc_rx_references(unsigned refs) { - auto req_prod = _rx_ring.req_prod_pvt; - rmb(); - - for (auto i = req_prod; (i < _rx_ring.nr_ents) && (i < refs); ++i) { +future<> xenfront_net_device::alloc_rx_references() { + return _rx_ring.entries.get_index().then([this] (unsigned i) { + auto req_prod = _rx_ring.req_prod_pvt; alloc_one_rx_reference(i); ++req_prod; - } - - _rx_ring.req_prod_pvt = req_prod; - wmb(); - _rx_ring._sring->req_prod = req_prod; - /* ready */ - _evtchn->notify(_rx_evtchn); - return make_ready_future(); + _rx_ring.req_prod_pvt = req_prod; + wmb(); + _rx_ring._sring->req_prod = req_prod; + /* ready */ + _evtchn->notify(_rx_evtchn); + }); } future<> xenfront_net_device::handle_tx_completions() { @@ -332,7 +322,9 @@ xenfront_net_device::xenfront_net_device(boost::program_options::variables_map o _xenstore->write(path("state"), 4, t); } - alloc_rx_references(_rx_ring.nr_ents); + keep_doing([this] { + return alloc_rx_references(); + }); keep_doing([this] () { return _evtchn->pending(_tx_evtchn).then([this] { handle_tx_completions();