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.
This commit is contained in:
Avi Kivity
2014-11-07 13:09:24 +02:00
parent dbfd636a0b
commit 8dff32eea5
2 changed files with 15 additions and 10 deletions

View File

@@ -158,12 +158,17 @@ xenfront_net_device::send(packet _p) {
template <typename T>
future<unsigned> front_ring<T>::entries::get_index() {
return _ids.pop_eventually();
return _available.wait().then([this] {
auto ret = _ids.front();
_ids.pop();
return make_ready_future<unsigned>(ret);
});
}
template <typename T>
future<> front_ring<T>::entries::free_index(unsigned id) {
return _ids.push_eventually(std::move(id));
void front_ring<T>::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<>();

View File

@@ -73,12 +73,13 @@ class front_ring {
public:
class entries {
protected:
queue<unsigned> _ids;
std::queue<unsigned, circular_buffer<unsigned>> _ids;
semaphore _available = { front_ring::nr_ents };
private:
std::array<gntref, front_ring<T>::nr_ents> _entries;
front_ring<T> *_ring;
public:
entries(front_ring<T> *ring) : _ids(front_ring<T>::nr_ents), _ring(ring) {
entries(front_ring<T> *ring) : _ring(ring) {
for (unsigned i = 0; i < front_ring<T>::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<unsigned> get_index();
future<> free_index(unsigned index);
void free_index(unsigned index);
};
protected:
uint32_t idx(int i) { return i & (nr_ents - 1); }