All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jason Wang <jasowang@redhat.com>
To: Stefano Garzarella <sgarzare@redhat.com>
Cc: virtualization <virtualization@lists.linux-foundation.org>,
	Parav Pandit <parav@nvidia.com>,
	"Michael S. Tsirkin" <mst@redhat.com>,
	linux-kernel <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] vdpa: add driver_override support
Date: Fri, 5 Nov 2021 11:01:30 +0800	[thread overview]
Message-ID: <CACGkMEsTxO0-pASV_4MohEs0dkP+7eahVuWiSZSOcffuG5ZV3A@mail.gmail.com> (raw)
In-Reply-To: <20211104161729.258294-1-sgarzare@redhat.com>

On Fri, Nov 5, 2021 at 12:17 AM Stefano Garzarella <sgarzare@redhat.com> wrote:
>
> `driver_override` allows to control which of the vDPA bus drivers
> binds to a vDPA device.
>
> If `driver_override` is not set, the previous behaviour is followed:
> devices use the first vDPA bus driver loaded (unless auto binding
> is disabled).
>
> Tested on Fedora 34 with driverctl(8):
>   $ modprobe virtio-vdpa
>   $ modprobe vhost-vdpa
>   $ modprobe vdpa-sim-net
>
>   $ vdpa dev add mgmtdev vdpasim_net name dev1
>
>   # dev1 is attached to the first vDPA bus driver loaded
>   $ driverctl -b vdpa list-devices
>     dev1 virtio_vdpa
>
>   $ driverctl -b vdpa set-override dev1 vhost_vdpa
>
>   $ driverctl -b vdpa list-devices
>     dev1 vhost_vdpa [*]
>
>   Note: driverctl(8) integrates with udev so the binding is
>   preserved.
>
> Suggested-by: Jason Wang <jasowang@redhat.com>
> Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
> ---
>  include/linux/vdpa.h |  2 ++
>  drivers/vdpa/vdpa.c  | 74 ++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 76 insertions(+)
>
> diff --git a/include/linux/vdpa.h b/include/linux/vdpa.h
> index c3011ccda430..ae34015b37b7 100644
> --- a/include/linux/vdpa.h
> +++ b/include/linux/vdpa.h
> @@ -64,6 +64,7 @@ struct vdpa_mgmt_dev;
>   * struct vdpa_device - representation of a vDPA device
>   * @dev: underlying device
>   * @dma_dev: the actual device that is performing DMA
> + * @driver_override: driver name to force a match

This seems useless?

>   * @config: the configuration ops for this device.
>   * @cf_mutex: Protects get and set access to configuration layout.
>   * @index: device index
> @@ -76,6 +77,7 @@ struct vdpa_mgmt_dev;
>  struct vdpa_device {
>         struct device dev;
>         struct device *dma_dev;
> +       const char *driver_override;
>         const struct vdpa_config_ops *config;
>         struct mutex cf_mutex; /* Protects get/set config */
>         unsigned int index;
> diff --git a/drivers/vdpa/vdpa.c b/drivers/vdpa/vdpa.c
> index 7332a74a4b00..659231bbfee8 100644
> --- a/drivers/vdpa/vdpa.c
> +++ b/drivers/vdpa/vdpa.c
> @@ -52,8 +52,81 @@ static void vdpa_dev_remove(struct device *d)
>                 drv->remove(vdev);
>  }
>
> +static int vdpa_dev_match(struct device *dev, struct device_driver *drv)
> +{
> +       struct vdpa_device *vdev = dev_to_vdpa(dev);
> +
> +       /* Check override first, and if set, only use the named driver */
> +       if (vdev->driver_override)
> +               return strcmp(vdev->driver_override, drv->name) == 0;
> +
> +       /* Currently devices must be supported by all vDPA bus drivers */
> +       return 1;
> +}
> +
> +static ssize_t driver_override_store(struct device *dev,
> +                                    struct device_attribute *attr,
> +                                    const char *buf, size_t count)
> +{
> +       struct vdpa_device *vdev = dev_to_vdpa(dev);
> +       const char *driver_override, *old;
> +       char *cp;
> +
> +       /* We need to keep extra room for a newline */
> +       if (count >= (PAGE_SIZE - 1))
> +               return -EINVAL;
> +
> +       driver_override = kstrndup(buf, count, GFP_KERNEL);
> +       if (!driver_override)
> +               return -ENOMEM;
> +
> +       cp = strchr(driver_override, '\n');
> +       if (cp)
> +               *cp = '\0';
> +
> +       device_lock(dev);
> +       old = vdev->driver_override;
> +       if (strlen(driver_override)) {
> +               vdev->driver_override = driver_override;
> +       } else {
> +               kfree(driver_override);
> +               vdev->driver_override = NULL;
> +       }
> +       device_unlock(dev);
> +
> +       kfree(old);
> +
> +       return count;
> +}
> +
> +static ssize_t driver_override_show(struct device *dev,
> +                                   struct device_attribute *attr, char *buf)
> +{
> +       struct vdpa_device *vdev = dev_to_vdpa(dev);
> +       ssize_t len;
> +
> +       device_lock(dev);
> +       len = snprintf(buf, PAGE_SIZE, "%s\n", vdev->driver_override);
> +       device_unlock(dev);
> +
> +       return len;
> +}
> +static DEVICE_ATTR_RW(driver_override);
> +
> +static struct attribute *vdpa_dev_attrs[] = {
> +       &dev_attr_driver_override.attr,
> +       NULL,
> +};
> +
> +static const struct attribute_group vdpa_dev_group = {
> +       .attrs  = vdpa_dev_attrs,
> +};
> +__ATTRIBUTE_GROUPS(vdpa_dev);
> +
>  static struct bus_type vdpa_bus = {
>         .name  = "vdpa",
> +       .dev_groups = vdpa_dev_groups,

This reminds me that we probably need to document the sysfs interface
in Documentation/ABI/testing/sysfs-bus-vdpa.

But it's not the fault of this patch which look good.

Thanks

> +       .match = vdpa_dev_match,
>         .probe = vdpa_dev_probe,
>         .remove = vdpa_dev_remove,
>  };
> @@ -68,6 +141,7 @@ static void vdpa_release_dev(struct device *d)
>
>         ida_simple_remove(&vdpa_index_ida, vdev->index);
>         mutex_destroy(&vdev->cf_mutex);
> +       kfree(vdev->driver_override);
>         kfree(vdev);
>  }
>
> --
> 2.31.1
>


WARNING: multiple messages have this Message-ID (diff)
From: Jason Wang <jasowang@redhat.com>
To: Stefano Garzarella <sgarzare@redhat.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>,
	linux-kernel <linux-kernel@vger.kernel.org>,
	virtualization <virtualization@lists.linux-foundation.org>
Subject: Re: [PATCH] vdpa: add driver_override support
Date: Fri, 5 Nov 2021 11:01:30 +0800	[thread overview]
Message-ID: <CACGkMEsTxO0-pASV_4MohEs0dkP+7eahVuWiSZSOcffuG5ZV3A@mail.gmail.com> (raw)
In-Reply-To: <20211104161729.258294-1-sgarzare@redhat.com>

On Fri, Nov 5, 2021 at 12:17 AM Stefano Garzarella <sgarzare@redhat.com> wrote:
>
> `driver_override` allows to control which of the vDPA bus drivers
> binds to a vDPA device.
>
> If `driver_override` is not set, the previous behaviour is followed:
> devices use the first vDPA bus driver loaded (unless auto binding
> is disabled).
>
> Tested on Fedora 34 with driverctl(8):
>   $ modprobe virtio-vdpa
>   $ modprobe vhost-vdpa
>   $ modprobe vdpa-sim-net
>
>   $ vdpa dev add mgmtdev vdpasim_net name dev1
>
>   # dev1 is attached to the first vDPA bus driver loaded
>   $ driverctl -b vdpa list-devices
>     dev1 virtio_vdpa
>
>   $ driverctl -b vdpa set-override dev1 vhost_vdpa
>
>   $ driverctl -b vdpa list-devices
>     dev1 vhost_vdpa [*]
>
>   Note: driverctl(8) integrates with udev so the binding is
>   preserved.
>
> Suggested-by: Jason Wang <jasowang@redhat.com>
> Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
> ---
>  include/linux/vdpa.h |  2 ++
>  drivers/vdpa/vdpa.c  | 74 ++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 76 insertions(+)
>
> diff --git a/include/linux/vdpa.h b/include/linux/vdpa.h
> index c3011ccda430..ae34015b37b7 100644
> --- a/include/linux/vdpa.h
> +++ b/include/linux/vdpa.h
> @@ -64,6 +64,7 @@ struct vdpa_mgmt_dev;
>   * struct vdpa_device - representation of a vDPA device
>   * @dev: underlying device
>   * @dma_dev: the actual device that is performing DMA
> + * @driver_override: driver name to force a match

This seems useless?

>   * @config: the configuration ops for this device.
>   * @cf_mutex: Protects get and set access to configuration layout.
>   * @index: device index
> @@ -76,6 +77,7 @@ struct vdpa_mgmt_dev;
>  struct vdpa_device {
>         struct device dev;
>         struct device *dma_dev;
> +       const char *driver_override;
>         const struct vdpa_config_ops *config;
>         struct mutex cf_mutex; /* Protects get/set config */
>         unsigned int index;
> diff --git a/drivers/vdpa/vdpa.c b/drivers/vdpa/vdpa.c
> index 7332a74a4b00..659231bbfee8 100644
> --- a/drivers/vdpa/vdpa.c
> +++ b/drivers/vdpa/vdpa.c
> @@ -52,8 +52,81 @@ static void vdpa_dev_remove(struct device *d)
>                 drv->remove(vdev);
>  }
>
> +static int vdpa_dev_match(struct device *dev, struct device_driver *drv)
> +{
> +       struct vdpa_device *vdev = dev_to_vdpa(dev);
> +
> +       /* Check override first, and if set, only use the named driver */
> +       if (vdev->driver_override)
> +               return strcmp(vdev->driver_override, drv->name) == 0;
> +
> +       /* Currently devices must be supported by all vDPA bus drivers */
> +       return 1;
> +}
> +
> +static ssize_t driver_override_store(struct device *dev,
> +                                    struct device_attribute *attr,
> +                                    const char *buf, size_t count)
> +{
> +       struct vdpa_device *vdev = dev_to_vdpa(dev);
> +       const char *driver_override, *old;
> +       char *cp;
> +
> +       /* We need to keep extra room for a newline */
> +       if (count >= (PAGE_SIZE - 1))
> +               return -EINVAL;
> +
> +       driver_override = kstrndup(buf, count, GFP_KERNEL);
> +       if (!driver_override)
> +               return -ENOMEM;
> +
> +       cp = strchr(driver_override, '\n');
> +       if (cp)
> +               *cp = '\0';
> +
> +       device_lock(dev);
> +       old = vdev->driver_override;
> +       if (strlen(driver_override)) {
> +               vdev->driver_override = driver_override;
> +       } else {
> +               kfree(driver_override);
> +               vdev->driver_override = NULL;
> +       }
> +       device_unlock(dev);
> +
> +       kfree(old);
> +
> +       return count;
> +}
> +
> +static ssize_t driver_override_show(struct device *dev,
> +                                   struct device_attribute *attr, char *buf)
> +{
> +       struct vdpa_device *vdev = dev_to_vdpa(dev);
> +       ssize_t len;
> +
> +       device_lock(dev);
> +       len = snprintf(buf, PAGE_SIZE, "%s\n", vdev->driver_override);
> +       device_unlock(dev);
> +
> +       return len;
> +}
> +static DEVICE_ATTR_RW(driver_override);
> +
> +static struct attribute *vdpa_dev_attrs[] = {
> +       &dev_attr_driver_override.attr,
> +       NULL,
> +};
> +
> +static const struct attribute_group vdpa_dev_group = {
> +       .attrs  = vdpa_dev_attrs,
> +};
> +__ATTRIBUTE_GROUPS(vdpa_dev);
> +
>  static struct bus_type vdpa_bus = {
>         .name  = "vdpa",
> +       .dev_groups = vdpa_dev_groups,

This reminds me that we probably need to document the sysfs interface
in Documentation/ABI/testing/sysfs-bus-vdpa.

But it's not the fault of this patch which look good.

Thanks

> +       .match = vdpa_dev_match,
>         .probe = vdpa_dev_probe,
>         .remove = vdpa_dev_remove,
>  };
> @@ -68,6 +141,7 @@ static void vdpa_release_dev(struct device *d)
>
>         ida_simple_remove(&vdpa_index_ida, vdev->index);
>         mutex_destroy(&vdev->cf_mutex);
> +       kfree(vdev->driver_override);
>         kfree(vdev);
>  }
>
> --
> 2.31.1
>

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

  reply	other threads:[~2021-11-05  3:01 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-04 16:17 [PATCH] vdpa: add driver_override support Stefano Garzarella
2021-11-04 16:17 ` Stefano Garzarella
2021-11-05  3:01 ` Jason Wang [this message]
2021-11-05  3:01   ` Jason Wang
2021-11-05  8:04   ` Stefano Garzarella
2021-11-05  8:04     ` Stefano Garzarella
2021-11-05  8:26     ` Jason Wang
2021-11-05  8:26       ` Jason Wang
2021-11-05  8:31       ` Stefano Garzarella
2021-11-05  8:31         ` Stefano Garzarella
2021-11-08 17:05   ` Stefano Garzarella
2021-11-08 17:05     ` Stefano Garzarella
2021-11-09 13:10     ` Michael S. Tsirkin
2021-11-09 13:10       ` Michael S. Tsirkin
2021-11-09 13:31       ` Stefano Garzarella
2021-11-09 13:31         ` Stefano Garzarella

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=CACGkMEsTxO0-pASV_4MohEs0dkP+7eahVuWiSZSOcffuG5ZV3A@mail.gmail.com \
    --to=jasowang@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mst@redhat.com \
    --cc=parav@nvidia.com \
    --cc=sgarzare@redhat.com \
    --cc=virtualization@lists.linux-foundation.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.