From: wafer Xie <[email protected]> Using multiple statically allocated buffers to store virtio indirect descriptors
Signed-off-by: wafer Xie <[email protected]> --- hw/virtio/vhost-shadow-virtqueue.h | 46 ++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h index 9c273739d6..b0f236f049 100644 --- a/hw/virtio/vhost-shadow-virtqueue.h +++ b/hw/virtio/vhost-shadow-virtqueue.h @@ -23,6 +23,13 @@ typedef struct SVQDescState { * guest's */ unsigned int ndescs; + + /* + * Index into the indirect descriptor + * buffer (0 to SVQ_NUM_INDIRECT_BUFS - 1) if using indirect. + * -1 if not using indirect descriptors. + */ + int indirect_buf_idx; } SVQDescState; typedef struct VhostShadowVirtqueue VhostShadowVirtqueue; @@ -46,6 +53,32 @@ typedef struct VhostShadowVirtqueueOps { VirtQueueAvailCallback avail_handler; } VhostShadowVirtqueueOps; +/** + * State of an indirect descriptor buffer + */ +typedef enum SVQIndirectBufState { + SVQ_INDIRECT_BUF_FREED, /* Buffer is free and can be used */ + SVQ_INDIRECT_BUF_FREEING, /* Buffer is being freed */ +} SVQIndirectBufState; + +/** + * Pre-allocated indirect descriptor buffer + * Each SVQ has two of these buffers for double-buffering + */ +typedef struct SVQIndirectDescBuf { + vring_desc_t *desc; /* Descriptor table size = num_descs) */ + hwaddr iova; /* IOVA of the descriptor table */ + size_t size; /* Size of the mmap'd region */ + SVQIndirectBufState state; /* Current state of this buffer */ + uint16_t num_descs; /* Total number of descs (N * vring.num) */ + uint16_t freed_descs; /* Number of descriptors available for use */ + uint16_t freeing_descs; /* Number of descs being freed from used ring */ + uint16_t freed_head; /* Next free descriptor index in this buffer */ +} SVQIndirectDescBuf; + +/* Number of indirect descriptor buffers per SVQ for double-buffering */ +#define SVQ_NUM_INDIRECT_BUFS 2 + /* Shadow virtqueue to relay notifications */ typedef struct VhostShadowVirtqueue { /* Shadow vring */ @@ -96,6 +129,19 @@ typedef struct VhostShadowVirtqueue { /* Caller callbacks opaque */ void *ops_opaque; + /* + * Pre-allocated indirect descriptor buffers for double-buffering. + * These are allocated when SVQ starts if VIRTIO_RING_F_INDIRECT_DESC + * is negotiated. + */ + SVQIndirectDescBuf indirect_bufs[SVQ_NUM_INDIRECT_BUFS]; + + /* Index of the current active indirect buffer, -1 if not using */ + int current_indirect_buf; + + /* Whether indirect descriptors are enabled */ + bool indirect_enabled; + /* Next head to expose to the device */ uint16_t shadow_avail_idx; -- 2.48.1
