From 8dff32eea519c77d5d13f1aaa66d52bb62514a17 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Fri, 7 Nov 2014 13:09:24 +0200 Subject: [PATCH] xen: simplify free grant table ref id management There is no reason to wait when pushing back a free id - there is nothing that could possibly block there. Switch from a queue<> to an std::queue<> and use a semaphore to guard popping from the queue. --- net/xenfront.cc | 18 +++++++++++------- net/xenfront.hh | 7 ++++--- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/net/xenfront.cc b/net/xenfront.cc index a74cede9e3..ecb153ca4e 100644 --- a/net/xenfront.cc +++ b/net/xenfront.cc @@ -158,12 +158,17 @@ xenfront_net_device::send(packet _p) { template future front_ring::entries::get_index() { - return _ids.pop_eventually(); + return _available.wait().then([this] { + auto ret = _ids.front(); + _ids.pop(); + return make_ready_future(ret); + }); } template -future<> front_ring::entries::free_index(unsigned id) { - return _ids.push_eventually(std::move(id)); +void front_ring::entries::free_index(unsigned id) { + _ids.push(id); + _available.signal(); } future<> xenfront_net_device::queue_rx_packet() { @@ -198,9 +203,8 @@ future<> xenfront_net_device::queue_rx_packet() { rsp_prod = _rx_ring._sring->rsp_prod; _rx_refs->free_ref(entry); - _rx_ring.entries.free_index(rsp.id).then([this, id = rsp.id]() { - alloc_one_rx_reference(id); - }); + _rx_ring.entries.free_index(rsp.id); + alloc_one_rx_reference(rsp.id); } // FIXME: Queue_rx maybe should not be a future then @@ -252,7 +256,7 @@ future<> xenfront_net_device::handle_tx_completions() { auto entry = _tx_ring.entries[rsp.id]; _tx_refs->free_ref(entry); - _tx_ring.entries.free_index(rsp.id).then([this]() {}); + _tx_ring.entries.free_index(rsp.id); } _tx_ring.rsp_cons = prod; return make_ready_future<>(); diff --git a/net/xenfront.hh b/net/xenfront.hh index 04ebb1681c..f8440ec465 100644 --- a/net/xenfront.hh +++ b/net/xenfront.hh @@ -73,12 +73,13 @@ class front_ring { public: class entries { protected: - queue _ids; + std::queue> _ids; + semaphore _available = { front_ring::nr_ents }; private: std::array::nr_ents> _entries; front_ring *_ring; public: - entries(front_ring *ring) : _ids(front_ring::nr_ents), _ring(ring) { + entries(front_ring *ring) : _ring(ring) { for (unsigned i = 0; i < front_ring::nr_ents; ++i) { _ids.push(std::move(i)); } @@ -86,7 +87,7 @@ public: gntref& operator[](std::size_t i) { return _entries[_ring->idx(i)]; } friend front_ring; future get_index(); - future<> free_index(unsigned index); + void free_index(unsigned index); }; protected: uint32_t idx(int i) { return i & (nr_ents - 1); }