diff options
author | Damjan Marion <damarion@cisco.com> | 2018-12-20 10:44:47 +0100 |
---|---|---|
committer | Damjan Marion <dmarion@me.com> | 2019-01-08 17:03:56 +0000 |
commit | e40231b1ecf4b49faaa9ce7b615a7d867104825b (patch) | |
tree | f7f7b4fed09740dadee4d270ffb68155a06195a1 /src/vnet/devices/virtio/node.c | |
parent | 294afe297c74c7c9413c6bd4856e92c9bc439e7c (diff) |
virtio: fix kick race issue
Change-Id: I25b2a28513821bc5eab9ac6890a3964d412b0399
Signed-off-by: Damjan Marion <damarion@cisco.com>
Diffstat (limited to 'src/vnet/devices/virtio/node.c')
-rw-r--r-- | src/vnet/devices/virtio/node.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/src/vnet/devices/virtio/node.c b/src/vnet/devices/virtio/node.c index e0195139321..d7a0b3964b4 100644 --- a/src/vnet/devices/virtio/node.c +++ b/src/vnet/devices/virtio/node.c @@ -87,17 +87,23 @@ virtio_refill_vring (vlib_main_t * vm, virtio_vring_t * vring) u16 sz = vring->size; u16 mask = sz - 1; +more: used = vring->desc_in_use; if (sz - used < sz / 8) return; - n_slots = sz - used; + /* deliver free buffers in chunks of 64 */ + n_slots = clib_min (sz - used, 64); + next = vring->desc_next; avail = vring->avail->idx; n_slots = vlib_buffer_alloc_to_ring (vm, vring->buffers, next, vring->size, n_slots); + if (n_slots == 0) + return; + while (n_slots) { struct vring_desc *d = &vring->desc[next];; @@ -117,10 +123,8 @@ virtio_refill_vring (vlib_main_t * vm, virtio_vring_t * vring) vring->desc_in_use = used; if ((vring->used->flags & VIRTIO_RING_FLAG_MASK_INT) == 0) - { - u64 b = 1; - CLIB_UNUSED (int r) = write (vring->kick_fd, &b, sizeof (b)); - } + virtio_kick (vring); + goto more; } static_always_inline uword @@ -140,6 +144,10 @@ virtio_device_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, u16 last = vring->last_used_idx; u16 n_left = vring->used->idx - last; + if ((vring->used->flags & VIRTIO_RING_FLAG_MASK_INT) == 0 && + vring->last_kick_avail_idx != vring->avail->idx) + virtio_kick (vring); + if (n_left == 0) goto refill; |