From mboxrd@z Thu Jan 1 00:00:00 1970 From: Tiwei Bie Subject: Re: [PATCH v6 09/11] net/virtio: add virtio send command packed queue support Date: Fri, 21 Sep 2018 20:37:15 +0800 Message-ID: <20180921123715.GB25292@debian> References: <20180921103308.16357-1-jfreimann@redhat.com> <20180921103308.16357-10-jfreimann@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Cc: dev@dpdk.org, maxime.coquelin@redhat.com, Gavin.Hu@arm.com, zhihong.wang@intel.com To: Jens Freimann Return-path: Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by dpdk.org (Postfix) with ESMTP id A4FD3A49 for ; Fri, 21 Sep 2018 14:38:40 +0200 (CEST) Content-Disposition: inline In-Reply-To: <20180921103308.16357-10-jfreimann@redhat.com> List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" On Fri, Sep 21, 2018 at 12:33:06PM +0200, Jens Freimann wrote: > Use packed virtqueue format when reading and writing descriptors > to/from the ring. > > Signed-off-by: Jens Freimann > --- > drivers/net/virtio/virtio_ethdev.c | 90 ++++++++++++++++++++++++++++++ > 1 file changed, 90 insertions(+) > > diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c > index c4ef095ed..c1d95141d 100644 > --- a/drivers/net/virtio/virtio_ethdev.c > +++ b/drivers/net/virtio/virtio_ethdev.c The support for virtio-user is missing. And virtio-user will break when packed ring is enabled. FYI, below is the relvelant code in virtio-user: https://github.com/DPDK/dpdk/blob/55d6bb67c9b3/drivers/net/virtio/virtio_user/virtio_user_dev.c#L584-L606 > @@ -141,6 +141,90 @@ static const struct rte_virtio_xstats_name_off rte_virtio_txq_stat_strings[] = { > > struct virtio_hw_internal virtio_hw_internal[RTE_MAX_ETHPORTS]; > > +static struct virtio_pmd_ctrl * > +virtio_pq_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl, > + int *dlen, int pkt_num) > +{ > + struct virtqueue *vq = cvq->vq; > + int head; > + struct vring_desc_packed *desc = vq->vq_ring.desc_packed; > + struct virtio_pmd_ctrl *result; > + int wrap_counter; > + int sum = 0; > + int k; > + > + /* > + * Format is enforced in qemu code: > + * One TX packet for header; > + * At least one TX packet per argument; > + * One RX packet for ACK. > + */ > + head = vq->vq_avail_idx; > + wrap_counter = vq->vq_ring.avail_wrap_counter; > + desc[head].flags = VRING_DESC_F_NEXT; > + desc[head].addr = cvq->virtio_net_hdr_mem; > + desc[head].len = sizeof(struct virtio_net_ctrl_hdr); > + vq->vq_free_cnt--; > + if (++vq->vq_avail_idx >= vq->vq_nentries) { > + vq->vq_avail_idx -= vq->vq_nentries; > + vq->vq_ring.avail_wrap_counter ^= 1; > + } > + > + for (k = 0; k < pkt_num; k++) { > + desc[vq->vq_avail_idx].addr = cvq->virtio_net_hdr_mem > + + sizeof(struct virtio_net_ctrl_hdr) > + + sizeof(ctrl->status) + sizeof(uint8_t) * sum; > + desc[vq->vq_avail_idx].len = dlen[k]; > + desc[vq->vq_avail_idx].flags = VRING_DESC_F_NEXT; > + sum += dlen[k]; > + vq->vq_free_cnt--; > + _set_desc_avail(&desc[vq->vq_avail_idx], > + vq->vq_ring.avail_wrap_counter); > + rte_smp_wmb(); > + vq->vq_free_cnt--; > + if (++vq->vq_avail_idx >= vq->vq_nentries) { > + vq->vq_avail_idx -= vq->vq_nentries; > + vq->vq_ring.avail_wrap_counter ^= 1; > + } > + } > + > + > + desc[vq->vq_avail_idx].addr = cvq->virtio_net_hdr_mem > + + sizeof(struct virtio_net_ctrl_hdr); > + desc[vq->vq_avail_idx].len = sizeof(ctrl->status); > + desc[vq->vq_avail_idx].flags = VRING_DESC_F_WRITE; > + _set_desc_avail(&desc[vq->vq_avail_idx], > + vq->vq_ring.avail_wrap_counter); > + _set_desc_avail(&desc[head], wrap_counter); > + rte_smp_wmb(); > + > + vq->vq_free_cnt--; > + if (++vq->vq_avail_idx >= vq->vq_nentries) { > + vq->vq_avail_idx -= vq->vq_nentries; > + vq->vq_ring.avail_wrap_counter ^= 1; > + } > + > + virtqueue_notify(vq); > + > + /* wait for used descriptors in virtqueue */ > + do { > + rte_rmb(); > + usleep(100); > + } while (!_desc_is_used(&desc[head])); > + > + /* now get used descriptors */ > + while(desc_is_used(&desc[vq->vq_used_cons_idx], &vq->vq_ring)) { > + vq->vq_free_cnt++; > + if (++vq->vq_used_cons_idx >= vq->vq_nentries) { > + vq->vq_used_cons_idx -= vq->vq_nentries; > + vq->vq_ring.used_wrap_counter ^= 1; > + } > + } > + > + result = cvq->virtio_net_hdr_mz->addr; > + return result; > +} > + > static int > virtio_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl, > int *dlen, int pkt_num) > @@ -174,6 +258,11 @@ virtio_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl, > memcpy(cvq->virtio_net_hdr_mz->addr, ctrl, > sizeof(struct virtio_pmd_ctrl)); > > + if (vtpci_packed_queue(vq->hw)) { > + result = virtio_pq_send_command(cvq, ctrl, dlen, pkt_num); > + goto out_unlock; > + } > + > /* > * Format is enforced in qemu code: > * One TX packet for header; > @@ -245,6 +334,7 @@ virtio_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl, > > result = cvq->virtio_net_hdr_mz->addr; > > +out_unlock: > rte_spinlock_unlock(&cvq->lock); > return result->status; > } > -- > 2.17.1 >