aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorIlya Maximets <i.maximets@ovn.org>2023-08-11 16:34:23 +0200
committerMichael S. Tsirkin <mst@redhat.com>2023-10-04 04:54:15 -0400
commit43d6376980d5567f2a6d00cfb30d10c0961671e6 (patch)
tree894ee07bbeba05676b153513f02426de97f64ca6 /hw
parente213c45a042db2506b5e8f16293f1f1c5083a577 (diff)
virtio: don't zero out memory region cache for indirect descriptors
Lots of virtio functions that are on a hot path in data transmission are initializing indirect descriptor cache at the point of stack allocation. It's a 112 byte structure that is getting zeroed out on each call adding unnecessary overhead. It's going to be correctly initialized later via special init function. The only reason to actually initialize right away is the ability to safely destruct it. Replacing a designated initializer with a function to only initialize what is necessary. Removal of the unnecessary stack initializations improves throughput of virtio-net devices in terms of 64B packets per second by 6-14 % depending on the case. Tested with a proposed af-xdp network backend and a dpdk testpmd application in the guest, but should be beneficial for other virtio devices as well. Signed-off-by: Ilya Maximets <i.maximets@ovn.org> Message-Id: <20230811143423.3258788-1-i.maximets@ovn.org> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Acked-by: Jason Wang <jasowang@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/virtio/virtio.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 4577f3f5b3..d3a22e3d36 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -1071,10 +1071,12 @@ static void virtqueue_split_get_avail_bytes(VirtQueue *vq,
VirtIODevice *vdev = vq->vdev;
unsigned int idx;
unsigned int total_bufs, in_total, out_total;
- MemoryRegionCache indirect_desc_cache = MEMORY_REGION_CACHE_INVALID;
+ MemoryRegionCache indirect_desc_cache;
int64_t len = 0;
int rc;
+ address_space_cache_init_empty(&indirect_desc_cache);
+
idx = vq->last_avail_idx;
total_bufs = in_total = out_total = 0;
@@ -1207,12 +1209,14 @@ static void virtqueue_packed_get_avail_bytes(VirtQueue *vq,
VirtIODevice *vdev = vq->vdev;
unsigned int idx;
unsigned int total_bufs, in_total, out_total;
+ MemoryRegionCache indirect_desc_cache;
MemoryRegionCache *desc_cache;
- MemoryRegionCache indirect_desc_cache = MEMORY_REGION_CACHE_INVALID;
int64_t len = 0;
VRingPackedDesc desc;
bool wrap_counter;
+ address_space_cache_init_empty(&indirect_desc_cache);
+
idx = vq->last_avail_idx;
wrap_counter = vq->last_avail_wrap_counter;
total_bufs = in_total = out_total = 0;
@@ -1487,7 +1491,7 @@ static void *virtqueue_split_pop(VirtQueue *vq, size_t sz)
{
unsigned int i, head, max;
VRingMemoryRegionCaches *caches;
- MemoryRegionCache indirect_desc_cache = MEMORY_REGION_CACHE_INVALID;
+ MemoryRegionCache indirect_desc_cache;
MemoryRegionCache *desc_cache;
int64_t len;
VirtIODevice *vdev = vq->vdev;
@@ -1498,6 +1502,8 @@ static void *virtqueue_split_pop(VirtQueue *vq, size_t sz)
VRingDesc desc;
int rc;
+ address_space_cache_init_empty(&indirect_desc_cache);
+
RCU_READ_LOCK_GUARD();
if (virtio_queue_empty_rcu(vq)) {
goto done;
@@ -1624,7 +1630,7 @@ static void *virtqueue_packed_pop(VirtQueue *vq, size_t sz)
{
unsigned int i, max;
VRingMemoryRegionCaches *caches;
- MemoryRegionCache indirect_desc_cache = MEMORY_REGION_CACHE_INVALID;
+ MemoryRegionCache indirect_desc_cache;
MemoryRegionCache *desc_cache;
int64_t len;
VirtIODevice *vdev = vq->vdev;
@@ -1636,6 +1642,8 @@ static void *virtqueue_packed_pop(VirtQueue *vq, size_t sz)
uint16_t id;
int rc;
+ address_space_cache_init_empty(&indirect_desc_cache);
+
RCU_READ_LOCK_GUARD();
if (virtio_queue_packed_empty_rcu(vq)) {
goto done;
@@ -3970,13 +3978,15 @@ VirtioQueueElement *qmp_x_query_virtio_queue_element(const char *path,
} else {
unsigned int head, i, max;
VRingMemoryRegionCaches *caches;
- MemoryRegionCache indirect_desc_cache = MEMORY_REGION_CACHE_INVALID;
+ MemoryRegionCache indirect_desc_cache;
MemoryRegionCache *desc_cache;
VRingDesc desc;
VirtioRingDescList *list = NULL;
VirtioRingDescList *node;
int rc; int ndescs;
+ address_space_cache_init_empty(&indirect_desc_cache);
+
RCU_READ_LOCK_GUARD();
max = vq->vring.num;