On Tue, Feb 7, 2023 at 4:18 PM Maxime Coquelin <maxime.coque...@redhat.com> wrote: > > If the backends supports control virtqueue, allocate a > shadow control virtqueue, and implement the notify callback > that writes into the kickfd. > > Signed-off-by: Maxime Coquelin <maxime.coque...@redhat.com> > Reviewed-by: Chenbo Xia <chenbo....@intel.com>
Even with the nitpick below, Acked-by: Eugenio PĂ©rez <epere...@redhat.com> > --- > .../net/virtio/virtio_user/virtio_user_dev.c | 47 ++++++++++++++++++- > .../net/virtio/virtio_user/virtio_user_dev.h | 5 ++ > drivers/net/virtio/virtio_user_ethdev.c | 6 +++ > 3 files changed, 56 insertions(+), 2 deletions(-) > > diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c > b/drivers/net/virtio/virtio_user/virtio_user_dev.c > index a3584e7735..16a0e07413 100644 > --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c > +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c > @@ -146,8 +146,9 @@ virtio_user_dev_set_features(struct virtio_user_dev *dev) > > /* Strip VIRTIO_NET_F_MAC, as MAC address is handled in vdev init */ > features &= ~(1ull << VIRTIO_NET_F_MAC); > - /* Strip VIRTIO_NET_F_CTRL_VQ, as devices do not really need to know > */ > - features &= ~(1ull << VIRTIO_NET_F_CTRL_VQ); > + /* Strip VIRTIO_NET_F_CTRL_VQ if the devices does not really support > control VQ */ > + if (!dev->hw_cvq) > + features &= ~(1ull << VIRTIO_NET_F_CTRL_VQ); > features &= ~(1ull << VIRTIO_NET_F_STATUS); > ret = dev->ops->set_features(dev, features); > if (ret < 0) > @@ -911,6 +912,48 @@ virtio_user_handle_cq(struct virtio_user_dev *dev, > uint16_t queue_idx) > } > } > > +static void > +virtio_user_control_queue_notify(struct virtqueue *vq, void *cookie) > +{ > + struct virtio_user_dev *dev = cookie; > + uint64_t buf = 1; > + > + if (write(dev->kickfds[vq->vq_queue_index], &buf, sizeof(buf)) < 0) > + PMD_DRV_LOG(ERR, "failed to kick backend: %s", > + strerror(errno)); > +} > + > +int > +virtio_user_dev_create_shadow_cvq(struct virtio_user_dev *dev, struct > virtqueue *vq) > +{ > + char name[VIRTQUEUE_MAX_NAME_SZ]; > + struct virtqueue *scvq; > + > + snprintf(name, sizeof(name), "port%d_shadow_cvq", vq->hw->port_id); > + scvq = virtqueue_alloc(&dev->hw, vq->vq_queue_index, vq->vq_nentries, > + VTNET_CQ, SOCKET_ID_ANY, name); > + if (!scvq) { > + PMD_INIT_LOG(ERR, "(%s) Failed to alloc shadow control vq\n", > dev->path); > + return -ENOMEM; > + } > + > + scvq->cq.notify_queue = &virtio_user_control_queue_notify; > + scvq->cq.notify_cookie = dev; > + dev->scvq = scvq; > + > + return 0; > +} > + > +void > +virtio_user_dev_destroy_shadow_cvq(struct virtio_user_dev *dev) > +{ > + if (!dev->scvq) > + return; > + > + virtqueue_free(dev->scvq); > + dev->scvq = NULL; > +} > + > int > virtio_user_dev_set_status(struct virtio_user_dev *dev, uint8_t status) > { > diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.h > b/drivers/net/virtio/virtio_user/virtio_user_dev.h > index 3c5453eac0..e0db4faf3f 100644 > --- a/drivers/net/virtio/virtio_user/virtio_user_dev.h > +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.h > @@ -58,6 +58,9 @@ struct virtio_user_dev { > pthread_mutex_t mutex; > bool started; > > + bool hw_cvq; > + struct virtqueue *scvq; > + > void *backend_data; > }; > > @@ -74,6 +77,8 @@ void virtio_user_handle_cq(struct virtio_user_dev *dev, > uint16_t queue_idx); > void virtio_user_handle_cq_packed(struct virtio_user_dev *dev, > uint16_t queue_idx); > uint8_t virtio_user_handle_mq(struct virtio_user_dev *dev, uint16_t q_pairs); > +int virtio_user_dev_create_shadow_cvq(struct virtio_user_dev *dev, struct > virtqueue *vq); > +void virtio_user_dev_destroy_shadow_cvq(struct virtio_user_dev *dev); > int virtio_user_dev_set_status(struct virtio_user_dev *dev, uint8_t status); > int virtio_user_dev_update_status(struct virtio_user_dev *dev); > int virtio_user_dev_update_link_state(struct virtio_user_dev *dev); > diff --git a/drivers/net/virtio/virtio_user_ethdev.c > b/drivers/net/virtio/virtio_user_ethdev.c > index 6c3e875793..626bd95b62 100644 > --- a/drivers/net/virtio/virtio_user_ethdev.c > +++ b/drivers/net/virtio/virtio_user_ethdev.c > @@ -232,6 +232,9 @@ virtio_user_setup_queue(struct virtio_hw *hw, struct > virtqueue *vq) > else > virtio_user_setup_queue_split(vq, dev); > > + if (dev->hw_cvq && hw->cvq && (virtnet_cq_to_vq(hw->cvq) == vq)) > + return virtio_user_dev_create_shadow_cvq(dev, vq); > + > return 0; > } > > @@ -251,6 +254,9 @@ virtio_user_del_queue(struct virtio_hw *hw, struct > virtqueue *vq) > > close(dev->callfds[vq->vq_queue_index]); > close(dev->kickfds[vq->vq_queue_index]); > + > + if (hw->cvq && (virtnet_cq_to_vq(hw->cvq) == vq) && dev->scvq) Not sure if intended, but check for dev->scvq is already in virtio_user_dev_destroy_shadow_cvq. > + virtio_user_dev_destroy_shadow_cvq(dev); > } > > static void > -- > 2.39.1 >