[Spice-devel] [PATCH] common: Add a udev helper to identify GPU Vendor (v2)
Frediano Ziglio
freddy77 at gmail.com
Tue Oct 3 19:36:15 UTC 2023
Il giorno lun 2 ott 2023 alle ore 06:41 Vivek Kasireddy
<vivek.kasireddy at intel.com> ha scritto:
>
> Given that libudev is widely available on many Linux distros, we
> can use the relevant APIs to iterate over all the devices associated
> with the drm subsystem to figure out if a specific vendor GPU
> is available or not.
>
> This capability (identifying GPU Vendor) is useful to determine
> whether to launch Gstreamer pipeline using h/w accelerated
> plugins. On systems where libudev is not available (Windows,
> MacOS, etc) we'd have to make this determination based on the
> availability of the relevant plugins in the Gstreamer registry.
>
> v2: (Frediano)
> - Added autoconf support
> - Added license text
> - Added pragma once and SPICE_BEGIN/END_DECLS to the header
> - Checked the vendor id udev attribute of the pci device to
> determine a vendor GPU instead of checking the driver name
>
Thanks. Do you want this part of the message to be part of the final
commit? Usually we don't put history... and not much useful IMHO.
> Cc: Frediano Ziglio <freddy77 at gmail.com>
> Cc: Gerd Hoffmann <kraxel at redhat.com>
> Cc: Marc-André Lureau <marcandre.lureau at redhat.com>
> Cc: Dongwon Kim <dongwon.kim at intel.com>
> Cc: Hazwan Arif Mazlan <hazwan.arif.mazlan at intel.com>
> Cc: Jin Chung Teng <jin.chung.teng at intel.com>
> Signed-off-by: Vivek Kasireddy <vivek.kasireddy at intel.com>
> ---
> common/meson.build | 2 ++
> common/udev.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++
> common/udev.h | 33 ++++++++++++++++++++
> configure.ac | 1 +
> m4/spice-deps.m4 | 12 +++++++
> meson.build | 7 +++++
> 6 files changed, 133 insertions(+)
> create mode 100644 common/udev.c
> create mode 100644 common/udev.h
>
> diff --git a/common/meson.build b/common/meson.build
> index 09e3ea7..63bd2db 100644
> --- a/common/meson.build
> +++ b/common/meson.build
> @@ -39,6 +39,8 @@ spice_common_sources = [
> 'snd_codec.h',
> 'utils.c',
> 'utils.h',
> + 'udev.c',
> + 'udev.h',
> 'verify.h',
> 'recorder.h'
> ]
> diff --git a/common/udev.c b/common/udev.c
> new file mode 100644
> index 0000000..3985fdd
> --- /dev/null
> +++ b/common/udev.c
> @@ -0,0 +1,78 @@
> +/*
> + Copyright (C) 2023 Intel Corporation.
> +
> + This library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + This library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with this library; if not, see <http://www.gnu.org/licenses/>.
> +*/
> +
> +#include <config.h>
> +
> +#ifdef HAVE_UDEV
> +#include <libudev.h>
> +#include <stdbool.h>
> +#include <stdlib.h>
> +#include "udev.h"
> +
> +GpuVendor spice_udev_detect_gpu(long gpu_vendor)
long type here looks a bit weird, considering that vendor numbers are
encoded as 16-bit unsigned integer in PCI specifications; maybe just
int?
> +{
> + struct udev *udev;
> + struct udev_device *drm_dev, *pci_dev;
> + struct udev_enumerate *udev_enum;
> + struct udev_list_entry *entry, *devices;
> + const char *path, *vendor_id;
> + GpuVendor vendor = VENDOR_GPU_NOTDETECTED;
> +
> + udev = udev_new();
> + if (!udev) {
> + return vendor;
wondering if in this case VENDOR_GPU_UNKNOWN would be better, if we
fail to get udev object we are not sure if there's the device or not.
> + }
> +
> + udev_enum = udev_enumerate_new(udev);
> + if (udev_enum) {
> + udev_enumerate_add_match_subsystem(udev_enum, "drm");
> + udev_enumerate_add_match_sysname(udev_enum, "card[0-9]");
> + udev_enumerate_scan_devices(udev_enum);
> + devices = udev_enumerate_get_list_entry(udev_enum);
> +
> + udev_list_entry_foreach(entry, devices) {
> + path = udev_list_entry_get_name(entry);
> + drm_dev = udev_device_new_from_syspath(udev, path);
> + if (!drm_dev) {
> + continue;
> + }
> +
> + pci_dev = udev_device_get_parent_with_subsystem_devtype(drm_dev,
> + "pci", NULL);
> + if (pci_dev) {
> + vendor_id = udev_device_get_sysattr_value(pci_dev, "vendor");
> + if (vendor_id && strtol(vendor_id, NULL, 16) == gpu_vendor) {
> + vendor = VENDOR_GPU_DETECTED;
> + udev_device_unref(drm_dev);
> + break;
> + }
> + }
> + udev_device_unref(drm_dev);
> + }
> + udev_enumerate_unref(udev_enum);
> + }
> + udev_unref(udev);
> +
> + return vendor;
> +}
> +#else
> +GpuVendor spice_udev_detect_gpu(long gpu_vendor)
This won't compile as GpuVendor is not defined (udev.h not included)
> +{
> + return VENDOR_GPU_UNKNOWN;
> +}
> +#endif
> +
> diff --git a/common/udev.h b/common/udev.h
> new file mode 100644
> index 0000000..6a3d068
> --- /dev/null
> +++ b/common/udev.h
> @@ -0,0 +1,33 @@
> +/*
> + Copyright (C) 2023 Intel Corporation.
> +
> + This library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + This library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with this library; if not, see <http://www.gnu.org/licenses/>.
> +*/
> +
> +#pragma once
> +#include <spice/macros.h>
> +
> +#define INTEL_VENDOR_ID 0x8086
> +
> +typedef enum {
> + VENDOR_GPU_UNKNOWN,
> + VENDOR_GPU_DETECTED,
> + VENDOR_GPU_NOTDETECTED,
> +} GpuVendor;
> +
> +SPICE_BEGIN_DECLS
> +
> +GpuVendor spice_udev_detect_gpu(long gpu_vendor);
> +
> +SPICE_END_DECLS
> diff --git a/configure.ac b/configure.ac
> index 0d4c22b..42e873d 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -61,6 +61,7 @@ SPICE_CHECK_GLIB2
> SPICE_CHECK_OPUS
> SPICE_CHECK_OPENSSL
> SPICE_CHECK_GDK_PIXBUF
> +SPICE_CHECK_UDEV
>
> SPICE_COMMON_CFLAGS='$(PIXMAN_CFLAGS) $(SMARTCARD_CFLAGS) $(GLIB2_CFLAGS) $(OPUS_CFLAGS) $(OPENSSL_CFLAGS)'
> SPICE_COMMON_CFLAGS="$SPICE_COMMON_CFLAGS -DG_LOG_DOMAIN=\\\"Spice\\\""
> diff --git a/m4/spice-deps.m4 b/m4/spice-deps.m4
> index e11fc4e..6a07ee6 100644
> --- a/m4/spice-deps.m4
> +++ b/m4/spice-deps.m4
> @@ -302,6 +302,18 @@ AC_DEFUN([SPICE_CHECK_OPENSSL], [
> PKG_CHECK_MODULES(OPENSSL, openssl)
> ])
>
> +# SPICE_CHECK_UDEV
> +# -----------------
> +# Check for the availability of libudev. If found, it will help to determine
> +# if a given vendor GPU is available or not.
> +#------------------
> +AC_DEFUN([SPICE_CHECK_UDEV], [
> + PKG_CHECK_MODULES([UDEV], [libudev], [have_udev=yes],[have_udev=no])
> + if test "x$have_udev" = "xyes"; then
> + AC_DEFINE([HAVE_UDEV], 1, [whether libudev is available to identify GPU])
> + fi
> +])
> +
> # SPICE_CHECK_INSTRUMENTATION
> # -----------------
> # Check for the availability of an instrumentation library.
> diff --git a/meson.build b/meson.build
> index eeccecd..cafbf03 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -147,6 +147,13 @@ if smartcard_dep.found()
> spice_common_config_data.set('USE_SMARTCARD', '1')
> endif
>
> +#udev
> +udev_dep = dependency('libudev')
> +if udev_dep.found()
> + spice_common_deps += udev_dep
> + spice_common_config_data.set('HAVE_UDEV', '1')
> +endif
> +
> #
> # global C defines
> #
Wrote some small fixups (also addressing some comments) at
https://gitlab.freedesktop.org/fziglio/spice-common/-/commits/udev/
(ignore the test, just for linking/Windows/CI checks).
Frediano
More information about the Spice-devel
mailing list