mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 09:12:24 +03:00
gpu: nvgpu: bvec for struct nvgpu_tsg_sm_error_state fields
Add Setter and Getter methods for accessing tsg->sm_error_states. Getter returns a constant pointer for struct nvgpu_tsg_sm_error_state. This renders it unnecessary to add BVEC for above fields for the struct in multiple locations. The current design ensures that only a constant pointer is obtained from the owner unit i.e. FIFO. The following new methods are added. Both unit tests and BVEC tests are added for them as well. nvgpu_tsg_store_sm_error_state nvgpu_tsg_get_sm_error_state Jira NVGPU-6947 Change-Id: I82c22a2774862c8579baa41b6fb8292fa164704a Signed-off-by: Debarshi Dutta <ddutta@nvidia.com> (cherry picked from commit 79574638671a0c6efe41cd3423668fcd1bd96826) Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2556938 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com> Reviewed-by: Shashank Singh <shashsingh@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Vaibhav Kachore <vkachore@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit
This commit is contained in:
committed by
mobile promotions
parent
6361653633
commit
791dc18666
@@ -851,6 +851,137 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int test_tsg_sm_error_state_set_get(struct unit_module *m,
|
||||
struct gk20a *g, void *args)
|
||||
{
|
||||
struct gpu_ops gops = g->ops;
|
||||
struct nvgpu_channel *ch = NULL;
|
||||
struct nvgpu_tsg *tsg = NULL;
|
||||
int ret = UNIT_FAIL;
|
||||
int err = 0;
|
||||
int num_sm = g->ops.gr.init.get_no_of_sm(g);
|
||||
u32 valid_sm_id[][2] = {{0, num_sm - 1}};
|
||||
u32 invalid_sm_id[][2] = {{num_sm, U32_MAX}};
|
||||
u32 i = 0, j = 0, sm_id_range, states, sm_id, t = 0, z = 0;
|
||||
u32 (*working_list)[2];
|
||||
const char *string_states[] = {"Min", "Max", "Mid"};
|
||||
struct nvgpu_tsg_sm_error_state *sm_error_states = NULL;
|
||||
const struct nvgpu_tsg_sm_error_state *get_error_state = NULL;
|
||||
u32 sm_error_states_values[] = {0, 0, 0, 0};
|
||||
u64 hww_warp_esr_pc = 0;
|
||||
|
||||
tsg = nvgpu_tsg_open(g, getpid());
|
||||
unit_assert(tsg != NULL, goto done);
|
||||
|
||||
ch = nvgpu_channel_open_new(g, ~0U, false, getpid(), getpid());
|
||||
unit_assert(ch != NULL, goto done);
|
||||
|
||||
err = nvgpu_tsg_bind_channel(tsg, ch);
|
||||
unit_assert(err == 0, goto done);
|
||||
|
||||
sm_error_states = tsg->sm_error_states;
|
||||
|
||||
//check for SM_ERROR_STATE null
|
||||
tsg->sm_error_states = NULL;
|
||||
err = nvgpu_tsg_store_sm_error_state(tsg, 0, 0, 0, 0, 0, 0);
|
||||
unit_assert(err != 0, goto done);
|
||||
|
||||
tsg->sm_error_states = sm_error_states;
|
||||
err = nvgpu_tsg_store_sm_error_state(tsg, 0, 0, 0, 0, 0, 0);
|
||||
unit_assert(err == 0, goto done);
|
||||
|
||||
//check for SM_ERROR_STATE null
|
||||
tsg->sm_error_states = NULL;
|
||||
get_error_state = nvgpu_tsg_get_sm_error_state(tsg, 0);
|
||||
unit_assert(get_error_state == NULL, goto done);
|
||||
tsg->sm_error_states = sm_error_states;
|
||||
|
||||
/* valid, invalid sm_ids */
|
||||
for (i = 0; i < 2; i++) {
|
||||
working_list = (i == 0) ? valid_sm_id : invalid_sm_id;
|
||||
sm_id_range = (i == 0) ? ARRAY_SIZE(valid_sm_id) : ARRAY_SIZE(invalid_sm_id);
|
||||
for (j = 0; j < sm_id_range; j++) {
|
||||
for (states = 0; states < 3; states++) {
|
||||
if (states == 0) {
|
||||
sm_id = working_list[j][0];
|
||||
} else if (states == 1) {
|
||||
sm_id = working_list[j][1];
|
||||
} else {
|
||||
if (working_list[j][1] - working_list[j][0] > 1) {
|
||||
sm_id = get_random_u32(working_list[j][0] + 1, working_list[j][1] - 1);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Invalid SM_ID case */
|
||||
if (i == 1) {
|
||||
unit_info(m, "BVEC testing for nvgpu_tsg_store_sm_error_state with sm_id = 0x%08x(Invalid range %s) \n", sm_id, string_states[states]);
|
||||
err = nvgpu_tsg_store_sm_error_state(tsg, sm_id, 0, 0, 0, 0, 0);
|
||||
unit_assert(err != 0, goto done);
|
||||
|
||||
unit_info(m, "BVEC testing for nvgpu_tsg_get_sm_error_state with sm_id = 0x%08x(Invalid range %s) \n", sm_id, string_states[states]);
|
||||
get_error_state = nvgpu_tsg_get_sm_error_state(tsg, sm_id);
|
||||
unit_assert(get_error_state == NULL, goto done);
|
||||
} else {
|
||||
for (t = 0; t < 3; t++) {
|
||||
/* Loop to fill the SM error values */
|
||||
for (z = 0; z < 4; z++) {
|
||||
if (t == 0) {
|
||||
/* Default 0*/
|
||||
} else if (t == 1) {
|
||||
sm_error_states_values[z] = U32_MAX;
|
||||
hww_warp_esr_pc = U32_MAX;
|
||||
} else {
|
||||
sm_error_states_values[z] = get_random_u32(1, U32_MAX - 1);
|
||||
hww_warp_esr_pc = 2ULL * U32_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
unit_info(m, "BVEC testing for nvgpu_tsg_store_sm_error_state with sm_id = 0x%08x(Valid range %s)\n", sm_id, string_states[t]);
|
||||
unit_info(m, "hww_global_esr = 0x%08x\n", sm_error_states_values[0]);
|
||||
unit_info(m, "hww_warp_esr = 0x%08x\n", sm_error_states_values[1]);
|
||||
unit_info(m, "hww_warp_esr_pc = 0x%016llx\n", hww_warp_esr_pc);
|
||||
unit_info(m, "hww_global_esr_report_mask = 0x%08x\n", sm_error_states_values[2]);
|
||||
unit_info(m, "hww_warp_esr_report_mask = 0x%08x\n", sm_error_states_values[3]);
|
||||
|
||||
err = nvgpu_tsg_store_sm_error_state(tsg, sm_id,
|
||||
sm_error_states_values[0], sm_error_states_values[1], hww_warp_esr_pc,
|
||||
sm_error_states_values[2], sm_error_states_values[3]);
|
||||
unit_assert(err == 0, goto done);
|
||||
|
||||
unit_info(m, "BVEC testing for nvgpu_tsg_get_sm_error_state with sm_id = %u(Valid range %s) \n", sm_id, string_states[t]);
|
||||
get_error_state = nvgpu_tsg_get_sm_error_state(tsg, sm_id);
|
||||
unit_assert(get_error_state != NULL, goto done);
|
||||
|
||||
unit_assert(get_error_state->hww_global_esr == sm_error_states_values[0], goto done);
|
||||
unit_assert(get_error_state->hww_warp_esr == sm_error_states_values[1], goto done);
|
||||
unit_assert(get_error_state->hww_warp_esr_pc == hww_warp_esr_pc, goto done);
|
||||
unit_assert(get_error_state->hww_global_esr_report_mask == sm_error_states_values[2], goto done);
|
||||
unit_assert(get_error_state->hww_warp_esr_report_mask == sm_error_states_values[3], goto done);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = UNIT_SUCCESS;
|
||||
done:
|
||||
if (ret == UNIT_FAIL) {
|
||||
unit_err(m, "branches=%s\n", __func__);
|
||||
}
|
||||
|
||||
if (ch != NULL) {
|
||||
nvgpu_tsg_force_unbind_channel(tsg, ch);
|
||||
nvgpu_channel_close(ch);
|
||||
}
|
||||
if (tsg != NULL) {
|
||||
nvgpu_ref_put(&tsg->refcount, nvgpu_tsg_release);
|
||||
}
|
||||
g->ops = gops;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define F_UNBIND_CHANNEL_CHECK_CTX_RELOAD_SET BIT(0)
|
||||
#define F_UNBIND_CHANNEL_CHECK_CTX_RELOAD_CHID_MATCH BIT(1)
|
||||
#define F_UNBIND_CHANNEL_CHECK_CTX_RELOAD_LAST BIT(2)
|
||||
@@ -1650,6 +1781,7 @@ struct unit_module_test nvgpu_tsg_tests[] = {
|
||||
UNIT_TEST(unbind_channel, test_tsg_unbind_channel, &unit_ctx, 0),
|
||||
UNIT_TEST(unbind_channel_check_hw_state,
|
||||
test_tsg_unbind_channel_check_hw_state, &unit_ctx, 0),
|
||||
UNIT_TEST(sm_error_states, test_tsg_sm_error_state_set_get, &unit_ctx, 0),
|
||||
UNIT_TEST(unbind_channel_check_ctx_reload,
|
||||
test_tsg_unbind_channel_check_ctx_reload, &unit_ctx, 0),
|
||||
UNIT_TEST(enable_disable, test_tsg_enable, &unit_ctx, 0),
|
||||
|
||||
@@ -220,6 +220,40 @@ int test_tsg_release(struct unit_module *m,
|
||||
int test_tsg_unbind_channel_check_hw_state(struct unit_module *m,
|
||||
struct gk20a *g, void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: struct nvgpu_tsg_sm_error_state
|
||||
*
|
||||
* Description: Check HW state during TSG unbind channel.
|
||||
*
|
||||
* Test Type: Feature, Boundary Value
|
||||
*
|
||||
* Targets: nvgpu_tsg_store_sm_error_state, nvgpu_tsg_get_sm_error_state
|
||||
*
|
||||
* Input: test_fifo_init_support() run for this GPU
|
||||
* Equivalence classes:
|
||||
* sm_id
|
||||
* - Invalid : [g->ops.gr.init.get_no_of_sm(g), U32_MAX]
|
||||
* - Valid : [0, g->ops.gr.init.get_no_of_sm(g) - 1]
|
||||
* struct nvgpu_tsg_sm_error_state fields
|
||||
* - Valid : [0, U32_MAX]
|
||||
*
|
||||
* Steps:
|
||||
* 1) tsg->sm_error_states = NULL (Invalid Case)
|
||||
* Verify nvgpu_tsg_store_sm_error_state returns error
|
||||
* Verify nvgpu_tsg_get_sm_error_state returns NULL
|
||||
* 2) sm_id >= g->ops.gr.init.get_no_of_sm(g) (Invalid Case)
|
||||
* Verify nvgpu_tsg_store_sm_error_state returns error
|
||||
* Verify nvgpu_tsg_get_sm_error_state returns NULL
|
||||
* 3) For Valid sm_id and tsg->sm_error_states != NULL
|
||||
* For each value within struct nvgpu_tsg_sm_error_state,
|
||||
* test with Min, Max and one random number between [0, U32_MAX].
|
||||
* a) Verify nvgpu_tsg_store_sm_error_state returns 0
|
||||
* b) Verify nvgpu_tsg_get_sm_error_state returns non NULL.
|
||||
*
|
||||
* Output: Returns PASS if all branches gave expected results. FAIL otherwise.
|
||||
*/
|
||||
int test_tsg_sm_error_state_set_get(struct unit_module *m,
|
||||
struct gk20a *g, void *args);
|
||||
/**
|
||||
* Test specification for: test_tsg_unbind_channel_check_ctx_reload
|
||||
*
|
||||
|
||||
@@ -199,12 +199,13 @@ static int gr_test_intr_allocate_ch(struct unit_module *m,
|
||||
|
||||
|
||||
static int gr_test_intr_block_ptr_as_current_ctx(struct unit_module *m,
|
||||
struct gk20a *g, struct nvgpu_channel *ch,
|
||||
struct gk20a *g, struct nvgpu_channel *ch, struct nvgpu_tsg *tsg,
|
||||
u32 pid)
|
||||
{
|
||||
int err, i;
|
||||
struct nvgpu_gr_intr *intr = g->gr->intr;
|
||||
u32 tsgid = nvgpu_inst_block_ptr(g, &ch->inst_block);
|
||||
struct nvgpu_tsg_sm_error_state *sm_error_states = NULL;
|
||||
|
||||
err = EXPECT_BUG(g->ops.gr.intr.stall_isr(g));
|
||||
if (err != 0) {
|
||||
@@ -219,6 +220,17 @@ static int gr_test_intr_block_ptr_as_current_ctx(struct unit_module *m,
|
||||
unit_return_fail(m, "failed stall isr\n");
|
||||
}
|
||||
|
||||
/* Cover the case where gv11b_gr_intr_read_sm_error_state fails */
|
||||
sm_error_states = tsg->sm_error_states;
|
||||
tsg->sm_error_states = NULL;
|
||||
|
||||
err = g->ops.gr.intr.stall_isr(g);
|
||||
if (err != 0) {
|
||||
unit_return_fail(m, "failed stall isr\n");
|
||||
}
|
||||
|
||||
tsg->sm_error_states = sm_error_states;
|
||||
|
||||
/* Make all entry valid so code with flush one */
|
||||
for (i = 0; i < GR_TEST_CHANNEL_MAP_TLB_SIZE; i++) {
|
||||
intr->chid_tlb[i].curr_ctx = pid;
|
||||
@@ -289,7 +301,7 @@ static int gr_test_intr_allocate_ch_tsg(struct unit_module *m,
|
||||
goto ch_cleanup;
|
||||
}
|
||||
|
||||
err = gr_test_intr_block_ptr_as_current_ctx(m, g, ch, tsgid);
|
||||
err = gr_test_intr_block_ptr_as_current_ctx(m, g, ch, tsg, tsgid);
|
||||
if (err != 0) {
|
||||
unit_err(m, "isr failed with block_ptr as current_ctx\n");
|
||||
goto tsg_unbind;
|
||||
|
||||
Reference in New Issue
Block a user