]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Include vdpa devices in node device list
authorJonathon Jongsma <jjongsma@redhat.com>
Wed, 14 Oct 2020 17:08:30 +0000 (12:08 -0500)
committerLaine Stump <laine@redhat.com>
Mon, 26 Oct 2020 06:39:29 +0000 (02:39 -0400)
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>
docs/formatnode.html.in
docs/schemas/nodedev.rng
include/libvirt/libvirt-nodedev.h
src/conf/node_device_conf.c
src/conf/node_device_conf.h
src/conf/virnodedeviceobj.c
src/node_device/node_device_udev.c
tools/virsh-nodedev.c

index 594427468b84f23a814ec6e8d493979f73683dae..6928bdd69c18ab54103e5ae7de88b8c7211ae659 100644 (file)
               <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>
index 166e278cf87d9803e4e88b8aae7f50fa2981b191..0456ddbe93ce3278503d287d850e641cc13d4da8 100644 (file)
@@ -86,6 +86,7 @@
         <ref name="capmdev"/>
         <ref name="capccwdev"/>
         <ref name="capcssdev"/>
+        <ref name="capvdpa"/>
       </choice>
     </element>
   </define>
     </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>
index dd2ffd5782f610201532df0ffa17e4bda08e4612..b73b076f140ea2cb61720631b3511c65e77bd264 100644 (file)
@@ -82,6 +82,7 @@ typedef enum {
     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_CSS_DEV       = 1 << 16, /* CSS device */
+    VIR_CONNECT_LIST_NODE_DEVICES_CAP_VDPA          = 1 << 17, /* vDPA device */
 } virConnectListAllNodeDeviceFlags;
 
 int                     virConnectListAllNodeDevices (virConnectPtr conn,
index 4adfdef572a17a2ce03f4e69ff031fa8d2166451..9e75f6f3a2ede205d478a9abac896501f0ae80e0 100644 (file)
@@ -66,6 +66,7 @@ VIR_ENUM_IMPL(virNodeDevCap,
               "mdev",
               "ccw",
               "css",
+              "vdpa",
 );
 
 VIR_ENUM_IMPL(virNodeDevNetCap,
@@ -518,6 +519,13 @@ virNodeDeviceCapMdevDefFormat(virBufferPtr buf,
     }
 }
 
+static void
+virNodeDeviceCapVDPADefFormat(virBufferPtr buf,
+                              const virNodeDevCapData *data)
+{
+    virBufferEscapeString(buf, "<chardev>%s</chardev>\n", data->vdpa.chardev);
+}
+
 char *
 virNodeDeviceDefFormat(const virNodeDeviceDef *def)
 {
@@ -611,6 +619,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:
@@ -1902,6 +1913,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'"),
@@ -2219,6 +2231,7 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps)
     case VIR_NODE_DEV_CAP_VPORTS:
     case VIR_NODE_DEV_CAP_CCW_DEV:
     case VIR_NODE_DEV_CAP_CSS_DEV:
+    case VIR_NODE_DEV_CAP_VDPA:
     case VIR_NODE_DEV_CAP_LAST:
         /* This case is here to shutup the compiler */
         break;
@@ -2273,6 +2286,7 @@ virNodeDeviceUpdateCaps(virNodeDeviceDefPtr def)
         case VIR_NODE_DEV_CAP_MDEV:
         case VIR_NODE_DEV_CAP_CCW_DEV:
         case VIR_NODE_DEV_CAP_CSS_DEV:
+        case VIR_NODE_DEV_CAP_VDPA:
         case VIR_NODE_DEV_CAP_LAST:
             break;
         }
index 5484bc340f06c19007a9956371be8b9e3da6ea90..3057c728a0a21a442316587bfc57ece551e60f1b 100644 (file)
@@ -65,6 +65,7 @@ typedef enum {
     VIR_NODE_DEV_CAP_MDEV,              /* Mediated device */
     VIR_NODE_DEV_CAP_CCW_DEV,           /* s390 CCW device */
     VIR_NODE_DEV_CAP_CSS_DEV,           /* s390 channel subsystem device */
+    VIR_NODE_DEV_CAP_VDPA,              /* vDPA device */
 
     VIR_NODE_DEV_CAP_LAST
 } virNodeDevCapType;
@@ -275,6 +276,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 {
@@ -293,6 +300,7 @@ struct _virNodeDevCapData {
         virNodeDevCapDRM drm;
         virNodeDevCapMdev mdev;
         virNodeDevCapCCW ccw_dev;
+        virNodeDevCapVDPA vdpa;
     };
 };
 
@@ -369,7 +377,8 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps);
                  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_CSS_DEV)
+                 VIR_CONNECT_LIST_NODE_DEVICES_CAP_CSS_DEV       | \
+                 VIR_CONNECT_LIST_NODE_DEVICES_CAP_VDPA)
 
 int
 virNodeDeviceGetSCSIHostCaps(virNodeDevCapSCSIHostPtr scsi_host);
index f240abf315914e3027a2220b2c13aa1f3542ef12..ad3726ba51c8afd8e27c919e1d4901184cdf6b21 100644 (file)
@@ -711,6 +711,7 @@ virNodeDeviceObjHasCap(const virNodeDeviceObj *obj,
         case VIR_NODE_DEV_CAP_MDEV:
         case VIR_NODE_DEV_CAP_CCW_DEV:
         case VIR_NODE_DEV_CAP_CSS_DEV:
+        case VIR_NODE_DEV_CAP_VDPA:
         case VIR_NODE_DEV_CAP_LAST:
             break;
         }
@@ -862,7 +863,8 @@ virNodeDeviceObjMatch(virNodeDeviceObjPtr obj,
               MATCH(MDEV_TYPES)    ||
               MATCH(MDEV)          ||
               MATCH(CCW_DEV)       ||
-              MATCH(CSS_DEV)))
+              MATCH(CSS_DEV)       ||
+              MATCH(VDPA)))
             return false;
     }
 
index 29a7eaa07c26cbb6991a27bdc2d3dd9997032005..b1b8427c0594452e73dc6b5503cbc87eb88c1869 100644 (file)
@@ -1142,6 +1142,55 @@ udevProcessCSS(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,
                    virNodeDeviceDefPtr def)
@@ -1221,6 +1270,8 @@ udevGetDeviceType(struct udev_device *device,
             *type = VIR_NODE_DEV_CAP_CCW_DEV;
         else if (STREQ_NULLABLE(subsystem, "css"))
             *type = VIR_NODE_DEV_CAP_CSS_DEV;
+        else if (STREQ_NULLABLE(subsystem, "vdpa"))
+            *type = VIR_NODE_DEV_CAP_VDPA;
 
         VIR_FREE(subsystem);
     }
@@ -1267,6 +1318,8 @@ udevGetDeviceDetails(struct udev_device *device,
         return udevProcessCCW(device, def);
     case VIR_NODE_DEV_CAP_CSS_DEV:
         return udevProcessCSS(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:
index 483e36bd534731d63cf67b0ec3dbf99f324ea2f0..527bf49fc3a35a9b150c83c3778365cae0854a25 100644 (file)
@@ -464,6 +464,9 @@ cmdNodeListDevices(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED)
         case VIR_NODE_DEV_CAP_CSS_DEV:
             flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_CSS_DEV;
             break;
+        case VIR_NODE_DEV_CAP_VDPA:
+            flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_VDPA;
+            break;
         case VIR_NODE_DEV_CAP_LAST:
             break;
         }