From 2a81cea0e091871187f533c2ae8b692afac1a31c Mon Sep 17 00:00:00 2001 From: vinodg Date: Mon, 25 Nov 2019 16:39:08 -0800 Subject: [PATCH] gpu: nvgpu: unit: setup preemption error test Add Setup set_preemption_mode error tests with test_gr_setup_preemption_mode_errors function. Update Doxygen for test_gr_setup_preemption_mode_errors. Jira NVGPU-3698 Change-Id: I21e84c9f7f2618656cb6b79b97802e182aed4516 Signed-off-by: vinodg Reviewed-on: https://git-master.nvidia.com/r/2247378 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/libnvgpu-drv_safe.export | 3 + userspace/units/gr/nvgpu-gr.c | 1 + userspace/units/gr/setup/nvgpu-gr-setup.c | 118 ++++++++++++++++++++- userspace/units/gr/setup/nvgpu-gr-setup.h | 44 +++++++- 4 files changed, 162 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/nvgpu/libnvgpu-drv_safe.export b/drivers/gpu/nvgpu/libnvgpu-drv_safe.export index 9e855f2b6..f5f4d25ce 100644 --- a/drivers/gpu/nvgpu/libnvgpu-drv_safe.export +++ b/drivers/gpu/nvgpu/libnvgpu-drv_safe.export @@ -161,6 +161,7 @@ nvgpu_gr_remove_support nvgpu_gr_prepare_sw nvgpu_gr_enable_hw nvgpu_gr_suspend +nvgpu_gr_sw_ready nvgpu_gr_falcon_get_fecs_ucode_segments nvgpu_gr_falcon_get_gpccs_ucode_segments nvgpu_gr_falcon_get_surface_desc_cpu_va @@ -201,6 +202,8 @@ nvgpu_gr_config_set_sm_info_sm_index nvgpu_gr_config_get_sm_info_sm_index nvgpu_gr_config_set_gpc_tpc_mask nvgpu_gr_config_get_gpc_tpc_mask +nvgpu_gr_obj_ctx_is_golden_image_ready +nvgpu_gr_ctx_get_tsgid nvgpu_hr_timestamp nvgpu_init_ltc_support nvgpu_ltc_get_cacheline_size diff --git a/userspace/units/gr/nvgpu-gr.c b/userspace/units/gr/nvgpu-gr.c index 987226b71..479b734e9 100644 --- a/userspace/units/gr/nvgpu-gr.c +++ b/userspace/units/gr/nvgpu-gr.c @@ -166,6 +166,7 @@ int test_gr_init_setup_ready(struct unit_module *m, } nvgpu_ref_init(&g->refcount); + nvgpu_gr_sw_ready(g, true); return UNIT_SUCCESS; } diff --git a/userspace/units/gr/setup/nvgpu-gr-setup.c b/userspace/units/gr/setup/nvgpu-gr-setup.c index 00aff00b4..85257b0d7 100644 --- a/userspace/units/gr/setup/nvgpu-gr-setup.c +++ b/userspace/units/gr/setup/nvgpu-gr-setup.c @@ -39,11 +39,13 @@ #include #include +#include #include #include "common/gr/gr_priv.h" #include "common/gr/obj_ctx_priv.h" +#include "common/gr/ctx_priv.h" #include "../nvgpu-gr.h" #include "nvgpu-gr-setup.h" @@ -84,6 +86,11 @@ static int stub_gr_falcon_ctrl_ctxsw(struct gk20a *g, u32 fecs_method, return 0; } +static int stub_gr_fifo_preempt_tsg(struct gk20a *g, struct nvgpu_tsg *tsg) +{ + return -1; +} + static int gr_test_setup_unbind_tsg(struct unit_module *m, struct gk20a *g) { int err = 0; @@ -180,17 +187,112 @@ ch_alloc_end: return (err == 0) ? UNIT_SUCCESS: UNIT_FAIL; } +struct test_gr_setup_preemption_mode { + u32 compute_mode; + u32 graphics_mode; + int result; +}; + +struct test_gr_setup_preemption_mode preemp_mode_types[] = { + [0] = { + .compute_mode = NVGPU_PREEMPTION_MODE_COMPUTE_CTA, + .graphics_mode = 0, + .result = 0, + }, + [1] = { + .compute_mode = BIT(2), + .graphics_mode = 0, + .result = -EINVAL, + }, + [2] = { + .compute_mode = NVGPU_PREEMPTION_MODE_COMPUTE_WFI, + .graphics_mode = 0, + .result = -EINVAL, + }, + [3] = { + .compute_mode = 0, + .graphics_mode = 0, + .result = 0, + }, + [4] = { + .compute_mode = 0, + .graphics_mode = BIT(1), + .result = -EINVAL, + }, +}; + +int test_gr_setup_preemption_mode_errors(struct unit_module *m, + struct gk20a *g, void *args) +{ + int err, i; + u32 class_num, tsgid; + int arry_cnt = sizeof(preemp_mode_types)/ + sizeof(struct test_gr_setup_preemption_mode); + + if (gr_setup_ch == NULL) { + unit_return_fail(m, "Failed setup for valid channel\n"); + } + + /* Various compute and grahics mode for error injection */ + for (i = 0; i < arry_cnt; i++) { + err = g->ops.gr.setup.set_preemption_mode(gr_setup_ch, + preemp_mode_types[i].graphics_mode, + preemp_mode_types[i].compute_mode); + if (err != preemp_mode_types[i].result) { + unit_return_fail(m, "Fail Preemp_mode Error Test-1\n"); + } + } + + /* disable preempt_tsg for failure */ + gr_setup_tsg->gr_ctx->compute_preempt_mode = + NVGPU_PREEMPTION_MODE_COMPUTE_WFI; + g->ops.fifo.preempt_tsg = stub_gr_fifo_preempt_tsg; + err = g->ops.gr.setup.set_preemption_mode(gr_setup_ch, 0, + NVGPU_PREEMPTION_MODE_COMPUTE_CTA); + if (err == 0) { + unit_return_fail(m, "Fail Preemp_mode Error Test-2\n"); + } + + class_num = gr_setup_ch->obj_class; + tsgid = gr_setup_ch->tsgid; + /* Unset the tsgid */ + gr_setup_ch->tsgid = NVGPU_INVALID_TSG_ID; + err = g->ops.gr.setup.set_preemption_mode(gr_setup_ch, 0, 0); + if (err == 0) { + unit_return_fail(m, "Fail Preemp_mode Error Test-2\n"); + } + + gr_setup_ch->tsgid = tsgid; + /* Unset the valid Class*/ + gr_setup_ch->obj_class = 0; + err = g->ops.gr.setup.set_preemption_mode(gr_setup_ch, 0, 0); + if (err == 0) { + unit_return_fail(m, "Fail Preemp_mode Error Test-2\n"); + } + + gr_setup_ch->obj_class = class_num; + return UNIT_SUCCESS; +} + int test_gr_setup_set_preemption_mode(struct unit_module *m, struct gk20a *g, void *args) { int err; + u32 compute_mode; + u32 graphic_mode = 0; if (gr_setup_ch == NULL) { unit_return_fail(m, "failed setup with valid channel\n"); } + g->ops.gr.init.get_default_preemption_modes(&graphic_mode, + &compute_mode); + + g->ops.gr.init.get_supported__preemption_modes(&graphic_mode, + &compute_mode); + err = g->ops.gr.setup.set_preemption_mode(gr_setup_ch, 0, - NVGPU_PREEMPTION_MODE_COMPUTE_CTA); + (compute_mode & NVGPU_PREEMPTION_MODE_COMPUTE_CTA)); if (err != 0) { unit_return_fail(m, "setup preemption_mode failed\n"); } @@ -215,6 +317,8 @@ int test_gr_setup_alloc_obj_ctx(struct unit_module *m, { u32 tsgid = getpid(); int err; + bool golden_image_status; + u32 curr_tsgid = 0; struct nvgpu_fifo *f = &g->fifo; nvgpu_posix_io_writel_reg_space(g, gr_fecs_current_ctx_r(), @@ -247,6 +351,17 @@ int test_gr_setup_alloc_obj_ctx(struct unit_module *m, unit_return_fail(m, "setup alloc ob as current_ctx\n"); } + golden_image_status = + nvgpu_gr_obj_ctx_is_golden_image_ready(g->gr->golden_image); + if (!golden_image_status) { + unit_return_fail(m, "No valid golden image created\n"); + } + + curr_tsgid = nvgpu_gr_ctx_get_tsgid(gr_setup_tsg->gr_ctx); + if (curr_tsgid != gr_setup_ch->tsgid) { + unit_return_fail(m, "Invalid tsg id\n"); + } + return UNIT_SUCCESS; } @@ -254,6 +369,7 @@ struct unit_module_test nvgpu_gr_setup_tests[] = { UNIT_TEST(gr_setup_setup, test_gr_init_setup_ready, NULL, 0), UNIT_TEST(gr_setup_alloc_obj_ctx, test_gr_setup_alloc_obj_ctx, NULL, 0), UNIT_TEST(gr_setup_set_preemption_mode, test_gr_setup_set_preemption_mode, NULL, 0), + UNIT_TEST(gr_setup_preemption_mode_errors, test_gr_setup_preemption_mode_errors, NULL, 0), UNIT_TEST(gr_setup_free_obj_ctx, test_gr_setup_free_obj_ctx, NULL, 0), UNIT_TEST(gr_setup_cleanup, test_gr_init_setup_cleanup, NULL, 0), }; diff --git a/userspace/units/gr/setup/nvgpu-gr-setup.h b/userspace/units/gr/setup/nvgpu-gr-setup.h index eb393eaa3..a0d4abd5b 100644 --- a/userspace/units/gr/setup/nvgpu-gr-setup.h +++ b/userspace/units/gr/setup/nvgpu-gr-setup.h @@ -40,6 +40,11 @@ struct unit_module; * * Test Type: Feature based. * + * Targets: #nvgpu_gr_setup_alloc_obj_ctx, + * #nvgpu_gr_obj_ctx_alloc, + * #nvgpu_gr_ctx_set_tsgid, + * #nvgpu_gr_ctx_get_tsgid. + * * Input: #test_gr_init_setup_ready must have been executed successfully. * * Steps: @@ -56,7 +61,6 @@ struct unit_module; * Output: Returns PASS if the steps above were executed successfully. FAIL * otherwise. */ - int test_gr_setup_alloc_obj_ctx(struct unit_module *m, struct gk20a *g, void *args); @@ -67,6 +71,14 @@ int test_gr_setup_alloc_obj_ctx(struct unit_module *m, * * Test Type: Feature based. * + * Targets: #nvgpu_gr_setup_set_preemption_mode, + * #nvgpu_gr_obj_ctx_set_ctxsw_preemption_mode, + * #nvgpu_gr_obj_ctx_update_ctxsw_preemption_mode, + * #nvgpu_gr_ctx_patch_write_begin, + * #nvgpu_gr_ctx_patch_write_end, + * gp10b_gr_init_commit_global_cb_manager, + * #nvgpu_gr_ctx_patch_write. + * * Input: #test_gr_init_setup_ready and #test_gr_setup_alloc_obj_ctx * must have been executed successfully. * @@ -76,7 +88,6 @@ int test_gr_setup_alloc_obj_ctx(struct unit_module *m, * Output: Returns PASS if the steps above were executed successfully. FAIL * otherwise. */ - int test_gr_setup_set_preemption_mode(struct unit_module *m, struct gk20a *g, void *args); @@ -87,6 +98,9 @@ int test_gr_setup_set_preemption_mode(struct unit_module *m, * * Test Type: Feature based. * + * Targets: #nvgpu_gr_setup_free_subctx, + * #nvgpu_gr_setup_free_gr_ctx, + * * Input: #test_gr_init_setup_ready and #test_gr_setup_alloc_obj_ctx * must have been executed successfully. * @@ -98,10 +112,34 @@ int test_gr_setup_set_preemption_mode(struct unit_module *m, * Output: Returns PASS if the steps above were executed successfully. FAIL * otherwise. */ - int test_gr_setup_free_obj_ctx(struct unit_module *m, struct gk20a *g, void *args); +/** + * Test specification for: test_gr_setup_preemption_mode_errors. + * + * Description: Helps to verify error paths in + * g->ops.gr.setup.set_preemption_mode call. + * + * Test Type: Error injection. + * + * Targets: #nvgpu_gr_setup_set_preemption_mode, + * #nvgpu_gr_obj_ctx_set_ctxsw_preemption_mode. + * + * Input: #test_gr_init_setup_ready and #test_gr_setup_alloc_obj_ctx + * must have been executed successfully. + * + * Steps: + * - Verify various combinations of compute and graphics modes. + * - Verify the error path by failing #nvgpu_preempt_channel. + * - Verify the error path for NVGPU_INVALID_TSG_ID as ch->tsgid. + * - Verify the error path for invalid ch->obj_class. + * + * Output: Returns PASS if the steps above were executed successfully. FAIL + * otherwise. + */ +int test_gr_setup_preemption_mode_errors(struct unit_module *m, + struct gk20a *g, void *args); #endif /* UNIT_NVGPU_GR_SETUP_H */ /**