kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Eric Farman <farman@linux.ibm.com>
To: Jason Gunthorpe <jgg@nvidia.com>,
	Christian Borntraeger <borntraeger@de.ibm.com>,
	Cornelia Huck <cohuck@redhat.com>,
	Vasily Gorbik <gor@linux.ibm.com>,
	Heiko Carstens <hca@linux.ibm.com>,
	kvm@vger.kernel.org, linux-s390@vger.kernel.org,
	Peter Oberparleiter <oberpar@linux.ibm.com>,
	Halil Pasic <pasic@linux.ibm.com>,
	Vineeth Vijayan <vneethv@linux.ibm.com>
Cc: "Raj, Ashok" <ashok.raj@intel.com>,
	Dan Williams <dan.j.williams@intel.com>,
	Daniel Vetter <daniel@ffwll.ch>, Christoph Hellwig <hch@lst.de>,
	Leon Romanovsky <leonro@nvidia.com>,
	Max Gurtovoy <mgurtovoy@nvidia.com>,
	Tarun Gupta <targupta@nvidia.com>
Subject: Re: [PATCH v2 07/13] vfio/ccw: Convert to use vfio_register_group_dev()
Date: Tue, 27 Apr 2021 16:06:04 -0400	[thread overview]
Message-ID: <5325cd47bf170b66591bc1e64bf9fa3aa9c365b5.camel@linux.ibm.com> (raw)
In-Reply-To: <7-v2-7667f42c9bad+935-vfio3_jgg@nvidia.com>

On Mon, 2021-04-26 at 17:00 -0300, Jason Gunthorpe wrote:
> This is more complicated because vfio_ccw is sharing the vfio_device
> between both the mdev_device and its vfio_device and the css_driver.
> 
> The mdev is a singleton, and the reason for this sharing appears to
> be to
> allow the extra css_driver function callbacks to be delivered to the
> vfio_device.
> 
> This keeps things as they were, with the css_driver allocating the
> singleton, not the mdev_driver, this is pretty confusing. I'm also
> uncertain how the lifetime model for the mdev works in the css_driver
> callbacks.
> 
> At this point embed the vfio_device in the vfio_ccw_private and
> instantiate it as a vfio_device when the mdev probes. The drvdata of
> both
> the css_device and the mdev_device point at the private, and
> container_of
> is used to get it back from the vfio_device.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  drivers/s390/cio/vfio_ccw_drv.c     |  21 +++--
>  drivers/s390/cio/vfio_ccw_ops.c     | 135 +++++++++++++++-----------
> --
>  drivers/s390/cio/vfio_ccw_private.h |   5 ++
>  3 files changed, 94 insertions(+), 67 deletions(-)
> 
> 

...snip...

> diff --git a/drivers/s390/cio/vfio_ccw_ops.c
> b/drivers/s390/cio/vfio_ccw_ops.c
> index 491a64c61fff1a..0fcf46031d3821 100644
> --- a/drivers/s390/cio/vfio_ccw_ops.c
> +++ b/drivers/s390/cio/vfio_ccw_ops.c
> @@ -17,13 +17,13 @@
>  
>  #include "vfio_ccw_private.h"
>  
> -static int vfio_ccw_mdev_reset(struct mdev_device *mdev)
> +static const struct vfio_device_ops vfio_ccw_dev_ops;
> +
> +static int vfio_ccw_mdev_reset(struct vfio_ccw_private *private)
>  {
> -	struct vfio_ccw_private *private;
>  	struct subchannel *sch;
>  	int ret;
>  
> -	private = dev_get_drvdata(mdev_parent_dev(mdev));
>  	sch = private->sch;
>  	/*
>  	 * TODO:
> @@ -61,7 +61,7 @@ static int vfio_ccw_mdev_notifier(struct
> notifier_block *nb,
>  		if (!cp_iova_pinned(&private->cp, unmap->iova))
>  			return NOTIFY_OK;
>  
> -		if (vfio_ccw_mdev_reset(private->mdev))
> +		if (vfio_ccw_mdev_reset(private))
>  			return NOTIFY_BAD;
>  
>  		cp_free(&private->cp);
> @@ -113,10 +113,11 @@ static struct attribute_group
> *mdev_type_groups[] = {
>  	NULL,
>  };
>  
> -static int vfio_ccw_mdev_create(struct mdev_device *mdev)
> +static int vfio_ccw_mdev_probe(struct mdev_device *mdev)
>  {
>  	struct vfio_ccw_private *private =
>  		dev_get_drvdata(mdev_parent_dev(mdev));
> +	int ret;
>  
>  	if (private->state == VFIO_CCW_STATE_NOT_OPER)
>  		return -ENODEV;
> @@ -124,6 +125,10 @@ static int vfio_ccw_mdev_create(struct
> mdev_device *mdev)
>  	if (atomic_dec_if_positive(&private->avail) < 0)
>  		return -EPERM;
>  
> +	memset(&private->vdev, 0, sizeof(private->vdev));
> +	vfio_init_group_dev(&private->vdev, &mdev->dev,
> +			    &vfio_ccw_dev_ops);
> +
>  	private->mdev = mdev;
>  	private->state = VFIO_CCW_STATE_IDLE;
>  
> @@ -132,19 +137,28 @@ static int vfio_ccw_mdev_create(struct
> mdev_device *mdev)
>  			   private->sch->schid.ssid,
>  			   private->sch->schid.sch_no);
>  
> +	ret = vfio_register_group_dev(&private->vdev);
> +	if (ret)
> +		goto err_atomic;
> +	dev_set_drvdata(&mdev->dev, private);
>  	return 0;
> +
> +err_atomic:
> +	atomic_inc(&private->avail);

Since we're unwinding, should also do

private->mdev = NULL
private->state = VFIO_CCW_STATE_STANDBY

> +	return ret;
>  }
>  
> -static int vfio_ccw_mdev_remove(struct mdev_device *mdev)
> +static void vfio_ccw_mdev_remove(struct mdev_device *mdev)
>  {
> -	struct vfio_ccw_private *private =
> -		dev_get_drvdata(mdev_parent_dev(mdev));
> +	struct vfio_ccw_private *private = dev_get_drvdata(&mdev->dev);
>  
>  	VFIO_CCW_MSG_EVENT(2, "mdev %pUl, sch %x.%x.%04x: remove\n",
>  			   mdev_uuid(mdev), private->sch->schid.cssid,
>  			   private->sch->schid.ssid,
>  			   private->sch->schid.sch_no);
>  
> +	vfio_unregister_group_dev(&private->vdev);
> +
>  	if ((private->state != VFIO_CCW_STATE_NOT_OPER) &&
>  	    (private->state != VFIO_CCW_STATE_STANDBY)) {
>  		if (!vfio_ccw_sch_quiesce(private->sch))
> @@ -155,20 +169,18 @@ static int vfio_ccw_mdev_remove(struct
> mdev_device *mdev)
>  	cp_free(&private->cp);
>  	private->mdev = NULL;
>  	atomic_inc(&private->avail);
> -
> -	return 0;
>  }
>  
> -static int vfio_ccw_mdev_open(struct mdev_device *mdev)
> +static int vfio_ccw_mdev_open(struct vfio_device *vdev)
>  {
>  	struct vfio_ccw_private *private =
> -		dev_get_drvdata(mdev_parent_dev(mdev));
> +		container_of(vdev, struct vfio_ccw_private, vdev);
>  	unsigned long events = VFIO_IOMMU_NOTIFY_DMA_UNMAP;
>  	int ret;
>  
>  	private->nb.notifier_call = vfio_ccw_mdev_notifier;
>  
> -	ret = vfio_register_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,
> +	ret = vfio_register_notifier(vdev->dev, VFIO_IOMMU_NOTIFY,
>  				     &events, &private->nb);
>  	if (ret)
>  		return ret;
> @@ -189,27 +201,26 @@ static int vfio_ccw_mdev_open(struct
> mdev_device *mdev)
>  
>  out_unregister:
>  	vfio_ccw_unregister_dev_regions(private);
> -	vfio_unregister_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,
> +	vfio_unregister_notifier(vdev->dev, VFIO_IOMMU_NOTIFY,
>  				 &private->nb);
>  	return ret;
>  }
>  
> -static void vfio_ccw_mdev_release(struct mdev_device *mdev)
> +static void vfio_ccw_mdev_release(struct vfio_device *vdev)
>  {
>  	struct vfio_ccw_private *private =
> -		dev_get_drvdata(mdev_parent_dev(mdev));
> +		container_of(vdev, struct vfio_ccw_private, vdev);
>  
>  	if ((private->state != VFIO_CCW_STATE_NOT_OPER) &&
>  	    (private->state != VFIO_CCW_STATE_STANDBY)) {
> -		if (!vfio_ccw_mdev_reset(mdev))
> +		if (!vfio_ccw_mdev_reset(private))
>  			private->state = VFIO_CCW_STATE_STANDBY;
>  		/* The state will be NOT_OPER on error. */
>  	}
>  
>  	cp_free(&private->cp);
>  	vfio_ccw_unregister_dev_regions(private);
> -	vfio_unregister_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,
> -				 &private->nb);
> +	vfio_unregister_notifier(vdev->dev, VFIO_IOMMU_NOTIFY,
> &private->nb);
>  }
>  
>  static ssize_t vfio_ccw_mdev_read_io_region(struct vfio_ccw_private
> *private,
> @@ -233,15 +244,14 @@ static ssize_t
> vfio_ccw_mdev_read_io_region(struct vfio_ccw_private *private,
>  	return ret;
>  }
>  
> -static ssize_t vfio_ccw_mdev_read(struct mdev_device *mdev,
> +static ssize_t vfio_ccw_mdev_read(struct vfio_device *vdev,
>  				  char __user *buf,
>  				  size_t count,
>  				  loff_t *ppos)
>  {
> +	struct vfio_ccw_private *private =
> +		container_of(vdev, struct vfio_ccw_private, vdev);
>  	unsigned int index = VFIO_CCW_OFFSET_TO_INDEX(*ppos);
> -	struct vfio_ccw_private *private;
> -
> -	private = dev_get_drvdata(mdev_parent_dev(mdev));
>  
>  	if (index >= VFIO_CCW_NUM_REGIONS + private->num_regions)
>  		return -EINVAL;
> @@ -288,15 +298,14 @@ static ssize_t
> vfio_ccw_mdev_write_io_region(struct vfio_ccw_private *private,
>  	return ret;
>  }
>  
> -static ssize_t vfio_ccw_mdev_write(struct mdev_device *mdev,
> +static ssize_t vfio_ccw_mdev_write(struct vfio_device *vdev,
>  				   const char __user *buf,
>  				   size_t count,
>  				   loff_t *ppos)
>  {
> +	struct vfio_ccw_private *private =
> +		container_of(vdev, struct vfio_ccw_private, vdev);
>  	unsigned int index = VFIO_CCW_OFFSET_TO_INDEX(*ppos);
> -	struct vfio_ccw_private *private;
> -
> -	private = dev_get_drvdata(mdev_parent_dev(mdev));
>  
>  	if (index >= VFIO_CCW_NUM_REGIONS + private->num_regions)
>  		return -EINVAL;
> @@ -313,12 +322,9 @@ static ssize_t vfio_ccw_mdev_write(struct
> mdev_device *mdev,
>  	return -EINVAL;
>  }
>  
> -static int vfio_ccw_mdev_get_device_info(struct vfio_device_info
> *info,
> -					 struct mdev_device *mdev)
> +static int vfio_ccw_mdev_get_device_info(struct vfio_ccw_private
> *private,
> +					 struct vfio_device_info *info)
>  {
> -	struct vfio_ccw_private *private;
> -
> -	private = dev_get_drvdata(mdev_parent_dev(mdev));
>  	info->flags = VFIO_DEVICE_FLAGS_CCW | VFIO_DEVICE_FLAGS_RESET;
>  	info->num_regions = VFIO_CCW_NUM_REGIONS + private-
> >num_regions;
>  	info->num_irqs = VFIO_CCW_NUM_IRQS;
> @@ -326,14 +332,12 @@ static int vfio_ccw_mdev_get_device_info(struct
> vfio_device_info *info,
>  	return 0;
>  }
>  
> -static int vfio_ccw_mdev_get_region_info(struct vfio_region_info
> *info,
> -					 struct mdev_device *mdev,
> +static int vfio_ccw_mdev_get_region_info(struct vfio_ccw_private
> *private,
> +					 struct vfio_region_info *info,
>  					 unsigned long arg)
>  {
> -	struct vfio_ccw_private *private;
>  	int i;
>  
> -	private = dev_get_drvdata(mdev_parent_dev(mdev));
>  	switch (info->index) {
>  	case VFIO_CCW_CONFIG_REGION_INDEX:
>  		info->offset = 0;
> @@ -408,19 +412,16 @@ static int vfio_ccw_mdev_get_irq_info(struct
> vfio_irq_info *info)
>  	return 0;
>  }
>  
> -static int vfio_ccw_mdev_set_irqs(struct mdev_device *mdev,
> +static int vfio_ccw_mdev_set_irqs(struct vfio_ccw_private *private,
>  				  uint32_t flags,
>  				  uint32_t index,
>  				  void __user *data)
>  {
> -	struct vfio_ccw_private *private;
>  	struct eventfd_ctx **ctx;
>  
>  	if (!(flags & VFIO_IRQ_SET_ACTION_TRIGGER))
>  		return -EINVAL;
>  
> -	private = dev_get_drvdata(mdev_parent_dev(mdev));
> -
>  	switch (index) {
>  	case VFIO_CCW_IO_IRQ_INDEX:
>  		ctx = &private->io_trigger;
> @@ -522,10 +523,12 @@ void vfio_ccw_unregister_dev_regions(struct
> vfio_ccw_private *private)
>  	private->region = NULL;
>  }
>  
> -static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev,
> +static ssize_t vfio_ccw_mdev_ioctl(struct vfio_device *vdev,
>  				   unsigned int cmd,
>  				   unsigned long arg)
>  {
> +	struct vfio_ccw_private *private =
> +		container_of(vdev, struct vfio_ccw_private, vdev);
>  	int ret = 0;
>  	unsigned long minsz;
>  
> @@ -542,7 +545,7 @@ static ssize_t vfio_ccw_mdev_ioctl(struct
> mdev_device *mdev,
>  		if (info.argsz < minsz)
>  			return -EINVAL;
>  
> -		ret = vfio_ccw_mdev_get_device_info(&info, mdev);
> +		ret = vfio_ccw_mdev_get_device_info(private, &info);
>  		if (ret)
>  			return ret;
>  
> @@ -560,7 +563,7 @@ static ssize_t vfio_ccw_mdev_ioctl(struct
> mdev_device *mdev,
>  		if (info.argsz < minsz)
>  			return -EINVAL;
>  
> -		ret = vfio_ccw_mdev_get_region_info(&info, mdev, arg);
> +		ret = vfio_ccw_mdev_get_region_info(private, &info,
> arg);
>  		if (ret)
>  			return ret;
>  
> @@ -605,47 +608,59 @@ static ssize_t vfio_ccw_mdev_ioctl(struct
> mdev_device *mdev,
>  			return ret;
>  
>  		data = (void __user *)(arg + minsz);
> -		return vfio_ccw_mdev_set_irqs(mdev, hdr.flags,
> hdr.index, data);
> +		return vfio_ccw_mdev_set_irqs(private, hdr.flags,
> hdr.index,
> +					      data);
>  	}
>  	case VFIO_DEVICE_RESET:
> -		return vfio_ccw_mdev_reset(mdev);
> +		return vfio_ccw_mdev_reset(private);
>  	default:
>  		return -ENOTTY;
>  	}
>  }
>  
>  /* Request removal of the device*/
> -static void vfio_ccw_mdev_request(struct mdev_device *mdev, unsigned
> int count)
> +static void vfio_ccw_mdev_request(struct vfio_device *vdev, unsigned
> int count)
>  {
> -	struct vfio_ccw_private *private =
> dev_get_drvdata(mdev_parent_dev(mdev));
> -
> -	if (!private)
> -		return;
> +	struct vfio_ccw_private *private =
> +		container_of(vdev, struct vfio_ccw_private, vdev);
> +	struct device *dev = private->vdev.dev;

This could be simply vdev->dev.
The rest seems okay.

Thanks,
Eric

>  
>  	if (private->req_trigger) {
>  		if (!(count % 10))
> -			dev_notice_ratelimited(mdev_dev(private->mdev),
> +			dev_notice_ratelimited(dev,
>  					       "Relaying device request
> to user (#%u)\n",
>  					       count);
>  
>  		eventfd_signal(private->req_trigger, 1);
>  	} else if (count == 0) {
> -		dev_notice(mdev_dev(private->mdev),
> +		dev_notice(dev,
>  			   "No device request channel registered,
> blocked until released by user\n");
>  	}
>  }
>  
> +static const struct vfio_device_ops vfio_ccw_dev_ops = {
> +	.open = vfio_ccw_mdev_open,
> +	.release = vfio_ccw_mdev_release,
> +	.read = vfio_ccw_mdev_read,
> +	.write = vfio_ccw_mdev_write,
> +	.ioctl = vfio_ccw_mdev_ioctl,
> +	.request = vfio_ccw_mdev_request,
> +};
> +
> +struct mdev_driver vfio_ccw_mdev_driver = {
> +	.driver = {
> +		.name = "vfio_ccw_mdev",
> +		.owner = THIS_MODULE,
> +		.mod_name = KBUILD_MODNAME,
> +	},
> +	.probe = vfio_ccw_mdev_probe,
> +	.remove = vfio_ccw_mdev_remove,
> +};
> +
>  static const struct mdev_parent_ops vfio_ccw_mdev_ops = {
>  	.owner			= THIS_MODULE,
> +	.device_driver		= &vfio_ccw_mdev_driver,
>  	.supported_type_groups  = mdev_type_groups,
> -	.create			= vfio_ccw_mdev_create,
> -	.remove			= vfio_ccw_mdev_remove,
> -	.open			= vfio_ccw_mdev_open,
> -	.release		= vfio_ccw_mdev_release,
> -	.read			= vfio_ccw_mdev_read,
> -	.write			= vfio_ccw_mdev_write,
> -	.ioctl			= vfio_ccw_mdev_ioctl,
> -	.request		= vfio_ccw_mdev_request,
>  };
>  
>  int vfio_ccw_mdev_reg(struct subchannel *sch)
> diff --git a/drivers/s390/cio/vfio_ccw_private.h
> b/drivers/s390/cio/vfio_ccw_private.h
> index b2c762eb42b9bb..7272eb78861244 100644
> --- a/drivers/s390/cio/vfio_ccw_private.h
> +++ b/drivers/s390/cio/vfio_ccw_private.h
> @@ -17,6 +17,7 @@
>  #include <linux/eventfd.h>
>  #include <linux/workqueue.h>
>  #include <linux/vfio_ccw.h>
> +#include <linux/vfio.h>
>  #include <asm/crw.h>
>  #include <asm/debug.h>
>  
> @@ -67,6 +68,7 @@ struct vfio_ccw_crw {
>  
>  /**
>   * struct vfio_ccw_private
> + * @vdev: Embedded VFIO device
>   * @sch: pointer to the subchannel
>   * @state: internal state of the device
>   * @completion: synchronization helper of the I/O completion
> @@ -90,6 +92,7 @@ struct vfio_ccw_crw {
>   * @crw_work: work for deferral process of CRW handling
>   */
>  struct vfio_ccw_private {
> +	struct vfio_device vdev;
>  	struct subchannel	*sch;
>  	int			state;
>  	struct completion	*completion;
> @@ -121,6 +124,8 @@ extern void vfio_ccw_mdev_unreg(struct subchannel
> *sch);
>  
>  extern int vfio_ccw_sch_quiesce(struct subchannel *sch);
>  
> +extern struct mdev_driver vfio_ccw_mdev_driver;
> +
>  /*
>   * States of the device statemachine.
>   */


  reply	other threads:[~2021-04-27 20:06 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-26 20:00 [PATCH v2 00/13] Remove vfio_mdev.c, mdev_parent_ops and more Jason Gunthorpe
2021-04-26 20:00 ` [PATCH v2 01/13] vfio/mdev: Remove CONFIG_VFIO_MDEV_DEVICE Jason Gunthorpe
2021-04-27 11:05   ` Cornelia Huck
2021-04-26 20:00 ` [PATCH v2 02/13] vfio/mdev: Allow the mdev_parent_ops to specify the device driver to bind Jason Gunthorpe
2021-04-27 12:32   ` Cornelia Huck
2021-04-27 23:20     ` Jason Gunthorpe
2021-04-28  6:03   ` Christoph Hellwig
2021-04-28  7:56     ` Dan Williams
2021-04-28 12:41       ` Christoph Hellwig
2021-04-28 14:00         ` Jason Gunthorpe
2021-04-28 19:58           ` Dan Williams
2021-04-28 23:38             ` Jason Gunthorpe
2021-04-29  0:00               ` Dave Jiang
2021-05-26  0:42             ` Jason Gunthorpe
2021-05-26  1:42               ` Dan Williams
2021-05-27 11:44               ` Christoph Hellwig
2021-05-27 14:53                 ` Jason Gunthorpe
2021-05-27 15:13                   ` Christoph Hellwig
2021-04-29  6:51           ` Christoph Hellwig
2021-05-04  9:36           ` Christoph Hellwig
2021-05-04 11:30             ` Jason Gunthorpe
2021-04-28  6:44   ` Leon Romanovsky
2021-04-28 14:14     ` Jason Gunthorpe
2021-04-28 14:24       ` Leon Romanovsky
2021-04-26 20:00 ` [PATCH v2 03/13] vfio/mtty: Convert to use vfio_register_group_dev() Jason Gunthorpe
2021-04-26 20:00 ` [PATCH v2 04/13] vfio/mdpy: " Jason Gunthorpe
2021-04-26 20:00 ` [PATCH v2 05/13] vfio/mbochs: " Jason Gunthorpe
2021-04-26 20:00 ` [PATCH v2 07/13] vfio/ccw: " Jason Gunthorpe
2021-04-27 20:06   ` Eric Farman [this message]
2021-04-27 22:10     ` Jason Gunthorpe
2021-04-28 12:55       ` Eric Farman
2021-04-28 13:21         ` Jason Gunthorpe
2021-04-28 17:09   ` Cornelia Huck
2021-04-28 17:20     ` Jason Gunthorpe
2021-04-29 11:58       ` Cornelia Huck
2021-04-29 18:13         ` Jason Gunthorpe
2021-04-30 12:31           ` Cornelia Huck
2021-04-30 17:19             ` Jason Gunthorpe
2021-05-03 10:54               ` s390 common I/O layer locking (was: [PATCH v2 07/13] vfio/ccw: Convert to use vfio_register_group_dev()) Cornelia Huck
2021-05-04 15:10                 ` s390 common I/O layer locking Vineeth Vijayan
2021-07-24 13:24                   ` Christoph Hellwig
2021-08-03 14:27                     ` Vineeth Vijayan
2021-08-10 15:00                       ` Cornelia Huck
2021-04-26 20:00 ` [PATCH v2 09/13] vfio/mdev: Remove vfio_mdev.c Jason Gunthorpe
2021-04-28  6:07   ` Christoph Hellwig
2021-04-28  6:36     ` Greg Kroah-Hartman
2021-04-28 12:53       ` Jason Gunthorpe
2021-04-29  6:53         ` Christoph Hellwig
2021-04-29  6:56           ` Greg Kroah-Hartman
2021-05-03 17:32             ` Jason Gunthorpe
2021-05-04  9:38               ` Christoph Hellwig
2021-05-04 16:20                 ` Jason Gunthorpe
2021-04-26 20:00 ` [PATCH v2 10/13] vfio/mdev: Remove mdev_parent_ops dev_attr_groups Jason Gunthorpe
2021-04-26 20:00 ` [PATCH v2 11/13] vfio/mdev: Remove mdev_parent_ops Jason Gunthorpe
2021-04-26 20:00 ` [PATCH v2 12/13] vfio/mdev: Use the driver core to create the 'remove' file Jason Gunthorpe
2021-04-26 20:00 ` [PATCH v2 13/13] vfio/mdev: Remove mdev drvdata Jason Gunthorpe
2021-04-27 21:30 ` [PATCH v2 00/13] Remove vfio_mdev.c, mdev_parent_ops and more Alex Williamson
2021-04-27 22:20   ` Jason Gunthorpe
2021-04-27 22:49     ` Alex Williamson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5325cd47bf170b66591bc1e64bf9fa3aa9c365b5.camel@linux.ibm.com \
    --to=farman@linux.ibm.com \
    --cc=ashok.raj@intel.com \
    --cc=borntraeger@de.ibm.com \
    --cc=cohuck@redhat.com \
    --cc=dan.j.williams@intel.com \
    --cc=daniel@ffwll.ch \
    --cc=gor@linux.ibm.com \
    --cc=hca@linux.ibm.com \
    --cc=hch@lst.de \
    --cc=jgg@nvidia.com \
    --cc=kvm@vger.kernel.org \
    --cc=leonro@nvidia.com \
    --cc=linux-s390@vger.kernel.org \
    --cc=mgurtovoy@nvidia.com \
    --cc=oberpar@linux.ibm.com \
    --cc=pasic@linux.ibm.com \
    --cc=targupta@nvidia.com \
    --cc=vneethv@linux.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).