mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-30 08:02:30 +00:00
Merge branch 'virtio-support-packed-ring'
Tiwei Bie says: ==================== virtio: support packed ring This patch set implements packed ring support in virtio driver. A performance test between pktgen (pktgen_sample03_burst_single_flow.sh) and DPDK vhost (testpmd/rxonly/vhost-PMD) has been done, I saw ~30% performance gain in packed ring in this case. To make this patch set work with below patch set for vhost, some hacks are needed to set the _F_NEXT flag in indirect descriptors (this should be fixed in vhost): https://lkml.org/lkml/2018/7/3/33 v2 -> v3: - Use leXX instead of virtioXX (MST); - Refactor split ring first (MST); - Add debug helpers (MST); - Put split/packed ring specific fields in sub structures (MST); - Handle normal descriptors and indirect descriptors differently (MST); - Track the DMA addr/len related info in a separate structure (MST); - Calculate AVAIL/USED flags only when wrap counter wraps (MST); - Define a struct/union to read event structure (MST); - Define a macro for wrap counter bit in uapi (MST); - Define the AVAIL/USED bits as shifts instead of values (MST); - s/_F_/_FLAG_/ in VRING_PACKED_EVENT_* as they are values (MST); - Drop the notify workaround for QEMU's tx-timer in packed ring (MST); v1 -> v2: - Use READ_ONCE() to read event off_wrap and flags together (Jason); - Add comments related to ccw (Jason); RFC v6 -> v1: - Avoid extra virtio_wmb() in virtqueue_enable_cb_delayed_packed() when event idx is off (Jason); - Fix bufs calculation in virtqueue_enable_cb_delayed_packed() (Jason); - Test the state of the desc at used_idx instead of last_used_idx in virtqueue_enable_cb_delayed_packed() (Jason); - Save wrap counter (as part of queue state) in the return value of virtqueue_enable_cb_prepare_packed(); - Refine the packed ring definitions in uapi; - Rebase on the net-next tree; RFC v5 -> RFC v6: - Avoid tracking addr/len/flags when DMA API isn't used (MST/Jason); - Define wrap counter as bool (Jason); - Use ALIGN() in vring_init_packed() (Jason); - Avoid using pointer to track `next` in detach_buf_packed() (Jason); - Add comments for barriers (Jason); - Don't enable RING_PACKED on ccw for now (noticed by Jason); - Refine the memory barrier in virtqueue_poll(); - Add a missing memory barrier in virtqueue_enable_cb_delayed_packed(); - Remove the hacks in virtqueue_enable_cb_prepare_packed(); RFC v4 -> RFC v5: - Save DMA addr, etc in desc state (Jason); - Track used wrap counter; RFC v3 -> RFC v4: - Make ID allocation support out-of-order (Jason); - Various fixes for EVENT_IDX support; RFC v2 -> RFC v3: - Split into small patches (Jason); - Add helper virtqueue_use_indirect() (Jason); - Just set id for the last descriptor of a list (Jason); - Calculate the prev in virtqueue_add_packed() (Jason); - Fix/improve desc suppression code (Jason/MST); - Refine the code layout for XXX_split/packed and wrappers (MST); - Fix the comments and API in uapi (MST); - Remove the BUG_ON() for indirect (Jason); - Some other refinements and bug fixes; RFC v1 -> RFC v2: - Add indirect descriptor support - compile test only; - Add event suppression supprt - compile test only; - Move vring_packed_init() out of uapi (Jason, MST); - Merge two loops into one in virtqueue_add_packed() (Jason); - Split vring_unmap_one() for packed ring and split ring (Jason); - Avoid using '%' operator (Jason); - Rename free_head -> next_avail_idx (Jason); - Add comments for virtio_wmb() in virtqueue_add_packed() (Jason); - Some other refinements and bug fixes; ==================== Acked-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
02c72d5eda
6 changed files with 1530 additions and 376 deletions
|
@ -129,6 +129,16 @@ static u64 vop_get_features(struct virtio_device *vdev)
|
|||
return features;
|
||||
}
|
||||
|
||||
static void vop_transport_features(struct virtio_device *vdev)
|
||||
{
|
||||
/*
|
||||
* Packed ring isn't enabled on virtio_vop for now,
|
||||
* because virtio_vop uses vring_new_virtqueue() which
|
||||
* creates virtio rings on preallocated memory.
|
||||
*/
|
||||
__virtio_clear_bit(vdev, VIRTIO_F_RING_PACKED);
|
||||
}
|
||||
|
||||
static int vop_finalize_features(struct virtio_device *vdev)
|
||||
{
|
||||
unsigned int i, bits;
|
||||
|
@ -141,6 +151,9 @@ static int vop_finalize_features(struct virtio_device *vdev)
|
|||
/* Give virtio_ring a chance to accept features. */
|
||||
vring_transport_features(vdev);
|
||||
|
||||
/* Give virtio_vop a chance to accept features. */
|
||||
vop_transport_features(vdev);
|
||||
|
||||
memset_io(out_features, 0, feature_len);
|
||||
bits = min_t(unsigned, feature_len,
|
||||
sizeof(vdev->features)) * 8;
|
||||
|
|
|
@ -214,6 +214,16 @@ static u64 rproc_virtio_get_features(struct virtio_device *vdev)
|
|||
return rsc->dfeatures;
|
||||
}
|
||||
|
||||
static void rproc_transport_features(struct virtio_device *vdev)
|
||||
{
|
||||
/*
|
||||
* Packed ring isn't enabled on remoteproc for now,
|
||||
* because remoteproc uses vring_new_virtqueue() which
|
||||
* creates virtio rings on preallocated memory.
|
||||
*/
|
||||
__virtio_clear_bit(vdev, VIRTIO_F_RING_PACKED);
|
||||
}
|
||||
|
||||
static int rproc_virtio_finalize_features(struct virtio_device *vdev)
|
||||
{
|
||||
struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
|
||||
|
@ -224,6 +234,9 @@ static int rproc_virtio_finalize_features(struct virtio_device *vdev)
|
|||
/* Give virtio_ring a chance to accept features */
|
||||
vring_transport_features(vdev);
|
||||
|
||||
/* Give virtio_rproc a chance to accept features. */
|
||||
rproc_transport_features(vdev);
|
||||
|
||||
/* Make sure we don't have any features > 32 bits! */
|
||||
BUG_ON((u32)vdev->features != vdev->features);
|
||||
|
||||
|
|
|
@ -765,6 +765,17 @@ static u64 virtio_ccw_get_features(struct virtio_device *vdev)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static void ccw_transport_features(struct virtio_device *vdev)
|
||||
{
|
||||
/*
|
||||
* Packed ring isn't enabled on virtio_ccw for now,
|
||||
* because virtio_ccw uses some legacy accessors,
|
||||
* e.g. virtqueue_get_avail() and virtqueue_get_used()
|
||||
* which aren't available in packed ring currently.
|
||||
*/
|
||||
__virtio_clear_bit(vdev, VIRTIO_F_RING_PACKED);
|
||||
}
|
||||
|
||||
static int virtio_ccw_finalize_features(struct virtio_device *vdev)
|
||||
{
|
||||
struct virtio_ccw_device *vcdev = to_vc_device(vdev);
|
||||
|
@ -791,6 +802,9 @@ static int virtio_ccw_finalize_features(struct virtio_device *vdev)
|
|||
/* Give virtio_ring a chance to accept features. */
|
||||
vring_transport_features(vdev);
|
||||
|
||||
/* Give virtio_ccw a chance to accept features. */
|
||||
ccw_transport_features(vdev);
|
||||
|
||||
features->index = 0;
|
||||
features->features = cpu_to_le32((u32)vdev->features);
|
||||
/* Write the first half of the feature bits to the host. */
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -75,6 +75,9 @@
|
|||
*/
|
||||
#define VIRTIO_F_IOMMU_PLATFORM 33
|
||||
|
||||
/* This feature indicates support for the packed virtqueue layout. */
|
||||
#define VIRTIO_F_RING_PACKED 34
|
||||
|
||||
/*
|
||||
* Does the device support Single Root I/O Virtualization?
|
||||
*/
|
||||
|
|
|
@ -44,6 +44,13 @@
|
|||
/* This means the buffer contains a list of buffer descriptors. */
|
||||
#define VRING_DESC_F_INDIRECT 4
|
||||
|
||||
/*
|
||||
* Mark a descriptor as available or used in packed ring.
|
||||
* Notice: they are defined as shifts instead of shifted values.
|
||||
*/
|
||||
#define VRING_PACKED_DESC_F_AVAIL 7
|
||||
#define VRING_PACKED_DESC_F_USED 15
|
||||
|
||||
/* The Host uses this in used->flags to advise the Guest: don't kick me when
|
||||
* you add a buffer. It's unreliable, so it's simply an optimization. Guest
|
||||
* will still kick if it's out of buffers. */
|
||||
|
@ -53,6 +60,23 @@
|
|||
* optimization. */
|
||||
#define VRING_AVAIL_F_NO_INTERRUPT 1
|
||||
|
||||
/* Enable events in packed ring. */
|
||||
#define VRING_PACKED_EVENT_FLAG_ENABLE 0x0
|
||||
/* Disable events in packed ring. */
|
||||
#define VRING_PACKED_EVENT_FLAG_DISABLE 0x1
|
||||
/*
|
||||
* Enable events for a specific descriptor in packed ring.
|
||||
* (as specified by Descriptor Ring Change Event Offset/Wrap Counter).
|
||||
* Only valid if VIRTIO_RING_F_EVENT_IDX has been negotiated.
|
||||
*/
|
||||
#define VRING_PACKED_EVENT_FLAG_DESC 0x2
|
||||
|
||||
/*
|
||||
* Wrap counter bit shift in event suppression structure
|
||||
* of packed ring.
|
||||
*/
|
||||
#define VRING_PACKED_EVENT_F_WRAP_CTR 15
|
||||
|
||||
/* We support indirect buffer descriptors */
|
||||
#define VIRTIO_RING_F_INDIRECT_DESC 28
|
||||
|
||||
|
@ -171,4 +195,32 @@ static inline int vring_need_event(__u16 event_idx, __u16 new_idx, __u16 old)
|
|||
return (__u16)(new_idx - event_idx - 1) < (__u16)(new_idx - old);
|
||||
}
|
||||
|
||||
struct vring_packed_desc_event {
|
||||
/* Descriptor Ring Change Event Offset/Wrap Counter. */
|
||||
__le16 off_wrap;
|
||||
/* Descriptor Ring Change Event Flags. */
|
||||
__le16 flags;
|
||||
};
|
||||
|
||||
struct vring_packed_desc {
|
||||
/* Buffer Address. */
|
||||
__le64 addr;
|
||||
/* Buffer Length. */
|
||||
__le32 len;
|
||||
/* Buffer ID. */
|
||||
__le16 id;
|
||||
/* The flags depending on descriptor type. */
|
||||
__le16 flags;
|
||||
};
|
||||
|
||||
struct vring_packed {
|
||||
unsigned int num;
|
||||
|
||||
struct vring_packed_desc *desc;
|
||||
|
||||
struct vring_packed_desc_event *driver;
|
||||
|
||||
struct vring_packed_desc_event *device;
|
||||
};
|
||||
|
||||
#endif /* _UAPI_LINUX_VIRTIO_RING_H */
|
||||
|
|
Loading…
Reference in a new issue