[PATCH i-g-t v11 4/6] lib/intel_multigpu: Add multi_fork_foreach_gpu_chip
Janusz Krzysztofik
janusz.krzysztofik at linux.intel.com
Wed Mar 6 19:03:11 UTC 2024
Hi Kamil,
On Wednesday, 6 March 2024 14:31:56 CET Kamil Konieczny wrote:
> Create macro for testing drm driver in multigpu scenarios with
> the help of few new multigpu functions. Also while at this,
> add documentation for public functions and use new helper in
> existing multi-gpu macro.
Is that correct? I can't see any existing macro modified.
>
> v2: corrected description (Kamil), rebased on corrected patches
> after Dominik review
> v3: corrected descriptions, renamed function to print_gpus
> and did small refactoring (Kamil)
> fixed typo in function name (Dominik)
> v4: fixed typos (Dominik)
> v10: rename new macro into multi_fork_foreach_gpu_chip (Zbigniew)
>
> Cc: "Zbigniew Kempczyński" <zbigniew.kempczynski at intel.com>
> Reviewed-by: "Dominik Karol Piątkowski" <dominik.karol.piatkowski at intel.com>
> Signed-off-by: Kamil Konieczny <kamil.konieczny at linux.intel.com>
> ---
> lib/intel_multigpu.c | 72 ++++++++++++++++++++++++++++++++++++++++++++
> lib/intel_multigpu.h | 10 ++++++
> 2 files changed, 82 insertions(+)
>
> diff --git a/lib/intel_multigpu.c b/lib/intel_multigpu.c
> index c4e7cf542..8b7d6f3fc 100644
> --- a/lib/intel_multigpu.c
> +++ b/lib/intel_multigpu.c
> @@ -4,6 +4,7 @@
> */
>
> #include "drmtest.h"
> +#include "i915/gem.h"
> #include "igt_core.h"
> #include "igt_device_scan.h"
> #include "intel_multigpu.h"
> @@ -60,3 +61,74 @@ void gem_require_multigpu(int gpus_wanted)
> print_gpus(gpus_wanted, gpu_filters);
> igt_skip_on(gpu_filters < gpus_wanted);
> }
> +
> +/**
> + * multigpu_acquire_view:
> + * @gpus_wanted: minimum number of GPUs required
That's what I think makes a non-iterating function multigpu specific -- an
argument for passing a minimum number of user required GPUs. But still not
Intel specific, I believe, then I'm not happy with the source file name.
> + * @chipset: chipset, e.g. DRIVER_XE or DRIVER_INTEL
> + *
> + * Function prepares filtered view for GPU cards with given chipset.
> + * On error skips and prints available GPUs found on PCI bus.
> + * Returns: number of GPUs found
> + */
> +int multigpu_acquire_view(int gpus_wanted, unsigned int chipset)
> +{
> + int gpu_count = drm_prepare_filtered_multigpu(chipset);
> +
> + igt_assert(gpus_wanted > 1);
Why? Can't we imagine a test that uses the same code for exercising any
number of GPUs, including 1 as a special case? I would call such test
"multigpu ready".
> + if (gpu_count >= gpus_wanted)
> + return gpu_count;
> +
> + print_gpus(gpus_wanted, gpu_count);
> + igt_skip_on(gpu_count < gpus_wanted);
> +
> + return gpu_count; /* non-reachable */
> +}
> +
> +/**
> + * multigpu_open_another:
> + * @idx: index of GPU card, starting from 0
> + * @chipset: chipset, e.g. DRIVER_XE or DRIVER_INTEL
> + *
> + * Function opens GPU card with drm_open_driver_another(). For i915 it
checks
> + * if opened card is functional. Skips on errors.
> + *
> + * Returns: opened fd for @idx card
> + */
> +int multigpu_open_another(int idx, unsigned int chipset)
> +{
> + int fd;
> +
> + igt_assert(idx >= 0);
I think the above check belongs to drm_open_driver_another().
> + fd = drm_open_driver_another(idx, chipset);
> +
> + if (chipset == DRIVER_INTEL)
> + igt_require_gem(fd);
> +
> + return fd;
This function doesn't look like multigpu specific, nor even Intel specific, as
other vendors may easily add their own chipset specific requirements. Do we
really want to give it a name multigpu_* and place it in an intel_* library?
Besides, we may not need it (see below).
> +}
> +
> +/**
> + * multigpu_open_filtered_card:
> + * @idx: index of GPU card, starting from 0
> + * @chipset: chipset, e.g. DRIVER_XE or DRIVER_INTEL
> + *
> + * Function opens GPU card prepared with filtered view. It also checks if
> + * opened card agrees with desired chipset or checks if opened card is
> + * functional. Skips on errors.
> + *
> + * Returns: opened fd for @idx card
> + */
> +int multigpu_open_filtered_card(int idx, unsigned int chipset)
> +{
> + int fd;
> +
> + igt_assert(idx >= 0);
> + fd = drm_open_filtered_card(idx);
> + if (chipset == DRIVER_XE)
> + igt_require_xe(fd);
> + else if (chipset == DRIVER_INTEL)
> + igt_require_gem(fd);
The same here (we may not need it if we call drm_open_filtered_card() after
multigpu_acquire_view() (or drm_prepare_filtered_multigpu()) -- see below).
> +
> + return fd;
> +}
> diff --git a/lib/intel_multigpu.h b/lib/intel_multigpu.h
> index 5acfcd5f6..a99e7a85e 100644
> --- a/lib/intel_multigpu.h
> +++ b/lib/intel_multigpu.h
> @@ -12,6 +12,10 @@
> void gem_require_multigpu(int count);
> int gem_multigpu_count_class(int chipset);
>
> +int multigpu_acquire_view(int min_gpus_wanted, unsigned int chipset);
> +int multigpu_open_another(int idx, unsigned int chipset);
> +int multigpu_open_filtered_card(int idx, unsigned int chipset);
> +
> #define igt_foreach_gpu(fd__, chipset__) \
> for (int igt_unique(i) = 0, fd__; \
> (fd__ = __drm_open_driver_another(igt_unique(i)++,
chipset__)) >= 0; \
> @@ -23,4 +27,10 @@ int gem_multigpu_count_class(int chipset);
> __fd >= 0; \
> drm_close_driver(__fd), __fd = -1) \
>
> +#define multi_fork_foreach_gpu_chip(__fd, __gpu_index, __chipset) \
> + igt_multi_fork(__gpu_index, multigpu_acquire_view(2, __chipset)) \
Instead of hardcoding the minimum number of 2 GPUs, maybe let this macro
accept a gpus_wanted parameter, and wrap another macro around it that passes 2
as gpus_wanted.
> + for (int __fd = multigpu_open_filtered_card(__gpu_index,
__chipset); \
Again, your multigpu_open_filtered_card() may skip, while igt_multi_fork()
documentation says it expects no skips.
We could avoid skips inside the body of igt_multi_fork() if we moved required
checks to a variant of multigpu_acquire_view() that sets up filters for GPUs
that not only match the selected chipset but also satisfy those checks. Since
devices are now iterated inside drm_prepare_filtered_multigpu(), we could
implement a new variant of this function that either performs some predefined
chipset based checks, like you proposed for multigpu_open_another() and
multigpu_open_filtered_card(), or accepts an argument that points to an
arbitrary user provided function, either boolean that returns OK/not OK for a
GPU file descriptor, or void that skips if not OK. That way, potential skips
would occur outside of igt_multi_fork() body, and you could drop those
multigpu_open_*() helpers which seem of limited use -- test functions
themselves should detect potential device issues.
> + __fd >= 0; \
> + drm_close_driver(__fd), __fd = -1) \
Another trailing backslash, not necessarily intended.
Thanks,
Janusz
> +
> #endif /* __INTEL_MULTIGPU_H */
>
More information about the igt-dev
mailing list