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 <glommer@cloudius-systems.com>
This commit is contained in:
Glauber Costa
2014-11-05 22:34:04 +01:00
parent ee172e36c1
commit ae1122bfc8
2 changed files with 18 additions and 8 deletions

View File

@@ -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 <typename T>
future<uint32_t> front_ring<T>::free_idx() {
static uint32_t idx = 0;
return make_ready_future<uint32_t>(idx++);
future<unsigned> front_ring<T>::entries::get_index() {
return _ids.pop_eventually();
}
template <typename T>
future<> front_ring<T>::entries::free_index(unsigned id) {
return _ids.push_eventually(std::move(id));
}
future<> xenfront_net_device::queue_rx_packet() {

View File

@@ -9,6 +9,7 @@
#include "net.hh"
#include "core/sstring.hh"
#include "core/xen/gntalloc.hh"
#include "core/queue.hh"
std::unique_ptr<net::device> 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 <typename T>
class front_ring {
public:
class entries {
protected:
queue<unsigned> _ids;
private:
std::array<gntref, front_ring<T>::nr_ents> _entries;
front_ring<T> *_ring;
public:
entries(front_ring<T> *ring) : _ring(ring) {}
entries(front_ring<T> *ring) : _ids(front_ring<T>::nr_ents), _ring(ring) {
for (unsigned i = 0; i < front_ring<T>::nr_ents; ++i) {
_ids.push(std::move(i));
}
}
gntref& operator[](std::size_t i) { return _entries[_ring->idx(i)]; }
friend front_ring;
future<unsigned> 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<T>()) {
}
future<uint32_t> free_idx();
entries entries;
sring<T> *_sring;