From: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Date: 2022-02-14 08:14:24
The virtio spec already supports the virtio queue reset function. This patch set
is to add this function to the kernel. The relevant virtio spec information is
here:
https://github.com/oasis-tcs/virtio-spec/issues/124
Also regarding MMIO support for queue reset, I plan to support it after this
patch is passed.
Performing reset on a queue is divided into four steps:
1. reset_vq: reset one vq
2. recycle the buffer from vq by virtqueue_detach_unused_buf()
3. release the ring of the vq by vring_release_virtqueue()
4. enable_reset_vq: re-enable the reset queue
#2-#8 : virtio ring support re-enable reset queue and release vring
#9-#14 : virtio PCI support reset queue and re-enable
#15 : add queue reset helper
#16-#17: virtio-net support rx, tx reset
#18-#22: virtio-net support set ringparam
Please review. Thanks.
v5:
1. add virtio-net support set_ringparam
v4:
1. just the code of virtio, without virtio-net
2. Performing reset on a queue is divided into these steps:
1. reset_vq: reset one vq
2. recycle the buffer from vq by virtqueue_detach_unused_buf()
3. release the ring of the vq by vring_release_virtqueue()
4. enable_reset_vq: re-enable the reset queue
3. Simplify the parameters of enable_reset_vq()
4. add container structures for virtio_pci_common_cfg
v3:
1. keep vq, irq unreleased
Xuan Zhuo (22):
virtio_pci: struct virtio_pci_common_cfg add queue_notify_data
virtio: queue_reset: add VIRTIO_F_RING_RESET
virtio_ring: queue_reset: add function vring_setup_virtqueue()
virtio_ring: queue_reset: split: add __vring_init_virtqueue()
virtio_ring: queue_reset: split: support enable reset queue
virtio_ring: queue_reset: packed: support enable reset queue
virtio_ring: queue_reset: extract the release function of the vq ring
virtio_ring: queue_reset: add vring_release_virtqueue()
virtio: queue_reset: struct virtio_config_ops add callbacks for
queue_reset
virtio_pci: queue_reset: update struct virtio_pci_common_cfg and
option functions
virtio_pci: queue_reset: release vq by vp_dev->vqs
virtio_pci: queue_reset: setup_vq() support vring_setup_virtqueue()
virtio_pci: queue_reset: reserve vq->priv for re-enable queue
virtio_pci: queue_reset: support VIRTIO_F_RING_RESET
virtio: queue_reset: add helper
virtio_net: split free_unused_bufs()
virtio_net: support rx/tx queue reset
virtio: add helper virtqueue_get_vring_max_size()
virtio: add helper virtio_set_max_ring_num()
virtio_net: set the default max ring num
virtio_net: get max ring size by virtqueue_get_vring_max_size()
virtio_net: support set_ringparam
drivers/net/virtio_net.c | 238 ++++++++++++++++++++++---
drivers/virtio/virtio_mmio.c | 2 +
drivers/virtio/virtio_pci_common.c | 61 +++++--
drivers/virtio/virtio_pci_common.h | 10 +-
drivers/virtio/virtio_pci_legacy.c | 6 +-
drivers/virtio/virtio_pci_modern.c | 82 ++++++++-
drivers/virtio/virtio_pci_modern_dev.c | 36 ++++
drivers/virtio/virtio_ring.c | 193 +++++++++++++++-----
include/linux/virtio.h | 15 ++
include/linux/virtio_config.h | 82 +++++++++
include/linux/virtio_pci_modern.h | 2 +
include/linux/virtio_ring.h | 37 ++--
include/uapi/linux/virtio_config.h | 7 +-
include/uapi/linux/virtio_pci.h | 14 ++
14 files changed, 668 insertions(+), 117 deletions(-)
--
2.31.0
From: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Date: 2022-02-14 08:14:24
Add queue_notify_data in struct virtio_pci_common_cfg, which comes from
here https://github.com/oasis-tcs/virtio-spec/issues/89
For not breaks uABI, add a new struct virtio_pci_common_cfg_notify.
Since I want to add queue_reset after queue_notify_data, I submitted
this patch first.
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
include/uapi/linux/virtio_pci.h | 7 +++++++
1 file changed, 7 insertions(+)
From: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Date: 2022-02-14 08:14:33
Added vring_release_virtqueue() to release the ring of the vq.
In this process, vq is removed from the vdev->vqs queue. And the memory
of the ring is released
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
drivers/virtio/virtio_ring.c | 18 +++++++++++++++++-
include/linux/virtio.h | 12 ++++++++++++
2 files changed, 29 insertions(+), 1 deletion(-)
From: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Date: 2022-02-14 08:14:34
Performing reset on a queue is divided into four steps:
1. reset_vq: reset one vq
2. recycle the buffer from vq by virtqueue_detach_unused_buf()
3. release the ring of the vq by vring_release_virtqueue()
4. enable_reset_vq: re-enable the reset queue
So add two callbacks reset_vq, enable_reset_vq to struct
virtio_config_ops.
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
include/linux/virtio_config.h | 14 ++++++++++++++
1 file changed, 14 insertions(+)
@@ -100,6 +112,8 @@ struct virtio_config_ops {intindex);bool(*get_shm_region)(structvirtio_device*vdev,structvirtio_shm_region*region,u8id);+int(*reset_vq)(structvirtqueue*vq);+int(*enable_reset_vq)(structvirtqueue*vq);};/* If driver didn't advertise the feature, it will never appear. */
From: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Date: 2022-02-14 08:14:37
Added VIRTIO_F_RING_RESET, it came from here
https://github.com/oasis-tcs/virtio-spec/issues/124
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
include/uapi/linux/virtio_config.h | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
@@ -52,7 +52,7 @@*restareper-devicefeaturebits.*/#define VIRTIO_TRANSPORT_F_START 28-#define VIRTIO_TRANSPORT_F_END 38+#define VIRTIO_TRANSPORT_F_END 41#ifndef VIRTIO_CONFIG_NO_LEGACY/* Do we get callbacks when the ring is completely used, even if we've
@@ -2169,23 +2169,17 @@ irqreturn_t vring_interrupt(int irq, void *_vq)EXPORT_SYMBOL_GPL(vring_interrupt);/* Only available for split ring */-structvirtqueue*__vring_new_virtqueue(unsignedintindex,-structvringvring,-structvirtio_device*vdev,-boolweak_barriers,-boolcontext,-bool(*notify)(structvirtqueue*),-void(*callback)(structvirtqueue*),-constchar*name)+staticint__vring_init_virtqueue(structvirtqueue*_vq,+unsignedintindex,+structvringvring,+structvirtio_device*vdev,+boolweak_barriers,+boolcontext,+bool(*notify)(structvirtqueue*),+void(*callback)(structvirtqueue*),+constchar*name){-structvring_virtqueue*vq;--if(virtio_has_feature(vdev,VIRTIO_F_RING_PACKED))-returnNULL;--vq=kmalloc(sizeof(*vq),GFP_KERNEL);-if(!vq)-returnNULL;+structvring_virtqueue*vq=to_vvq(_vq);vq->packed_ring=false;vq->vq.callback=callback;
@@ -2245,13 +2239,42 @@ struct virtqueue *__vring_new_virtqueue(unsigned int index,spin_lock(&vdev->vqs_list_lock);list_add_tail(&vq->vq.list,&vdev->vqs);spin_unlock(&vdev->vqs_list_lock);-return&vq->vq;+return0;err_extra:kfree(vq->split.desc_state);err_state:-kfree(vq);-returnNULL;+return-ENOMEM;+}++structvirtqueue*__vring_new_virtqueue(unsignedintindex,+structvringvring,+structvirtio_device*vdev,+boolweak_barriers,+boolcontext,+bool(*notify)(structvirtqueue*),+void(*callback)(structvirtqueue*),+constchar*name)+{+structvring_virtqueue*vq;+interr;++if(virtio_has_feature(vdev,VIRTIO_F_RING_PACKED))+returnNULL;++vq=kmalloc(sizeof(*vq),GFP_KERNEL);+if(!vq)+returnNULL;++err=__vring_init_virtqueue(&vq->vq,index,vring,vdev,weak_barriers,+context,notify,callback,name);++if(err){+kfree(vq);+returnNULL;+}++return&vq->vq;}EXPORT_SYMBOL_GPL(__vring_new_virtqueue);
From: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Date: 2022-02-14 08:14:38
Added function vring_setup_virtqueue() to allow passing existing vq
without reallocating vq.
The purpose of adding this function is to not break the form of
vring_create_virtqueue().
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
drivers/virtio/virtio_ring.c | 7 ++++---
include/linux/virtio_ring.h | 37 ++++++++++++++++++++++++++----------
2 files changed, 31 insertions(+), 13 deletions(-)
@@ -2277,7 +2278,7 @@ struct virtqueue *vring_create_virtqueue(vdev,weak_barriers,may_reduce_num,context,notify,callback,name);}-EXPORT_SYMBOL_GPL(vring_create_virtqueue);+EXPORT_SYMBOL_GPL(vring_setup_virtqueue);/* Only available for split ring */structvirtqueue*vring_new_virtqueue(unsignedintindex,
@@ -65,16 +65,33 @@ struct virtqueue;*expected.Thecallershouldqueryvirtqueue_get_vring_sizetolearn*theactualsizeofthering.*/-structvirtqueue*vring_create_virtqueue(unsignedintindex,-unsignedintnum,-unsignedintvring_align,-structvirtio_device*vdev,-boolweak_barriers,-boolmay_reduce_num,-boolctx,-bool(*notify)(structvirtqueue*vq),-void(*callback)(structvirtqueue*vq),-constchar*name);+structvirtqueue*vring_setup_virtqueue(unsignedintindex,+unsignedintnum,+unsignedintvring_align,+structvirtio_device*vdev,+boolweak_barriers,+boolmay_reduce_num,+boolctx,+bool(*notify)(structvirtqueue*vq),+void(*callback)(structvirtqueue*vq),+constchar*name,+structvirtqueue*vq);++staticinlinestructvirtqueue*vring_create_virtqueue(unsignedintindex,+unsignedintnum,+unsignedintvring_align,+structvirtio_device*vdev,+boolweak_barriers,+boolmay_reduce_num,+boolctx,+bool(*notify)(structvirtqueue*vq),+void(*callback)(structvirtqueue*vq),+constchar*name)+{+returnvring_setup_virtqueue(index,num,vring_align,vdev,+weak_barriers,may_reduce_num,ctx,+notify,callback,name,NULL);+}/* Creates a virtqueue with a custom layout. */structvirtqueue*__vring_new_virtqueue(unsignedintindex,
From: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Date: 2022-02-14 08:14:45
Reserve vq->priv during reset. Prevent vp_modern_map_vq_notify() from
being called repeatedly.
Only set vq->priv = NULL in normal setup virtqueue, and keep
vq->priv in the process of re-enable queue.
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
drivers/virtio/virtio_pci_modern.c | 8 +++++---
drivers/virtio/virtio_ring.c | 2 ++
2 files changed, 7 insertions(+), 3 deletions(-)
From: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Date: 2022-02-14 08:14:46
This patch implements virtio pci support for QUEUE RESET.
Performing reset on a queue is divided into these steps:
1. reset_vq: reset one vq
2. recycle the buffer from vq by virtqueue_detach_unused_buf()
3. release the ring of the vq by vring_release_virtqueue()
4. enable_reset_vq: re-enable the reset queue
This patch implements reset_vq, enable_reset_vq in the pci scenario.
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
drivers/virtio/virtio_pci_common.c | 8 ++--
drivers/virtio/virtio_pci_modern.c | 60 ++++++++++++++++++++++++++++++
2 files changed, 65 insertions(+), 3 deletions(-)
From: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Date: 2022-02-14 08:14:50
The purpose of this patch is to make vring split support re-enable reset
vq.
Based on whether the incoming vq passed by vring_setup_virtqueue() is
NULL or not, distinguish whether it is a normal create virtqueue or
re-enable a reset queue.
When re-enable a reset queue, reuse the original callback, name,
indirect.
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
drivers/virtio/virtio_ring.c | 52 +++++++++++++++++++++++++-----------
1 file changed, 37 insertions(+), 15 deletions(-)
@@ -2177,14 +2195,20 @@ static int __vring_init_virtqueue(struct virtqueue *_vq,boolcontext,bool(*notify)(structvirtqueue*),void(*callback)(structvirtqueue*),-constchar*name)+constchar*name,+boolreset){structvring_virtqueue*vq=to_vvq(_vq);+if(!reset){+vq->vq.callback=callback;+vq->vq.name=name;+vq->indirect=virtio_has_feature(vdev,VIRTIO_RING_F_INDIRECT_DESC)&&+!context;+}+vq->packed_ring=false;-vq->vq.callback=callback;vq->vq.vdev=vdev;-vq->vq.name=name;vq->vq.num_free=vring.num;vq->vq.index=index;vq->we_own_ring=false;
@@ -2200,8 +2224,6 @@ static int __vring_init_virtqueue(struct virtqueue *_vq,vq->last_add_time_valid=false;#endif-vq->indirect=virtio_has_feature(vdev,VIRTIO_RING_F_INDIRECT_DESC)&&-!context;vq->event=virtio_has_feature(vdev,VIRTIO_RING_F_EVENT_IDX);if(virtio_has_feature(vdev,VIRTIO_F_ORDER_PLATFORM))
@@ -2215,7 +2237,7 @@ static int __vring_init_virtqueue(struct virtqueue *_vq,vq->split.avail_idx_shadow=0;/* No callback? Tell other side not to bother us. */-if(!callback){+if(!vq->vq.callback){vq->split.avail_flags_shadow|=VRING_AVAIL_F_NO_INTERRUPT;if(!vq->event)vq->split.vring.avail->flags=cpu_to_virtio16(vdev,
@@ -2267,7 +2289,7 @@ struct virtqueue *__vring_new_virtqueue(unsigned int index,returnNULL;err=__vring_init_virtqueue(&vq->vq,index,vring,vdev,weak_barriers,-context,notify,callback,name);+context,notify,callback,name,false);if(err){kfree(vq);
From: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Date: 2022-02-14 08:15:01
The purpose of this patch is to make vring packed support re-enable reset
vq.
Based on whether the incoming vq passed by vring_setup_virtqueue() is
NULL or not, distinguish whether it is a normal create virtqueue or
re-enable a reset queue.
When re-enable a reset queue, reuse the original callback, name, indirect.
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
drivers/virtio/virtio_ring.c | 29 ++++++++++++++++++-----------
1 file changed, 18 insertions(+), 11 deletions(-)
@@ -1778,7 +1784,7 @@ static struct virtqueue *vring_create_virtqueue_packed(gotoerr_desc_extra;/* No callback? Tell other side not to bother us. */-if(!callback){+if(!vq->vq.callback){vq->packed.event_flags_shadow=VRING_PACKED_EVENT_FLAG_DISABLE;vq->packed.vring.driver->flags=cpu_to_le16(vq->packed.event_flags_shadow);
From: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Date: 2022-02-14 08:15:01
This patch separates two functions for freeing sq buf and rq buf from
free_unused_bufs().
When supporting the enable/disable tx/rq queue in the future, it is
necessary to support separate recovery of a sq buf or a rq buf.
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
drivers/net/virtio_net.c | 53 +++++++++++++++++++++++-----------------
1 file changed, 31 insertions(+), 22 deletions(-)
From: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Date: 2022-02-14 08:15:02
Add queue_reset in virtio_pci_common_cfg, and add related operation
functions.
For not breaks uABI, add a new struct virtio_pci_common_cfg_reset.
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
drivers/virtio/virtio_pci_modern_dev.c | 36 ++++++++++++++++++++++++++
include/linux/virtio_pci_modern.h | 2 ++
include/uapi/linux/virtio_pci.h | 7 +++++
3 files changed, 45 insertions(+)
From: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Date: 2022-02-14 08:15:02
Added helper virtio_set_max_ring_num() to set the upper limit of ring
num when creating a virtqueue.
Can be used to limit ring num before find_vqs() call. Or change ring num
when re-enable reset queue.
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
drivers/virtio/virtio_ring.c | 6 ++++++
include/linux/virtio.h | 1 +
include/linux/virtio_config.h | 30 ++++++++++++++++++++++++++++++
3 files changed, 37 insertions(+)
@@ -943,6 +943,9 @@ static struct virtqueue *vring_create_virtqueue_split(size_tqueue_size_in_bytes;structvringvring;+if(vdev->max_ring_num&&num>vdev->max_ring_num)+num=vdev->max_ring_num;+/* We assume num is a power of 2. */if(num&(num-1)){dev_warn(&vdev->dev,"Bad virtqueue length %u\n",num);
From: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Date: 2022-02-14 08:15:03
Sets the default maximum ring num based on virtio_set_max_ring_num().
The default maximum ring num is 1024.
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
drivers/net/virtio_net.c | 4 ++++
1 file changed, 4 insertions(+)
From: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Date: 2022-02-14 08:15:03
Support set_ringparam based on virtio queue reset.
The rx,tx_pending required to be passed must be power of 2.
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
drivers/net/virtio_net.c | 50 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
From: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Date: 2022-02-14 08:15:04
Record the maximum queue num supported by the device.
virtio-net can display the maximum (supported by hardware) ring size in
ethtool -g eth0.
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
drivers/virtio/virtio_mmio.c | 2 ++
drivers/virtio/virtio_pci_legacy.c | 2 ++
drivers/virtio/virtio_pci_modern.c | 2 ++
drivers/virtio/virtio_ring.c | 13 +++++++++++++
include/linux/virtio.h | 2 ++
5 files changed, 21 insertions(+)
@@ -205,28 +205,33 @@ static int vp_request_msix_vectors(struct virtio_device *vdev, int nvectors,returnerr;}-staticstructvirtqueue*vp_setup_vq(structvirtio_device*vdev,unsignedindex,-void(*callback)(structvirtqueue*vq),-constchar*name,-boolctx,-u16msix_vec)+structvirtqueue*vp_setup_vq(structvirtio_device*vdev,unsignedintindex,+void(*callback)(structvirtqueue*vq),+constchar*name,+boolctx,+u16msix_vec){structvirtio_pci_device*vp_dev=to_vp_device(vdev);-structvirtio_pci_vq_info*info=kmalloc(sizeof*info,GFP_KERNEL);+structvirtio_pci_vq_info*info;structvirtqueue*vq;unsignedlongflags;-/* fill out our structure that represents an active queue */-if(!info)-returnERR_PTR(-ENOMEM);+info=vp_dev->vqs[index];+if(!info){+info=kzalloc(sizeof(*info),GFP_KERNEL);++/* fill out our structure that represents an active queue */+if(!info)+returnERR_PTR(-ENOMEM);+}vq=vp_dev->setup_vq(vp_dev,info,index,callback,name,ctx,-msix_vec);+msix_vec,info->vq);if(IS_ERR(vq))gotoout_info;info->vq=vq;-if(callback){+if(vq->callback){spin_lock_irqsave(&vp_dev->lock,flags);list_add(&info->node,&vp_dev->virtqueues);spin_unlock_irqrestore(&vp_dev->lock,flags);
@@ -117,6 +118,11 @@ int vp_find_vqs(struct virtio_device *vdev, unsigned nvqs,structvirtqueue*vqs[],vq_callback_t*callbacks[],constchar*constnames[],constbool*ctx,structirq_affinity*desc);+structvirtqueue*vp_setup_vq(structvirtio_device*vdev,unsignedintindex,+void(*callback)(structvirtqueue*vq),+constchar*name,+boolctx,+u16msix_vec);constchar*vp_bus_name(structvirtio_device*vdev);/* Setup the affinity for a virtqueue:
From: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Date: 2022-02-14 08:15:05
In the process of queue reset, vq leaves vdev->vqs, so the original
processing logic may miss some vq. So modify the processing method of
releasing vq. Release vq by listing vqs.
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
drivers/virtio/virtio_pci_common.c | 22 ++++++++++++++++++----
drivers/virtio/virtio_pci_common.h | 2 ++
2 files changed, 20 insertions(+), 4 deletions(-)
@@ -324,6 +334,8 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs,if(!vp_dev->vqs)return-ENOMEM;+vp_dev->nvqs=nvqs;+if(per_vq_vectors){/* Best option: one for change interrupt, one per vq. */nvectors=1;
@@ -60,6 +60,8 @@ struct virtio_pci_device {/* array of all queues for house-keeping */structvirtio_pci_vq_info**vqs;+u32nvqs;+/* MSI-X support */intmsix_enabled;intintx_enabled;
From: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Date: 2022-02-14 08:15:11
This patch implements the reset function of the rx, tx queues.
Based on this function, it is possible to modify the ring num of the
queue. And quickly recycle the buffer in the queue.
In the process of the queue disable, in theory, as long as virtio
supports queue reset, there will be no exceptions.
However, in the process of the queue enable, there may be exceptions due to
memory allocation. In this case, vq is not available, but we still have
to execute napi_enable(). Because napi_disable is similar to a lock,
napi_enable must be called after calling napi_disable.
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
drivers/net/virtio_net.c | 123 +++++++++++++++++++++++++++++++++++++++
1 file changed, 123 insertions(+)
@@ -1369,6 +1374,9 @@ static void virtnet_napi_enable(struct virtqueue *vq, struct napi_struct *napi){napi_enable(napi);+if(vq->reset)+return;+/* If all buffers were filled by other side before we napi_enabled, we*won'tgetanotherinterrupt,soprocessanyoutstandingpacketsnow.*Calllocal_bh_enableaftertotriggersoftIRQprocessing.
From: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Date: 2022-02-14 08:15:29
Use virtqueue_get_vring_max_size() in virtnet_get_ringparam() to set
tx,rx_max_pending.
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
drivers/net/virtio_net.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
From: Jason Wang <hidden> Date: 2022-02-16 04:14:22
On Mon, Feb 14, 2022 at 4:15 PM Xuan Zhuo [off-list ref] wrote:
Added helper virtio_set_max_ring_num() to set the upper limit of ring
num when creating a virtqueue.
Can be used to limit ring num before find_vqs() call. Or change ring num
when re-enable reset queue.
Do we have a chance that RX and TX may want different ring size? If
yes, it might be even better to have per vq limit via find_vqs()?
@@ -943,6 +943,9 @@ static struct virtqueue *vring_create_virtqueue_split(size_tqueue_size_in_bytes;structvringvring;+if(vdev->max_ring_num&&num>vdev->max_ring_num)+num=vdev->max_ring_num;+/* We assume num is a power of 2. */if(num&(num-1)){dev_warn(&vdev->dev,"Bad virtqueue length %u\n",num);
Having a dedicated helper for a per device parameter usually means the
use cases are greatly limited. For example, this seems can only be
used when DRIVER_OK is not set?
And in patch 17 this function is called even if we only modify the RX
size, this is probably another call for a more flexible API as I
suggest like exporting vring allocation/deallocation helper and extend
find_vqs()?
Thanks
From: Jason Wang <hidden> Date: 2022-02-16 04:14:32
On Mon, Feb 14, 2022 at 4:14 PM Xuan Zhuo [off-list ref] wrote:
quoted hunk
This patch implements the reset function of the rx, tx queues.
Based on this function, it is possible to modify the ring num of the
queue. And quickly recycle the buffer in the queue.
In the process of the queue disable, in theory, as long as virtio
supports queue reset, there will be no exceptions.
However, in the process of the queue enable, there may be exceptions due to
memory allocation. In this case, vq is not available, but we still have
to execute napi_enable(). Because napi_disable is similar to a lock,
napi_enable must be called after calling napi_disable.
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
drivers/net/virtio_net.c | 123 +++++++++++++++++++++++++++++++++++++++
1 file changed, 123 insertions(+)
@@ -1369,6 +1374,9 @@ static void virtnet_napi_enable(struct virtqueue *vq, struct napi_struct *napi){napi_enable(napi);+if(vq->reset)+return;+/* If all buffers were filled by other side before we napi_enabled, we*won'tgetanotherinterrupt,soprocessanyoutstandingpacketsnow.*Calllocal_bh_enableaftertotriggersoftIRQprocessing.
So the API should be design in a consistent way.
In rx_vq_disable() we do:
reset()
detach_unused_bufs()
vring_release_virtqueue()
here it's better to exactly the reverse
vring_attach_virtqueue() // this is the helper I guess in patch 5,
reverse of the vring_release_virtqueue()
try_refill_recv() // reverse of the detach_unused_bufs()
enable_reset() // reverse of the reset
So did for the tx (no need for refill in that case).
+
+ err = virtio_enable_resetq(rq->vq);
+
+ virtnet_napi_enable(rq->vq, &rq->napi);
+
+ return err;
+}
+
+static int virtnet_rx_vq_reset(struct virtnet_info *vi, int i)
+{
+ int err;
+
+ err = virtnet_rx_vq_disable(vi, vi->rq + i);
+ if (err)
+ return err;
+
+ err = virtnet_rx_vq_enable(vi, vi->rq + i);
+ if (err)
+ netdev_err(vi->dev,
+ "enable rx reset vq fail: rx queue index: %d err: %d\n", i, err);
+ return err;
+}
+
+static int virtnet_tx_vq_reset(struct virtnet_info *vi, int i)
+{
+ int err;
+
+ err = virtnet_tx_vq_disable(vi, vi->sq + i);
+ if (err)
+ return err;
+
+ err = virtnet_tx_vq_enable(vi, vi->sq + i);
+ if (err)
+ netdev_err(vi->dev,
+ "enable tx reset vq fail: tx queue index: %d err: %d\n", i, err);
+ return err;
+}
+
/*
* Send command via the control virtqueue and check status. Commands
* supported by the hypervisor, as indicated by feature bits, should
--
2.31.0
From: Jason Wang <hidden> Date: 2022-02-16 04:14:38
On Mon, Feb 14, 2022 at 4:14 PM Xuan Zhuo [off-list ref] wrote:
quoted hunk
The purpose of this patch is to make vring packed support re-enable reset
vq.
Based on whether the incoming vq passed by vring_setup_virtqueue() is
NULL or not, distinguish whether it is a normal create virtqueue or
re-enable a reset queue.
When re-enable a reset queue, reuse the original callback, name, indirect.
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
drivers/virtio/virtio_ring.c | 29 ++++++++++++++++++-----------
1 file changed, 18 insertions(+), 11 deletions(-)
The code looks tricky. Except for the memory we don't even need to
touch any of the other attributes.
I'd suggest splitting out the vring allocation into a dedicated helper
that could be called by both vring_create_queue_XXX and the enable()
logic (and in the enable logic we don't even need to relocate if size
is not changed).
Thanks
@@ -1778,7 +1784,7 @@ static struct virtqueue *vring_create_virtqueue_packed( goto err_desc_extra; /* No callback? Tell other side not to bother us. */- if (!callback) {+ if (!vq->vq.callback) { vq->packed.event_flags_shadow = VRING_PACKED_EVENT_FLAG_DISABLE; vq->packed.vring.driver->flags = cpu_to_le16(vq->packed.event_flags_shadow);
From: Jason Wang <hidden> Date: 2022-02-16 04:14:44
On Mon, Feb 14, 2022 at 4:14 PM Xuan Zhuo [off-list ref] wrote:
quoted hunk
This patch implements virtio pci support for QUEUE RESET.
Performing reset on a queue is divided into these steps:
1. reset_vq: reset one vq
2. recycle the buffer from vq by virtqueue_detach_unused_buf()
3. release the ring of the vq by vring_release_virtqueue()
4. enable_reset_vq: re-enable the reset queue
This patch implements reset_vq, enable_reset_vq in the pci scenario.
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
drivers/virtio/virtio_pci_common.c | 8 ++--
drivers/virtio/virtio_pci_modern.c | 60 ++++++++++++++++++++++++++++++
2 files changed, 65 insertions(+), 3 deletions(-)
So we only care about moden devices, this means using vp_setup_vq()
with NULL seems tricky.
As replied in another thread, I would simply ask the caller to call
the vring reallocation helper. See the reply for patch 17.
Thanks
From: Jason Wang <hidden> Date: 2022-02-16 04:14:49
On Mon, Feb 14, 2022 at 4:14 PM Xuan Zhuo [off-list ref] wrote:
Sets the default maximum ring num based on virtio_set_max_ring_num().
The default maximum ring num is 1024.
Having a default value is pretty useful, I see 32K is used by default for IFCVF.
Rethink this, how about having a different default value based on the speed?
Without SPEED_DUPLEX, we use 1024. Otherwise
10g 4096
40g 8192
etc.
(The number are just copied from the 10g/40g default parameter from
other vendors)
Thanks
From: Jason Wang <hidden> Date: 2022-02-16 04:14:54
On Mon, Feb 14, 2022 at 4:14 PM Xuan Zhuo [off-list ref] wrote:
quoted hunk
Added vring_release_virtqueue() to release the ring of the vq.
In this process, vq is removed from the vdev->vqs queue. And the memory
of the ring is released
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
drivers/virtio/virtio_ring.c | 18 +++++++++++++++++-
include/linux/virtio.h | 12 ++++++++++++
2 files changed, 29 insertions(+), 1 deletion(-)
So we don't have a similar check for detach_unused_buf(), I guess it
should be sufficient to document the API requirement. Otherwise we
probably need some barriers/ordering which are not worthwhile just for
figuring out bad API usage.
From: Jason Wang <hidden> Date: 2022-02-16 04:14:58
On Mon, Feb 14, 2022 at 4:15 PM Xuan Zhuo [off-list ref] wrote:
quoted hunk
Support set_ringparam based on virtio queue reset.
The rx,tx_pending required to be passed must be power of 2.
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
drivers/net/virtio_net.c | 50 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
We'd better leave those checks to the virtio core where it knows
packed virtqueue doesn't have this limitation.
+
+ for (i = 0; i < vi->max_queue_pairs; i++) {
+ if (ring->tx_pending != tx_pending) {
+ virtio_set_max_ring_num(vi->vdev, ring->tx_pending);
The name is kind of confusing, I guess it should not be the maximum
ring. And this needs to be done after the reset, and it would be even
better to disallow such change when virtqueue is not resetted.
From: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Date: 2022-02-16 07:21:55
On Wed, 16 Feb 2022 12:14:39 +0800, Jason Wang [off-list ref] wrote:
On Mon, Feb 14, 2022 at 4:15 PM Xuan Zhuo [off-list ref] wrote:
quoted
Support set_ringparam based on virtio queue reset.
The rx,tx_pending required to be passed must be power of 2.
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
drivers/net/virtio_net.c | 50 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
We'd better leave those checks to the virtio core where it knows
packed virtqueue doesn't have this limitation.
OK.
quoted
+
+ for (i = 0; i < vi->max_queue_pairs; i++) {
+ if (ring->tx_pending != tx_pending) {
+ virtio_set_max_ring_num(vi->vdev, ring->tx_pending);
The name is kind of confusing, I guess it should not be the maximum
ring. And this needs to be done after the reset, and it would be even
better to disallow such change when virtqueue is not resetted.
From: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Date: 2022-02-16 07:53:20
On Wed, 16 Feb 2022 12:14:31 +0800, Jason Wang [off-list ref] wrote:
On Mon, Feb 14, 2022 at 4:14 PM Xuan Zhuo [off-list ref] wrote:
quoted
Sets the default maximum ring num based on virtio_set_max_ring_num().
The default maximum ring num is 1024.
Having a default value is pretty useful, I see 32K is used by default for IFCVF.
Rethink this, how about having a different default value based on the speed?
Without SPEED_DUPLEX, we use 1024. Otherwise
10g 4096
40g 8192
We can define different default values of tx and rx by the way. This way I can
just use it in the new interface of find_vqs().
without SPEED_DUPLEX: tx 512 rx 1024
Thanks.
etc.
(The number are just copied from the 10g/40g default parameter from
other vendors)
Thanks
From: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Date: 2022-02-16 07:55:01
On Wed, 16 Feb 2022 12:14:04 +0800, Jason Wang [off-list ref] wrote:
On Mon, Feb 14, 2022 at 4:15 PM Xuan Zhuo [off-list ref] wrote:
quoted
Added helper virtio_set_max_ring_num() to set the upper limit of ring
num when creating a virtqueue.
Can be used to limit ring num before find_vqs() call. Or change ring num
when re-enable reset queue.
Do we have a chance that RX and TX may want different ring size? If
yes, it might be even better to have per vq limit via find_vqs()?
@@ -943,6 +943,9 @@ static struct virtqueue *vring_create_virtqueue_split(size_tqueue_size_in_bytes;structvringvring;+if(vdev->max_ring_num&&num>vdev->max_ring_num)+num=vdev->max_ring_num;+/* We assume num is a power of 2. */if(num&(num-1)){dev_warn(&vdev->dev,"Bad virtqueue length %u\n",num);
Having a dedicated helper for a per device parameter usually means the
use cases are greatly limited. For example, this seems can only be
used when DRIVER_OK is not set?
And in patch 17 this function is called even if we only modify the RX
size, this is probably another call for a more flexible API as I
suggest like exporting vring allocation/deallocation helper and extend
find_vqs()?
From: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Date: 2022-02-16 08:03:05
On Wed, 16 Feb 2022 12:14:11 +0800, Jason Wang [off-list ref] wrote:
On Mon, Feb 14, 2022 at 4:14 PM Xuan Zhuo [off-list ref] wrote:
quoted
This patch implements the reset function of the rx, tx queues.
Based on this function, it is possible to modify the ring num of the
queue. And quickly recycle the buffer in the queue.
In the process of the queue disable, in theory, as long as virtio
supports queue reset, there will be no exceptions.
However, in the process of the queue enable, there may be exceptions due to
memory allocation. In this case, vq is not available, but we still have
to execute napi_enable(). Because napi_disable is similar to a lock,
napi_enable must be called after calling napi_disable.
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
drivers/net/virtio_net.c | 123 +++++++++++++++++++++++++++++++++++++++
1 file changed, 123 insertions(+)
@@ -1369,6 +1374,9 @@ static void virtnet_napi_enable(struct virtqueue *vq, struct napi_struct *napi){napi_enable(napi);+if(vq->reset)+return;+/* If all buffers were filled by other side before we napi_enabled, we*won'tgetanotherinterrupt,soprocessanyoutstandingpacketsnow.*Calllocal_bh_enableaftertotriggersoftIRQprocessing.
So the API should be design in a consistent way.
In rx_vq_disable() we do:
reset()
detach_unused_bufs()
vring_release_virtqueue()
here it's better to exactly the reverse
vring_attach_virtqueue() // this is the helper I guess in patch 5,
reverse of the vring_release_virtqueue()
try_refill_recv() // reverse of the detach_unused_bufs()
enable_reset() // reverse of the reset
Such an api is ok
1. reset()
2. detach_unused_bufs()
3. vring_release_virtqueue()
---------------
4. vring_attach_virtqueue()
5. try_refill_recv()
6. enable_reset()
But if, we just want to recycle the buffer without modifying the ring num. As
you mentioned before, in the case where the ring num is not modified, we don't
have to reallocate, but can use the original vring.
1. reset()
2. detach_unused_bufs()
---------------
3. vring_reset_virtqueue() // just reset, no reallocate
4. try_refill_recv()
5. enable_reset()
Thanks.
So did for the tx (no need for refill in that case).
quoted
+
+ err = virtio_enable_resetq(rq->vq);
+
+ virtnet_napi_enable(rq->vq, &rq->napi);
+
+ return err;
+}
+
+static int virtnet_rx_vq_reset(struct virtnet_info *vi, int i)
+{
+ int err;
+
+ err = virtnet_rx_vq_disable(vi, vi->rq + i);
+ if (err)
+ return err;
+
+ err = virtnet_rx_vq_enable(vi, vi->rq + i);
+ if (err)
+ netdev_err(vi->dev,
+ "enable rx reset vq fail: rx queue index: %d err: %d\n", i, err);
+ return err;
+}
+
+static int virtnet_tx_vq_reset(struct virtnet_info *vi, int i)
+{
+ int err;
+
+ err = virtnet_tx_vq_disable(vi, vi->sq + i);
+ if (err)
+ return err;
+
+ err = virtnet_tx_vq_enable(vi, vi->sq + i);
+ if (err)
+ netdev_err(vi->dev,
+ "enable tx reset vq fail: tx queue index: %d err: %d\n", i, err);
+ return err;
+}
+
/*
* Send command via the control virtqueue and check status. Commands
* supported by the hypervisor, as indicated by feature bits, should
--
2.31.0
From: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Date: 2022-02-16 08:08:11
On Wed, 16 Feb 2022 12:14:25 +0800, Jason Wang [off-list ref] wrote:
On Mon, Feb 14, 2022 at 4:14 PM Xuan Zhuo [off-list ref] wrote:
quoted
This patch implements virtio pci support for QUEUE RESET.
Performing reset on a queue is divided into these steps:
1. reset_vq: reset one vq
2. recycle the buffer from vq by virtqueue_detach_unused_buf()
3. release the ring of the vq by vring_release_virtqueue()
4. enable_reset_vq: re-enable the reset queue
This patch implements reset_vq, enable_reset_vq in the pci scenario.
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
drivers/virtio/virtio_pci_common.c | 8 ++--
drivers/virtio/virtio_pci_modern.c | 60 ++++++++++++++++++++++++++++++
2 files changed, 65 insertions(+), 3 deletions(-)
Any reason that we don't need to disable irq here as the previous versions did?
Based on the spec, for the case of one interrupt per queue, there will be no
more interrupts after the reset queue operation. Whether the interrupt is turned
off or not has no effect. I turned off the interrupt before just to be safe.
And for irq sharing scenarios, I don't want to turn off shared interrupts for a
queue.
And the following list_del has been guaranteed to be safe, so I removed the code
for closing interrupts in the previous version.
Thanks.
So we only care about moden devices, this means using vp_setup_vq()
with NULL seems tricky.
As replied in another thread, I would simply ask the caller to call
the vring reallocation helper. See the reply for patch 17.
Thanks
From: "Michael S. Tsirkin" <mst@redhat.com> Date: 2022-02-16 08:35:13
On Wed, Feb 16, 2022 at 03:56:13PM +0800, Xuan Zhuo wrote:
On Wed, 16 Feb 2022 12:14:11 +0800, Jason Wang [off-list ref] wrote:
quoted
On Mon, Feb 14, 2022 at 4:14 PM Xuan Zhuo [off-list ref] wrote:
quoted
This patch implements the reset function of the rx, tx queues.
Based on this function, it is possible to modify the ring num of the
queue. And quickly recycle the buffer in the queue.
In the process of the queue disable, in theory, as long as virtio
supports queue reset, there will be no exceptions.
However, in the process of the queue enable, there may be exceptions due to
memory allocation. In this case, vq is not available, but we still have
to execute napi_enable(). Because napi_disable is similar to a lock,
napi_enable must be called after calling napi_disable.
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
drivers/net/virtio_net.c | 123 +++++++++++++++++++++++++++++++++++++++
1 file changed, 123 insertions(+)
@@ -1369,6 +1374,9 @@ static void virtnet_napi_enable(struct virtqueue *vq, struct napi_struct *napi){napi_enable(napi);+if(vq->reset)+return;+/* If all buffers were filled by other side before we napi_enabled, we*won'tgetanotherinterrupt,soprocessanyoutstandingpacketsnow.*Calllocal_bh_enableaftertotriggersoftIRQprocessing.
So the API should be design in a consistent way.
In rx_vq_disable() we do:
reset()
detach_unused_bufs()
vring_release_virtqueue()
here it's better to exactly the reverse
vring_attach_virtqueue() // this is the helper I guess in patch 5,
reverse of the vring_release_virtqueue()
try_refill_recv() // reverse of the detach_unused_bufs()
enable_reset() // reverse of the reset
Such an api is ok
1. reset()
2. detach_unused_bufs()
3. vring_release_virtqueue()
---------------
4. vring_attach_virtqueue()
5. try_refill_recv()
6. enable_reset()
But if, we just want to recycle the buffer without modifying the ring num. As
you mentioned before, in the case where the ring num is not modified, we don't
have to reallocate, but can use the original vring.
1. reset()
2. detach_unused_bufs()
---------------
3. vring_reset_virtqueue() // just reset, no reallocate
4. try_refill_recv()
5. enable_reset()
Thanks.
Further, can we queue the buffers instead of detach_unused_bufs
and just requeue them instead of try_refill_recv?
quoted
So did for the tx (no need for refill in that case).
quoted
+
+ err = virtio_enable_resetq(rq->vq);
+
+ virtnet_napi_enable(rq->vq, &rq->napi);
+
+ return err;
+}
+
+static int virtnet_rx_vq_reset(struct virtnet_info *vi, int i)
+{
+ int err;
+
+ err = virtnet_rx_vq_disable(vi, vi->rq + i);
+ if (err)
+ return err;
+
+ err = virtnet_rx_vq_enable(vi, vi->rq + i);
+ if (err)
+ netdev_err(vi->dev,
+ "enable rx reset vq fail: rx queue index: %d err: %d\n", i, err);
+ return err;
+}
+
+static int virtnet_tx_vq_reset(struct virtnet_info *vi, int i)
+{
+ int err;
+
+ err = virtnet_tx_vq_disable(vi, vi->sq + i);
+ if (err)
+ return err;
+
+ err = virtnet_tx_vq_enable(vi, vi->sq + i);
+ if (err)
+ netdev_err(vi->dev,
+ "enable tx reset vq fail: tx queue index: %d err: %d\n", i, err);
+ return err;
+}
+
/*
* Send command via the control virtqueue and check status. Commands
* supported by the hypervisor, as indicated by feature bits, should
--
2.31.0
From: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Date: 2022-02-16 08:44:54
On Wed, 16 Feb 2022 03:35:01 -0500, "Michael S. Tsirkin" [off-list ref] wrote:
On Wed, Feb 16, 2022 at 03:56:13PM +0800, Xuan Zhuo wrote:
quoted
On Wed, 16 Feb 2022 12:14:11 +0800, Jason Wang [off-list ref] wrote:
quoted
On Mon, Feb 14, 2022 at 4:14 PM Xuan Zhuo [off-list ref] wrote:
quoted
This patch implements the reset function of the rx, tx queues.
Based on this function, it is possible to modify the ring num of the
queue. And quickly recycle the buffer in the queue.
In the process of the queue disable, in theory, as long as virtio
supports queue reset, there will be no exceptions.
However, in the process of the queue enable, there may be exceptions due to
memory allocation. In this case, vq is not available, but we still have
to execute napi_enable(). Because napi_disable is similar to a lock,
napi_enable must be called after calling napi_disable.
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
drivers/net/virtio_net.c | 123 +++++++++++++++++++++++++++++++++++++++
1 file changed, 123 insertions(+)
@@ -1369,6 +1374,9 @@ static void virtnet_napi_enable(struct virtqueue *vq, struct napi_struct *napi){napi_enable(napi);+if(vq->reset)+return;+/* If all buffers were filled by other side before we napi_enabled, we*won'tgetanotherinterrupt,soprocessanyoutstandingpacketsnow.*Calllocal_bh_enableaftertotriggersoftIRQprocessing.
So the API should be design in a consistent way.
In rx_vq_disable() we do:
reset()
detach_unused_bufs()
vring_release_virtqueue()
here it's better to exactly the reverse
vring_attach_virtqueue() // this is the helper I guess in patch 5,
reverse of the vring_release_virtqueue()
try_refill_recv() // reverse of the detach_unused_bufs()
enable_reset() // reverse of the reset
Such an api is ok
1. reset()
2. detach_unused_bufs()
3. vring_release_virtqueue()
---------------
4. vring_attach_virtqueue()
5. try_refill_recv()
6. enable_reset()
But if, we just want to recycle the buffer without modifying the ring num. As
you mentioned before, in the case where the ring num is not modified, we don't
have to reallocate, but can use the original vring.
1. reset()
2. detach_unused_bufs()
---------------
3. vring_reset_virtqueue() // just reset, no reallocate
4. try_refill_recv()
5. enable_reset()
Thanks.
Further, can we queue the buffers instead of detach_unused_bufs
and just requeue them instead of try_refill_recv?
I think this is a good note, for support set_ringparam, this will be more
friendly.
I think I can implement this after the support for AF_XDP is done.
Thanks.
quoted
quoted
So did for the tx (no need for refill in that case).
quoted
+
+ err = virtio_enable_resetq(rq->vq);
+
+ virtnet_napi_enable(rq->vq, &rq->napi);
+
+ return err;
+}
+
+static int virtnet_rx_vq_reset(struct virtnet_info *vi, int i)
+{
+ int err;
+
+ err = virtnet_rx_vq_disable(vi, vi->rq + i);
+ if (err)
+ return err;
+
+ err = virtnet_rx_vq_enable(vi, vi->rq + i);
+ if (err)
+ netdev_err(vi->dev,
+ "enable rx reset vq fail: rx queue index: %d err: %d\n", i, err);
+ return err;
+}
+
+static int virtnet_tx_vq_reset(struct virtnet_info *vi, int i)
+{
+ int err;
+
+ err = virtnet_tx_vq_disable(vi, vi->sq + i);
+ if (err)
+ return err;
+
+ err = virtnet_tx_vq_enable(vi, vi->sq + i);
+ if (err)
+ netdev_err(vi->dev,
+ "enable tx reset vq fail: tx queue index: %d err: %d\n", i, err);
+ return err;
+}
+
/*
* Send command via the control virtqueue and check status. Commands
* supported by the hypervisor, as indicated by feature bits, should
--
2.31.0
From: Jason Wang <hidden> Date: 2022-02-17 07:21:44
On Wed, Feb 16, 2022 at 3:52 PM Xuan Zhuo [off-list ref] wrote:
On Wed, 16 Feb 2022 12:14:31 +0800, Jason Wang [off-list ref] wrote:
quoted
On Mon, Feb 14, 2022 at 4:14 PM Xuan Zhuo [off-list ref] wrote:
quoted
Sets the default maximum ring num based on virtio_set_max_ring_num().
The default maximum ring num is 1024.
Having a default value is pretty useful, I see 32K is used by default for IFCVF.
Rethink this, how about having a different default value based on the speed?
Without SPEED_DUPLEX, we use 1024. Otherwise
10g 4096
40g 8192
We can define different default values of tx and rx by the way. This way I can
just use it in the new interface of find_vqs().
without SPEED_DUPLEX: tx 512 rx 1024
Any reason that TX is smaller than RX?
Thanks
Thanks.
quoted
etc.
(The number are just copied from the 10g/40g default parameter from
other vendors)
Thanks
From: Jason Wang <hidden> Date: 2022-02-17 07:25:34
On Wed, Feb 16, 2022 at 4:08 PM Xuan Zhuo [off-list ref] wrote:
On Wed, 16 Feb 2022 12:14:25 +0800, Jason Wang [off-list ref] wrote:
quoted
On Mon, Feb 14, 2022 at 4:14 PM Xuan Zhuo [off-list ref] wrote:
quoted
This patch implements virtio pci support for QUEUE RESET.
Performing reset on a queue is divided into these steps:
1. reset_vq: reset one vq
2. recycle the buffer from vq by virtqueue_detach_unused_buf()
3. release the ring of the vq by vring_release_virtqueue()
4. enable_reset_vq: re-enable the reset queue
This patch implements reset_vq, enable_reset_vq in the pci scenario.
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
drivers/virtio/virtio_pci_common.c | 8 ++--
drivers/virtio/virtio_pci_modern.c | 60 ++++++++++++++++++++++++++++++
2 files changed, 65 insertions(+), 3 deletions(-)
Any reason that we don't need to disable irq here as the previous versions did?
Based on the spec, for the case of one interrupt per queue, there will be no
more interrupts after the reset queue operation. Whether the interrupt is turned
off or not has no effect. I turned off the interrupt before just to be safe.
So:
1) CPU0 -> get an interrupt
2) CPU1 -> vp_modern_reset_vq
2) CPU0 -> do_IRQ()
We still need to synchronize with the irq handler in this case?
Thanks
And for irq sharing scenarios, I don't want to turn off shared interrupts for a
queue.
And the following list_del has been guaranteed to be safe, so I removed the code
for closing interrupts in the previous version.
Thanks.
So we only care about moden devices, this means using vp_setup_vq()
with NULL seems tricky.
As replied in another thread, I would simply ask the caller to call
the vring reallocation helper. See the reply for patch 17.
From: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Date: 2022-02-17 09:38:15
On Thu, 17 Feb 2022 15:21:26 +0800, Jason Wang [off-list ref] wrote:
On Wed, Feb 16, 2022 at 3:52 PM Xuan Zhuo [off-list ref] wrote:
quoted
On Wed, 16 Feb 2022 12:14:31 +0800, Jason Wang [off-list ref] wrote:
quoted
On Mon, Feb 14, 2022 at 4:14 PM Xuan Zhuo [off-list ref] wrote:
quoted
Sets the default maximum ring num based on virtio_set_max_ring_num().
The default maximum ring num is 1024.
Having a default value is pretty useful, I see 32K is used by default for IFCVF.
Rethink this, how about having a different default value based on the speed?
Without SPEED_DUPLEX, we use 1024. Otherwise
10g 4096
40g 8192
We can define different default values of tx and rx by the way. This way I can
just use it in the new interface of find_vqs().
without SPEED_DUPLEX: tx 512 rx 1024
Any reason that TX is smaller than RX?
I've seen some NIC drivers with default tx smaller than rx.
One problem I have now is that inside virtnet_probe, init_vqs is before getting
speed/duplex. I'm not sure, can the logic to get speed/duplex be put before
init_vqs? Is there any risk?
Can you help me?
Thanks.
Thanks
quoted
Thanks.
quoted
etc.
(The number are just copied from the 10g/40g default parameter from
other vendors)
Thanks
From: Jason Wang <hidden> Date: 2022-02-21 03:40:32
在 2022/2/17 下午5:30, Xuan Zhuo 写道:
On Thu, 17 Feb 2022 15:21:26 +0800, Jason Wang [off-list ref] wrote:
quoted
On Wed, Feb 16, 2022 at 3:52 PM Xuan Zhuo [off-list ref] wrote:
quoted
On Wed, 16 Feb 2022 12:14:31 +0800, Jason Wang [off-list ref] wrote:
quoted
On Mon, Feb 14, 2022 at 4:14 PM Xuan Zhuo [off-list ref] wrote:
quoted
Sets the default maximum ring num based on virtio_set_max_ring_num().
The default maximum ring num is 1024.
Having a default value is pretty useful, I see 32K is used by default for IFCVF.
Rethink this, how about having a different default value based on the speed?
Without SPEED_DUPLEX, we use 1024. Otherwise
10g 4096
40g 8192
We can define different default values of tx and rx by the way. This way I can
just use it in the new interface of find_vqs().
without SPEED_DUPLEX: tx 512 rx 1024
Any reason that TX is smaller than RX?
I've seen some NIC drivers with default tx smaller than rx.
Interesting, do they use combined channels?
One problem I have now is that inside virtnet_probe, init_vqs is before getting
speed/duplex. I'm not sure, can the logic to get speed/duplex be put before
init_vqs? Is there any risk?
Can you help me?
The feature has been negotiated during probe(), so I don't see any risk.
Thanks
Thanks.
quoted
Thanks
quoted
Thanks.
quoted
etc.
(The number are just copied from the 10g/40g default parameter from
other vendors)
Thanks
From: Jason Wang <hidden> Date: 2022-02-21 07:00:36
在 2022/2/21 上午11:40, Jason Wang 写道:
在 2022/2/17 下午5:30, Xuan Zhuo 写道:
quoted
On Thu, 17 Feb 2022 15:21:26 +0800, Jason Wang [off-list ref]
wrote:
quoted
On Wed, Feb 16, 2022 at 3:52 PM Xuan Zhuo
[off-list ref] wrote:
quoted
On Wed, 16 Feb 2022 12:14:31 +0800, Jason Wang
[off-list ref] wrote:
quoted
On Mon, Feb 14, 2022 at 4:14 PM Xuan Zhuo
[off-list ref] wrote:
quoted
Sets the default maximum ring num based on
virtio_set_max_ring_num().
The default maximum ring num is 1024.
Having a default value is pretty useful, I see 32K is used by
default for IFCVF.
Rethink this, how about having a different default value based on
the speed?
Without SPEED_DUPLEX, we use 1024. Otherwise
10g 4096
40g 8192
We can define different default values of tx and rx by the way.
This way I can
just use it in the new interface of find_vqs().
without SPEED_DUPLEX: tx 512 rx 1024
Any reason that TX is smaller than RX?
I've seen some NIC drivers with default tx smaller than rx.
Interesting, do they use combined channels?
Adding Ling Shan.
I see 32K is used for IFCVF by default, this is another call for the
this patch:
# ethtool -g eth0
Ring parameters for eth0:
Pre-set maximums:
RX: 32768
RX Mini: 0
RX Jumbo: 0
TX: 32768
Current hardware settings:
RX: 32768
RX Mini: 0
RX Jumbo: 0
TX: 32768
Thanks
quoted
One problem I have now is that inside virtnet_probe, init_vqs is
before getting
speed/duplex. I'm not sure, can the logic to get speed/duplex be put
before
init_vqs? Is there any risk?
Can you help me?
The feature has been negotiated during probe(), so I don't see any risk.
Thanks
quoted
Thanks.
quoted
Thanks
quoted
Thanks.
quoted
etc.
(The number are just copied from the 10g/40g default parameter from
other vendors)
Thanks