aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/devices/virtio/device.c
diff options
context:
space:
mode:
authorMohsin Kazmi <sykazmi@cisco.com>2019-05-23 14:32:58 +0200
committerDamjan Marion <dmarion@me.com>2019-05-24 08:25:04 +0000
commitaea0df3d54d90eac3b8085ab8023c502b96bdbf0 (patch)
treeafefa093e60dafe231bd19cedaba8768040c8494 /src/vnet/devices/virtio/device.c
parentf2d5cdbfa674a2ac9e81fd49d69594f0cdbcffd3 (diff)
Tap: Fix the indirect buffers allocation VPP-1660
Indirect buffers are used to store indirect descriptors to xmit big packets. This patch moves the indirect buffer allocation from interface creation to device node. Now it allocates or deallocates buffers during tx for chained buffers. Change-Id: I55cec208a2a7432e12fe9254a7f8ef84a9302bd5 Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com> (cherry picked from commit 55203e745f5e3f1f6c4dbe99d6eab8dee4d13ea6)
Diffstat (limited to 'src/vnet/devices/virtio/device.c')
-rw-r--r--src/vnet/devices/virtio/device.c47
1 files changed, 35 insertions, 12 deletions
diff --git a/src/vnet/devices/virtio/device.c b/src/vnet/devices/virtio/device.c
index 04cf9ec49c8..e560c29e5e7 100644
--- a/src/vnet/devices/virtio/device.c
+++ b/src/vnet/devices/virtio/device.c
@@ -90,9 +90,8 @@ format_virtio_tx_trace (u8 * s, va_list * args)
return s;
}
-#ifndef CLIB_MARCH_VARIANT
-inline void
-virtio_free_used_desc (vlib_main_t * vm, virtio_vring_t * vring)
+static_always_inline void
+virtio_free_used_device_desc (vlib_main_t * vm, virtio_vring_t * vring)
{
u16 used = vring->desc_in_use;
u16 sz = vring->size;
@@ -106,17 +105,35 @@ virtio_free_used_desc (vlib_main_t * vm, virtio_vring_t * vring)
while (n_left)
{
struct vring_used_elem *e = &vring->used->ring[last & mask];
- u16 slot = e->id;
+ u16 slot, n_buffers;
+ slot = n_buffers = e->id;
- vlib_buffer_free (vm, &vring->buffers[slot], 1);
- used--;
- last++;
- n_left--;
+ while (e->id == n_buffers)
+ {
+ n_left--;
+ last++;
+ n_buffers++;
+ if (n_left == 0)
+ break;
+ e = &vring->used->ring[last & mask];
+ }
+ vlib_buffer_free_from_ring (vm, vring->buffers, slot,
+ sz, (n_buffers - slot));
+ used -= (n_buffers - slot);
+
+ if (n_left > 0)
+ {
+ slot = e->id;
+
+ vlib_buffer_free (vm, &vring->buffers[slot], 1);
+ used--;
+ last++;
+ n_left--;
+ }
}
vring->desc_in_use = used;
vring->last_used_idx = last;
}
-#endif /* CLIB_MARCH_VARIANT */
static_always_inline u16
add_buffer_to_slot (vlib_main_t * vm, virtio_if_t * vif,
@@ -170,9 +187,15 @@ add_buffer_to_slot (vlib_main_t * vm, virtio_if_t * vif,
* It can easily support 65535 bytes of Jumbo frames with
* each data buffer size of 512 bytes minimum.
*/
- vlib_buffer_t *indirect_desc =
- vlib_get_buffer (vm, vring->indirect_buffers[next]);
+ u32 indirect_buffer = 0;
+ if (PREDICT_FALSE (vlib_buffer_alloc (vm, &indirect_buffer, 1) == 0))
+ return n_added;
+
+ vlib_buffer_t *indirect_desc = vlib_get_buffer (vm, indirect_buffer);
indirect_desc->current_data = 0;
+ indirect_desc->flags |= VLIB_BUFFER_NEXT_PRESENT;
+ indirect_desc->next_buffer = bi;
+ bi = indirect_buffer;
struct vring_desc *id =
(struct vring_desc *) vlib_buffer_get_current (indirect_desc);
@@ -261,7 +284,7 @@ virtio_interface_tx_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
virtio_kick (vm, vring, vif);
/* free consumed buffers */
- virtio_free_used_desc (vm, vring);
+ virtio_free_used_device_desc (vm, vring);
used = vring->desc_in_use;
next = vring->desc_next;