From 9229c13a2cbb860693f5bf5c3e3926e343170262 Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Wed, 8 Nov 2023 17:08:49 -0800 Subject: [PATCH] venus: move the rest ring belongings into ring This change only moves the fields without changing the accessors. It's better to let ring own its own upload cs encoder (which is backed by shmem array) to avoid lock contention between indirect submissions across rings. Signed-off-by: Yiwei Zhang Part-of: --- src/virtio/vulkan/vn_device_memory.c | 2 +- src/virtio/vulkan/vn_instance.c | 32 ++++++++++------------------ src/virtio/vulkan/vn_instance.h | 4 ---- src/virtio/vulkan/vn_queue.c | 5 +++-- src/virtio/vulkan/vn_ring.c | 13 +++++++++-- src/virtio/vulkan/vn_ring.h | 12 +++++++++++ 6 files changed, 38 insertions(+), 30 deletions(-) diff --git a/src/virtio/vulkan/vn_device_memory.c b/src/virtio/vulkan/vn_device_memory.c index f61f753fc86..e94f7e34e2c 100644 --- a/src/virtio/vulkan/vn_device_memory.c +++ b/src/virtio/vulkan/vn_device_memory.c @@ -73,7 +73,7 @@ vn_device_memory_wait_alloc(struct vn_device *dev, uint32_t local_data[8]; struct vn_cs_encoder local_enc = VN_CS_ENCODER_INITIALIZER_LOCAL(local_data, sizeof(local_data)); - vn_encode_vkWaitRingSeqnoMESA(&local_enc, 0, dev->instance->ring.id, + vn_encode_vkWaitRingSeqnoMESA(&local_enc, 0, dev->instance->ring.ring->id, mem->bo_ring_seqno); return vn_renderer_submit_simple(dev->renderer, local_data, vn_cs_encoder_get_len(&local_enc)); diff --git a/src/virtio/vulkan/vn_instance.c b/src/virtio/vulkan/vn_instance.c index 87e44086f64..191a0122ab9 100644 --- a/src/virtio/vulkan/vn_instance.c +++ b/src/virtio/vulkan/vn_instance.c @@ -116,19 +116,15 @@ vn_instance_fini_ring(struct vn_instance *instance) { mtx_destroy(&instance->ring.roundtrip_mutex); - vn_cs_encoder_fini(&instance->ring.upload); - uint32_t destroy_ring_data[4]; struct vn_cs_encoder local_enc = VN_CS_ENCODER_INITIALIZER_LOCAL( destroy_ring_data, sizeof(destroy_ring_data)); - vn_encode_vkDestroyRingMESA(&local_enc, 0, instance->ring.id); + vn_encode_vkDestroyRingMESA(&local_enc, 0, instance->ring.ring->id); vn_renderer_submit_simple(instance->renderer, destroy_ring_data, vn_cs_encoder_get_len(&local_enc)); vn_watchdog_fini(&instance->ring.watchdog); - mtx_destroy(&instance->ring.mutex); - vn_ring_destroy(instance->ring.ring); } @@ -144,10 +140,6 @@ vn_instance_init_ring(struct vn_instance *instance) if (!instance->ring.ring) return VK_ERROR_OUT_OF_HOST_MEMORY; - instance->ring.id = (uintptr_t)instance->ring.ring; - - mtx_init(&instance->ring.mutex, mtx_plain); - vn_watchdog_init(&instance->ring.watchdog); const struct VkRingMonitorInfoMESA monitor_info = { @@ -172,13 +164,10 @@ vn_instance_init_ring(struct vn_instance *instance) uint32_t create_ring_data[64]; struct vn_cs_encoder local_enc = VN_CS_ENCODER_INITIALIZER_LOCAL( create_ring_data, sizeof(create_ring_data)); - vn_encode_vkCreateRingMESA(&local_enc, 0, instance->ring.id, &info); + vn_encode_vkCreateRingMESA(&local_enc, 0, instance->ring.ring->id, &info); vn_renderer_submit_simple(instance->renderer, create_ring_data, vn_cs_encoder_get_len(&local_enc)); - vn_cs_encoder_init(&instance->ring.upload, instance, - VN_CS_ENCODER_STORAGE_SHMEM_ARRAY, 1 * 1024 * 1024); - mtx_init(&instance->ring.roundtrip_mutex, mtx_plain); instance->ring.roundtrip_next = 1; @@ -264,8 +253,8 @@ vn_instance_submit_roundtrip(struct vn_instance *instance, mtx_lock(&instance->ring.roundtrip_mutex); const uint64_t seqno = instance->ring.roundtrip_next++; - vn_encode_vkSubmitVirtqueueSeqnoMESA(&local_enc, 0, instance->ring.id, - seqno); + vn_encode_vkSubmitVirtqueueSeqnoMESA(&local_enc, 0, + instance->ring.ring->id, seqno); VkResult result = vn_renderer_submit_simple( instance->renderer, local_data, vn_cs_encoder_get_len(&local_enc)); mtx_unlock(&instance->ring.roundtrip_mutex); @@ -417,7 +406,7 @@ vn_instance_ring_cs_upload_locked(struct vn_instance *instance, const size_t cs_size = cs->total_committed_size; assert(cs_size == vn_cs_encoder_get_len(cs)); - struct vn_cs_encoder *upload = &instance->ring.upload; + struct vn_cs_encoder *upload = &instance->ring.ring->upload; vn_cs_encoder_reset(upload); if (!vn_cs_encoder_reserve(upload, cs_size)) @@ -457,7 +446,8 @@ vn_instance_ring_submit_locked(struct vn_instance *instance, uint32_t notify_ring_data[8]; struct vn_cs_encoder local_enc = VN_CS_ENCODER_INITIALIZER_LOCAL( notify_ring_data, sizeof(notify_ring_data)); - vn_encode_vkNotifyRingMESA(&local_enc, 0, instance->ring.id, seqno, 0); + vn_encode_vkNotifyRingMESA(&local_enc, 0, instance->ring.ring->id, + seqno, 0); vn_renderer_submit_simple(instance->renderer, notify_ring_data, vn_cs_encoder_get_len(&local_enc)); } @@ -474,9 +464,9 @@ VkResult vn_instance_ring_submit(struct vn_instance *instance, const struct vn_cs_encoder *cs) { - mtx_lock(&instance->ring.mutex); + mtx_lock(&instance->ring.ring->mutex); VkResult result = vn_instance_ring_submit_locked(instance, cs, NULL, NULL); - mtx_unlock(&instance->ring.mutex); + mtx_unlock(&instance->ring.ring->mutex); return result; } @@ -518,7 +508,7 @@ vn_instance_submit_command(struct vn_instance *instance, return; } - mtx_lock(&instance->ring.mutex); + mtx_lock(&instance->ring.ring->mutex); if (submit->reply_size) { vn_instance_set_reply_shmem_locked(instance, submit->reply_shmem, reply_offset, submit->reply_size); @@ -527,7 +517,7 @@ vn_instance_submit_command(struct vn_instance *instance, VK_SUCCESS == vn_instance_ring_submit_locked(instance, &submit->command, submit->reply_shmem, &submit->ring_seqno); - mtx_unlock(&instance->ring.mutex); + mtx_unlock(&instance->ring.ring->mutex); if (submit->reply_size) { void *reply_ptr = submit->reply_shmem->mmap_ptr + reply_offset; diff --git a/src/virtio/vulkan/vn_instance.h b/src/virtio/vulkan/vn_instance.h index e1ab750e11a..64aaff069da 100644 --- a/src/virtio/vulkan/vn_instance.h +++ b/src/virtio/vulkan/vn_instance.h @@ -50,10 +50,6 @@ struct vn_instance { struct { struct vn_ring *ring; - uint64_t id; - mtx_t mutex; - - struct vn_cs_encoder upload; /* to synchronize renderer/ring */ mtx_t roundtrip_mutex; diff --git a/src/virtio/vulkan/vn_queue.c b/src/virtio/vulkan/vn_queue.c index e1136660f8b..fc7007d841a 100644 --- a/src/virtio/vulkan/vn_queue.c +++ b/src/virtio/vulkan/vn_queue.c @@ -1044,7 +1044,7 @@ vn_queue_wsi_present(struct vn_queue_submission *submit) struct vn_cs_encoder local_enc = VN_CS_ENCODER_INITIALIZER_LOCAL(local_data, sizeof(local_data)); if (submit->external_payload.ring_seqno_valid) { - vn_encode_vkWaitRingSeqnoMESA(&local_enc, 0, instance->ring.id, + vn_encode_vkWaitRingSeqnoMESA(&local_enc, 0, instance->ring.ring->id, submit->external_payload.ring_seqno); batch.cs_data = local_data; batch.cs_size = vn_cs_encoder_get_len(&local_enc); @@ -1832,7 +1832,8 @@ vn_create_sync_file(struct vn_device *dev, struct vn_cs_encoder local_enc = VN_CS_ENCODER_INITIALIZER_LOCAL(local_data, sizeof(local_data)); if (external_payload->ring_seqno_valid) { - vn_encode_vkWaitRingSeqnoMESA(&local_enc, 0, dev->instance->ring.id, + vn_encode_vkWaitRingSeqnoMESA(&local_enc, 0, + dev->instance->ring.ring->id, external_payload->ring_seqno); batch.cs_data = local_data; batch.cs_size = vn_cs_encoder_get_len(&local_enc); diff --git a/src/virtio/vulkan/vn_ring.c b/src/virtio/vulkan/vn_ring.c index 84c60d83f28..f7129539110 100644 --- a/src/virtio/vulkan/vn_ring.c +++ b/src/virtio/vulkan/vn_ring.c @@ -194,6 +194,8 @@ vn_ring_create(struct vn_instance *instance, if (!ring) return NULL; + ring->id = (uintptr_t)ring; + ring->instance = instance; ring->shmem = vn_renderer_shmem_create(instance->renderer, layout->shmem_size); if (!ring->shmem) { @@ -206,8 +208,6 @@ vn_ring_create(struct vn_instance *instance, void *shared = ring->shmem->mmap_ptr; memset(shared, 0, layout->shmem_size); - ring->instance = instance; - assert(layout->buffer_size && util_is_power_of_two_or_zero(layout->buffer_size)); ring->buffer_size = layout->buffer_size; @@ -219,6 +219,11 @@ vn_ring_create(struct vn_instance *instance, ring->shared.buffer = shared + layout->buffer_offset; ring->shared.extra = shared + layout->extra_offset; + mtx_init(&ring->mutex, mtx_plain); + + vn_cs_encoder_init(&ring->upload, instance, + VN_CS_ENCODER_STORAGE_SHMEM_ARRAY, 1 * 1024 * 1024); + list_inithead(&ring->submits); list_inithead(&ring->free_submits); @@ -239,6 +244,10 @@ vn_ring_destroy(struct vn_ring *ring) &ring->free_submits, head) vk_free(alloc, submit); + vn_cs_encoder_fini(&ring->upload); + + mtx_destroy(&ring->mutex); + vk_free(alloc, ring); } diff --git a/src/virtio/vulkan/vn_ring.h b/src/virtio/vulkan/vn_ring.h index 86b2542edf5..6faf466c59a 100644 --- a/src/virtio/vulkan/vn_ring.h +++ b/src/virtio/vulkan/vn_ring.h @@ -8,6 +8,8 @@ #include "vn_common.h" +#include "vn_cs.h" + /** * A ring is a single-producer and single-consumer circular buffer. The data * in the buffer are produced and consumed in order. An externally-defined @@ -60,6 +62,7 @@ struct vn_ring_submit { }; struct vn_ring { + uint64_t id; struct vn_instance *instance; struct vn_renderer_shmem *shmem; @@ -69,6 +72,15 @@ struct vn_ring { struct vn_ring_shared shared; uint32_t cur; + /* This mutex ensures below: + * - atomic of ring submission + * - reply shmem resource set and ring submission are paired + */ + mtx_t mutex; + + /* used for indirect submission of large command (non-VkCommandBuffer) */ + struct vn_cs_encoder upload; + struct list_head submits; struct list_head free_submits; };