[Spice-devel] [PATCH] common: Add a udev helper to identify GPU Vendor
Kasireddy, Vivek
vivek.kasireddy at intel.com
Mon Sep 18 05:43:21 UTC 2023
Hi Frediano,
> > Given that libudev is widely available on many distros, we can
> > use the relevant APIs to iterate over all the PCI devices on
> > any given system to identify if a GPU is available by looking
> > at the driver name associated with it.
> >
> > 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),
>
> Nor MacOS I think.
>
> > we'd have to make this determination based on the availability
> > of the plugins in Gstreamer registry.
> >
> > 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 | 60
> ++++++++++++++++++++++++++++++++++++++++++++++
> > common/udev.h | 12 ++++++++++
> > meson.build | 7 ++++++
> > 4 files changed, 81 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..995a37e
> > --- /dev/null
> > +++ b/common/udev.c
> > @@ -0,0 +1,60 @@
>
> Can you add license comments?
>
> > +#include <config.h>
> > +
> > +#ifdef HAVE_UDEV
> > +#include <libudev.h>
> > +#include <stdbool.h>
> > +#include <string.h>
> > +#include "udev.h"
> > +
> > +#define INTEL_GFX_DRV_NAME "i915"
> > +
> > +static bool is_intel_gpu(const char *drv_name)
> > +{
> > + return !strcmp(drv_name, INTEL_GFX_DRV_NAME);
> > +}
> > +
> > +GpuVendor spice_udev_detect_gpu()
> > +{
> > + struct udev *udev;
> > + struct udev_device *udev_dev;
> > + struct udev_enumerate *udev_enum;
> > + struct udev_list_entry *entry, *devices;
> > + const char *path, *driver;
> > + GpuVendor vendor = GPU_VENDOR_OTHER;
> > +
> > + udev = udev_new();
> > + if (!udev) {
> > + return vendor;
> > + }
> > +
> > + udev_enum = udev_enumerate_new(udev);
> > + if (udev_enum) {
> > + udev_enumerate_add_match_subsystem(udev_enum, "pci");
> > + 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);
> > + udev_dev = udev_device_new_from_syspath(udev, path);
> > +
> > + driver = udev_device_get_driver(udev_dev);
> > + if (driver && is_intel_gpu(driver)) {
> > + vendor = GPU_VENDOR_INTEL;
> > + udev_device_unref(udev_dev);
> > + break;
> > + }
> > + udev_device_unref(udev_dev);
> > + }
> > + udev_enumerate_unref(udev_enum);
> > + }
> > + udev_unref(udev);
> > +
> > + return vendor;
> > +}
> > +#else
> > +GpuVendor spice_udev_detect_gpu()
> > +{
> > + return GPU_VENDOR_UNKNOWN;
> > +}
> > +#endif
> > +
> > diff --git a/common/udev.h b/common/udev.h
> > new file mode 100644
> > index 0000000..f1ba0ec
> > --- /dev/null
> > +++ b/common/udev.h
> > @@ -0,0 +1,12 @@
> > +#ifndef H_SPICE_COMMON_UDEV
> > +#define H_SPICE_COMMON_UDEV
> > +
> > +typedef enum {
> > + GPU_VENDOR_UNKNOWN,
> > + GPU_VENDOR_OTHER,
> > + GPU_VENDOR_INTEL,
> > +} GpuVendor;
> > +
> > +GpuVendor spice_udev_detect_gpu();
> > +
>
> What if the machine has more than one GPU ?
I think we can have the following situations:
- more than one GPU from different vendors:
In this case, user preference can be determined based on which Gstreamer
plugins are installed on the machine. In other words if the user wants to
use a specific GPU for this use-case, he needs to ensure that only the
plugins that work with that GPU are installed.
- more than one GPU from same vendor:
AFAIK, in this case the same Gstreamer plugins would work with both
GPUs. Therefore, the onus is on Gstreamer to associate the current
"context" with the right GPU. I don't think there is anything else that
can be done at the Spice level for this case.
> Maybe a
>
> bool spice_udev_has_intel_gpu(void);
I think doing it this way will prevent checking for this condition
in spice-gtk :
if (vendor == GPU_VENDOR_INTEL ||
vendor == GPU_VENDOR_UNKNOWN) {
>
> function instead?
>
> Note that in C something like void funcname() is K&R style, something
> you don't want, you need to specify the argument list and types (in
> this case "void").
>
> Recently we use "#pragma once" for new headers but it's your call.
>
> I would use something like
>
> /* SPDX-License-Identifier: BSD-3-Clause */
>
> #pragma once
>
> #include <stdbool.h>
> #include <spice/macros.h>
>
> SPICE_BEGIN_DECLS
>
> bool spice_udev_has_intel_gpu(void);
>
> SPICE_END_DECLS
Ok, I'll incorporate your suggestions in v2.
>
> > +#endif
> > 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
> > #
>
> Can you add autoconf support?
Sure, will add it in v2.
Thanks,
Vivek
>
> diff --git a/configure.ac b/configure.ac
> index 0d4c22b..4fc4263 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -65,6 +65,8 @@ SPICE_COMMON_LIBS='$(PIXMAN_LIBS) $(GLIB2_LIBS)
> $(OPUS_LIBS) $(OPENSSL_LIBS)'
> AC_SUBST(SPICE_COMMON_CFLAGS)
> AC_SUBST(SPICE_COMMON_LIBS)
>
> +PKG_CHECK_MODULES([UDEV], [libudev], AC_DEFINE([HAVE_UDEV], [1],
> [Define if we have libudev support]))
> +
> # The End!
> AC_CONFIG_FILES([
> Makefile
>
> Frediano
More information about the Spice-devel
mailing list