From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 9EA87A0548 for ; Tue, 17 Aug 2021 04:30:45 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 6E23540142; Tue, 17 Aug 2021 04:30:45 +0200 (CEST) Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by mails.dpdk.org (Postfix) with ESMTP id E236940142 for ; Tue, 17 Aug 2021 04:30:43 +0200 (CEST) X-IronPort-AV: E=McAfee;i="6200,9189,10078"; a="238055914" X-IronPort-AV: E=Sophos;i="5.84,327,1620716400"; d="scan'208";a="238055914" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Aug 2021 19:30:42 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.84,327,1620716400"; d="scan'208";a="487736052" Received: from npg-dpdk-virtual-marvin-dev.sh.intel.com ([10.67.119.143]) by fmsmga008.fm.intel.com with ESMTP; 16 Aug 2021 19:30:41 -0700 From: Marvin Liu To: stable@dpdk.org Cc: Marvin Liu , Cheng Jiang Date: Tue, 17 Aug 2021 17:52:36 +0800 Message-Id: <20210817095236.36985-1-yong.liu@intel.com> X-Mailer: git-send-email 2.17.1 Subject: [dpdk-stable] [PATCH 19.11] net/virtio: fix refill order in packed ring datapath X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: stable-bounces@dpdk.org Sender: "stable" [ upstream commit 2d91b28730a945def257bc372a525c9b5dbf181c ] The front-end should refill the descriptor with the mbuf indicated by the buff_id rather then the index of used descriptor. Back-end may return buffers out of order if async copy mode is enabled. When initializing rxq, refill the descriptors in order as buff_id is not available at that time. Fixes: a76290c8f1cf ("net/virtio: implement Rx path for packed queues") Signed-off-by: Marvin Liu Signed-off-by: Cheng Jiang Reviewed-by: Maxime Coquelin diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c index 5211736d2..421e4847e 100644 --- a/drivers/net/virtio/virtio_rxtx.c +++ b/drivers/net/virtio/virtio_rxtx.c @@ -474,13 +474,35 @@ virtqueue_enqueue_recv_refill(struct virtqueue *vq, struct rte_mbuf **cookie, return 0; } +static inline void +virtqueue_refill_single_packed(struct virtqueue *vq, + struct vring_packed_desc *dp, + struct rte_mbuf *cookie) +{ + uint16_t flags = vq->vq_packed.cached_flags; + struct virtio_hw *hw = vq->hw; + + dp->addr = VIRTIO_MBUF_ADDR(cookie, vq) + + RTE_PKTMBUF_HEADROOM - hw->vtnet_hdr_size; + dp->len = cookie->buf_len - + RTE_PKTMBUF_HEADROOM + hw->vtnet_hdr_size; + + virtqueue_store_flags_packed(dp, flags, + hw->weak_barriers); + + if (++vq->vq_avail_idx >= vq->vq_nentries) { + vq->vq_avail_idx -= vq->vq_nentries; + vq->vq_packed.cached_flags ^= + VRING_PACKED_DESC_F_AVAIL_USED; + flags = vq->vq_packed.cached_flags; + } +} + static inline int -virtqueue_enqueue_recv_refill_packed(struct virtqueue *vq, +virtqueue_enqueue_recv_refill_packed_init(struct virtqueue *vq, struct rte_mbuf **cookie, uint16_t num) { struct vring_packed_desc *start_dp = vq->vq_packed.ring.desc; - uint16_t flags = vq->vq_packed.cached_flags; - struct virtio_hw *hw = vq->hw; struct vq_desc_extra *dxp; uint16_t idx; int i; @@ -496,24 +518,34 @@ virtqueue_enqueue_recv_refill_packed(struct virtqueue *vq, dxp->cookie = (void *)cookie[i]; dxp->ndescs = 1; - start_dp[idx].addr = VIRTIO_MBUF_ADDR(cookie[i], vq) + - RTE_PKTMBUF_HEADROOM - hw->vtnet_hdr_size; - start_dp[idx].len = cookie[i]->buf_len - RTE_PKTMBUF_HEADROOM - + hw->vtnet_hdr_size; + virtqueue_refill_single_packed(vq, &start_dp[idx], cookie[i]); + } + vq->vq_free_cnt = (uint16_t)(vq->vq_free_cnt - num); + return 0; +} - vq->vq_desc_head_idx = dxp->next; - if (vq->vq_desc_head_idx == VQ_RING_DESC_CHAIN_END) - vq->vq_desc_tail_idx = vq->vq_desc_head_idx; +static inline int +virtqueue_enqueue_recv_refill_packed(struct virtqueue *vq, + struct rte_mbuf **cookie, uint16_t num) +{ + struct vring_packed_desc *start_dp = vq->vq_packed.ring.desc; + struct vq_desc_extra *dxp; + uint16_t idx, did; + int i; - virtqueue_store_flags_packed(&start_dp[idx], flags, - hw->weak_barriers); + if (unlikely(vq->vq_free_cnt == 0)) + return -ENOSPC; + if (unlikely(vq->vq_free_cnt < num)) + return -EMSGSIZE; - if (++vq->vq_avail_idx >= vq->vq_nentries) { - vq->vq_avail_idx -= vq->vq_nentries; - vq->vq_packed.cached_flags ^= - VRING_PACKED_DESC_F_AVAIL_USED; - flags = vq->vq_packed.cached_flags; - } + for (i = 0; i < num; i++) { + idx = vq->vq_avail_idx; + did = start_dp[idx].id; + dxp = &vq->vq_descx[did]; + dxp->cookie = (void *)cookie[i]; + dxp->ndescs = 1; + + virtqueue_refill_single_packed(vq, &start_dp[idx], cookie[i]); } vq->vq_free_cnt = (uint16_t)(vq->vq_free_cnt - num); return 0; @@ -1022,7 +1054,7 @@ virtio_dev_rx_queue_setup_finish(struct rte_eth_dev *dev, uint16_t queue_idx) /* Enqueue allocated buffers */ if (vtpci_packed_queue(vq->hw)) - error = virtqueue_enqueue_recv_refill_packed(vq, + error = virtqueue_enqueue_recv_refill_packed_init(vq, &m, 1); else error = virtqueue_enqueue_recv_refill(vq, -- 2.17.1