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.
> */
next prev parent 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).