79c4324644
Change-Id: I2d302dda68298877c65c99147f5bf22186a59aac
323 lines
11 KiB
Diff
323 lines
11 KiB
Diff
From e8597e64126a5cf77fbb9422977268878a6376b6 Mon Sep 17 00:00:00 2001
|
|
From: AlexChen <alex.chen@huawei.com>
|
|
Date: Wed, 14 Oct 2020 12:08:30 -0500
|
|
Subject: [PATCH] Include vdpa devices in node device list
|
|
|
|
The current udev node device driver ignores all events related to vdpa
|
|
devices. Since libvirt now supports vDPA network devices, include these
|
|
devices in the device list.
|
|
|
|
Example output:
|
|
|
|
virsh # nodedev-list
|
|
[...ommitted long list of nodedevs...]
|
|
vdpa_vdpa0
|
|
|
|
virsh # nodedev-dumpxml vdpa_vdpa0
|
|
<device>
|
|
<name>vdpa_vdpa0</name>
|
|
<path>/sys/devices/vdpa0</path>
|
|
<parent>computer</parent>
|
|
<driver>
|
|
<name>vhost_vdpa</name>
|
|
</driver>
|
|
<capability type='vdpa'>
|
|
<chardev>/dev/vhost-vdpa-0</chardev>
|
|
</capability>
|
|
</device>
|
|
|
|
NOTE: normally the 'parent' would be a PCI device instead of 'computer',
|
|
but this example output is from the vdpa_sim kernel module, so it
|
|
doesn't have a normal parent device.
|
|
|
|
Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
|
|
Signed-off-by: AlexChen <alex.chen@huawei.com>
|
|
---
|
|
docs/formatnode.html.in | 9 ++++++
|
|
docs/schemas/nodedev.rng | 10 ++++++
|
|
include/libvirt/libvirt-nodedev.h | 1 +
|
|
src/conf/node_device_conf.c | 13 ++++++++
|
|
src/conf/node_device_conf.h | 11 ++++++-
|
|
src/conf/virnodedeviceobj.c | 4 ++-
|
|
src/node_device/node_device_udev.c | 51 ++++++++++++++++++++++++++++++
|
|
tools/virsh-nodedev.c | 3 ++
|
|
8 files changed, 100 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/docs/formatnode.html.in b/docs/formatnode.html.in
|
|
index c2a8f8fb7a..573391ef0f 100644
|
|
--- a/docs/formatnode.html.in
|
|
+++ b/docs/formatnode.html.in
|
|
@@ -341,6 +341,15 @@
|
|
<dd>The device number.</dd>
|
|
</dl>
|
|
</dd>
|
|
+ <dt><code>vdpa</code></dt>
|
|
+ <dd>Describes a virtual datapath acceleration (vDPA) network device.
|
|
+ <span class="since">Since 6.9.0</span>. Sub-elements include:
|
|
+ <dl>
|
|
+ <dt><code>chardev</code></dt>
|
|
+ <dd>The path to the character device that is used to access the
|
|
+ device.</dd>
|
|
+ </dl>
|
|
+ </dd>
|
|
</dl>
|
|
</dd>
|
|
</dl>
|
|
diff --git a/docs/schemas/nodedev.rng b/docs/schemas/nodedev.rng
|
|
index fe6ffa0b53..4f197b327a 100644
|
|
--- a/docs/schemas/nodedev.rng
|
|
+++ b/docs/schemas/nodedev.rng
|
|
@@ -85,6 +85,7 @@
|
|
<ref name="capdrm"/>
|
|
<ref name="capmdev"/>
|
|
<ref name="capccwdev"/>
|
|
+ <ref name="capvdpa"/>
|
|
</choice>
|
|
</element>
|
|
</define>
|
|
@@ -651,6 +652,15 @@
|
|
</element>
|
|
</define>
|
|
|
|
+ <define name="capvdpa">
|
|
+ <attribute name="type">
|
|
+ <value>vdpa</value>
|
|
+ </attribute>
|
|
+ <element name="chardev">
|
|
+ <ref name="path"/>
|
|
+ </element>
|
|
+ </define>
|
|
+
|
|
<define name='address'>
|
|
<element name='address'>
|
|
<attribute name='domain'><ref name='hexuint'/></attribute>
|
|
diff --git a/include/libvirt/libvirt-nodedev.h b/include/libvirt/libvirt-nodedev.h
|
|
index a2ad61ac6d..4129f1afed 100644
|
|
--- a/include/libvirt/libvirt-nodedev.h
|
|
+++ b/include/libvirt/libvirt-nodedev.h
|
|
@@ -81,6 +81,7 @@ typedef enum {
|
|
VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV_TYPES = 1 << 13, /* Capable of mediated devices */
|
|
VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV = 1 << 14, /* Mediated device */
|
|
VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCW_DEV = 1 << 15, /* CCW device */
|
|
+ VIR_CONNECT_LIST_NODE_DEVICES_CAP_VDPA = 1 << 17, /* vDPA device */
|
|
} virConnectListAllNodeDeviceFlags;
|
|
|
|
int virConnectListAllNodeDevices (virConnectPtr conn,
|
|
diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c
|
|
index d64f6d3986..41d7c7d12e 100644
|
|
--- a/src/conf/node_device_conf.c
|
|
+++ b/src/conf/node_device_conf.c
|
|
@@ -65,6 +65,7 @@ VIR_ENUM_IMPL(virNodeDevCap,
|
|
"mdev_types",
|
|
"mdev",
|
|
"ccw",
|
|
+ "vdpa",
|
|
);
|
|
|
|
VIR_ENUM_IMPL(virNodeDevNetCap,
|
|
@@ -500,6 +501,12 @@ virNodeDeviceCapStorageDefFormat(virBufferPtr buf,
|
|
virBufferAddLit(buf, "<capability type='hotpluggable'/>\n");
|
|
}
|
|
|
|
+static void
|
|
+virNodeDeviceCapVDPADefFormat(virBufferPtr buf,
|
|
+ const virNodeDevCapData *data)
|
|
+{
|
|
+ virBufferEscapeString(buf, "<chardev>%s</chardev>\n", data->vdpa.chardev);
|
|
+}
|
|
|
|
char *
|
|
virNodeDeviceDefFormat(const virNodeDeviceDef *def)
|
|
@@ -595,6 +602,9 @@ virNodeDeviceDefFormat(const virNodeDeviceDef *def)
|
|
virBufferAsprintf(&buf, "<devno>0x%04x</devno>\n",
|
|
data->ccw_dev.devno);
|
|
break;
|
|
+ case VIR_NODE_DEV_CAP_VDPA:
|
|
+ virNodeDeviceCapVDPADefFormat(&buf, data);
|
|
+ break;
|
|
case VIR_NODE_DEV_CAP_MDEV_TYPES:
|
|
case VIR_NODE_DEV_CAP_FC_HOST:
|
|
case VIR_NODE_DEV_CAP_VPORTS:
|
|
@@ -1897,6 +1907,7 @@ virNodeDevCapsDefParseXML(xmlXPathContextPtr ctxt,
|
|
case VIR_NODE_DEV_CAP_FC_HOST:
|
|
case VIR_NODE_DEV_CAP_VPORTS:
|
|
case VIR_NODE_DEV_CAP_SCSI_GENERIC:
|
|
+ case VIR_NODE_DEV_CAP_VDPA:
|
|
case VIR_NODE_DEV_CAP_LAST:
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
_("unknown capability type '%d' for '%s'"),
|
|
@@ -2209,6 +2220,7 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps)
|
|
case VIR_NODE_DEV_CAP_FC_HOST:
|
|
case VIR_NODE_DEV_CAP_VPORTS:
|
|
case VIR_NODE_DEV_CAP_CCW_DEV:
|
|
+ case VIR_NODE_DEV_CAP_VDPA:
|
|
case VIR_NODE_DEV_CAP_LAST:
|
|
/* This case is here to shutup the compiler */
|
|
break;
|
|
@@ -2262,6 +2274,7 @@ virNodeDeviceUpdateCaps(virNodeDeviceDefPtr def)
|
|
case VIR_NODE_DEV_CAP_MDEV_TYPES:
|
|
case VIR_NODE_DEV_CAP_MDEV:
|
|
case VIR_NODE_DEV_CAP_CCW_DEV:
|
|
+ case VIR_NODE_DEV_CAP_VDPA:
|
|
case VIR_NODE_DEV_CAP_LAST:
|
|
break;
|
|
}
|
|
diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h
|
|
index 9e4b0847fb..a14eaef742 100644
|
|
--- a/src/conf/node_device_conf.h
|
|
+++ b/src/conf/node_device_conf.h
|
|
@@ -64,6 +64,7 @@ typedef enum {
|
|
VIR_NODE_DEV_CAP_MDEV_TYPES, /* Device capable of mediated devices */
|
|
VIR_NODE_DEV_CAP_MDEV, /* Mediated device */
|
|
VIR_NODE_DEV_CAP_CCW_DEV, /* s390 CCW device */
|
|
+ VIR_NODE_DEV_CAP_VDPA, /* vDPA device */
|
|
|
|
VIR_NODE_DEV_CAP_LAST
|
|
} virNodeDevCapType;
|
|
@@ -271,6 +272,12 @@ struct _virNodeDevCapCCW {
|
|
unsigned int devno;
|
|
};
|
|
|
|
+typedef struct _virNodeDevCapVDPA virNodeDevCapVDPA;
|
|
+typedef virNodeDevCapVDPA *virNodeDevCapVDPAPtr;
|
|
+struct _virNodeDevCapVDPA {
|
|
+ char *chardev;
|
|
+};
|
|
+
|
|
typedef struct _virNodeDevCapData virNodeDevCapData;
|
|
typedef virNodeDevCapData *virNodeDevCapDataPtr;
|
|
struct _virNodeDevCapData {
|
|
@@ -289,6 +296,7 @@ struct _virNodeDevCapData {
|
|
virNodeDevCapDRM drm;
|
|
virNodeDevCapMdev mdev;
|
|
virNodeDevCapCCW ccw_dev;
|
|
+ virNodeDevCapVDPA vdpa;
|
|
};
|
|
};
|
|
|
|
@@ -364,7 +372,8 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps);
|
|
VIR_CONNECT_LIST_NODE_DEVICES_CAP_DRM | \
|
|
VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV_TYPES | \
|
|
VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV | \
|
|
- VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCW_DEV)
|
|
+ VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCW_DEV | \
|
|
+ VIR_CONNECT_LIST_NODE_DEVICES_CAP_VDPA)
|
|
|
|
int
|
|
virNodeDeviceGetSCSIHostCaps(virNodeDevCapSCSIHostPtr scsi_host);
|
|
diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c
|
|
index 3a34a324ca..be111741bf 100644
|
|
--- a/src/conf/virnodedeviceobj.c
|
|
+++ b/src/conf/virnodedeviceobj.c
|
|
@@ -676,6 +676,7 @@ virNodeDeviceObjHasCap(const virNodeDeviceObj *obj,
|
|
case VIR_NODE_DEV_CAP_MDEV_TYPES:
|
|
case VIR_NODE_DEV_CAP_MDEV:
|
|
case VIR_NODE_DEV_CAP_CCW_DEV:
|
|
+ case VIR_NODE_DEV_CAP_VDPA:
|
|
case VIR_NODE_DEV_CAP_LAST:
|
|
break;
|
|
}
|
|
@@ -826,7 +827,8 @@ virNodeDeviceObjMatch(virNodeDeviceObjPtr obj,
|
|
MATCH(DRM) ||
|
|
MATCH(MDEV_TYPES) ||
|
|
MATCH(MDEV) ||
|
|
- MATCH(CCW_DEV)))
|
|
+ MATCH(CCW_DEV) ||
|
|
+ MATCH(VDPA)))
|
|
return false;
|
|
}
|
|
|
|
diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
|
|
index 0d8a7db5c6..2764315325 100644
|
|
--- a/src/node_device/node_device_udev.c
|
|
+++ b/src/node_device/node_device_udev.c
|
|
@@ -1089,6 +1089,53 @@ udevProcessCCW(struct udev_device *device,
|
|
return 0;
|
|
}
|
|
|
|
+static int
|
|
+udevGetVDPACharDev(const char *sysfs_path,
|
|
+ virNodeDevCapDataPtr data)
|
|
+{
|
|
+ struct dirent *entry;
|
|
+ DIR *dir = NULL;
|
|
+ int direrr;
|
|
+
|
|
+ if (virDirOpenIfExists(&dir, sysfs_path) <= 0)
|
|
+ return -1;
|
|
+
|
|
+ while ((direrr = virDirRead(dir, &entry, NULL)) > 0) {
|
|
+ if (g_str_has_prefix(entry->d_name, "vhost-vdpa")) {
|
|
+ g_autofree char *chardev = g_strdup_printf("/dev/%s", entry->d_name);
|
|
+
|
|
+ if (!virFileExists(chardev)) {
|
|
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
+ _("vDPA chardev path '%s' does not exist"),
|
|
+ chardev);
|
|
+ return -1;
|
|
+ }
|
|
+ VIR_DEBUG("vDPA chardev is at '%s'", chardev);
|
|
+
|
|
+ data->vdpa.chardev = g_steal_pointer(&chardev);
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (direrr < 0)
|
|
+ return -1;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int
|
|
+udevProcessVDPA(struct udev_device *device,
|
|
+ virNodeDeviceDefPtr def)
|
|
+{
|
|
+ if (udevGenerateDeviceName(device, def, NULL) != 0)
|
|
+ return -1;
|
|
+
|
|
+ if (udevGetVDPACharDev(def->sysfs_path, &def->caps->data) < 0)
|
|
+ return -1;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
|
|
static int
|
|
udevGetDeviceNodes(struct udev_device *device,
|
|
@@ -1168,6 +1215,8 @@ udevGetDeviceType(struct udev_device *device,
|
|
*type = VIR_NODE_DEV_CAP_MDEV;
|
|
else if (STREQ_NULLABLE(subsystem, "ccw"))
|
|
*type = VIR_NODE_DEV_CAP_CCW_DEV;
|
|
+ else if (STREQ_NULLABLE(subsystem, "vdpa"))
|
|
+ *type = VIR_NODE_DEV_CAP_VDPA;
|
|
|
|
VIR_FREE(subsystem);
|
|
}
|
|
@@ -1212,6 +1261,8 @@ udevGetDeviceDetails(struct udev_device *device,
|
|
return udevProcessMediatedDevice(device, def);
|
|
case VIR_NODE_DEV_CAP_CCW_DEV:
|
|
return udevProcessCCW(device, def);
|
|
+ case VIR_NODE_DEV_CAP_VDPA:
|
|
+ return udevProcessVDPA(device, def);
|
|
case VIR_NODE_DEV_CAP_MDEV_TYPES:
|
|
case VIR_NODE_DEV_CAP_SYSTEM:
|
|
case VIR_NODE_DEV_CAP_FC_HOST:
|
|
diff --git a/tools/virsh-nodedev.c b/tools/virsh-nodedev.c
|
|
index 7f091d7cf8..f831b36054 100644
|
|
--- a/tools/virsh-nodedev.c
|
|
+++ b/tools/virsh-nodedev.c
|
|
@@ -462,6 +462,9 @@ cmdNodeListDevices(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED)
|
|
case VIR_NODE_DEV_CAP_CCW_DEV:
|
|
flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCW_DEV;
|
|
break;
|
|
+ case VIR_NODE_DEV_CAP_VDPA:
|
|
+ flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_VDPA;
|
|
+ break;
|
|
case VIR_NODE_DEV_CAP_LAST:
|
|
break;
|
|
}
|
|
--
|
|
2.27.0
|
|
|