On platforms (like PVC) that do not support walker mid-thread preemption, running tests in forked threads can lead to inconsistent states due to igt_skip being called mid-execution. Made changes to perform kernel preemption check at the beginning of each subtests. If the GPU version does not support the required features, the test is skipped gracefully, ensuring consistent behavior across different platforms. v2: Fixed review comments to move the compatibility check into the igt_fixture. [Priyanka] v3: Added check for thread group preemption and WMTP. Added enum flags for preemption type as per review . [Zbigniew] v4: Added check for preempt inside __run_intel_compute_kernel_preempt Refactored the code. [priyanka] v5: Refactor for finding the kernel and out of bound check. [Zbigniew] v6: Added NULL Check for kernel. [Zbigniew] v7: Moved TODO inside the code. [kamil] Modified the check condition for kernel [Priyanka] v8: Additional check for the kernel variants v9: Refactored in to logically related patches Signed-off-by: Sobin Thomas --- lib/intel_compute.c | 78 ++++++++++++++++++++++++++++---- lib/intel_compute.h | 11 +++++ tests/intel/xe_compute_preempt.c | 6 +++ 3 files changed, 86 insertions(+), 9 deletions(-) diff --git a/lib/intel_compute.c b/lib/intel_compute.c index 147dd2916..ae656a4f6 100644 --- a/lib/intel_compute.c +++ b/lib/intel_compute.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: MIT */ /* * Copyright © 2023 Intel Corporation - * + * TODO: Add kernel for PVC for preemption test * Authors: * Francois Dugast */ @@ -2193,40 +2193,72 @@ static const struct { bool threadgroup_preemption, enum execenv_alloc_prefs alloc_prefs); uint32_t compat; + enum xe_compute_preempt_type preempt_type; } intel_compute_preempt_batches[] = { { .ip_ver = IP_VER(20, 01), .compute_exec = xe2lpg_compute_preempt_exec, .compat = COMPAT_DRIVER_XE, + .preempt_type = PREEMPT_TGP | PREEMPT_WMTP, }, { .ip_ver = IP_VER(20, 04), .compute_exec = xe2lpg_compute_preempt_exec, .compat = COMPAT_DRIVER_XE, + .preempt_type = PREEMPT_TGP | PREEMPT_WMTP, }, { .ip_ver = IP_VER(30, 00), .compute_exec = xe2lpg_compute_preempt_exec, .compat = COMPAT_DRIVER_XE, + .preempt_type = PREEMPT_TGP | PREEMPT_WMTP, }, }; +static int find_preempt_batch(unsigned int ip_ver) +{ + for (int batch_idx = 0; batch_idx < ARRAY_SIZE(intel_compute_preempt_batches); batch_idx++) + if (ip_ver == intel_compute_preempt_batches[batch_idx].ip_ver) + return batch_idx; + return -1; +} + +static bool is_preemptable(int batch, enum xe_compute_preempt_type required_preempt) +{ + if (required_preempt && + !(intel_compute_preempt_batches[batch].preempt_type & required_preempt)) { + igt_info("Preemption not supported\n"); + return false; + } + return true; +} + +static const char *xe_preempt_type_to_str(enum xe_compute_preempt_type type) +{ + switch (type) { + case PREEMPT_TGP: + return "PREEMPT_TGP"; + case PREEMPT_WMTP: + return "PREEMPT_WMTP"; + default: + return "UNKNOWN_PREEMPT_TYPE"; + } +} + static bool __run_intel_compute_kernel_preempt(int fd, struct drm_xe_engine_class_instance *eci, bool threadgroup_preemption, enum execenv_alloc_prefs alloc_prefs) { unsigned int ip_ver = intel_graphics_ver(intel_get_drm_devid(fd)); - unsigned int batch; - const struct intel_compute_kernels *kernels = intel_compute_square_kernels; + int batch; + const struct intel_compute_kernels *kernel_entries = intel_compute_square_kernels, *kernels; enum intel_driver driver = get_intel_driver(fd); + enum xe_compute_preempt_type required_preempt = + threadgroup_preemption ? PREEMPT_TGP : PREEMPT_WMTP; - for (batch = 0; batch < ARRAY_SIZE(intel_compute_preempt_batches); batch++) - if (ip_ver == intel_compute_preempt_batches[batch].ip_ver) - break; - - - if (batch == ARRAY_SIZE(intel_compute_preempt_batches)) { + batch = find_preempt_batch(ip_ver); + if (batch < 0) { igt_debug("GPU version 0x%x not supported\n", ip_ver); return false; } @@ -2244,6 +2276,9 @@ static bool __run_intel_compute_kernel_preempt(int fd, kernels++; } + if (!is_preemptable(batch, required_preempt)) + return false; + if (!kernels->kernel || !kernels->sip_kernel || !kernels->long_kernel) return 0; @@ -2260,6 +2295,31 @@ static bool __run_intel_compute_kernel_preempt(int fd, return true; } + +/** + * xe_kernel_preempt_check - Checks IP version to confirm if provided + * preempt type is supported. + * @fd: file descriptor of the opened DRM Xe device + * @required_preempt: Preemption type (WMTP/TGP) + * + * Returns true on success, false otherwise. + */ +bool xe_kernel_preempt_check(int fd, enum xe_compute_preempt_type required_preempt) +{ + unsigned int ip_ver = intel_graphics_ver(intel_get_drm_devid(fd)); + int batch = find_preempt_batch(ip_ver); + + if (batch < 0) { + igt_debug("Preemption type %s not supported on GPU version 0x%x\n", + xe_preempt_type_to_str(required_preempt), ip_ver); + return false; + } + if (!is_preemptable(batch, required_preempt)) + return false; + + return true; +} + /** * run_intel_compute_kernel_preempt - runs compute kernels to * exercise preemption scenario. diff --git a/lib/intel_compute.h b/lib/intel_compute.h index 412791d07..6e18d93e9 100644 --- a/lib/intel_compute.h +++ b/lib/intel_compute.h @@ -71,6 +71,16 @@ enum execenv_alloc_prefs { EXECENV_PREF_VRAM_IF_POSSIBLE, }; +/** + * enum xe_compute_preempt_type - Types of compute preemption supported. + * PREEMPT_TGP: ThreadGroup Preemption + * PREEMPT_WMTP: Walker Mid Thread Preemption + */ +enum xe_compute_preempt_type { + PREEMPT_TGP = 1 << 0, + PREEMPT_WMTP = 1 << 1, +}; + extern const struct intel_compute_kernels intel_compute_square_kernels[]; bool run_intel_compute_kernel(int fd, struct user_execenv *user, @@ -81,4 +91,5 @@ bool xe_run_intel_compute_kernel_on_engine(int fd, struct drm_xe_engine_class_in bool run_intel_compute_kernel_preempt(int fd, struct drm_xe_engine_class_instance *eci, bool threadgroup_preemption, enum execenv_alloc_prefs alloc_prefs); +bool xe_kernel_preempt_check(int fd, enum xe_compute_preempt_type required_preempt); #endif /* INTEL_COMPUTE_H */ diff --git a/tests/intel/xe_compute_preempt.c b/tests/intel/xe_compute_preempt.c index c9b194869..076360f1d 100644 --- a/tests/intel/xe_compute_preempt.c +++ b/tests/intel/xe_compute_preempt.c @@ -76,6 +76,7 @@ igt_main } igt_subtest_with_dynamic("compute-preempt") { + igt_require(xe_kernel_preempt_check(xe, PREEMPT_WMTP)); xe_for_each_engine(xe, hwe) { if (hwe->engine_class != DRM_XE_ENGINE_CLASS_COMPUTE) continue; @@ -86,6 +87,7 @@ igt_main } igt_subtest_with_dynamic("compute-preempt-many") { + igt_require(xe_kernel_preempt_check(xe, PREEMPT_WMTP)); xe_for_each_engine(xe, hwe) { if (hwe->engine_class != DRM_XE_ENGINE_CLASS_COMPUTE) continue; @@ -112,6 +114,7 @@ igt_main igt_subtest_with_dynamic("compute-preempt-many-all-ram") { igt_require(swap_mb > CONTEXT_MB * 10); + igt_require(xe_kernel_preempt_check(xe, PREEMPT_WMTP)); xe_for_each_engine(xe, hwe) { if (hwe->engine_class != DRM_XE_ENGINE_CLASS_COMPUTE) continue; @@ -138,6 +141,7 @@ igt_main igt_subtest_with_dynamic("compute-preempt-many-vram") { igt_require(xe_has_vram(xe)); + igt_require(xe_kernel_preempt_check(xe, PREEMPT_WMTP)); xe_for_each_engine(xe, hwe) { if (hwe->engine_class != DRM_XE_ENGINE_CLASS_COMPUTE) continue; @@ -164,6 +168,7 @@ igt_main igt_subtest_with_dynamic("compute-preempt-many-vram-evict") { igt_require(xe_has_vram(xe)); + igt_require(xe_kernel_preempt_check(xe, PREEMPT_WMTP)); xe_for_each_engine(xe, hwe) { if (hwe->engine_class != DRM_XE_ENGINE_CLASS_COMPUTE) continue; @@ -188,6 +193,7 @@ igt_main } igt_subtest_with_dynamic("compute-threadgroup-preempt") { + igt_require(xe_kernel_preempt_check(xe, PREEMPT_TGP)); xe_for_each_engine(xe, hwe) { if (hwe->engine_class != DRM_XE_ENGINE_CLASS_COMPUTE) continue; -- 2.51.0