Re: [7/8] tests/intel/xe_err_injection: Add tests for L2 bank Corr err threshold scenarios
"Purkait, Soham" <[email protected]>
| Newsgroups | org.freedesktop.lists.igt-dev |
|---|---|
| Message-ID | <[email protected]> |
Hi Ravi, On 29-07-2026 17:49, Ravi Kishore Koppuravuri wrote: > Introduced L2 bank correctable error threshold subtests: > - single correctable error > - Correctable error with threshold set to 1 > - 16 Correctable error injections with threshold set to 0xF > > Add DRM RAS netlink error-notify event subscription to verify > correctable error detection across all the above subtests. > > Signed-off-by: Ravi Kishore Koppuravuri<[email protected]> > --- > tests/intel/xe_err_injection.c | 252 +++++++++++++++++++++++++++++++++ > tests/intel/xe_err_injection.h | 10 ++ > 2 files changed, 262 insertions(+) > > diff --git a/tests/intel/xe_err_injection.c b/tests/intel/xe_err_injection.c > index afbaf0646..0303f4a56 100644 > --- a/tests/intel/xe_err_injection.c > +++ b/tests/intel/xe_err_injection.c > @@ -35,6 +35,14 @@ enum { > RECOVERY_TIMEOUT = 3, > }; > > +time_t event_timeout = 10 * 1000; /* 10 seconds */ > + > +/* Cleanup helper for injection test functions */ > +#define CLEANUP_ON_ERROR(ctx, fw_handle) do { \ > + cleanup_nl_socket(&ctx); \ > + release_forcewake(fw_handle); \ > +} while (0) > + > static void run_xe_compute_on_all_engines(int fd, bool state) > { > struct drm_xe_engine_class_instance *hwe; > @@ -268,6 +276,238 @@ static void wkr_cmd_parity_err_injection(struct xe_mmio *mmio, int fd) > gt_uc_wkr_parity_recovered = true; > } > > +/* Inject a GT correctable error */ > +static void l2_bank_corr_err_injection(struct xe_mmio *mmio, int fd) > +{ > + /* Arm the Injection */ > + write_reg(mmio, L2_BANK_ERR_INJ, L2_BANK_DATA_1BIT_ERR_INJ_CONFIG); > + igt_info("Armed L2 Bank Correctable Error Injection\n"); > +} > + > +/** > + * SUBTEST: l2-bank-corr-err-threshold-1 > + * Description: Inject single bit error injection in SSA data array when this bit is written > + * (this bit is a self clearing bit, event will be generated once written) - Correctable Error > + * Functionality: error injection > + */ > +static void l2_bank_corr_err_injection_with_threshold_1(struct xe_mmio *mmio, int fd) > +{ > + int fw_handle; > + int ret; > + uint32_t current_threshold = UINT32_MAX; > + struct app_context ctx; > + > + fw_handle = acquire_forcewake(fd); > + > + ret = init_nl_socket(&ctx); > + if (ret < 0) { > + release_forcewake(fw_handle); > + igt_assert_f(false, "Failed to initialize netlink socket (ret=%d)\n", ret); > + } > + > + /* Subscribe to error-notify */ > + ret = subscribe_error_notify(&ctx, DRM_RAS_MCGRP_ERROR_NOTIFY); > + if (ret < 0) { > + CLEANUP_ON_ERROR(ctx, fw_handle); > + igt_assert_f(false, "Failed to subscribe to error-notify (ret=%d)\n", ret); > + } > + > + /* get current GT Correctable error threshold */ > + ctx.node_id = 0; > + ctx.error_id = 1; > + ret = get_error_threshold(&ctx); > + if (ret < 0) { > + CLEANUP_ON_ERROR(ctx, fw_handle); > + igt_assert_f(false, "Failed to query GT correctable error threshold before injection\n"); > + } > + current_threshold = ctx.error_threshold; > + igt_info("Current GT Correctable error threshold: %u\n", current_threshold); > + > + /* Set GT Correctable error threshold to 1 */ > + ctx.error_threshold = 1; > + ret = set_error_threshold(&ctx); > + if (ret < 0) { > + CLEANUP_ON_ERROR(ctx, fw_handle); > + igt_assert_f(false, "Failed to set GT correctable error threshold before injection\n"); > + } > + > + /* Inject a GT correctable error */ > + l2_bank_corr_err_injection(mmio, fd); > + > + ret = wait_for_error_notify_event(&ctx, event_timeout); /* wait for 10 secs */ > + if (ret == 0 && ctx.event_error_value == 1) { > + log_status(true, "L2 Bank Correctable Error with threshold 1"); > + } else { > + log_status(false, "L2 Bank Correctable Error with threshold 1"); > + /* restore threshold before failing */ > + ctx.error_threshold = current_threshold; > + set_error_threshold(&ctx); > + CLEANUP_ON_ERROR(ctx, fw_handle); > + igt_assert_f(false, "Did not receive expected RAS event or error_value after injection\n"); > + } > + > + /* restore GT Correctable error threshold to original value */ > + ctx.error_threshold = current_threshold; > + ret = set_error_threshold(&ctx); > + if (ret < 0) { > + CLEANUP_ON_ERROR(ctx, fw_handle); > + igt_assert_f(false, "Failed to restore GT correctable error threshold after injection\n"); > + } > + > + CLEANUP_ON_ERROR(ctx, fw_handle); > +} > + > +/** > + * SUBTEST: l2-bank-corr-err-16-times > + * Description: Inject single bit error injection in SSA data array when this bit is written > + * (this bit is a self clearing bit, event will be generated once written) - Correctable Error > + * Functionality: error injection > + */ > +static void l2_bank_corr_err_injection_16_times(struct xe_mmio *mmio, int fd) > +{ > + int fw_handle; > + uint32_t current_threshold = UINT32_MAX; > + uint32_t gt_corr_counter_before = 0, gt_corr_counter_current = 0; > + int ret; > + struct app_context ctx; > + > + fw_handle = acquire_forcewake(fd); > + > + ret = init_nl_socket(&ctx); > + if (ret < 0) { > + release_forcewake(fw_handle); > + igt_assert_f(false, "Failed to initialize netlink socket (ret=%d)\n", ret); > + } > + > + ret = subscribe_error_notify(&ctx, DRM_RAS_MCGRP_ERROR_NOTIFY); > + if (ret < 0) { > + CLEANUP_ON_ERROR(ctx, fw_handle); > + igt_assert_f(false, "Failed to subscribe to error-notify (ret=%d)\n", ret); > + } > + > + /* Query error counter before injection */ > + ctx.node_id = 0; > + ctx.error_id = 1; > + ret = get_error_counter(&ctx); > + if (ret < 0) { > + CLEANUP_ON_ERROR(ctx, fw_handle); > + igt_assert_f(false, > + "Failed to query GT correctable error counter before injection\n"); > + } > + gt_corr_counter_before = ctx.error_value; > + > + /* get current GT Correctable error threshold */ > + ret = get_error_threshold(&ctx); > + if (ret < 0) { > + CLEANUP_ON_ERROR(ctx, fw_handle); > + igt_assert_f(false, > + "Failed to query GT correctable error threshold before injection\n"); > + } > + current_threshold = ctx.error_threshold; > + igt_info("Current GT Correctable error threshold: %u\n", current_threshold); > + > + for (int i = 0; i < 16; i++) { > + igt_info("****** Injection iteration: %d ***********\n", i + 1); > + /* Inject a GT correctable error */ > + l2_bank_corr_err_injection(mmio, fd); > + > + /* Query error counter after injection */ > + ret = get_error_counter(&ctx); > + if (ret < 0) { > + CLEANUP_ON_ERROR(ctx, fw_handle); > + igt_assert_f(false, > + "Failed to query GT correctable error counter:iteration %d\n", > + i + 1); > + } > + gt_corr_counter_current = ctx.error_value; > + igt_info("GT Correctable error counter incremented by : %u " > + "since before initial injection\n", > + gt_corr_counter_current - gt_corr_counter_before); > + } > + > + /* Confirm whether error counter incremented by 16 after 16 injections */ > + if ((gt_corr_counter_current - gt_corr_counter_before) == 16) { > + log_status(true, "L2 Bank Correctable Error Injection 16 times"); > + } else { > + log_status(false, "L2 Bank Correctable Error Injection 16 times"); > + CLEANUP_ON_ERROR(ctx, fw_handle); > + igt_assert_f(false, > + "GT Correctable error counter didn't increment " > + "by 16 after 16 injections\n"); > + } > + > + ret = wait_for_error_notify_event(&ctx, event_timeout); > + if (ret == 0 && ctx.event_error_value == 1) { > + log_status(true, "L2 Bank Correctable Error Injection 16 times"); > + } else { > + log_status(false, "L2 Bank Correctable Error Injection 16 times"); > + CLEANUP_ON_ERROR(ctx, fw_handle); > + igt_assert_f(false, "Did not receive expected MSI event or " > + "error_value after injection\n"); > + } > + > + CLEANUP_ON_ERROR(ctx, fw_handle); > +} > + > +/** > + * SUBTEST: l2-bank-single-corr-err > + * Description: Inject single bit error injection in SSA data array when this bit is written > + * (this bit is a self clearing bit, event will be generated once written) - Correctable Error > + * Functionality: error injection > + */ > +static void l2_bank_single_corr_err_injection(struct xe_mmio *mmio, int fd) > +{ > + int fw_handle; > + int ret; > + uint32_t gt_corr_counter_before = 0, gt_corr_counter_after = 0; > + struct app_context ctx; > + > + fw_handle = acquire_forcewake(fd); > + > + ret = init_nl_socket(&ctx); > + if (ret < 0) { > + release_forcewake(fw_handle); > + igt_assert_f(false, "Failed to initialize netlink socket (ret=%d)\n", ret); > + } > + > + /* Query error counter before injection */ > + ctx.node_id = 0; > + ctx.error_id = 1; > + ret = get_error_counter(&ctx); > + if (ret < 0) { > + CLEANUP_ON_ERROR(ctx, fw_handle); > + igt_assert_f(false, > + "Failed to query GT correctable error counter before injection\n"); > + } > + gt_corr_counter_before = ctx.error_value; > + igt_info("GT Correctable error counter before injection: %u\n", gt_corr_counter_before); > + > + /* Inject a GT correctable error */ > + l2_bank_corr_err_injection(mmio, fd); > + > + /* Query error counter after injection */ > + ret = get_error_counter(&ctx); > + if (ret < 0) { > + CLEANUP_ON_ERROR(ctx, fw_handle); > + igt_assert_f(false, > + "Failed to query GT correctable error counter after injection\n"); > + } > + gt_corr_counter_after = ctx.error_value; > + igt_info("GT Correctable error counter after injection: %u\n", gt_corr_counter_after); > + > + if (gt_corr_counter_after > gt_corr_counter_before) { > + igt_info("GT Correctable error counter incremented by %u after injection\n", > + gt_corr_counter_after - gt_corr_counter_before); > + log_status(true, "L2 Bank Correctable Error"); > + } else { > + CLEANUP_ON_ERROR(ctx, fw_handle); > + igt_assert_f(false, > + "L2 Bank (GT) Correctable Error Injection count not incremented\n"); > + } > + > + CLEANUP_ON_ERROR(ctx, fw_handle); > +} > + > static void inject_error(const char *injection, struct xe_mmio *mmio, int fd) > { > igt_info("Starting Error Injection test: %s\n", injection); > @@ -306,6 +546,18 @@ int igt_main() > run_xe_compute_on_all_engines(fd, POST_RECOVERY_WL); > } > > + igt_describe("Inject GT correctable error and validate error-notify event with threshold set to 1."); > + igt_subtest("l2-bank-corr-err-threshold-1") > + l2_bank_corr_err_injection_with_threshold_1(&mmio, fd); Could this be also added as part of inject_error() ? > + > + igt_describe("Inject GT correctable error 16 times and validate counter/event behavior."); > + igt_subtest("l2-bank-corr-err-16-times") > + l2_bank_corr_err_injection_16_times(&mmio, fd); Same as above. > + > + igt_describe("Inject a single GT correctable error and validate counter increment."); > + igt_subtest("l2-bank-single-corr-err") > + l2_bank_single_corr_err_injection(&mmio, fd); Same as above. Thanks, Soham > + > igt_fixture() { > xe_mmio_access_fini(&mmio); > drm_close_driver(fd); > diff --git a/tests/intel/xe_err_injection.h b/tests/intel/xe_err_injection.h > index d7efc2fd2..1a9ea2f2e 100644 > --- a/tests/intel/xe_err_injection.h > +++ b/tests/intel/xe_err_injection.h > @@ -15,4 +15,14 @@ > #define POST_RECOVERY_WL 1 > #define POST_ARMING_INJECTION_WL 0 > > +/* L2 Bank (LBCFLOCKMSGREG) error injection */ > +#define L2_BANK_ERR_INJ 0xB1B4 > +#define DATA_1BIT_ERR_INJ_REQ (1 << 3) > +#define FUSA_TEST_MODE_ERR_INJ_REQ (1 << 2) > +#define MASK_BIT_FOR_DATA_1BIT_ERR_INJ_REQ (1 << 19) > +#define MASK_BIT_FOR_FUSA_TEST_MODE_ERR_INJ_REQ (1 << 18) > +#define L2_BANK_DATA_1BIT_ERR_INJ_CONFIG \ > + (DATA_1BIT_ERR_INJ_REQ | FUSA_TEST_MODE_ERR_INJ_REQ | \ > + MASK_BIT_FOR_DATA_1BIT_ERR_INJ_REQ | MASK_BIT_FOR_FUSA_TEST_MODE_ERR_INJ_REQ) > + > #endif /* XE_ERR_INJECTION_H */