gpu: nvgpu: Add negative test for gr.config unit

Add test to coverage the error injections in gr.config unit.
required_tests is updated with new test for gr.config and
missing test for gr.setup unit.

Jira NVGPU-4531

Change-Id: Idf089af5fec1e653793a620b4e7f7bd5d96210ba
Signed-off-by: vinodg <vinodg@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/2262230
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: Deepak Nibade <dnibade@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
vinodg
2019-12-13 16:52:49 -08:00
committed by Alex Waterman
parent 6b7c3c6d81
commit c25ccbb130
3 changed files with 368 additions and 35 deletions

View File

@@ -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
},

View File

@@ -27,9 +27,14 @@
#include <unit/io.h>
#include <nvgpu/posix/io.h>
#include <nvgpu/posix/kmem.h>
#include <nvgpu/posix/posix-fault-injection.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/gr/config.h>
#include <nvgpu/hw/gv11b/hw_proj_gv11b.h>
#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),
};

View File

@@ -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 */
/**