mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +03:00
gpu: nvgpu: unit: init: add quiesce testing
Add testing of quiesce functionality to init unit test. JIRA NVGPU-3981 Change-Id: Idc64179bc8d532bea385e705d96fb4b376d15cd9 Signed-off-by: Philip Elcan <pelcan@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2247154 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
Alex Waterman
parent
234a82fc9a
commit
b8c25a5a55
@@ -171,6 +171,7 @@ void nvgpu_sw_quiesce(struct gk20a *g)
|
|||||||
g->sw_quiesce_pending = true;
|
g->sw_quiesce_pending = true;
|
||||||
|
|
||||||
nvgpu_cond_signal(&g->sw_quiesce_cond);
|
nvgpu_cond_signal(&g->sw_quiesce_cond);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|||||||
@@ -465,7 +465,9 @@ nvgpu_sw_quiesce
|
|||||||
nvgpu_sw_quiesce_remove_support
|
nvgpu_sw_quiesce_remove_support
|
||||||
nvgpu_thread_create
|
nvgpu_thread_create
|
||||||
nvgpu_thread_create_priority
|
nvgpu_thread_create_priority
|
||||||
|
nvgpu_thread_get_fault_injection
|
||||||
nvgpu_thread_is_running
|
nvgpu_thread_is_running
|
||||||
|
nvgpu_thread_join
|
||||||
nvgpu_thread_should_stop
|
nvgpu_thread_should_stop
|
||||||
nvgpu_thread_stop
|
nvgpu_thread_stop
|
||||||
nvgpu_thread_stop_graceful
|
nvgpu_thread_stop_graceful
|
||||||
|
|||||||
@@ -66,11 +66,13 @@ void nvgpu_start_gpu_idle(struct gk20a *g)
|
|||||||
|
|
||||||
int nvgpu_enable_irqs(struct gk20a *g)
|
int nvgpu_enable_irqs(struct gk20a *g)
|
||||||
{
|
{
|
||||||
|
g->mc.irqs_enabled = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nvgpu_disable_irqs(struct gk20a *g)
|
void nvgpu_disable_irqs(struct gk20a *g)
|
||||||
{
|
{
|
||||||
|
g->mc.irqs_enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nvgpu_set_power_state(struct gk20a *g, u32 state)
|
void nvgpu_set_power_state(struct gk20a *g, u32 state)
|
||||||
|
|||||||
@@ -767,6 +767,12 @@
|
|||||||
"unit": "init",
|
"unit": "init",
|
||||||
"test_level": 0
|
"test_level": 0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"test": "test_quiesce",
|
||||||
|
"case": "init_quiesce",
|
||||||
|
"unit": "init",
|
||||||
|
"test_level": 0
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"test": "test_setup_env",
|
"test": "test_setup_env",
|
||||||
"case": "init_setup_env",
|
"case": "init_setup_env",
|
||||||
|
|||||||
@@ -689,6 +689,122 @@ int test_poweroff(struct unit_module *m, struct gk20a *g, void *args)
|
|||||||
return UNIT_SUCCESS;
|
return UNIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool intr_masked;
|
||||||
|
static void mock_intr_mask(struct gk20a *g)
|
||||||
|
{
|
||||||
|
intr_masked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mock_runlist_write_state(struct gk20a *g, u32 runlist_mask,
|
||||||
|
u32 runlist_state)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mock_fifo_preempt_runlists_for_rc(struct gk20a *g, u32 runlist_mask)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_quiesce(struct unit_module *m, struct gk20a *g, void *args)
|
||||||
|
{
|
||||||
|
int ret = UNIT_SUCCESS;
|
||||||
|
struct nvgpu_posix_fault_inj *thread_fi =
|
||||||
|
nvgpu_thread_get_fault_injection();
|
||||||
|
int err;
|
||||||
|
unsigned long *save_enabled_ptr;
|
||||||
|
|
||||||
|
/* assume quiesce has been initalized already */
|
||||||
|
|
||||||
|
/* make sure we're powered on */
|
||||||
|
nvgpu_set_power_state(g, NVGPU_STATE_POWERED_ON);
|
||||||
|
|
||||||
|
/* make sure we simulate interrupts enabled */
|
||||||
|
g->mc.irqs_enabled = true;
|
||||||
|
intr_masked = false;
|
||||||
|
|
||||||
|
/* setup HAL for masking interrupts */
|
||||||
|
g->ops.mc.intr_mask = mock_intr_mask;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* quiesce will request fifo to quiesce, so make sure we don't have
|
||||||
|
* anything to do.
|
||||||
|
*/
|
||||||
|
g->fifo.num_runlists = 0;
|
||||||
|
g->fifo.num_channels = 0;
|
||||||
|
|
||||||
|
/* mock out fifo HALs called during quiesce */
|
||||||
|
g->ops.runlist.write_state = mock_runlist_write_state;
|
||||||
|
g->ops.fifo.preempt_runlists_for_rc = mock_fifo_preempt_runlists_for_rc;
|
||||||
|
|
||||||
|
nvgpu_sw_quiesce(g);
|
||||||
|
/* wait for quiesce thread to complete */
|
||||||
|
nvgpu_thread_join(&g->sw_quiesce_thread);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (g->mc.irqs_enabled || !intr_masked) {
|
||||||
|
unit_err(m, "quiesce failed to disable interrupts\n");
|
||||||
|
ret = UNIT_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* coverage for thread_should_stop() being set using fault inj */
|
||||||
|
nvgpu_posix_enable_fault_injection(thread_fi, true, 0);
|
||||||
|
nvgpu_sw_quiesce(g);
|
||||||
|
/* wait for quiesce thread to complete */
|
||||||
|
nvgpu_thread_join(&g->sw_quiesce_thread);
|
||||||
|
nvgpu_posix_enable_fault_injection(thread_fi, false, 0);
|
||||||
|
|
||||||
|
/* 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");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* branch coverage for error states when requesting quiesce */
|
||||||
|
g->is_virtual = true;
|
||||||
|
nvgpu_sw_quiesce(g);
|
||||||
|
/* don't wait for quiesce thread to complete since this is error */
|
||||||
|
g->is_virtual = false;
|
||||||
|
save_enabled_ptr = g->enabled_flags;
|
||||||
|
g->enabled_flags = NULL;
|
||||||
|
nvgpu_sw_quiesce(g);
|
||||||
|
/* don't wait for quiesce thread to complete since this is error */
|
||||||
|
g->enabled_flags = save_enabled_ptr;
|
||||||
|
nvgpu_set_enabled(g, NVGPU_DISABLE_SW_QUIESCE, true);
|
||||||
|
nvgpu_sw_quiesce(g);
|
||||||
|
/* don't wait for quiesce thread to complete since this is error */
|
||||||
|
nvgpu_set_enabled(g, NVGPU_DISABLE_SW_QUIESCE, false);
|
||||||
|
/* Note: quiesce should still be configured */
|
||||||
|
|
||||||
|
/* coverage for device powered off when quiesce requested */
|
||||||
|
nvgpu_set_power_state(g, NVGPU_STATE_POWERED_OFF);
|
||||||
|
nvgpu_sw_quiesce(g);
|
||||||
|
/* wait for quiesce thread to complete */
|
||||||
|
nvgpu_thread_join(&g->sw_quiesce_thread);
|
||||||
|
nvgpu_set_power_state(g, NVGPU_STATE_POWERED_ON);
|
||||||
|
|
||||||
|
/* coverage for thread creation failing when creating thread */
|
||||||
|
nvgpu_sw_quiesce_remove_support(g);
|
||||||
|
set_poweron_funcs_success(g);
|
||||||
|
nvgpu_posix_enable_fault_injection(thread_fi, true, 0);
|
||||||
|
err = nvgpu_finalize_poweron(g);
|
||||||
|
if (err == 0) {
|
||||||
|
unit_return_fail(m, "failed to detect thread creation error\n");
|
||||||
|
}
|
||||||
|
nvgpu_posix_enable_fault_injection(thread_fi, false, 0);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
struct unit_module_test init_tests[] = {
|
struct unit_module_test init_tests[] = {
|
||||||
UNIT_TEST(init_setup_env, test_setup_env, NULL, 0),
|
UNIT_TEST(init_setup_env, test_setup_env, NULL, 0),
|
||||||
UNIT_TEST(get_litter_value, test_get_litter_value, NULL, 0),
|
UNIT_TEST(get_litter_value, test_get_litter_value, NULL, 0),
|
||||||
@@ -699,6 +815,7 @@ struct unit_module_test init_tests[] = {
|
|||||||
UNIT_TEST(init_poweron, test_poweron, NULL, 0),
|
UNIT_TEST(init_poweron, test_poweron, NULL, 0),
|
||||||
UNIT_TEST(init_poweron_branches, test_poweron_branches, NULL, 0),
|
UNIT_TEST(init_poweron_branches, test_poweron_branches, NULL, 0),
|
||||||
UNIT_TEST(init_poweroff, test_poweroff, NULL, 0),
|
UNIT_TEST(init_poweroff, test_poweroff, NULL, 0),
|
||||||
|
UNIT_TEST(init_quiesce, test_quiesce, NULL, 0),
|
||||||
UNIT_TEST(init_free_env, test_free_env, NULL, 0),
|
UNIT_TEST(init_free_env, test_free_env, NULL, 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -298,4 +298,25 @@ int test_poweron_branches(struct unit_module *m, struct gk20a *g, void *args);
|
|||||||
*/
|
*/
|
||||||
int test_poweroff(struct unit_module *m, struct gk20a *g, void *args);
|
int test_poweroff(struct unit_module *m, struct gk20a *g, void *args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test specification for: test_quiesce
|
||||||
|
*
|
||||||
|
* Description: Test putting device in quiesce
|
||||||
|
*
|
||||||
|
* Test Type: Feature based
|
||||||
|
*
|
||||||
|
* Targets: nvgpu_sw_quiesce_init_support, nvgpu_sw_quiesce_remove_support,
|
||||||
|
* nvgpu_sw_quiesce_thread, nvgpu_sw_quiesce
|
||||||
|
*
|
||||||
|
* Input:
|
||||||
|
* - test_setup_env() must be called before.
|
||||||
|
*
|
||||||
|
* Steps:
|
||||||
|
*
|
||||||
|
* Output:
|
||||||
|
* - UNIT_FAIL if nvgpu_finalize_poweron() ever returns the unexpected value.
|
||||||
|
* - UNIT_SUCCESS otherwise
|
||||||
|
*/
|
||||||
|
int test_quiesce(struct unit_module *m, struct gk20a *g, void *args);
|
||||||
|
|
||||||
#endif /* UNIT_NVGPU_INIT_H */
|
#endif /* UNIT_NVGPU_INIT_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user