[v5,04/11] net/virtio: flush packed receive virtqueues

Message ID 20180906181947.20646-5-jfreimann@redhat.com (mailing list archive)
State Superseded, archived
Delegated to: Maxime Coquelin
Headers
Series implement packed virtqueues |

Checks

Context Check Description
ci/Intel-compilation success Compilation OK

Commit Message

Jens Freimann Sept. 6, 2018, 6:19 p.m. UTC
  Flush used descriptors in packed receive virtqueue. As descriptors
can be chained we need to look at the stored number of used descriptors
to find out the length of the chain.

Signed-off-by: Jens Freimann <jfreimann@redhat.com>
---
 drivers/net/virtio/virtqueue.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
  

Comments

Maxime Coquelin Sept. 12, 2018, 9:12 a.m. UTC | #1
On 09/06/2018 08:19 PM, Jens Freimann wrote:
> Flush used descriptors in packed receive virtqueue. As descriptors
> can be chained we need to look at the stored number of used descriptors
> to find out the length of the chain.
> 
> Signed-off-by: Jens Freimann <jfreimann@redhat.com>
> ---
>   drivers/net/virtio/virtqueue.c | 17 +++++++++++++++++
>   1 file changed, 17 insertions(+)
> 
> diff --git a/drivers/net/virtio/virtqueue.c b/drivers/net/virtio/virtqueue.c
> index 56a77cc71..d0520dad1 100644
> --- a/drivers/net/virtio/virtqueue.c
> +++ b/drivers/net/virtio/virtqueue.c
> @@ -58,12 +58,29 @@ virtqueue_detach_unused(struct virtqueue *vq)
>   void
>   virtqueue_rxvq_flush(struct virtqueue *vq)
>   {
> +	struct vring_desc_packed *descs = vq->vq_ring.desc_packed;
>   	struct virtnet_rx *rxq = &vq->rxq;
>   	struct virtio_hw *hw = vq->hw;
>   	struct vring_used_elem *uep;
>   	struct vq_desc_extra *dxp;
>   	uint16_t used_idx, desc_idx;
>   	uint16_t nb_used, i;
> +	uint16_t size = vq->vq_nentries;
> +
> +	if (vtpci_packed_queue(vq->hw)) {
> +		i = vq->vq_used_cons_idx;
> +		while (desc_is_used(&descs[i], &vq->vq_ring) &&
> +			i < vq->vq_nentries) {
It may be preferable to ensure 'i' is within the ring size before using
it in desc_is_used(). And raise (at least) an error message if it isn't.

> +			dxp = &vq->vq_descx[i];
> +			if (dxp->cookie != NULL)
> +				rte_pktmbuf_free(dxp->cookie);
> +			vq->vq_free_cnt += dxp->ndescs;
> +			i = i + dxp->ndescs;
> +			i = i >= size ? i - size : i;
> +			dxp->ndescs = 0;
> +		}
> +		return;
> +	}
>   
>   	nb_used = VIRTQUEUE_NUSED(vq);
>   
>
  
Jens Freimann Sept. 12, 2018, 9:49 a.m. UTC | #2
On Wed, Sep 12, 2018 at 11:12:50AM +0200, Maxime Coquelin wrote:
>On 09/06/2018 08:19 PM, Jens Freimann wrote:
[...]
>>+	if (vtpci_packed_queue(vq->hw)) {
>>+		i = vq->vq_used_cons_idx;
>>+		while (desc_is_used(&descs[i], &vq->vq_ring) &&
>>+			i < vq->vq_nentries) {
>It may be preferable to ensure 'i' is within the ring size before using
>it in desc_is_used(). And raise (at least) an error message if it isn't.

Yes, I'll fix this. Thanks!

regards,
Jens
  

Patch

diff --git a/drivers/net/virtio/virtqueue.c b/drivers/net/virtio/virtqueue.c
index 56a77cc71..d0520dad1 100644
--- a/drivers/net/virtio/virtqueue.c
+++ b/drivers/net/virtio/virtqueue.c
@@ -58,12 +58,29 @@  virtqueue_detach_unused(struct virtqueue *vq)
 void
 virtqueue_rxvq_flush(struct virtqueue *vq)
 {
+	struct vring_desc_packed *descs = vq->vq_ring.desc_packed;
 	struct virtnet_rx *rxq = &vq->rxq;
 	struct virtio_hw *hw = vq->hw;
 	struct vring_used_elem *uep;
 	struct vq_desc_extra *dxp;
 	uint16_t used_idx, desc_idx;
 	uint16_t nb_used, i;
+	uint16_t size = vq->vq_nentries;
+
+	if (vtpci_packed_queue(vq->hw)) {
+		i = vq->vq_used_cons_idx;
+		while (desc_is_used(&descs[i], &vq->vq_ring) &&
+			i < vq->vq_nentries) {
+			dxp = &vq->vq_descx[i];
+			if (dxp->cookie != NULL)
+				rte_pktmbuf_free(dxp->cookie);
+			vq->vq_free_cnt += dxp->ndescs;
+			i = i + dxp->ndescs;
+			i = i >= size ? i - size : i;
+			dxp->ndescs = 0;
+		}
+		return;
+	}
 
 	nb_used = VIRTQUEUE_NUSED(vq);