gpu: nvgpu: add BVEC test for LTC isr

Add BVEC tests for following common.ltc unit API:
gops_ltc_intr.isr

Add unit test for boundary value check for ltc parameter of
the LTC isr.

JIRA NVGPU-6398

Change-Id: I0e075a3244d969d11faa4fd99e7e364218da6e30
Signed-off-by: Sagar Kamble <skamble@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2549802
(cherry picked from commit 3133a7173b0853a699e4ebf2fc50e866e3ac6211)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2623636
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com>
Reviewed-by: Shashank Singh <shashsingh@nvidia.com>
Reviewed-by: Vaibhav Kachore <vkachore@nvidia.com>
GVS: Gerrit_Virtual_Submit
This commit is contained in:
Sagar Kamble
2021-06-24 22:46:22 +05:30
committed by mobile promotions
parent 04587333ca
commit 4b73eb8a43
12 changed files with 155 additions and 17 deletions

View File

@@ -30,7 +30,7 @@
struct gk20a;
void ga10b_ltc_intr_configure(struct gk20a *g);
void ga10b_ltc_intr_isr(struct gk20a *g, u32 ltc);
int ga10b_ltc_intr_isr(struct gk20a *g, u32 ltc);
void ga10b_ltc_intr3_configure_extra(struct gk20a *g, u32 *reg);
void ga10b_ltc_intr3_interrupts(struct gk20a *g, u32 ltc, u32 slice,
u32 ltc_intr3);

View File

@@ -1078,13 +1078,19 @@ void ga10b_ltc_intr_handle_lts_intr(struct gk20a *g, u32 ltc, u32 slice)
reg_value);
}
void ga10b_ltc_intr_isr(struct gk20a *g, u32 ltc)
int ga10b_ltc_intr_isr(struct gk20a *g, u32 ltc)
{
u32 slice;
if (ltc >= nvgpu_ltc_get_ltc_count(g)) {
return -ENODEV;
}
for (slice = 0U; slice < g->ltc->slices_per_ltc; slice++) {
ga10b_ltc_intr_handle_lts_intr(g, ltc, slice);
ga10b_ltc_intr_handle_lts_intr2(g, ltc, slice);
ga10b_ltc_intr_handle_lts_intr3(g, ltc, slice);
}
return 0;
}

View File

@@ -1,7 +1,7 @@
/*
* GM20B L2 INTR
*
* Copyright (c) 2014-2020 NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2014-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"),
@@ -61,12 +61,18 @@ static void gm20b_ltc_intr_handle_lts_interrupts(struct gk20a *g,
nvgpu_safe_mult_u32(lts_stride, slice))), ltc_intr);
}
void gm20b_ltc_intr_isr(struct gk20a *g, u32 ltc)
int gm20b_ltc_intr_isr(struct gk20a *g, u32 ltc)
{
u32 slice;
if (ltc >= nvgpu_ltc_get_ltc_count(g)) {
return -ENODEV;
}
for (slice = 0U; slice < g->ltc->slices_per_ltc; slice =
nvgpu_safe_add_u32(slice, 1U)) {
gm20b_ltc_intr_handle_lts_interrupts(g, ltc, slice);
}
return 0;
}

View File

@@ -1,7 +1,7 @@
/*
* GM20B L2 INTR
*
* Copyright (c) 2014-2019, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2014-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"),
@@ -30,6 +30,6 @@
struct gk20a;
void gm20b_ltc_intr_configure(struct gk20a *g);
void gm20b_ltc_intr_isr(struct gk20a *g, u32 ltc);
int gm20b_ltc_intr_isr(struct gk20a *g, u32 ltc);
#endif

View File

@@ -1,7 +1,7 @@
/*
* GP10B L2 INTR
*
* Copyright (c) 2014-2019, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2014-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"),
@@ -33,14 +33,20 @@
#include "ltc_intr_gp10b.h"
#include "ltc_intr_gm20b.h"
void gp10b_ltc_intr_isr(struct gk20a *g, u32 ltc)
int gp10b_ltc_intr_isr(struct gk20a *g, u32 ltc)
{
u32 slice;
if (ltc >= nvgpu_ltc_get_ltc_count(g)) {
return -ENODEV;
}
for (slice = 0U; slice < g->ltc->slices_per_ltc; slice =
nvgpu_safe_add_u32(slice, 1U)) {
gp10b_ltc_intr_handle_lts_interrupts(g, ltc, slice);
}
return 0;
}
void gp10b_ltc_intr_configure(struct gk20a *g)

View File

@@ -1,7 +1,7 @@
/*
* GP10B L2 INTR
*
* Copyright (c) 2014-2019, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2014-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"),
@@ -32,7 +32,7 @@ struct gk20a;
void gp10b_ltc_intr_handle_lts_interrupts(struct gk20a *g, u32 ltc, u32 slice);
#ifdef CONFIG_NVGPU_FALCON_NON_FUSA
void gp10b_ltc_intr_configure(struct gk20a *g);
void gp10b_ltc_intr_isr(struct gk20a *g, u32 ltc);
int gp10b_ltc_intr_isr(struct gk20a *g, u32 ltc);
#endif
#endif

View File

@@ -1,7 +1,7 @@
/*
* GV11B L2 INTR
*
* Copyright (c) 2016-2021, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2016-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"),
@@ -30,7 +30,7 @@
struct gk20a;
void gv11b_ltc_intr_configure(struct gk20a *g);
void gv11b_ltc_intr_isr(struct gk20a *g, u32 ltc);
int gv11b_ltc_intr_isr(struct gk20a *g, u32 ltc);
#ifdef CONFIG_NVGPU_NON_FUSA
void gv11b_ltc_intr_en_illegal_compstat(struct gk20a *g, bool enable);
#endif

View File

@@ -341,11 +341,17 @@ static void gv11b_ltc_intr_handle_lts_interrupts(struct gk20a *g,
gv11b_ltc_intr_handle_ecc_sec_ded_interrupts(g, ltc, slice);
}
void gv11b_ltc_intr_isr(struct gk20a *g, u32 ltc)
int gv11b_ltc_intr_isr(struct gk20a *g, u32 ltc)
{
u32 slice;
if (ltc >= nvgpu_ltc_get_ltc_count(g)) {
return -ENODEV;
}
for (slice = 0U; slice < g->ltc->slices_per_ltc; slice++) {
gv11b_ltc_intr_handle_lts_interrupts(g, ltc, slice);
}
return 0;
}

View File

@@ -196,7 +196,7 @@ struct gops_ltc_intr {
* @return 0 in case of success, < 0 in case of failure.
* @retval -ENODEV if invalid LTC number specified.
*/
void (*isr)(struct gk20a *g, u32 ltc);
int (*isr)(struct gk20a *g, u32 ltc);
/** @cond DOXYGEN_SHOULD_SKIP_THIS */
void (*configure)(struct gk20a *g);

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"),
@@ -609,6 +609,80 @@ done:
return err;
}
int test_ltc_intr_bvec(struct unit_module *m, struct gk20a *g, void *args)
{
u32 ltc_stride = nvgpu_get_litter_value(g, GPU_LIT_LTC_STRIDE);
u32 invalid_ltc[] = { NUM_LTC, U32_MAX };
u32 valid_ltc[] = { 0, NUM_LTC - 1 };
int err = UNIT_SUCCESS;
u32 ecc_status;
u32 ltc_intr3;
u32 offset;
u32 i;
/* Init counter space */
nvgpu_init_list_node(&g->ecc.stats_list);
g->ltc->ltc_count = NUM_LTC;
err = NVGPU_ECC_COUNTER_INIT_PER_LTS(dstg_be_ecc_parity_count);
if (err != 0) {
unit_err(m, "failed to init dstg_be_ecc_parity_count\n");
err = UNIT_FAIL;
goto done;
}
/* Verify that isr for valid ltc (lts 0) is handled correctly. */
for (i = 0; i < ARRAY_SIZE(valid_ltc); i++) {
offset = nvgpu_safe_mult_u32(ltc_stride, valid_ltc[i]);
ltc_intr3 = nvgpu_safe_add_u32(ltc_ltc0_lts0_intr3_r(), offset);
ecc_status = nvgpu_safe_add_u32(
ltc_ltc0_lts0_l2_cache_ecc_status_r(), offset);
nvgpu_posix_io_writel_reg_space(g, nvgpu_safe_add_u32(
ltc_ltc0_lts0_l2_cache_ecc_uncorrected_err_count_r(),
offset),
ltc_ltc0_lts0_l2_cache_ecc_uncorrected_err_count_total_m());
nvgpu_posix_io_writel_reg_space(g, ltc_intr3,
ltc_ltcs_ltss_intr3_ecc_uncorrected_m());
nvgpu_posix_io_writel_reg_space(g, ecc_status,
ltc_ltc0_lts0_l2_cache_ecc_status_uncorrected_err_dstg_m());
g->ecc.ltc.dstg_be_ecc_parity_count[valid_ltc[i]][0].counter = 0;
err = g->ops.ltc.intr.isr(g, valid_ltc[i]);
if ((err != 0) ||
(g->ecc.ltc.dstg_be_ecc_parity_count[valid_ltc[i]][0].counter !=
ltc_ltc0_lts0_l2_cache_ecc_uncorrected_err_count_total_m())) {
unit_err(m, "failed to process valid corrected ltc intr %u\n", i);
err = UNIT_FAIL;
goto done;
}
}
/* Verify that isr for invalid ltc fails. */
for (i = 0; i < ARRAY_SIZE(invalid_ltc); i++) {
err = g->ops.ltc.intr.isr(g, invalid_ltc[i]);
if (err == 0) {
unit_err(m, "processed invalid corrected ltc intr %u\n", i);
err = UNIT_FAIL;
goto done;
}
}
err = UNIT_SUCCESS;
done:
for (i = 0; i < nvgpu_ltc_get_ltc_count(g); i++) {
if (g->ecc.ltc.ecc_sec_count != NULL) {
nvgpu_kfree(g, g->ecc.ltc.ecc_sec_count[i]);
}
}
return err;
}
int test_ltc_intr_configure(struct unit_module *m,
struct gk20a *g, void *args)
{
@@ -765,6 +839,7 @@ struct unit_module_test nvgpu_ltc_tests[] = {
UNIT_TEST(ltc_functionality_tests, test_ltc_functionality_tests,
NULL, 0),
UNIT_TEST(ltc_intr, test_ltc_intr, NULL, 0),
UNIT_TEST(ltc_intr_bvec, test_ltc_intr_bvec, NULL, 0),
UNIT_TEST(ltc_intr_configure, test_ltc_intr_configure, NULL, 0),
UNIT_TEST(ltc_determine_L2_size, test_determine_L2_size_bytes, NULL, 0),
#ifdef CONFIG_NVGPU_NON_FUSA

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"),
@@ -229,6 +229,43 @@ int test_ltc_remove_support(struct unit_module *m,
int test_ltc_intr(struct unit_module *m, struct gk20a *g, void *args);
/**
* Test specification for: test_ltc_intr_bvec
*
* Description: Validate ltc interrupt handler (isr) for valid and invalid LTC values.
*
* Test Type: Boundary Value
*
* Targets: gops_ltc_intr.isr, gv11b_ltc_intr_isr
*
* Input: test_ltc_init_support must have completed successfully.
*
* Equivalence classes:
* Variable: ltc
* - Valid: {0, NUM_LTC - 1}
* - Invalid: {NUM_LTC, U32_MAX}
*
* Steps:
* - Allocate ECC stat counter objects used by handler
* (dstg_be_ecc_parity_count).
* - Verify that isr for valid ltc (lts 0) is handled correctly.
* - Set the corrected counter in the ecc_uncorrected_err_count_r
* register for valid LTCs for LTS0.
* - Set the ecc_uncorrected_m in ltc_intr3 for valid LTCs.
* - Clear the dstg_be_ecc_parity_count for the valid LTC and LTS0.
* - Call the LTC isr through LTC unit gops.ltc.isr.
* - Verify that LTC isr is passing.
* - Verify that the dstg_be_ecc_parity_count is updated by the LTC isr.
* - Verify that isr for invalid ltc (lts 0) fails.
* - Call the LTC isr through LTC unit gops.ltc.isr.
* - Verify that LTC isr is failed.
*
* Output: Returns PASS if interrupt handler updates the counters correctly
* for valid LTCs and fails for invalid LTCs.
* Returns FAIL otherwise.
*/
int test_ltc_intr_bvec(struct unit_module *m, struct gk20a *g, void *args);
/*
* Test specification for: test_ltc_intr_configure
*
* Description: Validate the ltc interrupt configure API.

View File

@@ -213,9 +213,11 @@ static int mock_gr_stall_isr(struct gk20a *g)
return u.gr_isr_return;
}
static void mock_ltc_isr(struct gk20a *g, u32 ltc)
static int mock_ltc_isr(struct gk20a *g, u32 ltc)
{
u.ltc_isr = true;
return 0;
}
static void mock_pmu_isr(struct gk20a *g)