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:
@@ -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<>();
|
||||
|
||||
@@ -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); }
|
||||
|
||||
Reference in New Issue
Block a user