gpu: nvgpu: add BVEC test for nvgpu_rc_pbdma_fault

Update nvgpu_rc_pbdma_fault with invalid checks and add BVEC test
for it.

Make ga10b_fifo_pbdma_isr static.

NVGPU-6772

Change-Id: I5485760c53e1fff1278557a5b25659a1fc0e4eaf
Signed-off-by: Sagar Kamble <skamble@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2551617
(cherry picked from commit e917042d395d07cb902580bad3d5a7d0096cc303)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2623625
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Sagar Kamble
2021-06-29 23:44:25 +05:30
committed by mobile promotions
parent d8e8eb65d3
commit 80efe558b1
24 changed files with 298 additions and 92 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2019-2022, NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -172,13 +172,15 @@ done:
return ret;
}
static void stub_pbdma_handle_intr(struct gk20a *g, u32 pbdma_id, bool recover)
static int stub_pbdma_handle_intr(struct gk20a *g, u32 pbdma_id, bool recover)
{
if (nvgpu_readl(g, fifo_intr_pbdma_id_r()) != BIT(pbdma_id)) {
u.fail = true;
}
u.count++;
return 0;
}
int test_gk20a_fifo_pbdma_isr(struct unit_module *m,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2018-2022, NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -180,6 +180,9 @@ int test_pbdma_status(struct unit_module *m,
unit_assert(nvgpu_pbdma_status_is_chsw_valid(&pbdma_status) ==
(pbdma_status.chsw_status ==
NVGPU_PBDMA_CHSW_STATUS_VALID), goto done);
unit_assert(nvgpu_pbdma_status_ch_not_loaded(&pbdma_status) ==
(pbdma_status.chsw_status ==
NVGPU_PBDMA_CHSW_STATUS_INVALID), goto done);
}
pbdma_status.id_type = PBDMA_STATUS_ID_TYPE_CHID;

View File

@@ -144,8 +144,9 @@ done:
return ret;
}
static void stub_pbdma_handle_intr(struct gk20a *g, u32 pbdma_id, bool recover)
static int stub_pbdma_handle_intr(struct gk20a *g, u32 pbdma_id, bool recover)
{
return 0;
}
static int stub_fifo_preempt_tsg(struct gk20a *g, struct nvgpu_tsg *tsg)

View File

@@ -1579,7 +1579,7 @@ int test_nvgpu_tsg_set_error_notifier_bvec(struct unit_module *m,
int ret = 0;
u32 valid_error_notifier_ids[][2] = {{NVGPU_ERR_NOTIFIER_FIFO_ERROR_IDLE_TIMEOUT, NVGPU_ERR_NOTIFIER_PBDMA_PUSHBUFFER_CRC_MISMATCH}};
u32 invalid_error_notifier_ids[][2] = {{NVGPU_ERR_NOTIFIER_PBDMA_PUSHBUFFER_CRC_MISMATCH + 1, U32_MAX}};
u32 invalid_error_notifier_ids[][2] = {{NVGPU_ERR_NOTIFIER_INVAL, U32_MAX}};
u32 (*working_list)[2];
u32 error_code, error_notifier_range_len;
/*

View File

@@ -448,7 +448,7 @@ int test_tsg_mark_error(struct unit_module *m,
* Input: None
* Equivalence classes:
* error_notifier
* - Invalid : { NVGPU_ERR_NOTIFIER_PBDMA_PUSHBUFFER_CRC_MISMATCH + 1, U32_MAX }
* - Invalid : { NVGPU_ERR_NOTIFIER_INVAL, U32_MAX }
* - Valid : { NVGPU_ERR_NOTIFIER_FIFO_ERROR_IDLE_TIMEOUT, NVGPU_ERR_NOTIFIER_PBDMA_PUSHBUFFER_CRC_MISMATCH }
*
* Steps:

View File

@@ -23,6 +23,7 @@
#include <unistd.h>
#include <unit/unit.h>
#include <unit/io.h>
#include <unit/utils.h>
#include <nvgpu/types.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/hal_init.h>
@@ -146,6 +147,9 @@ int test_rc_init(struct unit_module *m, struct gk20a *g, void *args)
goto clear_posix_channel;
}
/* initialize the seed for random number generation needed in bvec tests */
srand(time(0));
return UNIT_SUCCESS;
clear_posix_channel:
@@ -294,13 +298,18 @@ int test_rc_mmu_fault(struct unit_module *m, struct gk20a *g, void *args)
return UNIT_SUCCESS;
}
#define F_RC_IS_CHSW_VALID_OR_SAVE 0U
#define F_RC_IS_CHSW_LOAD_OR_SWITCH 1U
#define F_RC_IS_CHSW_INVALID 2U
#define F_RC_IS_CHSW_VALID_OR_SAVE 0U
#define F_RC_IS_CHSW_LOAD_OR_SWITCH 1U
#define F_RC_IS_CHSW_INVALID 2U
#define F_RC_IS_CHSW_INVALID_STATE_MIN 3U
#define F_RC_IS_CHSW_INVALID_STATE_RANDOM 4U
#define F_RC_IS_CHSW_INVALID_STATE_MAX 5U
#define F_RC_ID_TYPE_TSG 0U
#define F_RC_ID_TYPE_CH 1U
#define F_RC_ID_TYPE_INVALID 2U
#define F_RC_ID_TYPE_INVALID_MIN 2U
#define F_RC_ID_TYPE_INVALID_RANDOM 3U
#define F_RC_ID_TYPE_INVALID_MAX 4U
#define F_RC_ID_TYPE_CH_NULL_CHANNEL 0U
#define F_RC_ID_TYPE_CH_NULL_TSG 1U
@@ -309,13 +318,18 @@ int test_rc_mmu_fault(struct unit_module *m, struct gk20a *g, void *args)
static const char *f_rc_chsw[] = {
"is_chsw_valid_or_save",
"is_chsw_load_or_switch",
"is_chsw_invalid",
"is_chsw_invalid channel not loaded on engine",
"is_chsw_inval_min",
"is_chsw_inval_random",
"is_chsw_inval_max",
};
static const char *f_rc_id_type[] = {
"id_type_tsg",
"id_type_ch",
"id_type_invalid",
"id_type_invalid_min",
"id_type_invalid_random",
"id_type_invalid_max",
};
static const char *f_rc_id_ch_subbranch[] = {
@@ -366,7 +380,13 @@ static void set_pbdma_info_id_type(u32 chsw_branches,
info->next_id_type = (chsw_branches == F_RC_IS_CHSW_LOAD_OR_SWITCH) ?
PBDMA_STATUS_NEXT_ID_TYPE_CHID : PBDMA_STATUS_NEXT_ID_TYPE_INVALID;
}
} else {
} else if (id_type_branches == F_RC_ID_TYPE_INVALID_MIN) {
info->id_type = PBDMA_STATUS_ID_TYPE_TSGID + 1;
info->next_id_type = PBDMA_STATUS_ID_TYPE_TSGID + 1;
} else if (id_type_branches == F_RC_ID_TYPE_INVALID_RANDOM) {
info->id_type = PBDMA_STATUS_ID_TYPE_TSGID + 2 + get_random_u32(PBDMA_STATUS_ID_TYPE_TSGID + 1, U32_MAX);
info->next_id_type = PBDMA_STATUS_ID_TYPE_TSGID + 2 + get_random_u32(PBDMA_STATUS_ID_TYPE_TSGID + 1, U32_MAX);
} else if (id_type_branches == F_RC_ID_TYPE_INVALID_MAX) {
info->id_type = PBDMA_STATUS_ID_INVALID;
info->next_id_type = PBDMA_STATUS_ID_INVALID;
}
@@ -374,7 +394,13 @@ static void set_pbdma_info_id_type(u32 chsw_branches,
int test_rc_pbdma_fault(struct unit_module *m, struct gk20a *g, void *args)
{
int notifiers[] = {NVGPU_ERR_NOTIFIER_FIFO_ERROR_IDLE_TIMEOUT, NVGPU_ERR_NOTIFIER_PBDMA_PUSHBUFFER_CRC_MISMATCH,
NVGPU_ERR_NOTIFIER_INVAL,
NVGPU_ERR_NOTIFIER_INVAL + 1 + get_random_u32(NVGPU_ERR_NOTIFIER_INVAL, INT_MAX), INT_MAX};
struct nvgpu_pbdma_status_info info = {0};
u32 chsw_branches, id_type_branches;
int err = UNIT_SUCCESS;
u32 i;
u32 chsw_subbranch;
struct nvgpu_channel *ch_without_tsg = NULL;
@@ -388,18 +414,19 @@ int test_rc_pbdma_fault(struct unit_module *m, struct gk20a *g, void *args)
g->sw_quiesce_pending = true;
for (chsw_branches = F_RC_IS_CHSW_VALID_OR_SAVE;
chsw_branches <= F_RC_IS_CHSW_INVALID; chsw_branches++) {
struct nvgpu_pbdma_status_info info = {0};
if (chsw_branches == F_RC_IS_CHSW_INVALID) {
info.chsw_status = NVGPU_PBDMA_CHSW_STATUS_INVALID;
unit_info(m, "%s branch: %s\n", __func__, f_rc_chsw[chsw_branches]);
nvgpu_rc_pbdma_fault(g, 0U, NVGPU_ERR_NOTIFIER_PBDMA_ERROR, &info);
continue;
for (i = 0; i < ARRAY_SIZE(notifiers); i++) {
err = nvgpu_rc_pbdma_fault(g, 0U, notifiers[i], &info);
if (err != (i < 2 ? 0 : -EINVAL)) {
unit_err(m, "fault processing error with notifier %d", notifiers[i]);
err = UNIT_FAIL;
goto out;
}
}
for (chsw_subbranch = 0U; chsw_subbranch < 2U; chsw_subbranch++) {
for (chsw_branches = F_RC_IS_CHSW_VALID_OR_SAVE;
chsw_branches <= F_RC_IS_CHSW_LOAD_OR_SWITCH; chsw_branches++) {
for (chsw_subbranch = 0U; chsw_subbranch <= chsw_branches; chsw_subbranch++) {
if (chsw_branches == F_RC_IS_CHSW_VALID_OR_SAVE) {
info.chsw_status =
(chsw_subbranch * NVGPU_PBDMA_CHSW_STATUS_VALID) +
@@ -411,7 +438,7 @@ int test_rc_pbdma_fault(struct unit_module *m, struct gk20a *g, void *args)
}
}
for (id_type_branches = F_RC_ID_TYPE_TSG; id_type_branches <= F_RC_ID_TYPE_INVALID;
for (id_type_branches = F_RC_ID_TYPE_TSG; id_type_branches <= F_RC_ID_TYPE_INVALID_MAX;
id_type_branches++) {
u32 id_type_ch_sub_branches = 0U;
if (id_type_branches == F_RC_ID_TYPE_CH) {
@@ -425,27 +452,81 @@ int test_rc_pbdma_fault(struct unit_module *m, struct gk20a *g, void *args)
f_rc_id_type[id_type_branches],
f_rc_id_ch_subbranch[id_type_ch_sub_branches]);
nvgpu_rc_pbdma_fault(g, 0U, NVGPU_ERR_NOTIFIER_PBDMA_ERROR, &info);
err = nvgpu_rc_pbdma_fault(g, 0U, NVGPU_ERR_NOTIFIER_PBDMA_ERROR, &info);
if ((id_type_branches >= F_RC_ID_TYPE_INVALID_MIN) ||
(id_type_ch_sub_branches < F_RC_ID_TYPE_CH_FULL)) {
if (err != -EINVAL) {
unit_err(m, "invalid id type or null ch/tsg passed");
err = UNIT_FAIL;
goto out;
}
} else if (err != 0) {
unit_err(m, "valid id type with full ch failed");
err = UNIT_FAIL;
goto out;
}
}
} else {
set_pbdma_info_id_type(chsw_branches, &info, ch_without_tsg,
id_type_branches, id_type_ch_sub_branches);
unit_info(m, "%s branch: %s - %s\n", __func__,
f_rc_chsw[chsw_branches],
f_rc_id_type[id_type_branches]);
nvgpu_rc_pbdma_fault(g, 0U, NVGPU_ERR_NOTIFIER_PBDMA_ERROR, &info);
err = nvgpu_rc_pbdma_fault(g, 0U, NVGPU_ERR_NOTIFIER_PBDMA_ERROR, &info);
if (id_type_branches >= F_RC_ID_TYPE_INVALID_MIN) {
if (err != -EINVAL) {
unit_err(m, "invalid id type passed");
err = UNIT_FAIL;
goto out;
}
} else if (err != 0) {
unit_err(m, "valid id type with tsg failed");
err = UNIT_FAIL;
goto out;
}
}
}
}
for (chsw_branches = F_RC_IS_CHSW_INVALID;
chsw_branches <= F_RC_IS_CHSW_INVALID_STATE_MAX; chsw_branches++) {
if (chsw_branches == F_RC_IS_CHSW_INVALID) {
info.chsw_status = NVGPU_PBDMA_CHSW_STATUS_INVALID;
}
if (chsw_branches == F_RC_IS_CHSW_INVALID_STATE_MIN) {
info.chsw_status = NVGPU_PBDMA_CHSW_STATUS_SWITCH + 1;
}
if (chsw_branches == F_RC_IS_CHSW_INVALID_STATE_RANDOM) {
info.chsw_status = NVGPU_PBDMA_CHSW_STATUS_SWITCH + 2 +
get_random_u32(NVGPU_PBDMA_CHSW_STATUS_SWITCH + 1, INT_MAX);
}
if (chsw_branches == F_RC_IS_CHSW_INVALID_STATE_MAX) {
info.chsw_status = INT_MAX;
}
unit_info(m, "%s branch: %s\n", __func__, f_rc_chsw[chsw_branches]);
err = nvgpu_rc_pbdma_fault(g, 0U, NVGPU_ERR_NOTIFIER_PBDMA_ERROR, &info);
if (err != ((chsw_branches == F_RC_IS_CHSW_INVALID) ? 0 : -EINVAL)) {
unit_err(m, "pbdma status check failed");
err = UNIT_FAIL;
goto out;
}
}
err = UNIT_SUCCESS;
out:
g->sw_quiesce_pending = false;
nvgpu_channel_close(ch_without_tsg);
return UNIT_SUCCESS;
return err;
}
struct unit_module_test nvgpu_rc_tests[] = {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2019-2022, NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -249,33 +249,49 @@ int test_rc_mmu_fault(struct unit_module *m, struct gk20a *g, void *args);
*
* Description: Coverage test for nvgpu_rc_pbdma_fault
*
* Test Type: Feature
* Test Type: Feature, Boundary Value
*
* Targets: nvgpu_rc_pbdma_fault
*
* Input: test_rc_init run for this GPU
*
* Equivalence classes:
* Variable: error_notifier
* - Valid: [NVGPU_ERR_NOTIFIER_FIFO_ERROR_IDLE_TIMEOUT, NVGPU_ERR_NOTIFIER_PBDMA_PUSHBUFFER_CRC_MISMATCH]
* - Invalid: [NVGPU_ERR_NOTIFIER_INVAL, INT_MAX]
* Variable: chsw state
* - Valid: [NVGPU_PBDMA_CHSW_STATUS_INVALID, NVGPU_PBDMA_CHSW_STATUS_SWITCH]
* - Invalid: [NVGPU_PBDMA_CHSW_STATUS_SWITCH + 1, INT_MAX]
* Variable: id_type
* - Valid: [PBDMA_STATUS_ID_TYPE_CHID, PBDMA_STATUS_ID_TYPE_TSGID]
* - Invalid: [PBDMA_STATUS_ID_TYPE_TSGID + 1, PBDMA_STATUS_ID_TYPE_INVALID]
*
* Steps:
* - initialize Channel error_notifier
* - test with valid and invalid error notifier values types
* - set g->sw_quiesce_pending = true
* - For each branch check with the following pbdma_status values
* - set chsw_status to chsw_valid_or_save
* - set id_type to TSG
* - set id_type to Channel
* - set Channel Id to Invalid
* - set Channel Id to a channel without TSG
* - set Channel Id to a channel with a valid TSG
* - set id_type to Invalid
* - set Channel Id to a channel without TSG
* - set Channel Id to a channel with a valid TSG
* - set id_type to chid, tsgid, tsgid + 1, tsgid + 1 + random, invalid_id
* - verify that nvgpu_rc_pbdma_fault fails for invalid id_types and invalid channel ids and succeeds otherwise.
* - set chsw_status to is_chsw_load_or_switch
* - set id_type to TSG
* - set id_type to Channel
* - set Channel Id to Invalid
* - set Channel Id to a channel without TSG
* - set Channel Id to a channel with a valid TSG
* - set id_type to Invalid
* - set chsw_status to chsw_invalid
* - set Channel Id to a channel without TSG
* - set Channel Id to a channel with a valid TSG
* - set id_type to chid, tsgid, tsgid + 1, tsgid + 1 + random, invalid_id
* - verify that nvgpu_rc_pbdma_fault fails for invalid id_types and invalid channel ids and succeeds otherwise.
* - set chsw_status to chsw_invalid and verify that nvgpu_rc_pbdma_fault succeeds.
* - set chsw_status to invalid states and verify that nvgpu_rc_pbdma_fault fails.
*
* Output: Cover all branch in safety build.
* Output: Returns PASS if nvgpu_rc_pbdma_fault succeeds for valid inputs
* and fails for invalid inputs. Returns FAIL otherwise.
*/
int test_rc_pbdma_fault(struct unit_module *m, struct gk20a *g, void *args);