* Re: [PATCH RFC 2/3] vdpa/mlx5: Support different address spaces for control and data
[not found] ` <20220616132725.50599-3-elic@nvidia.com>
@ 2022-06-20 8:47 ` Jason Wang
[not found] ` <CAJaqyWdFyT+QGce998vsTQNiGAF1LZqOXNZH1RS660tb6pvtgA@mail.gmail.com>
1 sibling, 0 replies; 12+ messages in thread
From: Jason Wang @ 2022-06-20 8:47 UTC (permalink / raw)
To: Eli Cohen; +Cc: mst, linux-kernel, virtualization, eperezma
On Thu, Jun 16, 2022 at 9:27 PM Eli Cohen <elic@nvidia.com> wrote:
>
> Partition virtqueues to two different address spaces: oce for control
Typo, should be "one"
> virtqueue which is implemented in software, and one for data virtqueus.
And should be "virtqueues".
Other than this.
Acked-by: Jason Wang <jasowang@redhat.com>
>
> Signed-off-by: Eli Cohen <elic@nvidia.com>
> ---
> drivers/vdpa/mlx5/core/mlx5_vdpa.h | 11 ++++
> drivers/vdpa/mlx5/net/mlx5_vnet.c | 101 +++++++++++++++++++++++++----
> 2 files changed, 101 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> index 44104093163b..6af9fdbb86b7 100644
> --- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> +++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> @@ -70,6 +70,16 @@ struct mlx5_vdpa_wq_ent {
> struct mlx5_vdpa_dev *mvdev;
> };
>
> +enum {
> + MLX5_VDPA_DATAVQ_GROUP,
> + MLX5_VDPA_CVQ_GROUP,
> + MLX5_VDPA_NUMVQ_GROUPS
> +};
> +
> +enum {
> + MLX5_VDPA_NUM_AS = MLX5_VDPA_NUMVQ_GROUPS
> +};
> +
> struct mlx5_vdpa_dev {
> struct vdpa_device vdev;
> struct mlx5_core_dev *mdev;
> @@ -85,6 +95,7 @@ struct mlx5_vdpa_dev {
> struct mlx5_vdpa_mr mr;
> struct mlx5_control_vq cvq;
> struct workqueue_struct *wq;
> + unsigned int group2asid[MLX5_VDPA_NUMVQ_GROUPS];
> };
>
> int mlx5_vdpa_alloc_pd(struct mlx5_vdpa_dev *dev, u32 *pdn, u16 uid);
> diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> index ea4bc8a0cd25..34bd81cb697c 100644
> --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
> +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> @@ -2125,9 +2125,14 @@ static u32 mlx5_vdpa_get_vq_align(struct vdpa_device *vdev)
> return PAGE_SIZE;
> }
>
> -static u32 mlx5_vdpa_get_vq_group(struct vdpa_device *vdpa, u16 idx)
> +static u32 mlx5_vdpa_get_vq_group(struct vdpa_device *vdev, u16 idx)
> {
> - return 0;
> + struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
> +
> + if (is_ctrl_vq_idx(mvdev, idx))
> + return MLX5_VDPA_CVQ_GROUP;
> +
> + return MLX5_VDPA_DATAVQ_GROUP;
> }
>
> enum { MLX5_VIRTIO_NET_F_GUEST_CSUM = 1 << 9,
> @@ -2541,6 +2546,15 @@ static void mlx5_vdpa_set_status(struct vdpa_device *vdev, u8 status)
> up_write(&ndev->reslock);
> }
>
> +static void init_group_to_asid_map(struct mlx5_vdpa_dev *mvdev)
> +{
> + int i;
> +
> + /* default mapping all groups are mapped to asid 0 */
> + for (i = 0; i < MLX5_VDPA_NUMVQ_GROUPS; i++)
> + mvdev->group2asid[i] = 0;
> +}
> +
> static int mlx5_vdpa_reset(struct vdpa_device *vdev)
> {
> struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
> @@ -2559,7 +2573,9 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev)
> ndev->mvdev.cvq.completed_desc = 0;
> memset(ndev->event_cbs, 0, sizeof(*ndev->event_cbs) * (mvdev->max_vqs + 1));
> ndev->mvdev.actual_features = 0;
> + init_group_to_asid_map(mvdev);
> ++mvdev->generation;
> +
> if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {
> if (mlx5_vdpa_create_mr(mvdev, NULL))
> mlx5_vdpa_warn(mvdev, "create MR failed\n");
> @@ -2597,26 +2613,76 @@ static u32 mlx5_vdpa_get_generation(struct vdpa_device *vdev)
> return mvdev->generation;
> }
>
> -static int mlx5_vdpa_set_map(struct vdpa_device *vdev, unsigned int asid,
> - struct vhost_iotlb *iotlb)
> +static u32 get_group(struct mlx5_vdpa_dev *mvdev, unsigned int asid)
> +{
> + u32 group;
> +
> + for (group = 0; group < MLX5_VDPA_NUMVQ_GROUPS; group++) {
> + if (mvdev->group2asid[group] == asid)
> + return group;
> + }
> + return -EINVAL;
> +}
> +
> +static int set_map_control(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb)
> +{
> + u64 start = 0ULL, last = 0ULL - 1;
> + struct vhost_iotlb_map *map;
> + int err = 0;
> +
> + spin_lock(&mvdev->cvq.iommu_lock);
> + vhost_iotlb_reset(mvdev->cvq.iotlb);
> +
> + for (map = vhost_iotlb_itree_first(iotlb, start, last); map;
> + map = vhost_iotlb_itree_next(map, start, last)) {
> + err = vhost_iotlb_add_range(mvdev->cvq.iotlb, map->start,
> + map->last, map->addr, map->perm);
> + if (err)
> + goto out;
> + }
> +
> +out:
> + spin_unlock(&mvdev->cvq.iommu_lock);
> + return err;
> +}
> +
> +static int set_map_data(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb)
> {
> - struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
> - struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
> bool change_map;
> int err;
>
> - down_write(&ndev->reslock);
> -
> err = mlx5_vdpa_handle_set_map(mvdev, iotlb, &change_map);
> if (err) {
> mlx5_vdpa_warn(mvdev, "set map failed(%d)\n", err);
> - goto err;
> + return err;
> }
>
> if (change_map)
> err = mlx5_vdpa_change_map(mvdev, iotlb);
>
> -err:
> + return err;
> +}
> +
> +static int mlx5_vdpa_set_map(struct vdpa_device *vdev, unsigned int asid,
> + struct vhost_iotlb *iotlb)
> +{
> + struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
> + struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
> + u32 group;
> + int err;
> +
> + down_write(&ndev->reslock);
> + group = get_group(mvdev, asid);
> + switch (group) {
> + case MLX5_VDPA_DATAVQ_GROUP:
> + err = set_map_data(mvdev, iotlb);
> + break;
> + case MLX5_VDPA_CVQ_GROUP:
> + err = set_map_control(mvdev, iotlb);
> + break;
> + default:
> + err = -EINVAL;
> + }
> up_write(&ndev->reslock);
> return err;
> }
> @@ -2796,6 +2862,18 @@ static int mlx5_vdpa_suspend(struct vdpa_device *vdev, bool suspend)
> return 0;
> }
>
> +static int mlx5_set_group_asid(struct vdpa_device *vdev, u32 group,
> + unsigned int asid)
> +{
> + struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
> +
> + if (group >= MLX5_VDPA_NUMVQ_GROUPS)
> + return -EINVAL;
> +
> + mvdev->group2asid[group] = asid;
> + return 0;
> +}
> +
> static const struct vdpa_config_ops mlx5_vdpa_ops = {
> .set_vq_address = mlx5_vdpa_set_vq_address,
> .set_vq_num = mlx5_vdpa_set_vq_num,
> @@ -2825,6 +2903,7 @@ static const struct vdpa_config_ops mlx5_vdpa_ops = {
> .set_config = mlx5_vdpa_set_config,
> .get_generation = mlx5_vdpa_get_generation,
> .set_map = mlx5_vdpa_set_map,
> + .set_group_asid = mlx5_set_group_asid,
> .free = mlx5_vdpa_free,
> .suspend = mlx5_vdpa_suspend,
> };
> @@ -3047,7 +3126,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name,
> }
>
> ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, mdev->device, &mlx5_vdpa_ops,
> - 1, 1, name, false);
> + MLX5_VDPA_NUMVQ_GROUPS, MLX5_VDPA_NUM_AS, name, false);
> if (IS_ERR(ndev))
> return PTR_ERR(ndev);
>
> --
> 2.35.1
>
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH RFC 3/3] vdpa/mlx5: Disable VLAN support to support live migration
[not found] ` <20220616132725.50599-4-elic@nvidia.com>
@ 2022-06-20 8:47 ` Jason Wang
[not found] ` <CAJaqyWdnuX0KLu7j3M4ovtW=N5kFObgaU3z2hu4xoRXY5Fk+aQ@mail.gmail.com>
0 siblings, 1 reply; 12+ messages in thread
From: Jason Wang @ 2022-06-20 8:47 UTC (permalink / raw)
To: Eli Cohen; +Cc: mst, linux-kernel, virtualization, eperezma
On Thu, Jun 16, 2022 at 9:28 PM Eli Cohen <elic@nvidia.com> wrote:
>
> Current qemu code does not support live migration for devices supporting
> VLAN. Disable it.
This looks like a bug that we need to fix in Qemu.
Thanks
>
> Note: this patch is provided just to enable testing with current qemu.
>
> Signed-off-by: Eli Cohen <elic@nvidia.com>
> ---
> drivers/vdpa/mlx5/net/mlx5_vnet.c | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> index 34bd81cb697c..1568cfdf07e6 100644
> --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
> +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> @@ -2172,7 +2172,6 @@ static u64 get_supported_features(struct mlx5_core_dev *mdev)
> mlx_vdpa_features |= BIT_ULL(VIRTIO_NET_F_MQ);
> mlx_vdpa_features |= BIT_ULL(VIRTIO_NET_F_STATUS);
> mlx_vdpa_features |= BIT_ULL(VIRTIO_NET_F_MTU);
> - mlx_vdpa_features |= BIT_ULL(VIRTIO_NET_F_CTRL_VLAN);
>
> return mlx_vdpa_features;
> }
> --
> 2.35.1
>
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH RFC 1/3] vdpa/mlx5: Implement susupend virtqueue callback
[not found] ` <20220616132725.50599-2-elic@nvidia.com>
@ 2022-06-20 8:56 ` Jason Wang
[not found] ` <DM8PR12MB54004277F21D682A3EE6D1C1ABB09@DM8PR12MB5400.namprd12.prod.outlook.com>
[not found] ` <CAJaqyWfTG_jVW6Vzf64QO=255kfwWKn4gCUMeGog-1shHx3O_g@mail.gmail.com>
0 siblings, 2 replies; 12+ messages in thread
From: Jason Wang @ 2022-06-20 8:56 UTC (permalink / raw)
To: Eli Cohen; +Cc: mst, linux-kernel, virtualization, eperezma
On Thu, Jun 16, 2022 at 9:27 PM Eli Cohen <elic@nvidia.com> wrote:
>
> Implement the suspend callback allowing to suspend the virtqueues so
> they stop processing descriptors. This is required to allow the shadow
> virtqueue to kick in.
>
> Signed-off-by: Eli Cohen <elic@nvidia.com>
> ---
> drivers/vdpa/mlx5/net/mlx5_vnet.c | 68 +++++++++++++++++++++++++++++-
> include/linux/mlx5/mlx5_ifc_vdpa.h | 8 ++++
> 2 files changed, 75 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> index fb0b23e71383..ea4bc8a0cd25 100644
> --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
> +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> @@ -895,6 +895,7 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque
> if (err)
> goto err_cmd;
>
> + mvq->fw_state = MLX5_VIRTIO_NET_Q_OBJECT_STATE_INIT;
> kfree(in);
> mvq->virtq_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
>
> @@ -922,6 +923,7 @@ static void destroy_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtq
> mlx5_vdpa_warn(&ndev->mvdev, "destroy virtqueue 0x%x\n", mvq->virtq_id);
> return;
> }
> + mvq->fw_state = MLX5_VIRTIO_NET_Q_OBJECT_NONE;
> umems_destroy(ndev, mvq);
> }
>
> @@ -1121,6 +1123,20 @@ static int query_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueu
> return err;
> }
>
> +static bool is_valid_state_change(int oldstate, int newstate)
> +{
> + switch (oldstate) {
> + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_INIT:
> + return newstate == MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY;
> + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY:
> + return newstate == MLX5_VIRTIO_NET_Q_OBJECT_STATE_SUSPEND;
> + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_SUSPEND:
> + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_ERR:
> + default:
> + return false;
> + }
> +}
> +
> static int modify_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq, int state)
> {
> int inlen = MLX5_ST_SZ_BYTES(modify_virtio_net_q_in);
> @@ -1130,6 +1146,12 @@ static int modify_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque
> void *in;
> int err;
>
> + if (mvq->fw_state == MLX5_VIRTIO_NET_Q_OBJECT_NONE)
> + return 0;
> +
> + if (!is_valid_state_change(mvq->fw_state, state))
> + return -EINVAL;
> +
> in = kzalloc(inlen, GFP_KERNEL);
> if (!in)
> return -ENOMEM;
> @@ -1991,6 +2013,7 @@ static void mlx5_vdpa_set_vq_ready(struct vdpa_device *vdev, u16 idx, bool ready
> struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
> struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
> struct mlx5_vdpa_virtqueue *mvq;
> + int err;
>
> if (!mvdev->actual_features)
> return;
> @@ -2004,8 +2027,16 @@ static void mlx5_vdpa_set_vq_ready(struct vdpa_device *vdev, u16 idx, bool ready
> }
>
> mvq = &ndev->vqs[idx];
> - if (!ready)
> + if (!ready) {
> suspend_vq(ndev, mvq);
> + } else {
> + err = modify_virtqueue(ndev, mvq, MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY);
> + if (err) {
> + mlx5_vdpa_warn(mvdev, "modify VQ %d to ready failed (%d)\n", idx, err);
> + ready = false;
> + }
> + }
> +
>
> mvq->ready = ready;
> }
> @@ -2732,6 +2763,39 @@ static int mlx5_vdpa_get_vendor_vq_stats(struct vdpa_device *vdev, u16 idx,
> return err;
> }
>
> +static void mlx5_vdpa_cvq_suspend(struct mlx5_vdpa_dev *mvdev, bool suspend)
> +{
> + struct mlx5_control_vq *cvq;
> +
> + if (!(mvdev->actual_features & BIT_ULL(VIRTIO_NET_F_CTRL_VQ)))
> + return;
> +
> + cvq = &mvdev->cvq;
> + cvq->ready = !suspend;
> +}
It looks to me we need to synchronize this with reslock. And this
probably deserve a dedicated fix.
> +
> +static int mlx5_vdpa_suspend(struct vdpa_device *vdev, bool suspend)
> +{
> + struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
> + struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
> + struct mlx5_vdpa_virtqueue *mvq;
> + int i;
> +
> + if (!suspend) {
> + mlx5_vdpa_warn(mvdev, "Resume of virtqueues is not supported\n");
> + return -EOPNOTSUPP;
> + }
> +
> + down_write(&ndev->reslock);
> + for (i = 0; i < ndev->cur_num_vqs; i++) {
> + mvq = &ndev->vqs[i];
> + suspend_vq(ndev, mvq);
> + }
> + mlx5_vdpa_cvq_suspend(mvdev, suspend);
Do we need to synchronize with the carrier work here? Otherwise we may
get config notification after suspending.
> + up_write(&ndev->reslock);
> + return 0;
> +}
> +
> static const struct vdpa_config_ops mlx5_vdpa_ops = {
> .set_vq_address = mlx5_vdpa_set_vq_address,
> .set_vq_num = mlx5_vdpa_set_vq_num,
> @@ -2762,6 +2826,7 @@ static const struct vdpa_config_ops mlx5_vdpa_ops = {
> .get_generation = mlx5_vdpa_get_generation,
> .set_map = mlx5_vdpa_set_map,
> .free = mlx5_vdpa_free,
> + .suspend = mlx5_vdpa_suspend,
I don't see the vDPA bus patch to enable this method. Or anything I missed here?
Thanks
> };
>
> static int query_mtu(struct mlx5_core_dev *mdev, u16 *mtu)
> @@ -2827,6 +2892,7 @@ static void init_mvqs(struct mlx5_vdpa_net *ndev)
> mvq->index = i;
> mvq->ndev = ndev;
> mvq->fwqp.fw = true;
> + mvq->fw_state = MLX5_VIRTIO_NET_Q_OBJECT_NONE;
> }
> for (; i < ndev->mvdev.max_vqs; i++) {
> mvq = &ndev->vqs[i];
> diff --git a/include/linux/mlx5/mlx5_ifc_vdpa.h b/include/linux/mlx5/mlx5_ifc_vdpa.h
> index 4414ed5b6ed2..423562f39d3c 100644
> --- a/include/linux/mlx5/mlx5_ifc_vdpa.h
> +++ b/include/linux/mlx5/mlx5_ifc_vdpa.h
> @@ -150,6 +150,14 @@ enum {
> MLX5_VIRTIO_NET_Q_OBJECT_STATE_ERR = 0x3,
> };
>
> +/* This indicates that the object was not created or has alreadyi
> + * been desroyed. It is very safe to assume that this object will never
> + * have so many states
> + */
> +enum {
> + MLX5_VIRTIO_NET_Q_OBJECT_NONE = 0xffffffff
> +};
> +
> enum {
> MLX5_RQTC_LIST_Q_TYPE_RQ = 0x0,
> MLX5_RQTC_LIST_Q_TYPE_VIRTIO_NET_Q = 0x1,
> --
> 2.35.1
>
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH RFC 2/3] vdpa/mlx5: Support different address spaces for control and data
[not found] ` <CAJaqyWdFyT+QGce998vsTQNiGAF1LZqOXNZH1RS660tb6pvtgA@mail.gmail.com>
@ 2022-06-20 9:20 ` Jason Wang
0 siblings, 0 replies; 12+ messages in thread
From: Jason Wang @ 2022-06-20 9:20 UTC (permalink / raw)
To: Eugenio Perez Martin
Cc: Michael Tsirkin, linux-kernel, virtualization, Eli Cohen
On Mon, Jun 20, 2022 at 4:58 PM Eugenio Perez Martin
<eperezma@redhat.com> wrote:
>
> On Thu, Jun 16, 2022 at 3:27 PM Eli Cohen <elic@nvidia.com> wrote:
> >
> > Partition virtqueues to two different address spaces: oce for control
> > virtqueue which is implemented in software, and one for data virtqueus.
> >
> > Signed-off-by: Eli Cohen <elic@nvidia.com>
> > ---
> > drivers/vdpa/mlx5/core/mlx5_vdpa.h | 11 ++++
> > drivers/vdpa/mlx5/net/mlx5_vnet.c | 101 +++++++++++++++++++++++++----
> > 2 files changed, 101 insertions(+), 11 deletions(-)
> >
> > diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> > index 44104093163b..6af9fdbb86b7 100644
> > --- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> > +++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> > @@ -70,6 +70,16 @@ struct mlx5_vdpa_wq_ent {
> > struct mlx5_vdpa_dev *mvdev;
> > };
> >
> > +enum {
> > + MLX5_VDPA_DATAVQ_GROUP,
> > + MLX5_VDPA_CVQ_GROUP,
> > + MLX5_VDPA_NUMVQ_GROUPS
> > +};
> > +
> > +enum {
> > + MLX5_VDPA_NUM_AS = MLX5_VDPA_NUMVQ_GROUPS
> > +};
> > +
> > struct mlx5_vdpa_dev {
> > struct vdpa_device vdev;
> > struct mlx5_core_dev *mdev;
> > @@ -85,6 +95,7 @@ struct mlx5_vdpa_dev {
> > struct mlx5_vdpa_mr mr;
> > struct mlx5_control_vq cvq;
> > struct workqueue_struct *wq;
> > + unsigned int group2asid[MLX5_VDPA_NUMVQ_GROUPS];
> > };
> >
> > int mlx5_vdpa_alloc_pd(struct mlx5_vdpa_dev *dev, u32 *pdn, u16 uid);
> > diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > index ea4bc8a0cd25..34bd81cb697c 100644
> > --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > @@ -2125,9 +2125,14 @@ static u32 mlx5_vdpa_get_vq_align(struct vdpa_device *vdev)
> > return PAGE_SIZE;
> > }
> >
> > -static u32 mlx5_vdpa_get_vq_group(struct vdpa_device *vdpa, u16 idx)
> > +static u32 mlx5_vdpa_get_vq_group(struct vdpa_device *vdev, u16 idx)
> > {
> > - return 0;
> > + struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
> > +
> > + if (is_ctrl_vq_idx(mvdev, idx))
> > + return MLX5_VDPA_CVQ_GROUP;
> > +
> > + return MLX5_VDPA_DATAVQ_GROUP;
> > }
> >
> > enum { MLX5_VIRTIO_NET_F_GUEST_CSUM = 1 << 9,
> > @@ -2541,6 +2546,15 @@ static void mlx5_vdpa_set_status(struct vdpa_device *vdev, u8 status)
> > up_write(&ndev->reslock);
> > }
> >
> > +static void init_group_to_asid_map(struct mlx5_vdpa_dev *mvdev)
> > +{
> > + int i;
> > +
> > + /* default mapping all groups are mapped to asid 0 */
> > + for (i = 0; i < MLX5_VDPA_NUMVQ_GROUPS; i++)
> > + mvdev->group2asid[i] = 0;
> > +}
> > +
> > static int mlx5_vdpa_reset(struct vdpa_device *vdev)
> > {
> > struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
> > @@ -2559,7 +2573,9 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev)
> > ndev->mvdev.cvq.completed_desc = 0;
> > memset(ndev->event_cbs, 0, sizeof(*ndev->event_cbs) * (mvdev->max_vqs + 1));
> > ndev->mvdev.actual_features = 0;
> > + init_group_to_asid_map(mvdev);
> > ++mvdev->generation;
> > +
> > if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {
> > if (mlx5_vdpa_create_mr(mvdev, NULL))
> > mlx5_vdpa_warn(mvdev, "create MR failed\n");
> > @@ -2597,26 +2613,76 @@ static u32 mlx5_vdpa_get_generation(struct vdpa_device *vdev)
> > return mvdev->generation;
> > }
> >
> > -static int mlx5_vdpa_set_map(struct vdpa_device *vdev, unsigned int asid,
> > - struct vhost_iotlb *iotlb)
> > +static u32 get_group(struct mlx5_vdpa_dev *mvdev, unsigned int asid)
> > +{
> > + u32 group;
> > +
> > + for (group = 0; group < MLX5_VDPA_NUMVQ_GROUPS; group++) {
> > + if (mvdev->group2asid[group] == asid)
> > + return group;
> > + }
> > + return -EINVAL;
> > +}
> > +
> > +static int set_map_control(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb)
> > +{
> > + u64 start = 0ULL, last = 0ULL - 1;
> > + struct vhost_iotlb_map *map;
> > + int err = 0;
> > +
> > + spin_lock(&mvdev->cvq.iommu_lock);
> > + vhost_iotlb_reset(mvdev->cvq.iotlb);
> > +
> > + for (map = vhost_iotlb_itree_first(iotlb, start, last); map;
> > + map = vhost_iotlb_itree_next(map, start, last)) {
> > + err = vhost_iotlb_add_range(mvdev->cvq.iotlb, map->start,
> > + map->last, map->addr, map->perm);
> > + if (err)
> > + goto out;
> > + }
> > +
> > +out:
> > + spin_unlock(&mvdev->cvq.iommu_lock);
> > + return err;
> > +}
> > +
> > +static int set_map_data(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb)
> > {
> > - struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
> > - struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
> > bool change_map;
> > int err;
> >
> > - down_write(&ndev->reslock);
> > -
> > err = mlx5_vdpa_handle_set_map(mvdev, iotlb, &change_map);
> > if (err) {
> > mlx5_vdpa_warn(mvdev, "set map failed(%d)\n", err);
> > - goto err;
> > + return err;
> > }
> >
> > if (change_map)
> > err = mlx5_vdpa_change_map(mvdev, iotlb);
> >
> > -err:
> > + return err;
> > +}
> > +
> > +static int mlx5_vdpa_set_map(struct vdpa_device *vdev, unsigned int asid,
> > + struct vhost_iotlb *iotlb)
> > +{
> > + struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
> > + struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
> > + u32 group;
> > + int err;
> > +
> > + down_write(&ndev->reslock);
> > + group = get_group(mvdev, asid);
> > + switch (group) {
> > + case MLX5_VDPA_DATAVQ_GROUP:
> > + err = set_map_data(mvdev, iotlb);
> > + break;
> > + case MLX5_VDPA_CVQ_GROUP:
> > + err = set_map_control(mvdev, iotlb);
> > + break;
> > + default:
> > + err = -EINVAL;
> > + }
>
> This shouldn't be a switch, but to check the asid assigned to the
> different vqs individually.
>
> In the current qemu version with no ASID support, all vq groups (data
> and cvq) are assigned to asid 0 at the device reset. In this case,
> emulated cvq also needs to receive the mappings, because guest's CVQ
> commands will go from the guest's ASID directly.
Ack.
Thanks
>
> Thanks!
>
> > up_write(&ndev->reslock);
> > return err;
> > }
> > @@ -2796,6 +2862,18 @@ static int mlx5_vdpa_suspend(struct vdpa_device *vdev, bool suspend)
> > return 0;
> > }
> >
> > +static int mlx5_set_group_asid(struct vdpa_device *vdev, u32 group,
> > + unsigned int asid)
> > +{
> > + struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
> > +
> > + if (group >= MLX5_VDPA_NUMVQ_GROUPS)
> > + return -EINVAL;
> > +
> > + mvdev->group2asid[group] = asid;
> > + return 0;
> > +}
> > +
> > static const struct vdpa_config_ops mlx5_vdpa_ops = {
> > .set_vq_address = mlx5_vdpa_set_vq_address,
> > .set_vq_num = mlx5_vdpa_set_vq_num,
> > @@ -2825,6 +2903,7 @@ static const struct vdpa_config_ops mlx5_vdpa_ops = {
> > .set_config = mlx5_vdpa_set_config,
> > .get_generation = mlx5_vdpa_get_generation,
> > .set_map = mlx5_vdpa_set_map,
> > + .set_group_asid = mlx5_set_group_asid,
> > .free = mlx5_vdpa_free,
> > .suspend = mlx5_vdpa_suspend,
> > };
> > @@ -3047,7 +3126,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name,
> > }
> >
> > ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, mdev->device, &mlx5_vdpa_ops,
> > - 1, 1, name, false);
> > + MLX5_VDPA_NUMVQ_GROUPS, MLX5_VDPA_NUM_AS, name, false);
> > if (IS_ERR(ndev))
> > return PTR_ERR(ndev);
> >
> > --
> > 2.35.1
> >
>
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH RFC 3/3] vdpa/mlx5: Disable VLAN support to support live migration
[not found] ` <CAJaqyWdnuX0KLu7j3M4ovtW=N5kFObgaU3z2hu4xoRXY5Fk+aQ@mail.gmail.com>
@ 2022-06-20 9:25 ` Jason Wang
0 siblings, 0 replies; 12+ messages in thread
From: Jason Wang @ 2022-06-20 9:25 UTC (permalink / raw)
To: Eugenio Perez Martin; +Cc: mst, linux-kernel, virtualization, Eli Cohen
On Mon, Jun 20, 2022 at 5:02 PM Eugenio Perez Martin
<eperezma@redhat.com> wrote:
>
> On Mon, Jun 20, 2022 at 10:48 AM Jason Wang <jasowang@redhat.com> wrote:
> >
> > On Thu, Jun 16, 2022 at 9:28 PM Eli Cohen <elic@nvidia.com> wrote:
> > >
> > > Current qemu code does not support live migration for devices supporting
> > > VLAN. Disable it.
> >
> > This looks like a bug that we need to fix in Qemu.
> >
>
> Not a but, but a lack of a feature :). Each cvq command needs new code
> to inject it at the destination, and only set mac cmd is implemented
> at the moment. Only to start simple.
I think we don't need this in the formal patch? (Anyhow we could
disable ctrl vlan vic command line)
Thanks
>
> Thanks!
>
> > Thanks
> >
> > >
> > > Note: this patch is provided just to enable testing with current qemu.
> > >
> > > Signed-off-by: Eli Cohen <elic@nvidia.com>
> > > ---
> > > drivers/vdpa/mlx5/net/mlx5_vnet.c | 1 -
> > > 1 file changed, 1 deletion(-)
> > >
> > > diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > > index 34bd81cb697c..1568cfdf07e6 100644
> > > --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > > +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > > @@ -2172,7 +2172,6 @@ static u64 get_supported_features(struct mlx5_core_dev *mdev)
> > > mlx_vdpa_features |= BIT_ULL(VIRTIO_NET_F_MQ);
> > > mlx_vdpa_features |= BIT_ULL(VIRTIO_NET_F_STATUS);
> > > mlx_vdpa_features |= BIT_ULL(VIRTIO_NET_F_MTU);
> > > - mlx_vdpa_features |= BIT_ULL(VIRTIO_NET_F_CTRL_VLAN);
> > >
> > > return mlx_vdpa_features;
> > > }
> > > --
> > > 2.35.1
> > >
> >
>
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH RFC 1/3] vdpa/mlx5: Implement susupend virtqueue callback
[not found] ` <CAJaqyWfTG_jVW6Vzf64QO=255kfwWKn4gCUMeGog-1shHx3O_g@mail.gmail.com>
@ 2022-06-20 10:06 ` Michael S. Tsirkin
2022-06-21 3:04 ` Jason Wang
1 sibling, 0 replies; 12+ messages in thread
From: Michael S. Tsirkin @ 2022-06-20 10:06 UTC (permalink / raw)
To: Eugenio Perez Martin; +Cc: linux-kernel, virtualization, Eli Cohen
On Mon, Jun 20, 2022 at 11:58:33AM +0200, Eugenio Perez Martin wrote:
> On Mon, Jun 20, 2022 at 10:56 AM Jason Wang <jasowang@redhat.com> wrote:
> >
> > On Thu, Jun 16, 2022 at 9:27 PM Eli Cohen <elic@nvidia.com> wrote:
> > >
> > > Implement the suspend callback allowing to suspend the virtqueues so
> > > they stop processing descriptors. This is required to allow the shadow
> > > virtqueue to kick in.
> > >
> > > Signed-off-by: Eli Cohen <elic@nvidia.com>
> > > ---
> > > drivers/vdpa/mlx5/net/mlx5_vnet.c | 68 +++++++++++++++++++++++++++++-
> > > include/linux/mlx5/mlx5_ifc_vdpa.h | 8 ++++
> > > 2 files changed, 75 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > > index fb0b23e71383..ea4bc8a0cd25 100644
> > > --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > > +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > > @@ -895,6 +895,7 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque
> > > if (err)
> > > goto err_cmd;
> > >
> > > + mvq->fw_state = MLX5_VIRTIO_NET_Q_OBJECT_STATE_INIT;
> > > kfree(in);
> > > mvq->virtq_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
> > >
> > > @@ -922,6 +923,7 @@ static void destroy_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtq
> > > mlx5_vdpa_warn(&ndev->mvdev, "destroy virtqueue 0x%x\n", mvq->virtq_id);
> > > return;
> > > }
> > > + mvq->fw_state = MLX5_VIRTIO_NET_Q_OBJECT_NONE;
> > > umems_destroy(ndev, mvq);
> > > }
> > >
> > > @@ -1121,6 +1123,20 @@ static int query_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueu
> > > return err;
> > > }
> > >
> > > +static bool is_valid_state_change(int oldstate, int newstate)
> > > +{
> > > + switch (oldstate) {
> > > + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_INIT:
> > > + return newstate == MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY;
> > > + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY:
> > > + return newstate == MLX5_VIRTIO_NET_Q_OBJECT_STATE_SUSPEND;
> > > + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_SUSPEND:
> > > + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_ERR:
> > > + default:
> > > + return false;
> > > + }
> > > +}
> > > +
> > > static int modify_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq, int state)
> > > {
> > > int inlen = MLX5_ST_SZ_BYTES(modify_virtio_net_q_in);
> > > @@ -1130,6 +1146,12 @@ static int modify_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque
> > > void *in;
> > > int err;
> > >
> > > + if (mvq->fw_state == MLX5_VIRTIO_NET_Q_OBJECT_NONE)
> > > + return 0;
> > > +
> > > + if (!is_valid_state_change(mvq->fw_state, state))
> > > + return -EINVAL;
> > > +
> > > in = kzalloc(inlen, GFP_KERNEL);
> > > if (!in)
> > > return -ENOMEM;
> > > @@ -1991,6 +2013,7 @@ static void mlx5_vdpa_set_vq_ready(struct vdpa_device *vdev, u16 idx, bool ready
> > > struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
> > > struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
> > > struct mlx5_vdpa_virtqueue *mvq;
> > > + int err;
> > >
> > > if (!mvdev->actual_features)
> > > return;
> > > @@ -2004,8 +2027,16 @@ static void mlx5_vdpa_set_vq_ready(struct vdpa_device *vdev, u16 idx, bool ready
> > > }
> > >
> > > mvq = &ndev->vqs[idx];
> > > - if (!ready)
> > > + if (!ready) {
> > > suspend_vq(ndev, mvq);
> > > + } else {
> > > + err = modify_virtqueue(ndev, mvq, MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY);
> > > + if (err) {
> > > + mlx5_vdpa_warn(mvdev, "modify VQ %d to ready failed (%d)\n", idx, err);
> > > + ready = false;
> > > + }
> > > + }
> > > +
> > >
> > > mvq->ready = ready;
> > > }
> > > @@ -2732,6 +2763,39 @@ static int mlx5_vdpa_get_vendor_vq_stats(struct vdpa_device *vdev, u16 idx,
> > > return err;
> > > }
> > >
> > > +static void mlx5_vdpa_cvq_suspend(struct mlx5_vdpa_dev *mvdev, bool suspend)
> > > +{
> > > + struct mlx5_control_vq *cvq;
> > > +
> > > + if (!(mvdev->actual_features & BIT_ULL(VIRTIO_NET_F_CTRL_VQ)))
> > > + return;
> > > +
> > > + cvq = &mvdev->cvq;
> > > + cvq->ready = !suspend;
> > > +}
> >
> > It looks to me we need to synchronize this with reslock. And this
> > probably deserve a dedicated fix.
> >
> > > +
> > > +static int mlx5_vdpa_suspend(struct vdpa_device *vdev, bool suspend)
> > > +{
> > > + struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
> > > + struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
> > > + struct mlx5_vdpa_virtqueue *mvq;
> > > + int i;
> > > +
> > > + if (!suspend) {
> > > + mlx5_vdpa_warn(mvdev, "Resume of virtqueues is not supported\n");
> > > + return -EOPNOTSUPP;
> > > + }
> > > +
> > > + down_write(&ndev->reslock);
> > > + for (i = 0; i < ndev->cur_num_vqs; i++) {
> > > + mvq = &ndev->vqs[i];
> > > + suspend_vq(ndev, mvq);
> > > + }
> > > + mlx5_vdpa_cvq_suspend(mvdev, suspend);
> >
> > Do we need to synchronize with the carrier work here? Otherwise we may
> > get config notification after suspending.
> >
> > > + up_write(&ndev->reslock);
> > > + return 0;
> > > +}
> > > +
> > > static const struct vdpa_config_ops mlx5_vdpa_ops = {
> > > .set_vq_address = mlx5_vdpa_set_vq_address,
> > > .set_vq_num = mlx5_vdpa_set_vq_num,
> > > @@ -2762,6 +2826,7 @@ static const struct vdpa_config_ops mlx5_vdpa_ops = {
> > > .get_generation = mlx5_vdpa_get_generation,
> > > .set_map = mlx5_vdpa_set_map,
> > > .free = mlx5_vdpa_free,
> > > + .suspend = mlx5_vdpa_suspend,
> >
> > I don't see the vDPA bus patch to enable this method. Or anything I missed here?
> >
>
> Should we add
> Based-on: <20220526124338.36247-1-eperezma@redhat.com>
>
> To this series?
If it's based on your patch then mentioning this in the log and
including the S.O.B. is customary. what would this tag add?
was there relevant discussion?
> > Thanks
> >
> > > };
> > >
> > > static int query_mtu(struct mlx5_core_dev *mdev, u16 *mtu)
> > > @@ -2827,6 +2892,7 @@ static void init_mvqs(struct mlx5_vdpa_net *ndev)
> > > mvq->index = i;
> > > mvq->ndev = ndev;
> > > mvq->fwqp.fw = true;
> > > + mvq->fw_state = MLX5_VIRTIO_NET_Q_OBJECT_NONE;
> > > }
> > > for (; i < ndev->mvdev.max_vqs; i++) {
> > > mvq = &ndev->vqs[i];
> > > diff --git a/include/linux/mlx5/mlx5_ifc_vdpa.h b/include/linux/mlx5/mlx5_ifc_vdpa.h
> > > index 4414ed5b6ed2..423562f39d3c 100644
> > > --- a/include/linux/mlx5/mlx5_ifc_vdpa.h
> > > +++ b/include/linux/mlx5/mlx5_ifc_vdpa.h
> > > @@ -150,6 +150,14 @@ enum {
> > > MLX5_VIRTIO_NET_Q_OBJECT_STATE_ERR = 0x3,
> > > };
> > >
> > > +/* This indicates that the object was not created or has alreadyi
> > > + * been desroyed. It is very safe to assume that this object will never
> > > + * have so many states
> > > + */
> > > +enum {
> > > + MLX5_VIRTIO_NET_Q_OBJECT_NONE = 0xffffffff
> > > +};
> > > +
> > > enum {
> > > MLX5_RQTC_LIST_Q_TYPE_RQ = 0x0,
> > > MLX5_RQTC_LIST_Q_TYPE_VIRTIO_NET_Q = 0x1,
> > > --
> > > 2.35.1
> > >
> >
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH RFC 1/3] vdpa/mlx5: Implement susupend virtqueue callback
[not found] ` <DM8PR12MB54004277F21D682A3EE6D1C1ABB09@DM8PR12MB5400.namprd12.prod.outlook.com>
@ 2022-06-21 2:58 ` Jason Wang
0 siblings, 0 replies; 12+ messages in thread
From: Jason Wang @ 2022-06-21 2:58 UTC (permalink / raw)
To: Eli Cohen; +Cc: mst, linux-kernel, virtualization, eperezma
On Mon, Jun 20, 2022 at 9:09 PM Eli Cohen <elic@nvidia.com> wrote:
>
> > -----Original Message-----
> > From: Jason Wang <jasowang@redhat.com>
> > Sent: Monday, June 20, 2022 11:56 AM
> > To: Eli Cohen <elic@nvidia.com>
> > Cc: eperezma <eperezma@redhat.com>; mst <mst@redhat.com>; virtualization <virtualization@lists.linux-foundation.org>; linux-
> > kernel <linux-kernel@vger.kernel.org>; Si-Wei Liu <si-wei.liu@oracle.com>; Parav Pandit <parav@nvidia.com>
> > Subject: Re: [PATCH RFC 1/3] vdpa/mlx5: Implement susupend virtqueue callback
> >
> > On Thu, Jun 16, 2022 at 9:27 PM Eli Cohen <elic@nvidia.com> wrote:
> > >
> > > Implement the suspend callback allowing to suspend the virtqueues so
> > > they stop processing descriptors. This is required to allow the shadow
> > > virtqueue to kick in.
> > >
> > > Signed-off-by: Eli Cohen <elic@nvidia.com>
> > > ---
> > > drivers/vdpa/mlx5/net/mlx5_vnet.c | 68 +++++++++++++++++++++++++++++-
> > > include/linux/mlx5/mlx5_ifc_vdpa.h | 8 ++++
> > > 2 files changed, 75 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > > index fb0b23e71383..ea4bc8a0cd25 100644
> > > --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > > +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > > @@ -895,6 +895,7 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque
> > > if (err)
> > > goto err_cmd;
> > >
> > > + mvq->fw_state = MLX5_VIRTIO_NET_Q_OBJECT_STATE_INIT;
> > > kfree(in);
> > > mvq->virtq_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
> > >
> > > @@ -922,6 +923,7 @@ static void destroy_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtq
> > > mlx5_vdpa_warn(&ndev->mvdev, "destroy virtqueue 0x%x\n", mvq->virtq_id);
> > > return;
> > > }
> > > + mvq->fw_state = MLX5_VIRTIO_NET_Q_OBJECT_NONE;
> > > umems_destroy(ndev, mvq);
> > > }
> > >
> > > @@ -1121,6 +1123,20 @@ static int query_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueu
> > > return err;
> > > }
> > >
> > > +static bool is_valid_state_change(int oldstate, int newstate)
> > > +{
> > > + switch (oldstate) {
> > > + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_INIT:
> > > + return newstate == MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY;
> > > + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY:
> > > + return newstate == MLX5_VIRTIO_NET_Q_OBJECT_STATE_SUSPEND;
> > > + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_SUSPEND:
> > > + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_ERR:
> > > + default:
> > > + return false;
> > > + }
> > > +}
> > > +
> > > static int modify_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq, int state)
> > > {
> > > int inlen = MLX5_ST_SZ_BYTES(modify_virtio_net_q_in);
> > > @@ -1130,6 +1146,12 @@ static int modify_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque
> > > void *in;
> > > int err;
> > >
> > > + if (mvq->fw_state == MLX5_VIRTIO_NET_Q_OBJECT_NONE)
> > > + return 0;
> > > +
> > > + if (!is_valid_state_change(mvq->fw_state, state))
> > > + return -EINVAL;
> > > +
> > > in = kzalloc(inlen, GFP_KERNEL);
> > > if (!in)
> > > return -ENOMEM;
> > > @@ -1991,6 +2013,7 @@ static void mlx5_vdpa_set_vq_ready(struct vdpa_device *vdev, u16 idx, bool ready
> > > struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
> > > struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
> > > struct mlx5_vdpa_virtqueue *mvq;
> > > + int err;
> > >
> > > if (!mvdev->actual_features)
> > > return;
> > > @@ -2004,8 +2027,16 @@ static void mlx5_vdpa_set_vq_ready(struct vdpa_device *vdev, u16 idx, bool ready
> > > }
> > >
> > > mvq = &ndev->vqs[idx];
> > > - if (!ready)
> > > + if (!ready) {
> > > suspend_vq(ndev, mvq);
> > > + } else {
> > > + err = modify_virtqueue(ndev, mvq, MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY);
> > > + if (err) {
> > > + mlx5_vdpa_warn(mvdev, "modify VQ %d to ready failed (%d)\n", idx, err);
> > > + ready = false;
> > > + }
> > > + }
> > > +
> > >
> > > mvq->ready = ready;
> > > }
> > > @@ -2732,6 +2763,39 @@ static int mlx5_vdpa_get_vendor_vq_stats(struct vdpa_device *vdev, u16 idx,
> > > return err;
> > > }
> > >
> > > +static void mlx5_vdpa_cvq_suspend(struct mlx5_vdpa_dev *mvdev, bool suspend)
> > > +{
> > > + struct mlx5_control_vq *cvq;
> > > +
> > > + if (!(mvdev->actual_features & BIT_ULL(VIRTIO_NET_F_CTRL_VQ)))
> > > + return;
> > > +
> > > + cvq = &mvdev->cvq;
> > > + cvq->ready = !suspend;
> > > +}
> >
> > It looks to me we need to synchronize this with reslock. And this
> > probably deserve a dedicated fix.
> >
>
> It's already being held by mlx5_vdpa_suspend
Right, but I meant this seems kind of duplicated with set_cvq_ready(),
can we unify them? (We don't hold reslock there).
>
> > > +
> > > +static int mlx5_vdpa_suspend(struct vdpa_device *vdev, bool suspend)
> > > +{
> > > + struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
> > > + struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
> > > + struct mlx5_vdpa_virtqueue *mvq;
> > > + int i;
> > > +
> > > + if (!suspend) {
> > > + mlx5_vdpa_warn(mvdev, "Resume of virtqueues is not supported\n");
> > > + return -EOPNOTSUPP;
> > > + }
> > > +
> > > + down_write(&ndev->reslock);
> > > + for (i = 0; i < ndev->cur_num_vqs; i++) {
> > > + mvq = &ndev->vqs[i];
> > > + suspend_vq(ndev, mvq);
> > > + }
> > > + mlx5_vdpa_cvq_suspend(mvdev, suspend);
> >
> > Do we need to synchronize with the carrier work here? Otherwise we may
> > get config notification after suspending.
> >
>
> Are you saying we should not allow carrier updates after the VQs have been suspended?
> Link state should not be related to suspension of VQs.
Yes, it's not related to the VQ but we suspend the device here. So we
probably need to flush the carrier work.
Thanks
>
> > > + up_write(&ndev->reslock);
> > > + return 0;
> > > +}
> > > +
> > > static const struct vdpa_config_ops mlx5_vdpa_ops = {
> > > .set_vq_address = mlx5_vdpa_set_vq_address,
> > > .set_vq_num = mlx5_vdpa_set_vq_num,
> > > @@ -2762,6 +2826,7 @@ static const struct vdpa_config_ops mlx5_vdpa_ops = {
> > > .get_generation = mlx5_vdpa_get_generation,
> > > .set_map = mlx5_vdpa_set_map,
> > > .free = mlx5_vdpa_free,
> > > + .suspend = mlx5_vdpa_suspend,
> >
> > I don't see the vDPA bus patch to enable this method. Or anything I missed here?
> >
> > Thanks
> >
> > > };
> > >
> > > static int query_mtu(struct mlx5_core_dev *mdev, u16 *mtu)
> > > @@ -2827,6 +2892,7 @@ static void init_mvqs(struct mlx5_vdpa_net *ndev)
> > > mvq->index = i;
> > > mvq->ndev = ndev;
> > > mvq->fwqp.fw = true;
> > > + mvq->fw_state = MLX5_VIRTIO_NET_Q_OBJECT_NONE;
> > > }
> > > for (; i < ndev->mvdev.max_vqs; i++) {
> > > mvq = &ndev->vqs[i];
> > > diff --git a/include/linux/mlx5/mlx5_ifc_vdpa.h b/include/linux/mlx5/mlx5_ifc_vdpa.h
> > > index 4414ed5b6ed2..423562f39d3c 100644
> > > --- a/include/linux/mlx5/mlx5_ifc_vdpa.h
> > > +++ b/include/linux/mlx5/mlx5_ifc_vdpa.h
> > > @@ -150,6 +150,14 @@ enum {
> > > MLX5_VIRTIO_NET_Q_OBJECT_STATE_ERR = 0x3,
> > > };
> > >
> > > +/* This indicates that the object was not created or has alreadyi
> > > + * been desroyed. It is very safe to assume that this object will never
> > > + * have so many states
> > > + */
> > > +enum {
> > > + MLX5_VIRTIO_NET_Q_OBJECT_NONE = 0xffffffff
> > > +};
> > > +
> > > enum {
> > > MLX5_RQTC_LIST_Q_TYPE_RQ = 0x0,
> > > MLX5_RQTC_LIST_Q_TYPE_VIRTIO_NET_Q = 0x1,
> > > --
> > > 2.35.1
> > >
>
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH RFC 1/3] vdpa/mlx5: Implement susupend virtqueue callback
[not found] ` <CAJaqyWfTG_jVW6Vzf64QO=255kfwWKn4gCUMeGog-1shHx3O_g@mail.gmail.com>
2022-06-20 10:06 ` Michael S. Tsirkin
@ 2022-06-21 3:04 ` Jason Wang
[not found] ` <CAJaqyWfDQ5RhHPuW2DnJ3o72+e5LMzZ9vjp6rD4kYh9G7KgCvw@mail.gmail.com>
[not found] ` <DM8PR12MB5400FDBB177693A55074D19EAB879@DM8PR12MB5400.namprd12.prod.outlook.com>
1 sibling, 2 replies; 12+ messages in thread
From: Jason Wang @ 2022-06-21 3:04 UTC (permalink / raw)
To: Eugenio Perez Martin; +Cc: mst, linux-kernel, virtualization, Eli Cohen
On Mon, Jun 20, 2022 at 5:59 PM Eugenio Perez Martin
<eperezma@redhat.com> wrote:
>
> On Mon, Jun 20, 2022 at 10:56 AM Jason Wang <jasowang@redhat.com> wrote:
> >
> > On Thu, Jun 16, 2022 at 9:27 PM Eli Cohen <elic@nvidia.com> wrote:
> > >
> > > Implement the suspend callback allowing to suspend the virtqueues so
> > > they stop processing descriptors. This is required to allow the shadow
> > > virtqueue to kick in.
> > >
> > > Signed-off-by: Eli Cohen <elic@nvidia.com>
> > > ---
> > > drivers/vdpa/mlx5/net/mlx5_vnet.c | 68 +++++++++++++++++++++++++++++-
> > > include/linux/mlx5/mlx5_ifc_vdpa.h | 8 ++++
> > > 2 files changed, 75 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > > index fb0b23e71383..ea4bc8a0cd25 100644
> > > --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > > +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > > @@ -895,6 +895,7 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque
> > > if (err)
> > > goto err_cmd;
> > >
> > > + mvq->fw_state = MLX5_VIRTIO_NET_Q_OBJECT_STATE_INIT;
> > > kfree(in);
> > > mvq->virtq_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
> > >
> > > @@ -922,6 +923,7 @@ static void destroy_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtq
> > > mlx5_vdpa_warn(&ndev->mvdev, "destroy virtqueue 0x%x\n", mvq->virtq_id);
> > > return;
> > > }
> > > + mvq->fw_state = MLX5_VIRTIO_NET_Q_OBJECT_NONE;
> > > umems_destroy(ndev, mvq);
> > > }
> > >
> > > @@ -1121,6 +1123,20 @@ static int query_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueu
> > > return err;
> > > }
> > >
> > > +static bool is_valid_state_change(int oldstate, int newstate)
> > > +{
> > > + switch (oldstate) {
> > > + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_INIT:
> > > + return newstate == MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY;
> > > + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY:
> > > + return newstate == MLX5_VIRTIO_NET_Q_OBJECT_STATE_SUSPEND;
> > > + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_SUSPEND:
> > > + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_ERR:
> > > + default:
> > > + return false;
> > > + }
> > > +}
> > > +
> > > static int modify_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq, int state)
> > > {
> > > int inlen = MLX5_ST_SZ_BYTES(modify_virtio_net_q_in);
> > > @@ -1130,6 +1146,12 @@ static int modify_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque
> > > void *in;
> > > int err;
> > >
> > > + if (mvq->fw_state == MLX5_VIRTIO_NET_Q_OBJECT_NONE)
> > > + return 0;
> > > +
> > > + if (!is_valid_state_change(mvq->fw_state, state))
> > > + return -EINVAL;
> > > +
> > > in = kzalloc(inlen, GFP_KERNEL);
> > > if (!in)
> > > return -ENOMEM;
> > > @@ -1991,6 +2013,7 @@ static void mlx5_vdpa_set_vq_ready(struct vdpa_device *vdev, u16 idx, bool ready
> > > struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
> > > struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
> > > struct mlx5_vdpa_virtqueue *mvq;
> > > + int err;
> > >
> > > if (!mvdev->actual_features)
> > > return;
> > > @@ -2004,8 +2027,16 @@ static void mlx5_vdpa_set_vq_ready(struct vdpa_device *vdev, u16 idx, bool ready
> > > }
> > >
> > > mvq = &ndev->vqs[idx];
> > > - if (!ready)
> > > + if (!ready) {
> > > suspend_vq(ndev, mvq);
> > > + } else {
> > > + err = modify_virtqueue(ndev, mvq, MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY);
> > > + if (err) {
> > > + mlx5_vdpa_warn(mvdev, "modify VQ %d to ready failed (%d)\n", idx, err);
> > > + ready = false;
> > > + }
> > > + }
> > > +
> > >
> > > mvq->ready = ready;
> > > }
> > > @@ -2732,6 +2763,39 @@ static int mlx5_vdpa_get_vendor_vq_stats(struct vdpa_device *vdev, u16 idx,
> > > return err;
> > > }
> > >
> > > +static void mlx5_vdpa_cvq_suspend(struct mlx5_vdpa_dev *mvdev, bool suspend)
> > > +{
> > > + struct mlx5_control_vq *cvq;
> > > +
> > > + if (!(mvdev->actual_features & BIT_ULL(VIRTIO_NET_F_CTRL_VQ)))
> > > + return;
> > > +
> > > + cvq = &mvdev->cvq;
> > > + cvq->ready = !suspend;
> > > +}
> >
> > It looks to me we need to synchronize this with reslock. And this
> > probably deserve a dedicated fix.
> >
> > > +
> > > +static int mlx5_vdpa_suspend(struct vdpa_device *vdev, bool suspend)
> > > +{
> > > + struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
> > > + struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
> > > + struct mlx5_vdpa_virtqueue *mvq;
> > > + int i;
> > > +
> > > + if (!suspend) {
> > > + mlx5_vdpa_warn(mvdev, "Resume of virtqueues is not supported\n");
> > > + return -EOPNOTSUPP;
> > > + }
> > > +
> > > + down_write(&ndev->reslock);
> > > + for (i = 0; i < ndev->cur_num_vqs; i++) {
> > > + mvq = &ndev->vqs[i];
> > > + suspend_vq(ndev, mvq);
> > > + }
> > > + mlx5_vdpa_cvq_suspend(mvdev, suspend);
> >
> > Do we need to synchronize with the carrier work here? Otherwise we may
> > get config notification after suspending.
> >
> > > + up_write(&ndev->reslock);
> > > + return 0;
> > > +}
> > > +
> > > static const struct vdpa_config_ops mlx5_vdpa_ops = {
> > > .set_vq_address = mlx5_vdpa_set_vq_address,
> > > .set_vq_num = mlx5_vdpa_set_vq_num,
> > > @@ -2762,6 +2826,7 @@ static const struct vdpa_config_ops mlx5_vdpa_ops = {
> > > .get_generation = mlx5_vdpa_get_generation,
> > > .set_map = mlx5_vdpa_set_map,
> > > .free = mlx5_vdpa_free,
> > > + .suspend = mlx5_vdpa_suspend,
> >
> > I don't see the vDPA bus patch to enable this method. Or anything I missed here?
> >
>
> Should we add
> Based-on: <20220526124338.36247-1-eperezma@redhat.com>
>
> To this series?
Probably, but that series seems to support resume while this series doesn't.
Any reason for this?
(I don't see any blocker for this especially considering parents can
choose to do reset + set_vring_state etc.)
Thanks
>
> > Thanks
> >
> > > };
> > >
> > > static int query_mtu(struct mlx5_core_dev *mdev, u16 *mtu)
> > > @@ -2827,6 +2892,7 @@ static void init_mvqs(struct mlx5_vdpa_net *ndev)
> > > mvq->index = i;
> > > mvq->ndev = ndev;
> > > mvq->fwqp.fw = true;
> > > + mvq->fw_state = MLX5_VIRTIO_NET_Q_OBJECT_NONE;
> > > }
> > > for (; i < ndev->mvdev.max_vqs; i++) {
> > > mvq = &ndev->vqs[i];
> > > diff --git a/include/linux/mlx5/mlx5_ifc_vdpa.h b/include/linux/mlx5/mlx5_ifc_vdpa.h
> > > index 4414ed5b6ed2..423562f39d3c 100644
> > > --- a/include/linux/mlx5/mlx5_ifc_vdpa.h
> > > +++ b/include/linux/mlx5/mlx5_ifc_vdpa.h
> > > @@ -150,6 +150,14 @@ enum {
> > > MLX5_VIRTIO_NET_Q_OBJECT_STATE_ERR = 0x3,
> > > };
> > >
> > > +/* This indicates that the object was not created or has alreadyi
> > > + * been desroyed. It is very safe to assume that this object will never
> > > + * have so many states
> > > + */
> > > +enum {
> > > + MLX5_VIRTIO_NET_Q_OBJECT_NONE = 0xffffffff
> > > +};
> > > +
> > > enum {
> > > MLX5_RQTC_LIST_Q_TYPE_RQ = 0x0,
> > > MLX5_RQTC_LIST_Q_TYPE_VIRTIO_NET_Q = 0x1,
> > > --
> > > 2.35.1
> > >
> >
>
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH RFC 1/3] vdpa/mlx5: Implement susupend virtqueue callback
[not found] ` <CAJaqyWfDQ5RhHPuW2DnJ3o72+e5LMzZ9vjp6rD4kYh9G7KgCvw@mail.gmail.com>
@ 2022-06-21 7:52 ` Jason Wang
0 siblings, 0 replies; 12+ messages in thread
From: Jason Wang @ 2022-06-21 7:52 UTC (permalink / raw)
To: Eugenio Perez Martin; +Cc: mst, linux-kernel, virtualization, Eli Cohen
On Tue, Jun 21, 2022 at 3:49 PM Eugenio Perez Martin
<eperezma@redhat.com> wrote:
>
> On Tue, Jun 21, 2022 at 5:05 AM Jason Wang <jasowang@redhat.com> wrote:
> >
> > On Mon, Jun 20, 2022 at 5:59 PM Eugenio Perez Martin
> > <eperezma@redhat.com> wrote:
> > >
> > > On Mon, Jun 20, 2022 at 10:56 AM Jason Wang <jasowang@redhat.com> wrote:
> > > >
> > > > On Thu, Jun 16, 2022 at 9:27 PM Eli Cohen <elic@nvidia.com> wrote:
> > > > >
> > > > > Implement the suspend callback allowing to suspend the virtqueues so
> > > > > they stop processing descriptors. This is required to allow the shadow
> > > > > virtqueue to kick in.
> > > > >
> > > > > Signed-off-by: Eli Cohen <elic@nvidia.com>
> > > > > ---
> > > > > drivers/vdpa/mlx5/net/mlx5_vnet.c | 68 +++++++++++++++++++++++++++++-
> > > > > include/linux/mlx5/mlx5_ifc_vdpa.h | 8 ++++
> > > > > 2 files changed, 75 insertions(+), 1 deletion(-)
> > > > >
> > > > > diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > > > > index fb0b23e71383..ea4bc8a0cd25 100644
> > > > > --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > > > > +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > > > > @@ -895,6 +895,7 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque
> > > > > if (err)
> > > > > goto err_cmd;
> > > > >
> > > > > + mvq->fw_state = MLX5_VIRTIO_NET_Q_OBJECT_STATE_INIT;
> > > > > kfree(in);
> > > > > mvq->virtq_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
> > > > >
> > > > > @@ -922,6 +923,7 @@ static void destroy_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtq
> > > > > mlx5_vdpa_warn(&ndev->mvdev, "destroy virtqueue 0x%x\n", mvq->virtq_id);
> > > > > return;
> > > > > }
> > > > > + mvq->fw_state = MLX5_VIRTIO_NET_Q_OBJECT_NONE;
> > > > > umems_destroy(ndev, mvq);
> > > > > }
> > > > >
> > > > > @@ -1121,6 +1123,20 @@ static int query_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueu
> > > > > return err;
> > > > > }
> > > > >
> > > > > +static bool is_valid_state_change(int oldstate, int newstate)
> > > > > +{
> > > > > + switch (oldstate) {
> > > > > + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_INIT:
> > > > > + return newstate == MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY;
> > > > > + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY:
> > > > > + return newstate == MLX5_VIRTIO_NET_Q_OBJECT_STATE_SUSPEND;
> > > > > + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_SUSPEND:
> > > > > + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_ERR:
> > > > > + default:
> > > > > + return false;
> > > > > + }
> > > > > +}
> > > > > +
> > > > > static int modify_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq, int state)
> > > > > {
> > > > > int inlen = MLX5_ST_SZ_BYTES(modify_virtio_net_q_in);
> > > > > @@ -1130,6 +1146,12 @@ static int modify_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque
> > > > > void *in;
> > > > > int err;
> > > > >
> > > > > + if (mvq->fw_state == MLX5_VIRTIO_NET_Q_OBJECT_NONE)
> > > > > + return 0;
> > > > > +
> > > > > + if (!is_valid_state_change(mvq->fw_state, state))
> > > > > + return -EINVAL;
> > > > > +
> > > > > in = kzalloc(inlen, GFP_KERNEL);
> > > > > if (!in)
> > > > > return -ENOMEM;
> > > > > @@ -1991,6 +2013,7 @@ static void mlx5_vdpa_set_vq_ready(struct vdpa_device *vdev, u16 idx, bool ready
> > > > > struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
> > > > > struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
> > > > > struct mlx5_vdpa_virtqueue *mvq;
> > > > > + int err;
> > > > >
> > > > > if (!mvdev->actual_features)
> > > > > return;
> > > > > @@ -2004,8 +2027,16 @@ static void mlx5_vdpa_set_vq_ready(struct vdpa_device *vdev, u16 idx, bool ready
> > > > > }
> > > > >
> > > > > mvq = &ndev->vqs[idx];
> > > > > - if (!ready)
> > > > > + if (!ready) {
> > > > > suspend_vq(ndev, mvq);
> > > > > + } else {
> > > > > + err = modify_virtqueue(ndev, mvq, MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY);
> > > > > + if (err) {
> > > > > + mlx5_vdpa_warn(mvdev, "modify VQ %d to ready failed (%d)\n", idx, err);
> > > > > + ready = false;
> > > > > + }
> > > > > + }
> > > > > +
> > > > >
> > > > > mvq->ready = ready;
> > > > > }
> > > > > @@ -2732,6 +2763,39 @@ static int mlx5_vdpa_get_vendor_vq_stats(struct vdpa_device *vdev, u16 idx,
> > > > > return err;
> > > > > }
> > > > >
> > > > > +static void mlx5_vdpa_cvq_suspend(struct mlx5_vdpa_dev *mvdev, bool suspend)
> > > > > +{
> > > > > + struct mlx5_control_vq *cvq;
> > > > > +
> > > > > + if (!(mvdev->actual_features & BIT_ULL(VIRTIO_NET_F_CTRL_VQ)))
> > > > > + return;
> > > > > +
> > > > > + cvq = &mvdev->cvq;
> > > > > + cvq->ready = !suspend;
> > > > > +}
> > > >
> > > > It looks to me we need to synchronize this with reslock. And this
> > > > probably deserve a dedicated fix.
> > > >
> > > > > +
> > > > > +static int mlx5_vdpa_suspend(struct vdpa_device *vdev, bool suspend)
> > > > > +{
> > > > > + struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
> > > > > + struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
> > > > > + struct mlx5_vdpa_virtqueue *mvq;
> > > > > + int i;
> > > > > +
> > > > > + if (!suspend) {
> > > > > + mlx5_vdpa_warn(mvdev, "Resume of virtqueues is not supported\n");
> > > > > + return -EOPNOTSUPP;
> > > > > + }
> > > > > +
> > > > > + down_write(&ndev->reslock);
> > > > > + for (i = 0; i < ndev->cur_num_vqs; i++) {
> > > > > + mvq = &ndev->vqs[i];
> > > > > + suspend_vq(ndev, mvq);
> > > > > + }
> > > > > + mlx5_vdpa_cvq_suspend(mvdev, suspend);
> > > >
> > > > Do we need to synchronize with the carrier work here? Otherwise we may
> > > > get config notification after suspending.
> > > >
> > > > > + up_write(&ndev->reslock);
> > > > > + return 0;
> > > > > +}
> > > > > +
> > > > > static const struct vdpa_config_ops mlx5_vdpa_ops = {
> > > > > .set_vq_address = mlx5_vdpa_set_vq_address,
> > > > > .set_vq_num = mlx5_vdpa_set_vq_num,
> > > > > @@ -2762,6 +2826,7 @@ static const struct vdpa_config_ops mlx5_vdpa_ops = {
> > > > > .get_generation = mlx5_vdpa_get_generation,
> > > > > .set_map = mlx5_vdpa_set_map,
> > > > > .free = mlx5_vdpa_free,
> > > > > + .suspend = mlx5_vdpa_suspend,
> > > >
> > > > I don't see the vDPA bus patch to enable this method. Or anything I missed here?
> > > >
> > >
> > > Should we add
> > > Based-on: <20220526124338.36247-1-eperezma@redhat.com>
> > >
> > > To this series?
> >
> > Probably, but that series seems to support resume while this series doesn't.
> >
> > Any reason for this?
> >
> > (I don't see any blocker for this especially considering parents can
> > choose to do reset + set_vring_state etc.)
> >
>
> I suggest starting simple and modify the vdpa_sim series so it only
> provides suspend() operation, with no parameters. We can always add
> the resume() later if needed at all.
This complicates the feature a little bit.
>
> To provide the reset + set_vring_state etc seems simpler if done from userland.
One issue for the current API is that it only works for networking
devices since we don't have a way to set device state.
By having stop/resume, we know the device state is kept.
Thanks
>
> Thanks!
>
> > Thanks
> >
> > >
> > > > Thanks
> > > >
> > > > > };
> > > > >
> > > > > static int query_mtu(struct mlx5_core_dev *mdev, u16 *mtu)
> > > > > @@ -2827,6 +2892,7 @@ static void init_mvqs(struct mlx5_vdpa_net *ndev)
> > > > > mvq->index = i;
> > > > > mvq->ndev = ndev;
> > > > > mvq->fwqp.fw = true;
> > > > > + mvq->fw_state = MLX5_VIRTIO_NET_Q_OBJECT_NONE;
> > > > > }
> > > > > for (; i < ndev->mvdev.max_vqs; i++) {
> > > > > mvq = &ndev->vqs[i];
> > > > > diff --git a/include/linux/mlx5/mlx5_ifc_vdpa.h b/include/linux/mlx5/mlx5_ifc_vdpa.h
> > > > > index 4414ed5b6ed2..423562f39d3c 100644
> > > > > --- a/include/linux/mlx5/mlx5_ifc_vdpa.h
> > > > > +++ b/include/linux/mlx5/mlx5_ifc_vdpa.h
> > > > > @@ -150,6 +150,14 @@ enum {
> > > > > MLX5_VIRTIO_NET_Q_OBJECT_STATE_ERR = 0x3,
> > > > > };
> > > > >
> > > > > +/* This indicates that the object was not created or has alreadyi
> > > > > + * been desroyed. It is very safe to assume that this object will never
> > > > > + * have so many states
> > > > > + */
> > > > > +enum {
> > > > > + MLX5_VIRTIO_NET_Q_OBJECT_NONE = 0xffffffff
> > > > > +};
> > > > > +
> > > > > enum {
> > > > > MLX5_RQTC_LIST_Q_TYPE_RQ = 0x0,
> > > > > MLX5_RQTC_LIST_Q_TYPE_VIRTIO_NET_Q = 0x1,
> > > > > --
> > > > > 2.35.1
> > > > >
> > > >
> > >
> >
>
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH RFC 1/3] vdpa/mlx5: Implement susupend virtqueue callback
[not found] ` <DM8PR12MB5400FDBB177693A55074D19EAB879@DM8PR12MB5400.namprd12.prod.outlook.com>
@ 2022-07-12 8:14 ` Jason Wang
[not found] ` <CAJaqyWcUUk1H2+aeoj7yAFKXSg1gdV2GzTdWUTAGi0AiW9r64w@mail.gmail.com>
0 siblings, 1 reply; 12+ messages in thread
From: Jason Wang @ 2022-07-12 8:14 UTC (permalink / raw)
To: Eli Cohen; +Cc: mst, linux-kernel, virtualization, Eugenio Perez Martin
On Mon, Jul 11, 2022 at 2:14 PM Eli Cohen <elic@nvidia.com> wrote:
>
> > From: Jason Wang <jasowang@redhat.com>
> > Sent: Tuesday, June 21, 2022 6:05 AM
> > To: Eugenio Perez Martin <eperezma@redhat.com>
> > Cc: Eli Cohen <elic@nvidia.com>; mst <mst@redhat.com>; virtualization <virtualization@lists.linux-foundation.org>; linux-kernel
> > <linux-kernel@vger.kernel.org>; Si-Wei Liu <si-wei.liu@oracle.com>; Parav Pandit <parav@nvidia.com>
> > Subject: Re: [PATCH RFC 1/3] vdpa/mlx5: Implement susupend virtqueue callback
> >
> > On Mon, Jun 20, 2022 at 5:59 PM Eugenio Perez Martin
> > <eperezma@redhat.com> wrote:
> > >
> > > On Mon, Jun 20, 2022 at 10:56 AM Jason Wang <jasowang@redhat.com> wrote:
> > > >
> > > > On Thu, Jun 16, 2022 at 9:27 PM Eli Cohen <elic@nvidia.com> wrote:
> > > > >
> > > > > Implement the suspend callback allowing to suspend the virtqueues so
> > > > > they stop processing descriptors. This is required to allow the shadow
> > > > > virtqueue to kick in.
> > > > >
> > > > > Signed-off-by: Eli Cohen <elic@nvidia.com>
> > > > > ---
> > > > > drivers/vdpa/mlx5/net/mlx5_vnet.c | 68 +++++++++++++++++++++++++++++-
> > > > > include/linux/mlx5/mlx5_ifc_vdpa.h | 8 ++++
> > > > > 2 files changed, 75 insertions(+), 1 deletion(-)
> > > > >
> > > > > diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > > > > index fb0b23e71383..ea4bc8a0cd25 100644
> > > > > --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > > > > +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > > > > @@ -895,6 +895,7 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque
> > > > > if (err)
> > > > > goto err_cmd;
> > > > >
> > > > > + mvq->fw_state = MLX5_VIRTIO_NET_Q_OBJECT_STATE_INIT;
> > > > > kfree(in);
> > > > > mvq->virtq_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
> > > > >
> > > > > @@ -922,6 +923,7 @@ static void destroy_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtq
> > > > > mlx5_vdpa_warn(&ndev->mvdev, "destroy virtqueue 0x%x\n", mvq->virtq_id);
> > > > > return;
> > > > > }
> > > > > + mvq->fw_state = MLX5_VIRTIO_NET_Q_OBJECT_NONE;
> > > > > umems_destroy(ndev, mvq);
> > > > > }
> > > > >
> > > > > @@ -1121,6 +1123,20 @@ static int query_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueu
> > > > > return err;
> > > > > }
> > > > >
> > > > > +static bool is_valid_state_change(int oldstate, int newstate)
> > > > > +{
> > > > > + switch (oldstate) {
> > > > > + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_INIT:
> > > > > + return newstate == MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY;
> > > > > + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY:
> > > > > + return newstate == MLX5_VIRTIO_NET_Q_OBJECT_STATE_SUSPEND;
> > > > > + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_SUSPEND:
> > > > > + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_ERR:
> > > > > + default:
> > > > > + return false;
> > > > > + }
> > > > > +}
> > > > > +
> > > > > static int modify_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq, int state)
> > > > > {
> > > > > int inlen = MLX5_ST_SZ_BYTES(modify_virtio_net_q_in);
> > > > > @@ -1130,6 +1146,12 @@ static int modify_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque
> > > > > void *in;
> > > > > int err;
> > > > >
> > > > > + if (mvq->fw_state == MLX5_VIRTIO_NET_Q_OBJECT_NONE)
> > > > > + return 0;
> > > > > +
> > > > > + if (!is_valid_state_change(mvq->fw_state, state))
> > > > > + return -EINVAL;
> > > > > +
> > > > > in = kzalloc(inlen, GFP_KERNEL);
> > > > > if (!in)
> > > > > return -ENOMEM;
> > > > > @@ -1991,6 +2013,7 @@ static void mlx5_vdpa_set_vq_ready(struct vdpa_device *vdev, u16 idx, bool ready
> > > > > struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
> > > > > struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
> > > > > struct mlx5_vdpa_virtqueue *mvq;
> > > > > + int err;
> > > > >
> > > > > if (!mvdev->actual_features)
> > > > > return;
> > > > > @@ -2004,8 +2027,16 @@ static void mlx5_vdpa_set_vq_ready(struct vdpa_device *vdev, u16 idx, bool ready
> > > > > }
> > > > >
> > > > > mvq = &ndev->vqs[idx];
> > > > > - if (!ready)
> > > > > + if (!ready) {
> > > > > suspend_vq(ndev, mvq);
> > > > > + } else {
> > > > > + err = modify_virtqueue(ndev, mvq, MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY);
> > > > > + if (err) {
> > > > > + mlx5_vdpa_warn(mvdev, "modify VQ %d to ready failed (%d)\n", idx, err);
> > > > > + ready = false;
> > > > > + }
> > > > > + }
> > > > > +
> > > > >
> > > > > mvq->ready = ready;
> > > > > }
> > > > > @@ -2732,6 +2763,39 @@ static int mlx5_vdpa_get_vendor_vq_stats(struct vdpa_device *vdev, u16 idx,
> > > > > return err;
> > > > > }
> > > > >
> > > > > +static void mlx5_vdpa_cvq_suspend(struct mlx5_vdpa_dev *mvdev, bool suspend)
> > > > > +{
> > > > > + struct mlx5_control_vq *cvq;
> > > > > +
> > > > > + if (!(mvdev->actual_features & BIT_ULL(VIRTIO_NET_F_CTRL_VQ)))
> > > > > + return;
> > > > > +
> > > > > + cvq = &mvdev->cvq;
> > > > > + cvq->ready = !suspend;
> > > > > +}
> > > >
> > > > It looks to me we need to synchronize this with reslock. And this
> > > > probably deserve a dedicated fix.
> > > >
> > > > > +
> > > > > +static int mlx5_vdpa_suspend(struct vdpa_device *vdev, bool suspend)
> > > > > +{
> > > > > + struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
> > > > > + struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
> > > > > + struct mlx5_vdpa_virtqueue *mvq;
> > > > > + int i;
> > > > > +
> > > > > + if (!suspend) {
> > > > > + mlx5_vdpa_warn(mvdev, "Resume of virtqueues is not supported\n");
> > > > > + return -EOPNOTSUPP;
> > > > > + }
> > > > > +
> > > > > + down_write(&ndev->reslock);
> > > > > + for (i = 0; i < ndev->cur_num_vqs; i++) {
> > > > > + mvq = &ndev->vqs[i];
> > > > > + suspend_vq(ndev, mvq);
> > > > > + }
> > > > > + mlx5_vdpa_cvq_suspend(mvdev, suspend);
> > > >
> > > > Do we need to synchronize with the carrier work here? Otherwise we may
> > > > get config notification after suspending.
> > > >
> > > > > + up_write(&ndev->reslock);
> > > > > + return 0;
> > > > > +}
> > > > > +
> > > > > static const struct vdpa_config_ops mlx5_vdpa_ops = {
> > > > > .set_vq_address = mlx5_vdpa_set_vq_address,
> > > > > .set_vq_num = mlx5_vdpa_set_vq_num,
> > > > > @@ -2762,6 +2826,7 @@ static const struct vdpa_config_ops mlx5_vdpa_ops = {
> > > > > .get_generation = mlx5_vdpa_get_generation,
> > > > > .set_map = mlx5_vdpa_set_map,
> > > > > .free = mlx5_vdpa_free,
> > > > > + .suspend = mlx5_vdpa_suspend,
> > > >
> > > > I don't see the vDPA bus patch to enable this method. Or anything I missed here?
> > > >
> > >
> > > Should we add
> > > Based-on: <20220526124338.36247-1-eperezma@redhat.com>
> > >
> > > To this series?
> >
> > Probably, but that series seems to support resume while this series doesn't.
> >
> > Any reason for this?
>
> I think Eugenio agreed that resume is not really required since we're going stop using this
> instance and migrate. In any case, we don't support resume for the hardware object
> though it could be simulated should it be absolutely necessary.
This is fine if everything is fine during the live migration. But when
migration fails due to some reason, management (libvirt) may choose to
restart the device in the source.
This means we should either
1) support resume in the parent
2) emulate it in the qemu (with a lot of restoring of the states)
And it is not only used for live migration, it could be used for vmstop/start.
Thanks
>
> >
> > (I don't see any blocker for this especially considering parents can
> > choose to do reset + set_vring_state etc.)
> >
> > Thanks
> >
> > >
> > > > Thanks
> > > >
> > > > > };
> > > > >
> > > > > static int query_mtu(struct mlx5_core_dev *mdev, u16 *mtu)
> > > > > @@ -2827,6 +2892,7 @@ static void init_mvqs(struct mlx5_vdpa_net *ndev)
> > > > > mvq->index = i;
> > > > > mvq->ndev = ndev;
> > > > > mvq->fwqp.fw = true;
> > > > > + mvq->fw_state = MLX5_VIRTIO_NET_Q_OBJECT_NONE;
> > > > > }
> > > > > for (; i < ndev->mvdev.max_vqs; i++) {
> > > > > mvq = &ndev->vqs[i];
> > > > > diff --git a/include/linux/mlx5/mlx5_ifc_vdpa.h b/include/linux/mlx5/mlx5_ifc_vdpa.h
> > > > > index 4414ed5b6ed2..423562f39d3c 100644
> > > > > --- a/include/linux/mlx5/mlx5_ifc_vdpa.h
> > > > > +++ b/include/linux/mlx5/mlx5_ifc_vdpa.h
> > > > > @@ -150,6 +150,14 @@ enum {
> > > > > MLX5_VIRTIO_NET_Q_OBJECT_STATE_ERR = 0x3,
> > > > > };
> > > > >
> > > > > +/* This indicates that the object was not created or has alreadyi
> > > > > + * been desroyed. It is very safe to assume that this object will never
> > > > > + * have so many states
> > > > > + */
> > > > > +enum {
> > > > > + MLX5_VIRTIO_NET_Q_OBJECT_NONE = 0xffffffff
> > > > > +};
> > > > > +
> > > > > enum {
> > > > > MLX5_RQTC_LIST_Q_TYPE_RQ = 0x0,
> > > > > MLX5_RQTC_LIST_Q_TYPE_VIRTIO_NET_Q = 0x1,
> > > > > --
> > > > > 2.35.1
> > > > >
> > > >
> > >
>
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH RFC 1/3] vdpa/mlx5: Implement susupend virtqueue callback
[not found] ` <CAJaqyWcUUk1H2+aeoj7yAFKXSg1gdV2GzTdWUTAGi0AiW9r64w@mail.gmail.com>
@ 2022-07-13 3:29 ` Jason Wang
[not found] ` <DM8PR12MB5400DBB3EBA91C250E703E1EAB899@DM8PR12MB5400.namprd12.prod.outlook.com>
0 siblings, 1 reply; 12+ messages in thread
From: Jason Wang @ 2022-07-13 3:29 UTC (permalink / raw)
To: Eugenio Perez Martin; +Cc: mst, linux-kernel, virtualization, Eli Cohen
On Tue, Jul 12, 2022 at 5:16 PM Eugenio Perez Martin
<eperezma@redhat.com> wrote:
>
> On Tue, Jul 12, 2022 at 10:14 AM Jason Wang <jasowang@redhat.com> wrote:
> >
> > On Mon, Jul 11, 2022 at 2:14 PM Eli Cohen <elic@nvidia.com> wrote:
> > >
> > > > From: Jason Wang <jasowang@redhat.com>
> > > > Sent: Tuesday, June 21, 2022 6:05 AM
> > > > To: Eugenio Perez Martin <eperezma@redhat.com>
> > > > Cc: Eli Cohen <elic@nvidia.com>; mst <mst@redhat.com>; virtualization <virtualization@lists.linux-foundation.org>; linux-kernel
> > > > <linux-kernel@vger.kernel.org>; Si-Wei Liu <si-wei.liu@oracle.com>; Parav Pandit <parav@nvidia.com>
> > > > Subject: Re: [PATCH RFC 1/3] vdpa/mlx5: Implement susupend virtqueue callback
> > > >
> > > > On Mon, Jun 20, 2022 at 5:59 PM Eugenio Perez Martin
> > > > <eperezma@redhat.com> wrote:
> > > > >
> > > > > On Mon, Jun 20, 2022 at 10:56 AM Jason Wang <jasowang@redhat.com> wrote:
> > > > > >
> > > > > > On Thu, Jun 16, 2022 at 9:27 PM Eli Cohen <elic@nvidia.com> wrote:
> > > > > > >
> > > > > > > Implement the suspend callback allowing to suspend the virtqueues so
> > > > > > > they stop processing descriptors. This is required to allow the shadow
> > > > > > > virtqueue to kick in.
> > > > > > >
> > > > > > > Signed-off-by: Eli Cohen <elic@nvidia.com>
> > > > > > > ---
> > > > > > > drivers/vdpa/mlx5/net/mlx5_vnet.c | 68 +++++++++++++++++++++++++++++-
> > > > > > > include/linux/mlx5/mlx5_ifc_vdpa.h | 8 ++++
> > > > > > > 2 files changed, 75 insertions(+), 1 deletion(-)
> > > > > > >
> > > > > > > diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > > > > > > index fb0b23e71383..ea4bc8a0cd25 100644
> > > > > > > --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > > > > > > +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > > > > > > @@ -895,6 +895,7 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque
> > > > > > > if (err)
> > > > > > > goto err_cmd;
> > > > > > >
> > > > > > > + mvq->fw_state = MLX5_VIRTIO_NET_Q_OBJECT_STATE_INIT;
> > > > > > > kfree(in);
> > > > > > > mvq->virtq_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
> > > > > > >
> > > > > > > @@ -922,6 +923,7 @@ static void destroy_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtq
> > > > > > > mlx5_vdpa_warn(&ndev->mvdev, "destroy virtqueue 0x%x\n", mvq->virtq_id);
> > > > > > > return;
> > > > > > > }
> > > > > > > + mvq->fw_state = MLX5_VIRTIO_NET_Q_OBJECT_NONE;
> > > > > > > umems_destroy(ndev, mvq);
> > > > > > > }
> > > > > > >
> > > > > > > @@ -1121,6 +1123,20 @@ static int query_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueu
> > > > > > > return err;
> > > > > > > }
> > > > > > >
> > > > > > > +static bool is_valid_state_change(int oldstate, int newstate)
> > > > > > > +{
> > > > > > > + switch (oldstate) {
> > > > > > > + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_INIT:
> > > > > > > + return newstate == MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY;
> > > > > > > + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY:
> > > > > > > + return newstate == MLX5_VIRTIO_NET_Q_OBJECT_STATE_SUSPEND;
> > > > > > > + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_SUSPEND:
> > > > > > > + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_ERR:
> > > > > > > + default:
> > > > > > > + return false;
> > > > > > > + }
> > > > > > > +}
> > > > > > > +
> > > > > > > static int modify_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq, int state)
> > > > > > > {
> > > > > > > int inlen = MLX5_ST_SZ_BYTES(modify_virtio_net_q_in);
> > > > > > > @@ -1130,6 +1146,12 @@ static int modify_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque
> > > > > > > void *in;
> > > > > > > int err;
> > > > > > >
> > > > > > > + if (mvq->fw_state == MLX5_VIRTIO_NET_Q_OBJECT_NONE)
> > > > > > > + return 0;
> > > > > > > +
> > > > > > > + if (!is_valid_state_change(mvq->fw_state, state))
> > > > > > > + return -EINVAL;
> > > > > > > +
> > > > > > > in = kzalloc(inlen, GFP_KERNEL);
> > > > > > > if (!in)
> > > > > > > return -ENOMEM;
> > > > > > > @@ -1991,6 +2013,7 @@ static void mlx5_vdpa_set_vq_ready(struct vdpa_device *vdev, u16 idx, bool ready
> > > > > > > struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
> > > > > > > struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
> > > > > > > struct mlx5_vdpa_virtqueue *mvq;
> > > > > > > + int err;
> > > > > > >
> > > > > > > if (!mvdev->actual_features)
> > > > > > > return;
> > > > > > > @@ -2004,8 +2027,16 @@ static void mlx5_vdpa_set_vq_ready(struct vdpa_device *vdev, u16 idx, bool ready
> > > > > > > }
> > > > > > >
> > > > > > > mvq = &ndev->vqs[idx];
> > > > > > > - if (!ready)
> > > > > > > + if (!ready) {
> > > > > > > suspend_vq(ndev, mvq);
> > > > > > > + } else {
> > > > > > > + err = modify_virtqueue(ndev, mvq, MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY);
> > > > > > > + if (err) {
> > > > > > > + mlx5_vdpa_warn(mvdev, "modify VQ %d to ready failed (%d)\n", idx, err);
> > > > > > > + ready = false;
> > > > > > > + }
> > > > > > > + }
> > > > > > > +
> > > > > > >
> > > > > > > mvq->ready = ready;
> > > > > > > }
> > > > > > > @@ -2732,6 +2763,39 @@ static int mlx5_vdpa_get_vendor_vq_stats(struct vdpa_device *vdev, u16 idx,
> > > > > > > return err;
> > > > > > > }
> > > > > > >
> > > > > > > +static void mlx5_vdpa_cvq_suspend(struct mlx5_vdpa_dev *mvdev, bool suspend)
> > > > > > > +{
> > > > > > > + struct mlx5_control_vq *cvq;
> > > > > > > +
> > > > > > > + if (!(mvdev->actual_features & BIT_ULL(VIRTIO_NET_F_CTRL_VQ)))
> > > > > > > + return;
> > > > > > > +
> > > > > > > + cvq = &mvdev->cvq;
> > > > > > > + cvq->ready = !suspend;
> > > > > > > +}
> > > > > >
> > > > > > It looks to me we need to synchronize this with reslock. And this
> > > > > > probably deserve a dedicated fix.
> > > > > >
> > > > > > > +
> > > > > > > +static int mlx5_vdpa_suspend(struct vdpa_device *vdev, bool suspend)
> > > > > > > +{
> > > > > > > + struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
> > > > > > > + struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
> > > > > > > + struct mlx5_vdpa_virtqueue *mvq;
> > > > > > > + int i;
> > > > > > > +
> > > > > > > + if (!suspend) {
> > > > > > > + mlx5_vdpa_warn(mvdev, "Resume of virtqueues is not supported\n");
> > > > > > > + return -EOPNOTSUPP;
> > > > > > > + }
> > > > > > > +
> > > > > > > + down_write(&ndev->reslock);
> > > > > > > + for (i = 0; i < ndev->cur_num_vqs; i++) {
> > > > > > > + mvq = &ndev->vqs[i];
> > > > > > > + suspend_vq(ndev, mvq);
> > > > > > > + }
> > > > > > > + mlx5_vdpa_cvq_suspend(mvdev, suspend);
> > > > > >
> > > > > > Do we need to synchronize with the carrier work here? Otherwise we may
> > > > > > get config notification after suspending.
> > > > > >
> > > > > > > + up_write(&ndev->reslock);
> > > > > > > + return 0;
> > > > > > > +}
> > > > > > > +
> > > > > > > static const struct vdpa_config_ops mlx5_vdpa_ops = {
> > > > > > > .set_vq_address = mlx5_vdpa_set_vq_address,
> > > > > > > .set_vq_num = mlx5_vdpa_set_vq_num,
> > > > > > > @@ -2762,6 +2826,7 @@ static const struct vdpa_config_ops mlx5_vdpa_ops = {
> > > > > > > .get_generation = mlx5_vdpa_get_generation,
> > > > > > > .set_map = mlx5_vdpa_set_map,
> > > > > > > .free = mlx5_vdpa_free,
> > > > > > > + .suspend = mlx5_vdpa_suspend,
> > > > > >
> > > > > > I don't see the vDPA bus patch to enable this method. Or anything I missed here?
> > > > > >
> > > > >
> > > > > Should we add
> > > > > Based-on: <20220526124338.36247-1-eperezma@redhat.com>
> > > > >
> > > > > To this series?
> > > >
> > > > Probably, but that series seems to support resume while this series doesn't.
> > > >
> > > > Any reason for this?
> > >
> > > I think Eugenio agreed that resume is not really required since we're going stop using this
> > > instance and migrate. In any case, we don't support resume for the hardware object
> > > though it could be simulated should it be absolutely necessary.
> >
> > This is fine if everything is fine during the live migration. But when
> > migration fails due to some reason, management (libvirt) may choose to
> > restart the device in the source.
> >
> > This means we should either
> >
> > 1) support resume in the parent
> > 2) emulate it in the qemu (with a lot of restoring of the states)
> >
>
> I think it should be handled in qemu (at least the POC reset the
> device), but I didn't exercise a lot of the failure paths there
> because, well, it was a POC :).
It looks like a must in the production environment. The failure is not
necessarily related to shadow virtqueue itself.
Thanks
>
> > And it is not only used for live migration, it could be used for vmstop/start.
> >
>
> I think it would be easier if we dedicate a feature flag for resuming
> the device in the future. Qemu could take advantage of it at some
> error paths of live migration, but less than it seems because it
> overrides things like ring addresses. And, obviously, in the
> vmstop/vmstart.
>
> Actually, net devices should be ok to restore with a full reset. The
> problem should be filesystems etc that are not part of vdpa at the
> moment.
>
> Thanks!
>
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH RFC 1/3] vdpa/mlx5: Implement susupend virtqueue callback
[not found] ` <DM8PR12MB5400DBB3EBA91C250E703E1EAB899@DM8PR12MB5400.namprd12.prod.outlook.com>
@ 2022-07-18 9:03 ` Jason Wang
0 siblings, 0 replies; 12+ messages in thread
From: Jason Wang @ 2022-07-18 9:03 UTC (permalink / raw)
To: Eli Cohen; +Cc: mst, linux-kernel, virtualization, Eugenio Perez Martin
On Wed, Jul 13, 2022 at 1:18 PM Eli Cohen <elic@nvidia.com> wrote:
>
> > From: Jason Wang <jasowang@redhat.com>
> > Sent: Wednesday, July 13, 2022 6:29 AM
> > To: Eugenio Perez Martin <eperezma@redhat.com>
> > Cc: Eli Cohen <elic@nvidia.com>; mst <mst@redhat.com>; virtualization <virtualization@lists.linux-foundation.org>; linux-kernel
> > <linux-kernel@vger.kernel.org>; Si-Wei Liu <si-wei.liu@oracle.com>; Parav Pandit <parav@nvidia.com>
> > Subject: Re: [PATCH RFC 1/3] vdpa/mlx5: Implement susupend virtqueue callback
> >
> > On Tue, Jul 12, 2022 at 5:16 PM Eugenio Perez Martin
> > <eperezma@redhat.com> wrote:
> > >
> > > On Tue, Jul 12, 2022 at 10:14 AM Jason Wang <jasowang@redhat.com> wrote:
> > > >
> > > > On Mon, Jul 11, 2022 at 2:14 PM Eli Cohen <elic@nvidia.com> wrote:
> > > > >
> > > > > > From: Jason Wang <jasowang@redhat.com>
> > > > > > Sent: Tuesday, June 21, 2022 6:05 AM
> > > > > > To: Eugenio Perez Martin <eperezma@redhat.com>
> > > > > > Cc: Eli Cohen <elic@nvidia.com>; mst <mst@redhat.com>; virtualization <virtualization@lists.linux-foundation.org>; linux-
> > kernel
> > > > > > <linux-kernel@vger.kernel.org>; Si-Wei Liu <si-wei.liu@oracle.com>; Parav Pandit <parav@nvidia.com>
> > > > > > Subject: Re: [PATCH RFC 1/3] vdpa/mlx5: Implement susupend virtqueue callback
> > > > > >
> > > > > > On Mon, Jun 20, 2022 at 5:59 PM Eugenio Perez Martin
> > > > > > <eperezma@redhat.com> wrote:
> > > > > > >
> > > > > > > On Mon, Jun 20, 2022 at 10:56 AM Jason Wang <jasowang@redhat.com> wrote:
> > > > > > > >
> > > > > > > > On Thu, Jun 16, 2022 at 9:27 PM Eli Cohen <elic@nvidia.com> wrote:
> > > > > > > > >
> > > > > > > > > Implement the suspend callback allowing to suspend the virtqueues so
> > > > > > > > > they stop processing descriptors. This is required to allow the shadow
> > > > > > > > > virtqueue to kick in.
> > > > > > > > >
> > > > > > > > > Signed-off-by: Eli Cohen <elic@nvidia.com>
> > > > > > > > > ---
> > > > > > > > > drivers/vdpa/mlx5/net/mlx5_vnet.c | 68 +++++++++++++++++++++++++++++-
> > > > > > > > > include/linux/mlx5/mlx5_ifc_vdpa.h | 8 ++++
> > > > > > > > > 2 files changed, 75 insertions(+), 1 deletion(-)
> > > > > > > > >
> > > > > > > > > diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > > > > > > > > index fb0b23e71383..ea4bc8a0cd25 100644
> > > > > > > > > --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > > > > > > > > +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > > > > > > > > @@ -895,6 +895,7 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque
> > > > > > > > > if (err)
> > > > > > > > > goto err_cmd;
> > > > > > > > >
> > > > > > > > > + mvq->fw_state = MLX5_VIRTIO_NET_Q_OBJECT_STATE_INIT;
> > > > > > > > > kfree(in);
> > > > > > > > > mvq->virtq_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
> > > > > > > > >
> > > > > > > > > @@ -922,6 +923,7 @@ static void destroy_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtq
> > > > > > > > > mlx5_vdpa_warn(&ndev->mvdev, "destroy virtqueue 0x%x\n", mvq->virtq_id);
> > > > > > > > > return;
> > > > > > > > > }
> > > > > > > > > + mvq->fw_state = MLX5_VIRTIO_NET_Q_OBJECT_NONE;
> > > > > > > > > umems_destroy(ndev, mvq);
> > > > > > > > > }
> > > > > > > > >
> > > > > > > > > @@ -1121,6 +1123,20 @@ static int query_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueu
> > > > > > > > > return err;
> > > > > > > > > }
> > > > > > > > >
> > > > > > > > > +static bool is_valid_state_change(int oldstate, int newstate)
> > > > > > > > > +{
> > > > > > > > > + switch (oldstate) {
> > > > > > > > > + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_INIT:
> > > > > > > > > + return newstate == MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY;
> > > > > > > > > + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY:
> > > > > > > > > + return newstate == MLX5_VIRTIO_NET_Q_OBJECT_STATE_SUSPEND;
> > > > > > > > > + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_SUSPEND:
> > > > > > > > > + case MLX5_VIRTIO_NET_Q_OBJECT_STATE_ERR:
> > > > > > > > > + default:
> > > > > > > > > + return false;
> > > > > > > > > + }
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > static int modify_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq, int state)
> > > > > > > > > {
> > > > > > > > > int inlen = MLX5_ST_SZ_BYTES(modify_virtio_net_q_in);
> > > > > > > > > @@ -1130,6 +1146,12 @@ static int modify_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque
> > > > > > > > > void *in;
> > > > > > > > > int err;
> > > > > > > > >
> > > > > > > > > + if (mvq->fw_state == MLX5_VIRTIO_NET_Q_OBJECT_NONE)
> > > > > > > > > + return 0;
> > > > > > > > > +
> > > > > > > > > + if (!is_valid_state_change(mvq->fw_state, state))
> > > > > > > > > + return -EINVAL;
> > > > > > > > > +
> > > > > > > > > in = kzalloc(inlen, GFP_KERNEL);
> > > > > > > > > if (!in)
> > > > > > > > > return -ENOMEM;
> > > > > > > > > @@ -1991,6 +2013,7 @@ static void mlx5_vdpa_set_vq_ready(struct vdpa_device *vdev, u16 idx, bool ready
> > > > > > > > > struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
> > > > > > > > > struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
> > > > > > > > > struct mlx5_vdpa_virtqueue *mvq;
> > > > > > > > > + int err;
> > > > > > > > >
> > > > > > > > > if (!mvdev->actual_features)
> > > > > > > > > return;
> > > > > > > > > @@ -2004,8 +2027,16 @@ static void mlx5_vdpa_set_vq_ready(struct vdpa_device *vdev, u16 idx, bool ready
> > > > > > > > > }
> > > > > > > > >
> > > > > > > > > mvq = &ndev->vqs[idx];
> > > > > > > > > - if (!ready)
> > > > > > > > > + if (!ready) {
> > > > > > > > > suspend_vq(ndev, mvq);
> > > > > > > > > + } else {
> > > > > > > > > + err = modify_virtqueue(ndev, mvq, MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY);
> > > > > > > > > + if (err) {
> > > > > > > > > + mlx5_vdpa_warn(mvdev, "modify VQ %d to ready failed (%d)\n", idx, err);
> > > > > > > > > + ready = false;
> > > > > > > > > + }
> > > > > > > > > + }
> > > > > > > > > +
> > > > > > > > >
> > > > > > > > > mvq->ready = ready;
> > > > > > > > > }
> > > > > > > > > @@ -2732,6 +2763,39 @@ static int mlx5_vdpa_get_vendor_vq_stats(struct vdpa_device *vdev, u16 idx,
> > > > > > > > > return err;
> > > > > > > > > }
> > > > > > > > >
> > > > > > > > > +static void mlx5_vdpa_cvq_suspend(struct mlx5_vdpa_dev *mvdev, bool suspend)
> > > > > > > > > +{
> > > > > > > > > + struct mlx5_control_vq *cvq;
> > > > > > > > > +
> > > > > > > > > + if (!(mvdev->actual_features & BIT_ULL(VIRTIO_NET_F_CTRL_VQ)))
> > > > > > > > > + return;
> > > > > > > > > +
> > > > > > > > > + cvq = &mvdev->cvq;
> > > > > > > > > + cvq->ready = !suspend;
> > > > > > > > > +}
> > > > > > > >
> > > > > > > > It looks to me we need to synchronize this with reslock. And this
> > > > > > > > probably deserve a dedicated fix.
> > > > > > > >
> > > > > > > > > +
> > > > > > > > > +static int mlx5_vdpa_suspend(struct vdpa_device *vdev, bool suspend)
> > > > > > > > > +{
> > > > > > > > > + struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
> > > > > > > > > + struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
> > > > > > > > > + struct mlx5_vdpa_virtqueue *mvq;
> > > > > > > > > + int i;
> > > > > > > > > +
> > > > > > > > > + if (!suspend) {
> > > > > > > > > + mlx5_vdpa_warn(mvdev, "Resume of virtqueues is not supported\n");
> > > > > > > > > + return -EOPNOTSUPP;
> > > > > > > > > + }
> > > > > > > > > +
> > > > > > > > > + down_write(&ndev->reslock);
> > > > > > > > > + for (i = 0; i < ndev->cur_num_vqs; i++) {
> > > > > > > > > + mvq = &ndev->vqs[i];
> > > > > > > > > + suspend_vq(ndev, mvq);
> > > > > > > > > + }
> > > > > > > > > + mlx5_vdpa_cvq_suspend(mvdev, suspend);
> > > > > > > >
> > > > > > > > Do we need to synchronize with the carrier work here? Otherwise we may
> > > > > > > > get config notification after suspending.
> > > > > > > >
> > > > > > > > > + up_write(&ndev->reslock);
> > > > > > > > > + return 0;
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > static const struct vdpa_config_ops mlx5_vdpa_ops = {
> > > > > > > > > .set_vq_address = mlx5_vdpa_set_vq_address,
> > > > > > > > > .set_vq_num = mlx5_vdpa_set_vq_num,
> > > > > > > > > @@ -2762,6 +2826,7 @@ static const struct vdpa_config_ops mlx5_vdpa_ops = {
> > > > > > > > > .get_generation = mlx5_vdpa_get_generation,
> > > > > > > > > .set_map = mlx5_vdpa_set_map,
> > > > > > > > > .free = mlx5_vdpa_free,
> > > > > > > > > + .suspend = mlx5_vdpa_suspend,
> > > > > > > >
> > > > > > > > I don't see the vDPA bus patch to enable this method. Or anything I missed here?
> > > > > > > >
> > > > > > >
> > > > > > > Should we add
> > > > > > > Based-on: <20220526124338.36247-1-eperezma@redhat.com>
> > > > > > >
> > > > > > > To this series?
> > > > > >
> > > > > > Probably, but that series seems to support resume while this series doesn't.
> > > > > >
> > > > > > Any reason for this?
> > > > >
> > > > > I think Eugenio agreed that resume is not really required since we're going stop using this
> > > > > instance and migrate. In any case, we don't support resume for the hardware object
> > > > > though it could be simulated should it be absolutely necessary.
> > > >
> > > > This is fine if everything is fine during the live migration. But when
> > > > migration fails due to some reason, management (libvirt) may choose to
> > > > restart the device in the source.
> > > >
> > > > This means we should either
> > > >
> > > > 1) support resume in the parent
> > > > 2) emulate it in the qemu (with a lot of restoring of the states)
> > > >
> > >
> > > I think it should be handled in qemu (at least the POC reset the
> > > device), but I didn't exercise a lot of the failure paths there
> > > because, well, it was a POC :).
> >
> > It looks like a must in the production environment. The failure is not
> > necessarily related to shadow virtqueue itself.
> >
>
> I don't see a specific interface to resume the device after suspend.
> Reset however could do the job and we already have it.
Yes, this is fine as long as we can emulate it via set_vq_state + reset.
Thanks
>
> > Thanks
> >
> > >
> > > > And it is not only used for live migration, it could be used for vmstop/start.
> > > >
> > >
> > > I think it would be easier if we dedicate a feature flag for resuming
> > > the device in the future. Qemu could take advantage of it at some
> > > error paths of live migration, but less than it seems because it
> > > overrides things like ring addresses. And, obviously, in the
> > > vmstop/vmstart.
> > >
> > > Actually, net devices should be ok to restore with a full reset. The
> > > problem should be filesystems etc that are not part of vdpa at the
> > > moment.
> > >
> > > Thanks!
> > >
>
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2022-07-18 9:04 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20220616132725.50599-1-elic@nvidia.com>
[not found] ` <20220616132725.50599-3-elic@nvidia.com>
2022-06-20 8:47 ` [PATCH RFC 2/3] vdpa/mlx5: Support different address spaces for control and data Jason Wang
[not found] ` <CAJaqyWdFyT+QGce998vsTQNiGAF1LZqOXNZH1RS660tb6pvtgA@mail.gmail.com>
2022-06-20 9:20 ` Jason Wang
[not found] ` <20220616132725.50599-4-elic@nvidia.com>
2022-06-20 8:47 ` [PATCH RFC 3/3] vdpa/mlx5: Disable VLAN support to support live migration Jason Wang
[not found] ` <CAJaqyWdnuX0KLu7j3M4ovtW=N5kFObgaU3z2hu4xoRXY5Fk+aQ@mail.gmail.com>
2022-06-20 9:25 ` Jason Wang
[not found] ` <20220616132725.50599-2-elic@nvidia.com>
2022-06-20 8:56 ` [PATCH RFC 1/3] vdpa/mlx5: Implement susupend virtqueue callback Jason Wang
[not found] ` <DM8PR12MB54004277F21D682A3EE6D1C1ABB09@DM8PR12MB5400.namprd12.prod.outlook.com>
2022-06-21 2:58 ` Jason Wang
[not found] ` <CAJaqyWfTG_jVW6Vzf64QO=255kfwWKn4gCUMeGog-1shHx3O_g@mail.gmail.com>
2022-06-20 10:06 ` Michael S. Tsirkin
2022-06-21 3:04 ` Jason Wang
[not found] ` <CAJaqyWfDQ5RhHPuW2DnJ3o72+e5LMzZ9vjp6rD4kYh9G7KgCvw@mail.gmail.com>
2022-06-21 7:52 ` Jason Wang
[not found] ` <DM8PR12MB5400FDBB177693A55074D19EAB879@DM8PR12MB5400.namprd12.prod.outlook.com>
2022-07-12 8:14 ` Jason Wang
[not found] ` <CAJaqyWcUUk1H2+aeoj7yAFKXSg1gdV2GzTdWUTAGi0AiW9r64w@mail.gmail.com>
2022-07-13 3:29 ` Jason Wang
[not found] ` <DM8PR12MB5400DBB3EBA91C250E703E1EAB899@DM8PR12MB5400.namprd12.prod.outlook.com>
2022-07-18 9:03 ` Jason Wang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).