From ae1122bfc8b15632d576f61e647c8e4cf326583b Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Wed, 5 Nov 2014 22:34:04 +0100 Subject: [PATCH] xen: manage index list Aside from managing the grant references, we also need to manage the positional indexes in the array. We need to keep track of which indexes are free, and which are used. Because we need the actual position number to fill xen's data structures, I figured we could use a queue and then fill it up with all the integers in our range. The queue is already futurized, so that's easy. Signed-off-by: Glauber Costa --- net/xenfront.cc | 13 ++++++++----- net/xenfront.hh | 13 ++++++++++--- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/net/xenfront.cc b/net/xenfront.cc index c2f0563876..f2a3bea12f 100644 --- a/net/xenfront.cc +++ b/net/xenfront.cc @@ -111,7 +111,7 @@ xenfront_net_device::send(packet _p) { // FIXME: negotiate and use scatter/gather _p.linearize(); - return _tx_ring.free_idx().then([this, p = std::move(_p), frag] (uint32_t idx) mutable { + return _tx_ring.entries.get_index().then([this, p = std::move(_p), frag] (unsigned idx) mutable { auto req_prod = _tx_ring._sring->req_prod; @@ -152,11 +152,14 @@ xenfront_net_device::send(packet _p) { #define rmb() asm volatile("lfence":::"memory"); #define wmb() asm volatile("":::"memory"); -// FIXME: This is totally wrong, just coded so we can gt started with sending template -future front_ring::free_idx() { - static uint32_t idx = 0; - return make_ready_future(idx++); +future front_ring::entries::get_index() { + return _ids.pop_eventually(); +} + +template +future<> front_ring::entries::free_index(unsigned id) { + return _ids.push_eventually(std::move(id)); } future<> xenfront_net_device::queue_rx_packet() { diff --git a/net/xenfront.hh b/net/xenfront.hh index f43a944f95..04ebb1681c 100644 --- a/net/xenfront.hh +++ b/net/xenfront.hh @@ -9,6 +9,7 @@ #include "net.hh" #include "core/sstring.hh" #include "core/xen/gntalloc.hh" +#include "core/queue.hh" std::unique_ptr create_xenfront_net_device(boost::program_options::variables_map opts, bool userspace); boost::program_options::options_description get_xenfront_net_options_description(); @@ -71,13 +72,21 @@ template class front_ring { public: class entries { + protected: + queue _ids; private: std::array::nr_ents> _entries; front_ring *_ring; public: - entries(front_ring *ring) : _ring(ring) {} + entries(front_ring *ring) : _ids(front_ring::nr_ents), _ring(ring) { + for (unsigned i = 0; i < front_ring::nr_ents; ++i) { + _ids.push(std::move(i)); + } + } gntref& operator[](std::size_t i) { return _entries[_ring->idx(i)]; } friend front_ring; + future get_index(); + future<> free_index(unsigned index); }; protected: uint32_t idx(int i) { return i & (nr_ents - 1); } @@ -92,8 +101,6 @@ public: , _sring(new (r.page) sring()) { } - - future free_idx(); entries entries; sring *_sring;