kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5 0/4] Implement vdpasim suspend operation
@ 2022-06-03 10:09 Eugenio Pérez
  2022-06-03 10:09 ` [PATCH v5 1/4] vdpa: Add " Eugenio Pérez
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Eugenio Pérez @ 2022-06-03 10:09 UTC (permalink / raw)
  To: kvm, Jason Wang, Michael S. Tsirkin, linux-kernel, netdev,
	virtualization
  Cc: Christophe JAILLET, Longpeng, Stefano Garzarella, dinang,
	Piotr.Uminski, martinpo, tanuj.kamde, Parav Pandit, Zhang Min,
	habetsm.xilinx, Zhu Lingshan, lulu, hanand, martinh, Si-Wei Liu,
	gautam.dawar, Xie Yongji, ecree.xilinx, pabloc, lvivier,
	Eli Cohen, Wu Zongyong, Dan Carpenter

Implement suspend operation for vdpa_sim devices, so vhost-vdpa will offer
that backend feature and userspace can effectively suspend the device.

This is a must before getting virtqueue indexes (base) for live migration,
since the device could modify them after userland gets them. There are
individual ways to perform that action for some devices
(VHOST_NET_SET_BACKEND, VHOST_VSOCK_SET_RUNNING, ...) but there was no
way to perform it for any vhost device (and, in particular, vhost-vdpa).

After a successful return of ioctl with suspend = 1, the device must not
process more virtqueue descriptors, and it must not send any config
interrupt. The device can answer to read or writes of config fields as
if it were not suspended. In particular, writing to "queue_enable" with
a value of 1 will not make the device start processing buffers of the
virtqueue until the device is resumed (suspend = 0).

After a successful return of ioctl with suspend = 0, the device will
start processing data of the virtqueues if other expected conditions are
met (queue is enabled, DRIVER_OK has already been set to status, etc.)
If not, the device should be in the same state as if no call to suspend
callback with suspend = 1 has been performed.

In the future, we will provide features similar to
VHOST_USER_GET_INFLIGHT_FD so the device can save pending operations.

Comments are welcome.

v6:
* s/stop/suspend/ to differentiate more from reset.
* Clarify scope of the suspend operation.

v5:
* s/not stop/resume/ in doc.

v4:
* Replace VHOST_STOP to VHOST_VDPA_STOP in vhost ioctl switch case too.

v3:
* s/VHOST_STOP/VHOST_VDPA_STOP/
* Add documentation and requirements of the ioctl above its definition.

v2:
* Replace raw _F_STOP with BIT_ULL(_F_STOP).
* Fix obtaining of stop ioctl arg (it was not obtained but written).
* Add stop to vdpa_sim_blk.

Eugenio Pérez (4):
  vdpa: Add suspend operation
  vhost-vdpa: introduce SUSPEND backend feature bit
  vhost-vdpa: uAPI to suspend the device
  vdpa_sim: Implement suspend vdpa op

 drivers/vdpa/vdpa_sim/vdpa_sim.c     | 21 +++++++++++++
 drivers/vdpa/vdpa_sim/vdpa_sim.h     |  1 +
 drivers/vdpa/vdpa_sim/vdpa_sim_blk.c |  3 ++
 drivers/vdpa/vdpa_sim/vdpa_sim_net.c |  3 ++
 drivers/vhost/vdpa.c                 | 47 +++++++++++++++++++++++++++-
 include/linux/vdpa.h                 |  5 +++
 include/uapi/linux/vhost.h           | 14 +++++++++
 include/uapi/linux/vhost_types.h     |  2 ++
 8 files changed, 95 insertions(+), 1 deletion(-)

--
2.31.1



^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v5 1/4] vdpa: Add suspend operation
  2022-06-03 10:09 [PATCH v5 0/4] Implement vdpasim suspend operation Eugenio Pérez
@ 2022-06-03 10:09 ` Eugenio Pérez
  2022-06-03 10:09 ` [PATCH v5 2/4] vhost-vdpa: introduce SUSPEND backend feature bit Eugenio Pérez
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Eugenio Pérez @ 2022-06-03 10:09 UTC (permalink / raw)
  To: kvm, Jason Wang, Michael S. Tsirkin, linux-kernel, netdev,
	virtualization
  Cc: Christophe JAILLET, Longpeng, Stefano Garzarella, dinang,
	Piotr.Uminski, martinpo, tanuj.kamde, Parav Pandit, Zhang Min,
	habetsm.xilinx, Zhu Lingshan, lulu, hanand, martinh, Si-Wei Liu,
	gautam.dawar, Xie Yongji, ecree.xilinx, pabloc, lvivier,
	Eli Cohen, Wu Zongyong, Dan Carpenter

This operation is optional: It it's not implemented, backend feature bit
will not be exposed.

Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
---
 include/linux/vdpa.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/include/linux/vdpa.h b/include/linux/vdpa.h
index 15af802d41c4c..8f4559795bf9f 100644
--- a/include/linux/vdpa.h
+++ b/include/linux/vdpa.h
@@ -215,6 +215,10 @@ struct vdpa_map_file {
  * @reset:			Reset device
  *				@vdev: vdpa device
  *				Returns integer: success (0) or error (< 0)
+ * @suspend:			Suspend or resume the device (optional)
+ *				@vdev: vdpa device
+ *				@suspend: suspend (true), resume (false)
+ *				Returns integer: success (0) or error (< 0)
  * @get_config_size:		Get the size of the configuration space includes
  *				fields that are conditional on feature bits.
  *				@vdev: vdpa device
@@ -316,6 +320,7 @@ struct vdpa_config_ops {
 	u8 (*get_status)(struct vdpa_device *vdev);
 	void (*set_status)(struct vdpa_device *vdev, u8 status);
 	int (*reset)(struct vdpa_device *vdev);
+	int (*suspend)(struct vdpa_device *vdev, bool suspend);
 	size_t (*get_config_size)(struct vdpa_device *vdev);
 	void (*get_config)(struct vdpa_device *vdev, unsigned int offset,
 			   void *buf, unsigned int len);
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v5 2/4] vhost-vdpa: introduce SUSPEND backend feature bit
  2022-06-03 10:09 [PATCH v5 0/4] Implement vdpasim suspend operation Eugenio Pérez
  2022-06-03 10:09 ` [PATCH v5 1/4] vdpa: Add " Eugenio Pérez
@ 2022-06-03 10:09 ` Eugenio Pérez
  2022-06-03 10:09 ` [PATCH v5 3/4] vhost-vdpa: uAPI to suspend the device Eugenio Pérez
  2022-06-03 10:09 ` [PATCH v5 4/4] vdpa_sim: Implement suspend vdpa op Eugenio Pérez
  3 siblings, 0 replies; 5+ messages in thread
From: Eugenio Pérez @ 2022-06-03 10:09 UTC (permalink / raw)
  To: kvm, Jason Wang, Michael S. Tsirkin, linux-kernel, netdev,
	virtualization
  Cc: Christophe JAILLET, Longpeng, Stefano Garzarella, dinang,
	Piotr.Uminski, martinpo, tanuj.kamde, Parav Pandit, Zhang Min,
	habetsm.xilinx, Zhu Lingshan, lulu, hanand, martinh, Si-Wei Liu,
	gautam.dawar, Xie Yongji, ecree.xilinx, pabloc, lvivier,
	Eli Cohen, Wu Zongyong, Dan Carpenter

Userland knows if it can suspend the device or not by checking this feature
bit.

It's only offered if the vdpa driver backend implements the suspend()
operation callback, and to offer it or userland to ack it if the backend
does not offer that callback is an error.

Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
---
 drivers/vhost/vdpa.c             | 16 +++++++++++++++-
 include/uapi/linux/vhost_types.h |  2 ++
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
index 935a1d0ddb97e..f4b492526c6f8 100644
--- a/drivers/vhost/vdpa.c
+++ b/drivers/vhost/vdpa.c
@@ -347,6 +347,14 @@ static long vhost_vdpa_set_config(struct vhost_vdpa *v,
 	return 0;
 }

+static bool vhost_vdpa_can_suspend(const struct vhost_vdpa *v)
+{
+	struct vdpa_device *vdpa = v->vdpa;
+	const struct vdpa_config_ops *ops = vdpa->config;
+
+	return ops->suspend;
+}
+
 static long vhost_vdpa_get_features(struct vhost_vdpa *v, u64 __user *featurep)
 {
 	struct vdpa_device *vdpa = v->vdpa;
@@ -575,7 +583,11 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
 	if (cmd == VHOST_SET_BACKEND_FEATURES) {
 		if (copy_from_user(&features, featurep, sizeof(features)))
 			return -EFAULT;
-		if (features & ~VHOST_VDPA_BACKEND_FEATURES)
+		if (features & ~(VHOST_VDPA_BACKEND_FEATURES |
+				 BIT_ULL(VHOST_BACKEND_F_SUSPEND)))
+			return -EOPNOTSUPP;
+		if ((features & BIT_ULL(VHOST_BACKEND_F_SUSPEND)) &&
+		     !vhost_vdpa_can_suspend(v))
 			return -EOPNOTSUPP;
 		vhost_set_backend_features(&v->vdev, features);
 		return 0;
@@ -626,6 +638,8 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
 		break;
 	case VHOST_GET_BACKEND_FEATURES:
 		features = VHOST_VDPA_BACKEND_FEATURES;
+		if (vhost_vdpa_can_suspend(v))
+			features |= BIT_ULL(VHOST_BACKEND_F_SUSPEND);
 		if (copy_to_user(featurep, &features, sizeof(features)))
 			r = -EFAULT;
 		break;
diff --git a/include/uapi/linux/vhost_types.h b/include/uapi/linux/vhost_types.h
index 634cee485abbc..1bdd6e363f4c9 100644
--- a/include/uapi/linux/vhost_types.h
+++ b/include/uapi/linux/vhost_types.h
@@ -161,5 +161,7 @@ struct vhost_vdpa_iova_range {
  * message
  */
 #define VHOST_BACKEND_F_IOTLB_ASID  0x3
+/* Device can be suspended */
+#define VHOST_BACKEND_F_SUSPEND  0x4

 #endif
--
2.31.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v5 3/4] vhost-vdpa: uAPI to suspend the device
  2022-06-03 10:09 [PATCH v5 0/4] Implement vdpasim suspend operation Eugenio Pérez
  2022-06-03 10:09 ` [PATCH v5 1/4] vdpa: Add " Eugenio Pérez
  2022-06-03 10:09 ` [PATCH v5 2/4] vhost-vdpa: introduce SUSPEND backend feature bit Eugenio Pérez
@ 2022-06-03 10:09 ` Eugenio Pérez
  2022-06-03 10:09 ` [PATCH v5 4/4] vdpa_sim: Implement suspend vdpa op Eugenio Pérez
  3 siblings, 0 replies; 5+ messages in thread
From: Eugenio Pérez @ 2022-06-03 10:09 UTC (permalink / raw)
  To: kvm, Jason Wang, Michael S. Tsirkin, linux-kernel, netdev,
	virtualization
  Cc: Christophe JAILLET, Longpeng, Stefano Garzarella, dinang,
	Piotr.Uminski, martinpo, tanuj.kamde, Parav Pandit, Zhang Min,
	habetsm.xilinx, Zhu Lingshan, lulu, hanand, martinh, Si-Wei Liu,
	gautam.dawar, Xie Yongji, ecree.xilinx, pabloc, lvivier,
	Eli Cohen, Wu Zongyong, Dan Carpenter

The ioctl adds support for suspending the device from userspace.

This is a must before getting virtqueue indexes (base) for live migration,
since the device could modify them after userland gets them. There are
individual ways to perform that action for some devices
(VHOST_NET_SET_BACKEND, VHOST_VSOCK_SET_RUNNING, ...) but there was no
way to perform it for any vhost device (and, in particular, vhost-vdpa).

After a successful return of ioctl with suspend = 1, the device must not
process more virtqueue descriptors, and it must not send any config
interrupt. The device can answer to read or writes of config fields as
if it were not suspended. In particular, writing to "queue_enable" with
a value of 1 will not make the device start processing buffers of the
virtqueue until the device is resumed (suspend = 0).

After a successful return of ioctl with suspend = 0, the device will
start processing data of the virtqueues if other expected conditions are
met (queue is enabled, DRIVER_OK has already been set to status, etc.)
If not, the device should be in the same state as if no call to suspend
callback with suspend = 1 has been performed.

Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
---
 drivers/vhost/vdpa.c       | 31 +++++++++++++++++++++++++++++++
 include/uapi/linux/vhost.h | 14 ++++++++++++++
 2 files changed, 45 insertions(+)

diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
index f4b492526c6f8..cb47c10bbf471 100644
--- a/drivers/vhost/vdpa.c
+++ b/drivers/vhost/vdpa.c
@@ -478,6 +478,34 @@ static long vhost_vdpa_get_vqs_count(struct vhost_vdpa *v, u32 __user *argp)
 	return 0;
 }
 
+/* After a successful return of ioctl with suspend = 1, the device must not
+ * process more virtqueue descriptors, and it must not send any config
+ * interrupt. The device can answer to read or writes of config fields as if it
+ * were not suspended. In particular, writing to "queue_enable" with a value of
+ * 1 will not make the device start processing buffers of the virtqueue until
+ * the device is resumed (suspend = 0).
+ *
+ * After a successful return of ioctl with suspend = 0, the device will start
+ * processing data of the virtqueues if other expected conditions are met
+ * (queue is enabled, DRIVER_OK has already been set to status, etc.) If not,
+ * the device should be in the same state as if no call to suspend callback
+ * with suspend = 1 has been performed.
+ */
+static long vhost_vdpa_suspend(struct vhost_vdpa *v, u32 __user *argp)
+{
+	struct vdpa_device *vdpa = v->vdpa;
+	const struct vdpa_config_ops *ops = vdpa->config;
+	int suspend;
+
+	if (!ops->suspend)
+		return -EOPNOTSUPP;
+
+	if (copy_from_user(&suspend, argp, sizeof(suspend)))
+		return -EFAULT;
+
+	return ops->suspend(vdpa, suspend);
+}
+
 static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd,
 				   void __user *argp)
 {
@@ -652,6 +680,9 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
 	case VHOST_VDPA_GET_VQS_COUNT:
 		r = vhost_vdpa_get_vqs_count(v, argp);
 		break;
+	case VHOST_VDPA_SUSPEND:
+		r = vhost_vdpa_suspend(v, argp);
+		break;
 	default:
 		r = vhost_dev_ioctl(&v->vdev, cmd, argp);
 		if (r == -ENOIOCTLCMD)
diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h
index cab645d4a6455..6d9f451631557 100644
--- a/include/uapi/linux/vhost.h
+++ b/include/uapi/linux/vhost.h
@@ -171,4 +171,18 @@
 #define VHOST_VDPA_SET_GROUP_ASID	_IOW(VHOST_VIRTIO, 0x7C, \
 					     struct vhost_vring_state)
 
+/* Suspend or resume a device so it does not process virtqueue requests anymore
+ *
+ * After the return of ioctl with suspend != 0, the device must finish any
+ * pending operations like in flight requests. It must also preserve all the
+ * necessary state (the virtqueue vring base plus the possible device specific
+ * states) that is required for restoring in the future. The device must not
+ * change its configuration after that point.
+ *
+ * After the return of ioctl with suspend == 0, the device can continue
+ * processing buffers as long as typical conditions are met (vq is enabled,
+ * DRIVER_OK status bit is enabled, etc).
+ */
+#define VHOST_VDPA_SUSPEND		_IOW(VHOST_VIRTIO, 0x7D, int)
+
 #endif
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v5 4/4] vdpa_sim: Implement suspend vdpa op
  2022-06-03 10:09 [PATCH v5 0/4] Implement vdpasim suspend operation Eugenio Pérez
                   ` (2 preceding siblings ...)
  2022-06-03 10:09 ` [PATCH v5 3/4] vhost-vdpa: uAPI to suspend the device Eugenio Pérez
@ 2022-06-03 10:09 ` Eugenio Pérez
  3 siblings, 0 replies; 5+ messages in thread
From: Eugenio Pérez @ 2022-06-03 10:09 UTC (permalink / raw)
  To: kvm, Jason Wang, Michael S. Tsirkin, linux-kernel, netdev,
	virtualization
  Cc: Christophe JAILLET, Longpeng, Stefano Garzarella, dinang,
	Piotr.Uminski, martinpo, tanuj.kamde, Parav Pandit, Zhang Min,
	habetsm.xilinx, Zhu Lingshan, lulu, hanand, martinh, Si-Wei Liu,
	gautam.dawar, Xie Yongji, ecree.xilinx, pabloc, lvivier,
	Eli Cohen, Wu Zongyong, Dan Carpenter

Implement suspend operation for vdpa_sim devices, so vhost-vdpa will
offer that backend feature and userspace can effectively suspend the
device.

This is a must before get virtqueue indexes (base) for live migration,
since the device could modify them after userland gets them. There are
individual ways to perform that action for some devices
(VHOST_NET_SET_BACKEND, VHOST_VSOCK_SET_RUNNING, ...) but there was no
way to perform it for any vhost device (and, in particular, vhost-vdpa).

Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
---
 drivers/vdpa/vdpa_sim/vdpa_sim.c     | 21 +++++++++++++++++++++
 drivers/vdpa/vdpa_sim/vdpa_sim.h     |  1 +
 drivers/vdpa/vdpa_sim/vdpa_sim_blk.c |  3 +++
 drivers/vdpa/vdpa_sim/vdpa_sim_net.c |  3 +++
 4 files changed, 28 insertions(+)

diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim.c b/drivers/vdpa/vdpa_sim/vdpa_sim.c
index 0f28658996472..01f9377830b3e 100644
--- a/drivers/vdpa/vdpa_sim/vdpa_sim.c
+++ b/drivers/vdpa/vdpa_sim/vdpa_sim.c
@@ -107,6 +107,7 @@ static void vdpasim_do_reset(struct vdpasim *vdpasim)
 	for (i = 0; i < vdpasim->dev_attr.nas; i++)
 		vhost_iotlb_reset(&vdpasim->iommu[i]);
 
+	vdpasim->running = true;
 	spin_unlock(&vdpasim->iommu_lock);
 
 	vdpasim->features = 0;
@@ -505,6 +506,24 @@ static int vdpasim_reset(struct vdpa_device *vdpa)
 	return 0;
 }
 
+static int vdpasim_suspend(struct vdpa_device *vdpa, bool suspend)
+{
+	struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
+	int i;
+
+	spin_lock(&vdpasim->lock);
+	vdpasim->running = !suspend;
+	if (vdpasim->running) {
+		/* Check for missed buffers */
+		for (i = 0; i < vdpasim->dev_attr.nvqs; ++i)
+			vdpasim_kick_vq(vdpa, i);
+
+	}
+	spin_unlock(&vdpasim->lock);
+
+	return 0;
+}
+
 static size_t vdpasim_get_config_size(struct vdpa_device *vdpa)
 {
 	struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
@@ -694,6 +713,7 @@ static const struct vdpa_config_ops vdpasim_config_ops = {
 	.get_status             = vdpasim_get_status,
 	.set_status             = vdpasim_set_status,
 	.reset			= vdpasim_reset,
+	.suspend		= vdpasim_suspend,
 	.get_config_size        = vdpasim_get_config_size,
 	.get_config             = vdpasim_get_config,
 	.set_config             = vdpasim_set_config,
@@ -726,6 +746,7 @@ static const struct vdpa_config_ops vdpasim_batch_config_ops = {
 	.get_status             = vdpasim_get_status,
 	.set_status             = vdpasim_set_status,
 	.reset			= vdpasim_reset,
+	.suspend		= vdpasim_suspend,
 	.get_config_size        = vdpasim_get_config_size,
 	.get_config             = vdpasim_get_config,
 	.set_config             = vdpasim_set_config,
diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim.h b/drivers/vdpa/vdpa_sim/vdpa_sim.h
index 622782e922391..061986f30911a 100644
--- a/drivers/vdpa/vdpa_sim/vdpa_sim.h
+++ b/drivers/vdpa/vdpa_sim/vdpa_sim.h
@@ -66,6 +66,7 @@ struct vdpasim {
 	u32 generation;
 	u64 features;
 	u32 groups;
+	bool running;
 	/* spinlock to synchronize iommu table */
 	spinlock_t iommu_lock;
 };
diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim_blk.c b/drivers/vdpa/vdpa_sim/vdpa_sim_blk.c
index 42d401d439117..bcdb1982c378e 100644
--- a/drivers/vdpa/vdpa_sim/vdpa_sim_blk.c
+++ b/drivers/vdpa/vdpa_sim/vdpa_sim_blk.c
@@ -204,6 +204,9 @@ static void vdpasim_blk_work(struct work_struct *work)
 	if (!(vdpasim->status & VIRTIO_CONFIG_S_DRIVER_OK))
 		goto out;
 
+	if (!vdpasim->running)
+		goto out;
+
 	for (i = 0; i < VDPASIM_BLK_VQ_NUM; i++) {
 		struct vdpasim_virtqueue *vq = &vdpasim->vqs[i];
 
diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim_net.c b/drivers/vdpa/vdpa_sim/vdpa_sim_net.c
index 5125976a4df87..886449e885026 100644
--- a/drivers/vdpa/vdpa_sim/vdpa_sim_net.c
+++ b/drivers/vdpa/vdpa_sim/vdpa_sim_net.c
@@ -154,6 +154,9 @@ static void vdpasim_net_work(struct work_struct *work)
 
 	spin_lock(&vdpasim->lock);
 
+	if (!vdpasim->running)
+		goto out;
+
 	if (!(vdpasim->status & VIRTIO_CONFIG_S_DRIVER_OK))
 		goto out;
 
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2022-06-03 10:10 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-03 10:09 [PATCH v5 0/4] Implement vdpasim suspend operation Eugenio Pérez
2022-06-03 10:09 ` [PATCH v5 1/4] vdpa: Add " Eugenio Pérez
2022-06-03 10:09 ` [PATCH v5 2/4] vhost-vdpa: introduce SUSPEND backend feature bit Eugenio Pérez
2022-06-03 10:09 ` [PATCH v5 3/4] vhost-vdpa: uAPI to suspend the device Eugenio Pérez
2022-06-03 10:09 ` [PATCH v5 4/4] vdpa_sim: Implement suspend vdpa op Eugenio Pérez

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).