From 726d2a8d4a7e2e9e03fde76978089eab69596449 Mon Sep 17 00:00:00 2001 From: Thomas Fleury Date: Fri, 17 Jan 2020 12:32:35 -0500 Subject: [PATCH] gpu: nvgpu: unit: improve coverage for quiesce Add more cases for branch coverage of the following functions: - nvgpu_sw_quiesce - nvgpu_sw_quiesce_init_support - nvgpu_sw_quiesce_bug_cb Add SWUTS steps for test_quiesce. Jira NVGPU-4905 Change-Id: Ib14c03f30bb7556123faf4d49abf2b307b82014b Signed-off-by: Thomas Fleury Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2280610 Reviewed-by: svc-mobile-coverity Reviewed-by: svc-mobile-cert Reviewed-by: Alex Waterman Reviewed-by: Philip Elcan Reviewed-by: Vijayakumar Subbu Reviewed-by: mobile promotions Tested-by: mobile promotions GVS: Gerrit_Virtual_Submit --- userspace/units/init/nvgpu-init.c | 44 +++++++++++++++++++++++++++++-- userspace/units/init/nvgpu-init.h | 22 ++++++++++++++-- 2 files changed, 62 insertions(+), 4 deletions(-) diff --git a/userspace/units/init/nvgpu-init.c b/userspace/units/init/nvgpu-init.c index a86709815..5377f3adc 100644 --- a/userspace/units/init/nvgpu-init.c +++ b/userspace/units/init/nvgpu-init.c @@ -740,8 +740,11 @@ int test_quiesce(struct unit_module *m, struct gk20a *g, void *args) nvgpu_thread_join(&g->sw_quiesce_thread); if (!intr_masked) { - unit_err(m, "quiesce failed to mask interrupts\n"); - ret = UNIT_FAIL; + unit_return_fail(m, "quiesce failed to mask interrupts\n"); + } + + if (nvgpu_can_busy(g)) { + unit_return_fail(m, "nvgpu_can_busy() should be false\n"); } /* setup quiesce again */ @@ -767,6 +770,30 @@ int test_quiesce(struct unit_module *m, struct gk20a *g, void *args) unit_return_fail(m, "failed to re-enable quiesce\n"); } + /* setup quiesce again */ + nvgpu_sw_quiesce_remove_support(g); + set_poweron_funcs_success(g); + err = nvgpu_finalize_poweron(g); + if (err != 0) { + unit_return_fail(m, "failed to re-enable quiesce\n"); + } + + /* make sure we simulate interrupts enabled */ + intr_masked = false; + + err = EXPECT_BUG(BUG()); + if (err == 0) { + unit_return_fail(m, "BUG() was expected\n"); + } + + /* wait for quiesce thread to complete */ + nvgpu_thread_join(&g->sw_quiesce_thread); + + if (!intr_masked) { + unit_err(m, "BUG() was expected to quiesce\n"); + ret = UNIT_FAIL; + } + /* branch coverage for error states when requesting quiesce */ g->is_virtual = true; nvgpu_sw_quiesce(g); @@ -783,6 +810,19 @@ int test_quiesce(struct unit_module *m, struct gk20a *g, void *args) nvgpu_set_enabled(g, NVGPU_DISABLE_SW_QUIESCE, false); /* Note: quiesce should still be configured */ + /* coverage for quiesce already requested */ + g->sw_quiesce_pending = true; + nvgpu_sw_quiesce(g); + g->sw_quiesce_pending = false; + + /* coverage for quiesce not initialized */ + g->sw_quiesce_init_done = false; + nvgpu_sw_quiesce(g); + g->sw_quiesce_init_done = true; + if (g->sw_quiesce_pending) { + unit_return_fail(m, "unexpected quiesce pending\n"); + } + /* coverage for device powered off when quiesce requested */ nvgpu_set_power_state(g, NVGPU_STATE_POWERED_OFF); nvgpu_sw_quiesce(g); diff --git a/userspace/units/init/nvgpu-init.h b/userspace/units/init/nvgpu-init.h index 6be4be02d..c9cc2fc96 100644 --- a/userspace/units/init/nvgpu-init.h +++ b/userspace/units/init/nvgpu-init.h @@ -307,15 +307,33 @@ int test_poweroff(struct unit_module *m, struct gk20a *g, void *args); * Test Type: Feature * * Targets: nvgpu_sw_quiesce_init_support, nvgpu_sw_quiesce_remove_support, - * nvgpu_sw_quiesce_thread, nvgpu_sw_quiesce + * nvgpu_sw_quiesce_thread, nvgpu_sw_quiesce, nvgpu_sw_quiesce_bug_cb * * Input: * - test_setup_env() must be called before. * * Steps: + * - Use stub for g->ops.mc.intr_mask, g->ops.runlist.write_state and + * g->ops.fifo.preempt_runlists_for_rc. + * - Call nvgpu_sw_quiesce, wait for SW quiesce threads to complete, + * and check that interrupts have been disabled. + * - Check SW quiesce invoked from BUG(). + * - Check cases where nvgpu_sw_quiesce does not wake up threads: + * - NVGPU_DISABLE_SW_QUIESCE is set. + * - g->sw_quiesce_pending is already true. + * - g->sw_quiesce_init_done is false. + * - Check cases where nvgpu_sw_quiesce_thread skips quiescing: + * - nvgpu_thread_should_stop is true (using fault injection). + * - g->is_virtual is true. + * - g->powered_on is false. + * - Check failure cases in nvgpu_sw_quiesce_init_support: + * - sw_quiesce_cond initialization failure (using cond fault injection). + * - sw_quiesce already initialized. + * - sw_quiesce_thread creation failure (using thread fault injection). + * - sw_quiesce_wdog creation failure (using thread fault injection). * * Output: - * - UNIT_FAIL if nvgpu_finalize_poweron() ever returns the unexpected value. + * - UNIT_FAIL if SW quiesce did not behave as expected. * - UNIT_SUCCESS otherwise */ int test_quiesce(struct unit_module *m, struct gk20a *g, void *args);