From 5a17ccb83f838a541cfb6d08f2a0432b3c5ef015 Mon Sep 17 00:00:00 2001 From: vinodg Date: Thu, 5 Dec 2019 16:40:25 -0800 Subject: [PATCH] gpu: nvgpu: unit: test coverage for gr.ecc unit Add more test for line/branch coverages in gr.ecc common and fusa code. Max gpc_count is one for gv11b, add a checking under CONFIG_NVGPU_NON_FUSA to avoid unwanted error handling. Jira NVGPU-4460 Change-Id: Ifac53394ebe58698b81e1e108731ccc36d624ff3 Signed-off-by: vinodg Reviewed-on: https://git-master.nvidia.com/r/2256451 Reviewed-by: svc-mobile-coverity Reviewed-by: svc-mobile-misra Reviewed-by: svc-mobile-cert GVS: Gerrit_Virtual_Submit Reviewed-by: Deepak Nibade Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/gr/gr_ecc.c | 3 +- userspace/units/gr/init/nvgpu-gr-init.c | 130 ++++++++++++++++++++---- userspace/units/gr/nvgpu-gr.h | 43 +++++--- 3 files changed, 146 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/nvgpu/common/gr/gr_ecc.c b/drivers/gpu/nvgpu/common/gr/gr_ecc.c index 3d9356721..bdad8a6c2 100644 --- a/drivers/gpu/nvgpu/common/gr/gr_ecc.c +++ b/drivers/gpu/nvgpu/common/gr/gr_ecc.c @@ -91,10 +91,11 @@ int nvgpu_ecc_counter_init_per_tpc(struct gk20a *g, fail: if (err != 0) { +#ifdef CONFIG_NVGPU_NON_FUSA while (gpc-- != 0u) { nvgpu_kfree(g, stats[gpc]); } - +#endif nvgpu_kfree(g, stats); } diff --git a/userspace/units/gr/init/nvgpu-gr-init.c b/userspace/units/gr/init/nvgpu-gr-init.c index c2e2f06b8..86905735c 100644 --- a/userspace/units/gr/init/nvgpu-gr-init.c +++ b/userspace/units/gr/init/nvgpu-gr-init.c @@ -27,8 +27,12 @@ #include #include +#include +#include + #include #include +#include #include #include @@ -40,32 +44,124 @@ #define GR_TEST_FUSES_OVERRIDE_DISABLE_TRUE 0x1U #define GR_TEST_FUSES_OVERRIDE_DISABLE_FALSE 0x0U -#define GR_TEST_FECS_FEATURE_OVERRIDE_ECC 0x00909999 -#define GR_TEST_FECS_FEATURE_OVERRIDE_ECC1 0x0000000F +#define GR_TEST_FECS_FEATURE_OVERRIDE_ECC 0x00909999 +#define GR_TEST_FECS_FEATURE_OVERRIDE_ECC_ONLY 0x00808888 +#define GR_TEST_FECS_FEATURE_OVERRIDE_ECC1 0x0000000F +#define GR_TEST_FECS_FEATURE_OVERRIDE_ECC1_ONLY 0x0000000A +#define GR_TEST_FECS_FEATURE_OVERRIDE_ECC1_FAIL1 0x00000002 +#define GR_TEST_FECS_FEATURE_OVERRIDE_ECC1_FAIL2 0x0000000B + +static int gr_init_ecc_fail_alloc(struct gk20a *g) +{ + int err, i, loop = 28; + struct nvgpu_posix_fault_inj *kmem_fi = + nvgpu_kmem_get_fault_injection(); + struct nvgpu_gr_config *save_gr_config = g->gr->config; + + for (i = 0; i < loop; i++) { + nvgpu_posix_enable_fault_injection(kmem_fi, true, i); + err = g->ops.gr.ecc.init(g); + if (err == 0) { + return UNIT_FAIL; + } + nvgpu_posix_enable_fault_injection(kmem_fi, false, 0); + g->ops.ecc.ecc_init_support(g); + } + + /* Set gr->config to NULL for branch covergae */ + g->gr->config = NULL; + g->ecc.initialized = true; + g->ops.ecc.ecc_remove_support(g); + g->ecc.initialized = false; + g->gr->config = save_gr_config; + + return UNIT_SUCCESS; +} + +struct gr_init_ecc_stats { + u32 fuse_override; + u32 opt_enable; + u32 fecs_override0; + u32 fecs_override1; +}; int test_gr_init_ecc_features(struct unit_module *m, struct gk20a *g, void *args) { - nvgpu_posix_io_writel_reg_space(g, - fuse_opt_feature_fuses_override_disable_r(), - GR_TEST_FUSES_OVERRIDE_DISABLE_TRUE); +struct gr_init_ecc_stats ecc_stats[] = { + [0] = { + .fuse_override = GR_TEST_FUSES_OVERRIDE_DISABLE_TRUE, + .opt_enable = 0x1, + .fecs_override0 = 0x0, + .fecs_override1 = 0x0, + }, + [1] = { + .fuse_override = GR_TEST_FUSES_OVERRIDE_DISABLE_TRUE, + .opt_enable = 0x0, + .fecs_override0 = 0x0, + .fecs_override1 = 0x0, + }, + [2] = { + .fuse_override = GR_TEST_FUSES_OVERRIDE_DISABLE_FALSE, + .opt_enable = 0x0, + .fecs_override0 = 0x0, + .fecs_override1 = 0x0, + }, + [3] = { + .fuse_override = GR_TEST_FUSES_OVERRIDE_DISABLE_FALSE, + .opt_enable = 0x1, + .fecs_override0 = 0, + .fecs_override1 = GR_TEST_FECS_FEATURE_OVERRIDE_ECC1_FAIL1, + }, + [4] = { + .fuse_override = GR_TEST_FUSES_OVERRIDE_DISABLE_FALSE, + .opt_enable = 0x1, + .fecs_override0 = 0, + .fecs_override1 = GR_TEST_FECS_FEATURE_OVERRIDE_ECC1_FAIL2, + }, + [5] = { + .fuse_override = GR_TEST_FUSES_OVERRIDE_DISABLE_FALSE, + .opt_enable = 0x1, + .fecs_override0 = GR_TEST_FECS_FEATURE_OVERRIDE_ECC_ONLY, + .fecs_override1 = GR_TEST_FECS_FEATURE_OVERRIDE_ECC1_ONLY, + }, + [6] = { + .fuse_override = GR_TEST_FUSES_OVERRIDE_DISABLE_FALSE, + .opt_enable = 0x1, + .fecs_override0 = GR_TEST_FECS_FEATURE_OVERRIDE_ECC, + .fecs_override1 = GR_TEST_FECS_FEATURE_OVERRIDE_ECC1, + }, +}; + int err, i; + int arry_cnt = sizeof(ecc_stats)/ + sizeof(struct gr_init_ecc_stats); - g->ops.gr.ecc.detect(g); + for (i = 0; i < arry_cnt; i++) { + nvgpu_posix_io_writel_reg_space(g, + fuse_opt_feature_fuses_override_disable_r(), + ecc_stats[i].fuse_override); - nvgpu_posix_io_writel_reg_space(g, - fuse_opt_feature_fuses_override_disable_r(), - GR_TEST_FUSES_OVERRIDE_DISABLE_FALSE); + nvgpu_posix_io_writel_reg_space(g, + fuse_opt_ecc_en_r(), + ecc_stats[i].opt_enable); - /* set fecs ecc override */ - nvgpu_posix_io_writel_reg_space(g, - gr_fecs_feature_override_ecc_r(), - GR_TEST_FECS_FEATURE_OVERRIDE_ECC); + /* set fecs ecc override */ + nvgpu_posix_io_writel_reg_space(g, + gr_fecs_feature_override_ecc_r(), + ecc_stats[i].fecs_override0); - nvgpu_posix_io_writel_reg_space(g, - gr_fecs_feature_override_ecc_1_r(), - GR_TEST_FECS_FEATURE_OVERRIDE_ECC1); + nvgpu_posix_io_writel_reg_space(g, + gr_fecs_feature_override_ecc_1_r(), + ecc_stats[i].fecs_override1); - g->ops.gr.ecc.detect(g); + g->ops.gr.ecc.detect(g); + + } + + err = gr_init_ecc_fail_alloc(g); + if (err != 0) { + unit_return_fail(m, "stall isr failed\n"); + } return UNIT_SUCCESS; } diff --git a/userspace/units/gr/nvgpu-gr.h b/userspace/units/gr/nvgpu-gr.h index 697ce5f65..e0bb5c409 100644 --- a/userspace/units/gr/nvgpu-gr.h +++ b/userspace/units/gr/nvgpu-gr.h @@ -40,7 +40,9 @@ struct unit_module; * * Test Type: Feature based. * - * Input: None + * Input: None. + * + * Targets: #nvgpu_gr_alloc. * * Steps: * - Initialize the test environment for common.gr unit testing: @@ -62,6 +64,8 @@ int test_gr_init_setup(struct unit_module *m, struct gk20a *g, void *args); * * Test Type: Feature based. * + * Targets: #nvgpu_gr_free. + * * Input: test_gr_init_setup must have been executed successfully. * * Steps: @@ -79,6 +83,8 @@ int test_gr_remove_setup(struct unit_module *m, struct gk20a *g, void *args); * * Test Type: Feature based. * + * Targets: #nvgpu_gr_prepare_sw, #nvgpu_gr_prepare_hw. + * * Input: test_gr_init_setup must have been executed successfully. * * Steps: @@ -96,6 +102,8 @@ int test_gr_init_prepare(struct unit_module *m, struct gk20a *g, void *args); * * Test Type: Feature based. * + * Targets: #nvgpu_gr_init_support. + * * Input: test_gr_init_setup and test_gr_init_prepare * must have been executed successfully. * @@ -120,7 +128,9 @@ int test_gr_init_support(struct unit_module *m, struct gk20a *g, void *args); * * Test Type: Feature based. * - * Input: test_gr_init_setup, test_gr_init_prepare and test_gr_init_support + * Targets: #nvgpu_gr_suspend. + * + * Input: #test_gr_init_setup, #test_gr_init_prepare and #test_gr_init_support * must have been executed successfully. * * Steps: @@ -137,11 +147,13 @@ int test_gr_suspend(struct unit_module *m, struct gk20a *g, void *args); * * Test Type: Feature based. * - * Input: test_gr_init_setup, test_gr_init_prepare and test_gr_init_support + * Targets: #nvgpu_gr_remove_support. + * + * Input: #test_gr_init_setup, #test_gr_init_prepare and #test_gr_init_support * must have been executed successfully. * * Steps: - * - Call g->ops.gr.ecc.ecc_remove_support. + * - Call g->ops.ecc.ecc_remove_support. * - Call nvgpu_gr_remove_support. * * Output: Returns PASS. @@ -153,18 +165,20 @@ int test_gr_remove_support(struct unit_module *m, struct gk20a *g, void *args); * * Description: Set the ECC feature based on fuse and fecs override registers. * - * Test Type: Feature based. + * Test Type: Feature based, Error Injection. * - * Input: test_gr_init_setup, test_gr_init_prepare and test_gr_init_support + * Input: #test_gr_init_setup, #test_gr_init_prepare and #test_gr_init_support * must have been executed successfully. * + * Targets: gv11b_gr_ecc_init, gv11b_ecc_detect_enabled_units. + * * Steps: - * - Set fuse register bit FUSES_OVERRIDE_DISABLE to TRUE. - * - Call g->ops.gr.ecc.detect. - * - Set fuse register bit FUSES_OVERRIDE_DISABLE to FALSE. - * - Set fecs register for ecc override. - * - Set fecs register for ecc1 override. + * - Array with various combinations setting register bits for + * FUSES_OVERRIDE_DISABLE, OPT_ECC_ENABLE, fecs register for ecc + * and ecc1 overrides. * - Call g->ops.gr.ecc.detect. + * - Error injection for allocation and other conditional checking + * in g->ops.gr.ecc.init call. * * Output: Returns PASS. */ @@ -180,6 +194,9 @@ int test_gr_init_ecc_features(struct unit_module *m, * * Input: None * + * Targets: #nvgpu_gr_prepare_sw, #nvgpu_gr_prepare_hw, + * and #nvgpu_gr_init_support. + * * Steps: * - Call #test_gr_init_setup. * - Setup gv11b arch and allocate struct for common.gr. @@ -199,7 +216,9 @@ int test_gr_init_setup_ready(struct unit_module *m, struct gk20a *g, void *args) * * Test Type: Feature based. * - * Input: test_gr_setup_ready must have been executed successfully. + * Input: #test_gr_setup_ready must have been executed successfully. + * + * Targets: #nvgpu_gr_free, #nvgpu_gr_remove_support. * * Steps: * - Call #test_gr_remove_support.