diff --git a/userspace/required_tests.json b/userspace/required_tests.json index 7af995ddb..246ef6fc9 100644 --- a/userspace/required_tests.json +++ b/userspace/required_tests.json @@ -1859,6 +1859,18 @@ "unit": "nvgpu_fifo_gv11b", "test_level": 0 }, + { + "test": "test_gr_init_setup", + "case": "gr_init_setup", + "unit": "nvgpu_gr_config", + "test_level": 0 + }, + { + "test": "test_gr_config_init", + "case": "config_init", + "unit": "nvgpu_gr_config", + "test_level": 0 + }, { "test": "test_gr_config_count", "case": "config_check_init", @@ -1871,24 +1883,18 @@ "unit": "nvgpu_gr_config", "test_level": 0 }, + { + "test": "test_gr_config_error_injection", + "case": "config_error_injection", + "unit": "nvgpu_gr_config", + "test_level": 0 + }, { "test": "test_gr_config_deinit", "case": "config_deinit", "unit": "nvgpu_gr_config", "test_level": 0 }, - { - "test": "test_gr_config_init", - "case": "config_init", - "unit": "nvgpu_gr_config", - "test_level": 0 - }, - { - "test": "test_gr_init_setup", - "case": "gr_init_setup", - "unit": "nvgpu_gr_config", - "test_level": 0 - }, { "test": "test_gr_remove_setup", "case": "gr_remove_setup", @@ -2021,30 +2027,18 @@ "unit": "nvgpu_gr_intr", "test_level": 0 }, + { + "test": "test_gr_init_setup_ready", + "case": "gr_setup_setup", + "unit": "nvgpu_gr_setup", + "test_level": 0 + }, { "test": "test_gr_setup_alloc_obj_ctx", "case": "gr_setup_alloc_obj_ctx", "unit": "nvgpu_gr_setup", "test_level": 0 }, - { - "test": "test_gr_init_setup_cleanup", - "case": "gr_setup_cleanup", - "unit": "nvgpu_gr_setup", - "test_level": 0 - }, - { - "test": "test_gr_setup_free_obj_ctx", - "case": "gr_setup_free_obj_ctx", - "unit": "nvgpu_gr_setup", - "test_level": 0 - }, - { - "test": "test_gr_setup_preemption_mode_errors", - "case": "gr_setup_preemption_mode_errors", - "unit": "nvgpu_gr_setup", - "test_level": 0 - }, { "test": "test_gr_setup_set_preemption_mode", "case": "gr_setup_set_preemption_mode", @@ -2052,8 +2046,26 @@ "test_level": 0 }, { - "test": "test_gr_init_setup_ready", - "case": "gr_setup_setup", + "test": "test_gr_setup_preemption_mode_errors", + "case": "gr_setup_preemption_mode_errors", + "unit": "nvgpu_gr_setup", + "test_level": 0 + }, + { + "test": "test_gr_setup_free_obj_ctx", + "case": "gr_setup_free_obj_ctx", + "unit": "nvgpu_gr_setup", + "test_level": 0 + }, + { + "test": "test_gr_setup_alloc_obj_ctx_error_injections", + "case": "gr_setup_alloc_obj_ctx_error_injections", + "unit": "nvgpu_gr_setup", + "test_level": 0 + }, + { + "test": "test_gr_init_setup_cleanup", + "case": "gr_setup_cleanup", "unit": "nvgpu_gr_setup", "test_level": 0 }, diff --git a/userspace/units/gr/config/nvgpu-gr-config.c b/userspace/units/gr/config/nvgpu-gr-config.c index 8a8dce67a..13fae0c59 100644 --- a/userspace/units/gr/config/nvgpu-gr-config.c +++ b/userspace/units/gr/config/nvgpu-gr-config.c @@ -27,9 +27,14 @@ #include #include +#include +#include + #include #include +#include + #include "common/gr/gr_config_priv.h" #include "../nvgpu-gr.h" @@ -37,6 +42,90 @@ static struct nvgpu_gr_config *unit_gr_config; +struct gr_gops_config_orgs { + u32 (*get_litter_value)(struct gk20a *g, + int value); + u32 (*priv_ring_get_gpc_count)(struct gk20a *g); + u32 (*get_pes_tpc_mask)(struct gk20a *g, + struct nvgpu_gr_config *gr_config, u32 gpc, u32 tpc); +}; + +struct gr_config_litvalues { + u32 pes_per_num; + bool sm_per_num; + u32 pes_tpc_mask; +}; + +struct gr_config_litvalues gr_test_config_lits; +struct gr_gops_config_orgs gr_test_config_gops; + +static void gr_test_config_save_gops(struct gk20a *g) +{ + gr_test_config_gops.get_litter_value = + g->ops.get_litter_value; + gr_test_config_gops.priv_ring_get_gpc_count = + g->ops.priv_ring.get_gpc_count; + gr_test_config_gops.get_pes_tpc_mask = + g->ops.gr.config.get_pes_tpc_mask; +} + +static void gr_test_config_restore_gops(struct gk20a *g) +{ + g->ops.get_litter_value = + gr_test_config_gops.get_litter_value; + g->ops.priv_ring.get_gpc_count = + gr_test_config_gops.priv_ring_get_gpc_count; + g->ops.gr.config.get_pes_tpc_mask = + gr_test_config_gops.get_pes_tpc_mask; +} + +static u32 gr_test_config_get_pes_tpc_mask(struct gk20a *g, + struct nvgpu_gr_config *gr_config, u32 gpc, u32 tpc) +{ + gr_test_config_lits.pes_tpc_mask += 1; + if (gr_test_config_lits.pes_tpc_mask == 2) { + return 0x1F; + }else if (gr_test_config_lits.pes_tpc_mask == 3) { + return 0; + }else if (gr_test_config_lits.pes_tpc_mask > 3) { + return 0xF; + }else { + return 0; + } +} + +static u32 gr_test_config_priv_ring_get_gpc_count(struct gk20a *g) +{ + return 0; +} + +static u32 gr_test_config_litter_value(struct gk20a *g, int value) +{ + u32 val = 0; + switch (value) { + case GPU_LIT_NUM_PES_PER_GPC: + if (gr_test_config_lits.pes_per_num >= 3) { + val = proj_scal_litter_num_pes_per_gpc_v(); + } else if (gr_test_config_lits.pes_per_num >= 1) { + val = 1; + } else { + val = GK20A_GR_MAX_PES_PER_GPC + 1; + } + gr_test_config_lits.pes_per_num += 1; + break; + case GPU_LIT_NUM_SM_PER_TPC: + if (gr_test_config_lits.sm_per_num) { + val = proj_scal_litter_num_sm_per_tpc_v(); + } else { + val = 0; /* Set zero sm per tpc */ + } + gr_test_config_lits.sm_per_num = true; + break; + } + + return val; +} + int test_gr_config_init(struct unit_module *m, struct gk20a *g, void *args) { @@ -264,11 +353,184 @@ int test_gr_config_set_get(struct unit_module *m, return UNIT_SUCCESS; } +static int gr_test_invalid_gpc_count(struct gk20a *g) +{ + struct nvgpu_gr_config *gr_conf; + + gr_test_config_restore_gops(g); + g->ops.priv_ring.get_gpc_count = + gr_test_config_priv_ring_get_gpc_count; + gr_conf = nvgpu_gr_config_init(g); + g->ops.priv_ring.get_gpc_count = + gr_test_config_gops.priv_ring_get_gpc_count; + if (gr_conf != NULL) { + return UNIT_FAIL; + } + + return UNIT_SUCCESS; +} + +static int gr_test_diff_pes_tpc_mask(struct gk20a *g) +{ + struct nvgpu_gr_config *gr_conf; + + gr_test_config_restore_gops(g); + g->ops.gr.config.get_pes_tpc_mask = + gr_test_config_get_pes_tpc_mask; + gr_conf = nvgpu_gr_config_init(g); + if (gr_conf == NULL) { + return UNIT_FAIL; + } + nvgpu_gr_config_deinit(g, gr_conf); + return UNIT_SUCCESS; +} + +static int gr_test_invalid_litter_values(struct gk20a *g) +{ + struct nvgpu_gr_config *gr_conf; + int i; + + gr_test_config_restore_gops(g); + g->ops.get_litter_value = gr_test_config_litter_value; + + for ( i = 0; i < 2; i++) { + gr_conf = nvgpu_gr_config_init(g); + if (gr_conf != NULL) { + return UNIT_FAIL; + } + } + return UNIT_SUCCESS; +} + +static int gr_test_diff_gpc_skip_mask(struct gk20a *g) +{ + struct nvgpu_gr_config *gr_conf; + int i, err; + + gr_test_config_restore_gops(g); + g->ops.get_litter_value = gr_test_config_litter_value; + + gr_conf = nvgpu_gr_config_init(g); + if (gr_conf == NULL) { + return UNIT_FAIL; + } + nvgpu_gr_config_deinit(g, gr_conf); + + for (i = 0; i < 2; i++) { + err = gr_test_diff_pes_tpc_mask(g); + if (err != 0) { + return UNIT_FAIL; + } + } + + return UNIT_SUCCESS; +} + +static int gr_test_invalid_pes_with_sm_id(struct gk20a *g, + struct nvgpu_gr_config *gr_conf) +{ + int err; + + /* Set pes tpc mask same */ + u32 pes_tpc_mask = gr_conf->pes_tpc_mask[1][0]; + u32 gpc_count = nvgpu_gr_config_get_gpc_count(gr_conf); + + gr_conf->pes_tpc_mask[1][0] = gr_conf->pes_tpc_mask[0][0]; + gr_conf->gpc_count = 2; + err = g->ops.gr.config.init_sm_id_table(g, gr_conf); + + gr_conf->pes_tpc_mask[1][0] = pes_tpc_mask; + gr_conf->gpc_count = gpc_count; + + return err; +} + +int test_gr_config_error_injection(struct unit_module *m, + struct gk20a *g, void *args) +{ + + int err, i; + struct nvgpu_gr_config *gr_conf; + struct nvgpu_posix_fault_inj *kmem_fi = + nvgpu_kmem_get_fault_injection(); + + gr_test_config_save_gops(g); + memset(&gr_test_config_lits, 0, + sizeof(struct gr_config_litvalues)); + + /* Fail gr_config struct mem allocation */ + for (i = 0; i < 9; i++) { + nvgpu_posix_enable_fault_injection(kmem_fi, true, i); + gr_conf = nvgpu_gr_config_init(g); + if (gr_conf != NULL) { + unit_return_fail(m, + "nvgpu_gr_config_init alloc test failed\n"); + } + nvgpu_posix_enable_fault_injection(kmem_fi, false, 0); + } + + /* Fail with zero gpc_count */ + err = gr_test_invalid_gpc_count(g); + if (err != 0) { + unit_return_fail(m, + "gr_test_invalid_gpc_count test failed\n"); + } + + /* Fail with wrong config litter values */ + err = gr_test_invalid_litter_values(g); + if (err != 0) { + unit_return_fail(m, + "gr_test_invalid_gpc_count test failed\n"); + } + + /* Pass with diff pes_tpc_mask */ + err = gr_test_diff_pes_tpc_mask(g); + if (err != 0) { + unit_return_fail(m, + "gr_test_invalid_pes_tpc_mask test failed\n"); + } + + /* Pass with diff gpc_skip_mask */ + err = gr_test_diff_gpc_skip_mask(g); + if (err != 0) { + unit_return_fail(m, + "gr_test_invalid_pes_tpc_mask test failed\n"); + } + + gr_test_config_restore_gops(g); + + gr_conf = nvgpu_gr_config_init(g); + + /* Fail sm_id table mem allocation */ + for (i = 0; i < 5; i++) { + nvgpu_posix_enable_fault_injection(kmem_fi, true, i); + err = g->ops.gr.config.init_sm_id_table(g, gr_conf); + if (err == 0) { + unit_return_fail(m, + "init_sm_id_table alloc failed\n"); + } + nvgpu_posix_enable_fault_injection(kmem_fi, false, 0); + } + + /* Fail sm_id table with wrong pes mask value */ + err = gr_test_invalid_pes_with_sm_id(g, gr_conf); + if (err == 0) { + unit_return_fail(m, + "gr_test_invalid_pes_with_sm_id test failed\n"); + } + + nvgpu_gr_config_deinit(g, gr_conf); + + return UNIT_SUCCESS; +} + struct unit_module_test nvgpu_gr_config_tests[] = { UNIT_TEST(gr_init_setup, test_gr_init_setup, NULL, 0), UNIT_TEST(config_init, test_gr_config_init, NULL, 0), UNIT_TEST(config_check_init, test_gr_config_count, NULL, 0), UNIT_TEST(config_check_set_get, test_gr_config_set_get, NULL, 0), + UNIT_TEST(config_error_injection, + test_gr_config_error_injection, NULL, 0), UNIT_TEST(config_deinit, test_gr_config_deinit, NULL, 0), UNIT_TEST(gr_remove_setup, test_gr_remove_setup, NULL, 0), }; diff --git a/userspace/units/gr/config/nvgpu-gr-config.h b/userspace/units/gr/config/nvgpu-gr-config.h index 51bf939b1..e0165cbd4 100644 --- a/userspace/units/gr/config/nvgpu-gr-config.h +++ b/userspace/units/gr/config/nvgpu-gr-config.h @@ -44,6 +44,8 @@ struct unit_module; * * Input: None * + * Targets: #nvgpu_gr_config_init. + * * Steps: * - Call nvgpu_gr_config_init * @@ -59,7 +61,10 @@ int test_gr_config_init(struct unit_module *m, struct gk20a *g, void *args); * * Test Type: Feature based. * - * Input: test_gr_config_init must have been executed successfully. + * Targets: #nvgpu_gr_config_deinit. + * + * Input: #test_gr_init_setup and #test_gr_config_init + * must have been executed successfully. * * Steps: * - Call nvgpu_gr_config_deinit @@ -78,7 +83,25 @@ int test_gr_config_deinit(struct unit_module *m, struct gk20a *g, void *args); * * Test Type: Feature based, Error guessing. * - * Input: test_gr_config_init must have been executed successfully. + * Input: #test_gr_init_setup and #test_gr_config_init + * must have been executed successfully. + * + * Targets: #nvgpu_gr_config_get_max_gpc_count, + * #nvgpu_gr_config_get_max_tpc_count, + * #nvgpu_gr_config_get_max_tpc_per_gpc_count, + * #nvgpu_gr_config_get_gpc_count, + * #nvgpu_gr_config_get_tpc_count, + * #nvgpu_gr_config_get_ppc_count, + * #nvgpu_gr_config_get_pe_count_per_gpc, + * #nvgpu_gr_config_get_sm_count_per_tpc, + * #nvgpu_gr_config_get_gpc_mask, + * #nvgpu_gr_config_get_gpc_ppc_count, + * #nvgpu_gr_config_get_gpc_skip_mask, + * #nvgpu_gr_config_get_gpc_tpc_count, + * #nvgpu_gr_config_get_pes_tpc_count, + * #nvgpu_gr_config_get_pes_tpc_mask, + * #nvgpu_gr_config_get_gpc_tpc_mask_base, + * #nvgpu_gr_config_get_gpc_tpc_count_base. * * Steps: * - Read configuration count and mask informations from the driver @@ -99,7 +122,16 @@ int test_gr_config_count(struct unit_module *m, struct gk20a *g, void *args); * * Test Type: Feature based, Error guessing * - * Input: nvgpu_gr_config_init must have been executed successfully. + * Targets: #nvgpu_gr_config_set_no_of_sm, + * #nvgpu_gr_config_get_sm_info, + * #nvgpu_gr_config_set_sm_info_tpc_index, + * #nvgpu_gr_config_set_sm_info_global_tpc_index, + * #nvgpu_gr_config_set_sm_info_sm_index, + * #nvgpu_gr_config_set_gpc_tpc_mask, + * #nvgpu_gr_config_get_gpc_tpc_mask. + * + * Input: #test_gr_init_setup and #test_gr_config_init + * must have been executed successfully. * * Steps: * - Random values are set for various configuration and read back to @@ -110,6 +142,33 @@ int test_gr_config_count(struct unit_module *m, struct gk20a *g, void *args); */ int test_gr_config_set_get(struct unit_module *m, struct gk20a *g, void *args); +/** + * Test specification for: test_gr_config_error_injection. + * + * Description: This test helps to verify whether the kernel handles all + * possible error conditions for memory allocation failure. Also + * provide different configurations in common.gr unit. + * + * Test Type: Feature based, Error guessing + * + * Input: #test_gr_init_setup must have been executed successfully. + * + * Targets: #nvgpu_gr_config_init, + * #nvgpu_gr_config_deinit, + * + * Steps: + * - Force memory allocation failures for various structures within + * nvgpu_gr_config_init call. + * - Set for various configuration like pes_tpc_count, gpc_tpc_mask, + * gpc_count by adding stub function for various gr.config hal and + * call nvgpu_gr_config_init. + * - Force memory allocation failures with + * g->ops.gr.config.init_sm_id_table call. + * + * Output: Returns PASS if the steps above were executed successfully. FAIL + * otherwise. + */ +int test_gr_config_error_injection(struct unit_module *m, struct gk20a *g, void *args); #endif /* UNIT_NVGPU_GR_CONFIG_H */ /**