Re: [PATCH V6 13/19] virtio_ring: introduce virtqueue ops
From: Jason Wang <jasowang@redhat.com>
Date: 2025-09-22 01:01:01
Also in:
lkml
On Mon, Sep 22, 2025 at 2:33 AM Michael S. Tsirkin [off-list ref] wrote:
On Fri, Sep 19, 2025 at 03:31:48PM +0800, Jason Wang wrote:quoted
This patch introduces virtqueue ops which is a set of the callbacks that will be called for different queue layout or features. This would help to avoid branches for split/packed and will ease the future implementation like in order. Note that in order to eliminate the indirect calls this patch uses global array of const ops to allow compiler to avoid indirect branches. Tested with CONFIG_MITIGATION_RETPOLINE, no performance differences were noticed. Acked-by: Eugenio Pérez <eperezma@redhat.com> Suggested-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Jason Wang <jasowang@redhat.com> --- drivers/virtio/virtio_ring.c | 173 ++++++++++++++++++++++++++--------- 1 file changed, 130 insertions(+), 43 deletions(-)diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index b1b6af297061..1045c553ee65 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c@@ -67,6 +67,12 @@ #define LAST_ADD_TIME_INVALID(vq) #endif +enum vq_layout { + SPLIT = 0, + PACKED, + VQ_TYPE_MAX, +}; + struct vring_desc_state_split { void *data; /* Data for callback. */@@ -159,12 +165,28 @@ struct vring_virtqueue_packed { size_t event_size_in_bytes; }; +struct vring_virtqueue; + +struct virtqueue_ops { + int (*add)(struct vring_virtqueue *_vq, struct scatterlist *sgs[], + unsigned int total_sg, unsigned int out_sgs, + unsigned int in_sgs, void *data, + void *ctx, bool premapped, gfp_t gfp);Why is it _vq here?
Fixed.
quoted
+ void *(*get)(struct vring_virtqueue *vq, unsigned int *len, void **ctx); + bool (*kick_prepare)(struct vring_virtqueue *vq); + void (*disable_cb)(struct vring_virtqueue *vq); + bool (*enable_cb_delayed)(struct vring_virtqueue *vq); + unsigned int (*enable_cb_prepare)(struct vring_virtqueue *vq); + bool (*poll)(const struct vring_virtqueue *vq, u16 last_used_idx); + void *(*detach_unused_buf)(struct vring_virtqueue *vq); + bool (*more_used)(const struct vring_virtqueue *vq); + int (*resize)(struct vring_virtqueue *vq, u32 num); + void (*reset)(struct vring_virtqueue *vq); +}; + struct vring_virtqueue { struct virtqueue vq; - /* Is this a packed ring? */ - bool packed_ring; - /* Is DMA API used? */ bool use_map_api;@@ -180,6 +202,8 @@ struct vring_virtqueue { /* Host publishes avail event idx */ bool event; + enum vq_layout layout; + /* Head of free buffer list. */ unsigned int free_head; /* Number we've added since last sync. */@@ -231,6 +255,12 @@ static void vring_free(struct virtqueue *_vq); #define to_vvq(_vq) container_of_const(_vq, struct vring_virtqueue, vq) +why the extra empty line?
And fix this. Thanks