History

vdpa: add driver_override support

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

Stefano Garzarella committed 4 years ago

Commit 539fec71 parent 9c25cde3 files · +96 −0Browse files

Unified · Split

3 files
  1. Documentation/ABI/testing/sysfs-bus-vdpa +20 −0
  2. drivers/vdpa/vdpa.c +74 −0
  3. include/linux/vdpa.h +2 −0
Documentation/ABI/testing/sysfs-bus-vdpa+20−0
@@ -35,3 +35,23 @@ Description: · 34 unmodified lines
3535 Writing a device name to this file will cause the driver to
3636 attempt to unbind from the device. This may be useful when
3737 overriding default bindings.
38+
39+What: /sys/bus/vdpa/devices/.../driver_override
40+Date: November 2021
41+Contact: virtualization@lists.linux-foundation.org
42+Description:
43+ This file allows the driver for a device to be specified.
44+ When specified, only a driver with a name matching the value
45+ written to driver_override will have an opportunity to bind to
46+ the device. The override is specified by writing a string to the
47+ driver_override file (echo vhost-vdpa > driver_override) and may
48+ be cleared with an empty string (echo > driver_override).
49+ This returns the device to standard matching rules binding.
50+ Writing to driver_override does not automatically unbind the
51+ device from its current driver or make any attempt to
52+ automatically load the specified driver. If no driver with a
53+ matching name is currently loaded in the kernel, the device will
54+ not bind to any driver. This also allows devices to opt-out of
55+ driver binding using a driver_override name such as "none".
56+ Only a single driver may be specified in the override, there is
57+ no support for parsing delimiters.
drivers/vdpa/vdpa.c+74−0
@@ -52,8 +52,81 @@ static void vdpa_dev_remove(struct device *d) · 51 unmodified lines
5252 drv->remove(vdev);
5353 }
5454
55+static int vdpa_dev_match(struct device *dev, struct device_driver *drv)
56+{
57+ struct vdpa_device *vdev = dev_to_vdpa(dev);
58+
59+ /* Check override first, and if set, only use the named driver */
60+ if (vdev->driver_override)
61+ return strcmp(vdev->driver_override, drv->name) == 0;
62+
63+ /* Currently devices must be supported by all vDPA bus drivers */
64+ return 1;
65+}
66+
67+static ssize_t driver_override_store(struct device *dev,
68+ struct device_attribute *attr,
69+ const char *buf, size_t count)
70+{
71+ struct vdpa_device *vdev = dev_to_vdpa(dev);
72+ const char *driver_override, *old;
73+ char *cp;
74+
75+ /* We need to keep extra room for a newline */
76+ if (count >= (PAGE_SIZE - 1))
77+ return -EINVAL;
78+
79+ driver_override = kstrndup(buf, count, GFP_KERNEL);
80+ if (!driver_override)
81+ return -ENOMEM;
82+
83+ cp = strchr(driver_override, '\n');
84+ if (cp)
85+ *cp = '\0';
86+
87+ device_lock(dev);
88+ old = vdev->driver_override;
89+ if (strlen(driver_override)) {
90+ vdev->driver_override = driver_override;
91+ } else {
92+ kfree(driver_override);
93+ vdev->driver_override = NULL;
94+ }
95+ device_unlock(dev);
96+
97+ kfree(old);
98+
99+ return count;
100+}
101+
102+static ssize_t driver_override_show(struct device *dev,
103+ struct device_attribute *attr, char *buf)
104+{
105+ struct vdpa_device *vdev = dev_to_vdpa(dev);
106+ ssize_t len;
107+
108+ device_lock(dev);
109+ len = snprintf(buf, PAGE_SIZE, "%s\n", vdev->driver_override);
110+ device_unlock(dev);
111+
112+ return len;
113+}
114+static DEVICE_ATTR_RW(driver_override);
115+
116+static struct attribute *vdpa_dev_attrs[] = {
117+ &dev_attr_driver_override.attr,
118+ NULL,
119+};
120+
121+static const struct attribute_group vdpa_dev_group = {
122+ .attrs = vdpa_dev_attrs,
123+};
124+__ATTRIBUTE_GROUPS(vdpa_dev);
125+
55126 static struct bus_type vdpa_bus = {
56127 .name = "vdpa",
128+ .dev_groups = vdpa_dev_groups,
129+ .match = vdpa_dev_match,
57130 .probe = vdpa_dev_probe,
58131 .remove = vdpa_dev_remove,
59132 };
@@ -68,6 +141,7 @@ static void vdpa_release_dev(struct device *d) · 8 unmodified lines
68141
69142 ida_simple_remove(&vdpa_index_ida, vdev->index);
70143 mutex_destroy(&vdev->cf_mutex);
144+ kfree(vdev->driver_override);
71145 kfree(vdev);
72146 }
73147
include/linux/vdpa.h+2−0
@@ -64,6 +64,7 @@ struct vdpa_mgmt_dev; · 63 unmodified lines
6464 * struct vdpa_device - representation of a vDPA device
6565 * @dev: underlying device
6666 * @dma_dev: the actual device that is performing DMA
67+ * @driver_override: driver name to force a match
6768 * @config: the configuration ops for this device.
6869 * @cf_mutex: Protects get and set access to configuration layout.
6970 * @index: device index
@@ -76,6 +77,7 @@ struct vdpa_mgmt_dev; · 6 unmodified lines
7677 struct vdpa_device {
7778 struct device dev;
7879 struct device *dma_dev;
80+ const char *driver_override;
7981 const struct vdpa_config_ops *config;
8082 struct mutex cf_mutex; /* Protects get/set config */
8183 unsigned int index;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t