From 9f55801a15b1a210a73535c9414d72d89265bec9 Mon Sep 17 00:00:00 2001 From: Deepak Nibade Date: Mon, 29 Nov 2021 17:08:06 +0530 Subject: [PATCH] gpu: nvgpu: move local golden context memory allocation to poweorn - Separate out local golden context memory allocation from nvgpu_gr_global_ctx_init_local_golden_image() into a new function nvgpu_gr_global_ctx_alloc_local_golden_image(). - Add a new member local_golden_image_copy to struct nvgpu_gr_obj_ctx_golden_image to store copy used for context verification. - Allocate local golden context memory from nvgpu_gr_obj_ctx_init() which is called during poweron path. - Remove memory allocation from nvgpu_gr_obj_ctx_save_golden_ctx(). - Disable test test_gr_obj_ctx_error_injection since it needs rework to accomodate the new changes. - Fix below tests to allocate local golden context memory : test_gr_global_ctx_local_ctx_error_injection test_gr_setup_alloc_obj_ctx Bug 3307637 Change-Id: I2f760d524881fd328346838ea9ce0234358f8e51 Signed-off-by: Deepak Nibade Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2633713 Tested-by: mobile promotions Reviewed-by: mobile promotions --- drivers/gpu/nvgpu/common/gr/global_ctx.c | 29 ++++---- drivers/gpu/nvgpu/common/gr/obj_ctx.c | 73 +++++++++---------- drivers/gpu/nvgpu/common/gr/obj_ctx_priv.h | 8 ++ .../gpu/nvgpu/include/nvgpu/gr/global_ctx.h | 29 ++++++-- libs/dgpu/libnvgpu-drv-dgpu_safe.export | 1 + libs/igpu/libnvgpu-drv-igpu_safe.export | 1 + userspace/required_tests.ini | 2 +- .../units/gr/global_ctx/nvgpu-gr-global-ctx.c | 34 +++------ .../units/gr/global_ctx/nvgpu-gr-global-ctx.h | 3 +- userspace/units/gr/obj_ctx/nvgpu-gr-obj-ctx.c | 38 +--------- userspace/units/gr/setup/nvgpu-gr-setup.c | 11 +++ 11 files changed, 102 insertions(+), 127 deletions(-) diff --git a/drivers/gpu/nvgpu/common/gr/global_ctx.c b/drivers/gpu/nvgpu/common/gr/global_ctx.c index 0dda4b557..6963a2f59 100644 --- a/drivers/gpu/nvgpu/common/gr/global_ctx.c +++ b/drivers/gpu/nvgpu/common/gr/global_ctx.c @@ -363,36 +363,35 @@ bool nvgpu_gr_global_ctx_buffer_ready( return false; } -struct nvgpu_gr_global_ctx_local_golden_image * -nvgpu_gr_global_ctx_init_local_golden_image(struct gk20a *g, - struct nvgpu_mem *source_mem, size_t size) +int nvgpu_gr_global_ctx_alloc_local_golden_image(struct gk20a *g, + struct nvgpu_gr_global_ctx_local_golden_image **img, + size_t size) { struct nvgpu_gr_global_ctx_local_golden_image *local_golden_image; -#ifdef NVGPU_UNITTEST_FAULT_INJECTION_ENABLEMENT - if (nvgpu_posix_fault_injection_handle_call( - nvgpu_local_golden_image_get_fault_injection())) { - return NULL; - } -#endif - local_golden_image = nvgpu_kzalloc(g, sizeof(*local_golden_image)); if (local_golden_image == NULL) { - return NULL; + return -ENOMEM; } local_golden_image->context = nvgpu_vzalloc(g, size); if (local_golden_image->context == NULL) { nvgpu_kfree(g, local_golden_image); - return NULL; + return -ENOMEM; } local_golden_image->size = size; - nvgpu_mem_rd_n(g, source_mem, 0, local_golden_image->context, - nvgpu_safe_cast_u64_to_u32(size)); + *img = local_golden_image; + return 0; +} - return local_golden_image; +void nvgpu_gr_global_ctx_init_local_golden_image(struct gk20a *g, + struct nvgpu_gr_global_ctx_local_golden_image *local_golden_image, + struct nvgpu_mem *source_mem, size_t size) +{ + nvgpu_mem_rd_n(g, source_mem, 0, local_golden_image->context, + nvgpu_safe_cast_u64_to_u32(local_golden_image->size)); } #ifdef CONFIG_NVGPU_GR_GOLDEN_CTX_VERIFICATION diff --git a/drivers/gpu/nvgpu/common/gr/obj_ctx.c b/drivers/gpu/nvgpu/common/gr/obj_ctx.c index a0d530b4f..76dda1636 100644 --- a/drivers/gpu/nvgpu/common/gr/obj_ctx.c +++ b/drivers/gpu/nvgpu/common/gr/obj_ctx.c @@ -629,14 +629,11 @@ static int nvgpu_gr_obj_ctx_save_golden_ctx(struct gk20a *g, struct nvgpu_mem *gr_mem; u64 size; u32 data; -#ifdef CONFIG_NVGPU_GR_GOLDEN_CTX_VERIFICATION - struct nvgpu_gr_global_ctx_local_golden_image *local_golden_image_temp = - NULL; -#endif nvgpu_log(g, gpu_dbg_gr, " "); gr_mem = nvgpu_gr_ctx_get_ctx_mem(gr_ctx); + size = nvgpu_gr_obj_ctx_get_golden_image_size(golden_image); #ifdef CONFIG_NVGPU_GR_GOLDEN_CTX_VERIFICATION /* @@ -644,15 +641,8 @@ static int nvgpu_gr_obj_ctx_save_golden_ctx(struct gk20a *g, * before second golden context save. This temporary copy is * saved in local_golden_image_temp. */ - - size = nvgpu_gr_obj_ctx_get_golden_image_size(golden_image); - - local_golden_image_temp = - nvgpu_gr_global_ctx_init_local_golden_image(g, gr_mem, size); - if (local_golden_image_temp == NULL) { - err = -ENOMEM; - goto clean_up; - } + nvgpu_gr_global_ctx_init_local_golden_image(g, + golden_image->local_golden_image_copy, gr_mem, size); #endif data = g->ops.gr.falcon.get_fecs_current_ctx_data(g, inst_block); @@ -662,23 +652,13 @@ static int nvgpu_gr_obj_ctx_save_golden_ctx(struct gk20a *g, goto clean_up; } - size = nvgpu_gr_obj_ctx_get_golden_image_size(golden_image); - - golden_image->local_golden_image = - nvgpu_gr_global_ctx_init_local_golden_image(g, gr_mem, size); - if (golden_image->local_golden_image == NULL) { - err = -ENOMEM; - goto clean_up; - } + nvgpu_gr_global_ctx_init_local_golden_image(g, + golden_image->local_golden_image, gr_mem, size); #ifdef CONFIG_NVGPU_GR_GOLDEN_CTX_VERIFICATION /* Before second golden context save restore to before known state */ nvgpu_gr_global_ctx_load_local_golden_image(g, - local_golden_image_temp, gr_mem); - /* free local copy now */ - nvgpu_gr_global_ctx_deinit_local_golden_image(g, - local_golden_image_temp); - local_golden_image_temp = NULL; + golden_image->local_golden_image_copy, gr_mem); /* Initiate second golden context save */ data = g->ops.gr.falcon.get_fecs_current_ctx_data(g, inst_block); @@ -689,32 +669,26 @@ static int nvgpu_gr_obj_ctx_save_golden_ctx(struct gk20a *g, } /* Copy the data to local buffer */ - local_golden_image_temp = - nvgpu_gr_global_ctx_init_local_golden_image(g, gr_mem, size); - if (local_golden_image_temp == NULL) { - err = -ENOMEM; - goto clean_up; - } + nvgpu_gr_global_ctx_init_local_golden_image(g, + golden_image->local_golden_image_copy, gr_mem, size); /* Compare two golden context images */ if (!nvgpu_gr_global_ctx_compare_golden_images(g, nvgpu_mem_is_sysmem(gr_mem), golden_image->local_golden_image, - local_golden_image_temp, + golden_image->local_golden_image_copy, size)) { nvgpu_err(g, "golden context mismatch"); err = -ENOMEM; } + + /* free temporary copy now */ + nvgpu_gr_global_ctx_deinit_local_golden_image(g, + golden_image->local_golden_image_copy); + golden_image->local_golden_image_copy = NULL; #endif clean_up: -#ifdef CONFIG_NVGPU_GR_GOLDEN_CTX_VERIFICATION - if (local_golden_image_temp != NULL) { - nvgpu_gr_global_ctx_deinit_local_golden_image(g, - local_golden_image_temp); - } -#endif - if (err == 0) { nvgpu_log(g, gpu_dbg_gr, "golden image saved with size = %llu", size); } @@ -961,6 +935,7 @@ int nvgpu_gr_obj_ctx_init(struct gk20a *g, struct nvgpu_gr_obj_ctx_golden_image **gr_golden_image, u32 size) { struct nvgpu_gr_obj_ctx_golden_image *golden_image; + int err; nvgpu_log(g, gpu_dbg_gr, "size = %u", size); @@ -973,6 +948,24 @@ int nvgpu_gr_obj_ctx_init(struct gk20a *g, nvgpu_mutex_init(&golden_image->ctx_mutex); + err = nvgpu_gr_global_ctx_alloc_local_golden_image(g, + &golden_image->local_golden_image, size); + if (err != 0) { + nvgpu_kfree(g, golden_image); + return err; + } + +#ifdef CONFIG_NVGPU_GR_GOLDEN_CTX_VERIFICATION + err = nvgpu_gr_global_ctx_alloc_local_golden_image(g, + &golden_image->local_golden_image_copy, size); + if (err != 0) { + nvgpu_gr_global_ctx_deinit_local_golden_image(g, + golden_image->local_golden_image); + nvgpu_kfree(g, golden_image); + return err; + } +#endif + *gr_golden_image = golden_image; return 0; diff --git a/drivers/gpu/nvgpu/common/gr/obj_ctx_priv.h b/drivers/gpu/nvgpu/common/gr/obj_ctx_priv.h index 52ae6d4e1..06767c0e9 100644 --- a/drivers/gpu/nvgpu/common/gr/obj_ctx_priv.h +++ b/drivers/gpu/nvgpu/common/gr/obj_ctx_priv.h @@ -53,6 +53,14 @@ struct nvgpu_gr_obj_ctx_golden_image { * Pointer to local Golden context image struct. */ struct nvgpu_gr_global_ctx_local_golden_image *local_golden_image; + +#ifdef CONFIG_NVGPU_GR_GOLDEN_CTX_VERIFICATION + /** + * Pointer to local Golden context image struct used for Golden + * context verification. + */ + struct nvgpu_gr_global_ctx_local_golden_image *local_golden_image_copy; +#endif }; #endif /* NVGPU_GR_OBJ_CTX_PRIV_H */ diff --git a/drivers/gpu/nvgpu/include/nvgpu/gr/global_ctx.h b/drivers/gpu/nvgpu/include/nvgpu/gr/global_ctx.h index 1d47d0a16..196fe2c02 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gr/global_ctx.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gr/global_ctx.h @@ -240,15 +240,30 @@ bool nvgpu_gr_global_ctx_buffer_ready( u32 index); /** - * @brief Initialize local golden context image. + * @brief Allocate memory for local golden context image. * - * @param g [in] Pointer to GPU driver struct. - * @param source_mem [in] Pointer to source memory. - * @param size [in] Size of local golden context image. + * @param g [in] Pointer to GPU driver struct. + * @param local_golden_image [in] Pointer to local golden context image struct. + * @param size [in] Size of local golden context image. * * This function allocates memory to store local golden context image * and also for #nvgpu_gr_global_ctx_local_golden_image structure. * + * @return 0 in case of success, < 0 in case of failure. + * @retval -ENOMEM if local golden image memory allocation fails. + */ +int nvgpu_gr_global_ctx_alloc_local_golden_image(struct gk20a *g, + struct nvgpu_gr_global_ctx_local_golden_image **img, + size_t size); + +/** + * @brief Initialize local golden context image. + * + * @param g [in] Pointer to GPU driver struct. + * @param local_golden_image [in] Pointer to local golden image to be initialized. + * @param source_mem [in] Pointer to source memory. + * @param size [in] Size of local golden context image. + * * This function will then initialize local golden context image by * copying contents of #source_mem into newly created image. * @@ -256,11 +271,9 @@ bool nvgpu_gr_global_ctx_buffer_ready( * ever graphics context image for any channel. Subsequent graphics * context allocations will re-use this local golden image to * initialize. See #nvgpu_gr_global_ctx_load_local_golden_image. - * - * @return Pointer to local golden context image struct. */ -struct nvgpu_gr_global_ctx_local_golden_image * -nvgpu_gr_global_ctx_init_local_golden_image(struct gk20a *g, +void nvgpu_gr_global_ctx_init_local_golden_image(struct gk20a *g, + struct nvgpu_gr_global_ctx_local_golden_image *local_golden_image, struct nvgpu_mem *source_mem, size_t size); /** diff --git a/libs/dgpu/libnvgpu-drv-dgpu_safe.export b/libs/dgpu/libnvgpu-drv-dgpu_safe.export index b197aba4f..f74a9712a 100644 --- a/libs/dgpu/libnvgpu-drv-dgpu_safe.export +++ b/libs/dgpu/libnvgpu-drv-dgpu_safe.export @@ -470,6 +470,7 @@ nvgpu_gr_falcon_remove_support nvgpu_gr_free nvgpu_gr_fs_state_init nvgpu_gr_get_config_ptr +nvgpu_gr_global_ctx_alloc_local_golden_image nvgpu_gr_global_ctx_buffer_alloc nvgpu_gr_global_ctx_buffer_free nvgpu_gr_global_ctx_buffer_get_mem diff --git a/libs/igpu/libnvgpu-drv-igpu_safe.export b/libs/igpu/libnvgpu-drv-igpu_safe.export index 9d34ed797..b05f2a888 100644 --- a/libs/igpu/libnvgpu-drv-igpu_safe.export +++ b/libs/igpu/libnvgpu-drv-igpu_safe.export @@ -486,6 +486,7 @@ nvgpu_gr_falcon_remove_support nvgpu_gr_free nvgpu_gr_fs_state_init nvgpu_gr_get_config_ptr +nvgpu_gr_global_ctx_alloc_local_golden_image nvgpu_gr_global_ctx_buffer_alloc nvgpu_gr_global_ctx_buffer_free nvgpu_gr_global_ctx_buffer_get_mem diff --git a/userspace/required_tests.ini b/userspace/required_tests.ini index d9fb21aaa..2d0ac1752 100644 --- a/userspace/required_tests.ini +++ b/userspace/required_tests.ini @@ -658,7 +658,7 @@ test_gr_intr_without_channel.gr_intr_channel_free=0 [nvgpu_gr_obj_ctx] test_gr_init_setup_cleanup.gr_obj_ctx_cleanup=0 test_gr_init_setup_ready.gr_obj_ctx_setup=0 -test_gr_obj_ctx_error_injection.gr_obj_ctx_alloc_errors=0 +test_gr_obj_ctx_error_injection.gr_obj_ctx_alloc_errors=2 [nvgpu_gr_setup] test_gr_init_setup_cleanup.gr_setup_cleanup=0 diff --git a/userspace/units/gr/global_ctx/nvgpu-gr-global-ctx.c b/userspace/units/gr/global_ctx/nvgpu-gr-global-ctx.c index 757cd1293..eea5e03d3 100644 --- a/userspace/units/gr/global_ctx/nvgpu-gr-global-ctx.c +++ b/userspace/units/gr/global_ctx/nvgpu-gr-global-ctx.c @@ -204,8 +204,6 @@ int test_gr_global_ctx_local_ctx_error_injection(struct unit_module *m, struct nvgpu_mem mem; struct nvgpu_gr_global_ctx_local_golden_image *local_golden_image; struct nvgpu_gr_global_ctx_local_golden_image *local_golden_image_bk; - struct nvgpu_posix_fault_inj *kmem_fi = - nvgpu_kmem_get_fault_injection(); /* Allocate dummy memory */ err = nvgpu_dma_alloc(g, DUMMY_SIZE, &mem); @@ -213,41 +211,27 @@ int test_gr_global_ctx_local_ctx_error_injection(struct unit_module *m, unit_return_fail(m, "failed to allocate dummy memory"); } - /* Fail allocation of nvgpu_gr_global_ctx_local_golden_image struct */ - nvgpu_posix_enable_fault_injection(kmem_fi, true, 0); - local_golden_image = nvgpu_gr_global_ctx_init_local_golden_image(g, - &mem, DUMMY_SIZE); - if (local_golden_image != NULL) { - unit_return_fail(m, "unexpected success"); - } - - /* Fail allocation of local_golden_image->context */ - nvgpu_posix_enable_fault_injection(kmem_fi, true, 1); - local_golden_image = nvgpu_gr_global_ctx_init_local_golden_image(g, - &mem, DUMMY_SIZE); - if (local_golden_image != NULL) { - unit_return_fail(m, "unexpected success"); - } - /* Successful allocation of local golden context */ - nvgpu_posix_enable_fault_injection(kmem_fi, false, 0); - local_golden_image = nvgpu_gr_global_ctx_init_local_golden_image(g, - &mem, DUMMY_SIZE); - if (local_golden_image == NULL) { + err = nvgpu_gr_global_ctx_alloc_local_golden_image(g, &local_golden_image, DUMMY_SIZE); + if (err != 0) { unit_return_fail(m, "failed to initialize local golden image"); } + nvgpu_gr_global_ctx_init_local_golden_image(g, local_golden_image, &mem, DUMMY_SIZE); + /* Trigger flush error during context load */ g->ops.mm.cache.l2_flush = dummy_l2_flush; nvgpu_gr_global_ctx_load_local_golden_image(g, local_golden_image, &mem); /* Allocate dummy local golden context image */ - local_golden_image_bk = nvgpu_gr_global_ctx_init_local_golden_image(g, - &mem, DUMMY_SIZE); - if (local_golden_image_bk == NULL) { + err = nvgpu_gr_global_ctx_alloc_local_golden_image(g, &local_golden_image_bk, DUMMY_SIZE); + if (err != 0) { unit_return_fail(m, "failed to initialize local golden image"); } + + nvgpu_gr_global_ctx_init_local_golden_image(g, local_golden_image_bk, &mem, DUMMY_SIZE); + #ifdef CONFIG_NVGPU_GR_GOLDEN_CTX_VERIFICATION bool valid; diff --git a/userspace/units/gr/global_ctx/nvgpu-gr-global-ctx.h b/userspace/units/gr/global_ctx/nvgpu-gr-global-ctx.h index 934bee4a8..0d8c21e6e 100644 --- a/userspace/units/gr/global_ctx/nvgpu-gr-global-ctx.h +++ b/userspace/units/gr/global_ctx/nvgpu-gr-global-ctx.h @@ -81,7 +81,8 @@ int test_gr_global_ctx_alloc_error_injection(struct unit_module *m, * * Test Type: Feature, Error guessing * - * Targets: nvgpu_gr_global_ctx_init_local_golden_image, + * Targets: nvgpu_gr_global_ctx_alloc_local_golden_image, + * nvgpu_gr_global_ctx_init_local_golden_image, * nvgpu_gr_global_ctx_load_local_golden_image, * nvgpu_gr_global_ctx_compare_golden_images, * nvgpu_gr_global_ctx_deinit_local_golden_image diff --git a/userspace/units/gr/obj_ctx/nvgpu-gr-obj-ctx.c b/userspace/units/gr/obj_ctx/nvgpu-gr-obj-ctx.c index 8163209f8..90f286dbc 100644 --- a/userspace/units/gr/obj_ctx/nvgpu-gr-obj-ctx.c +++ b/userspace/units/gr/obj_ctx/nvgpu-gr-obj-ctx.c @@ -314,42 +314,6 @@ int test_gr_obj_ctx_error_injection(struct unit_module *m, unit_return_fail(m, "unexpected success"); } - /* - * Fail first local golden image allocation in - * nvgpu_gr_global_ctx_init_local_golden_image() - */ - nvgpu_posix_enable_fault_injection(local_golden_image_fi, true, 0); - err = nvgpu_gr_obj_ctx_alloc(g, golden_image, global_desc, desc, - config, gr_ctx, subctx, vm, &inst_block, - VOLTA_COMPUTE_A, 0, false, false); - if (err == 0) { - unit_return_fail(m, "unexpected success"); - } - - /* - * Fail second local golden image allocation in - * nvgpu_gr_global_ctx_init_local_golden_image() - */ - nvgpu_posix_enable_fault_injection(local_golden_image_fi, true, 1); - err = nvgpu_gr_obj_ctx_alloc(g, golden_image, global_desc, desc, - config, gr_ctx, subctx, vm, &inst_block, - VOLTA_COMPUTE_A, 0, false, false); - if (err == 0) { - unit_return_fail(m, "unexpected success"); - } - - /* - * Fail third local golden image allocation in - * nvgpu_gr_global_ctx_init_local_golden_image() - */ - nvgpu_posix_enable_fault_injection(local_golden_image_fi, true, 2); - err = nvgpu_gr_obj_ctx_alloc(g, golden_image, global_desc, desc, - config, gr_ctx, subctx, vm, &inst_block, - VOLTA_COMPUTE_A, 0, false, false); - if (err == 0) { - unit_return_fail(m, "unexpected success"); - } - /* Disable error injection */ nvgpu_posix_enable_fault_injection(local_golden_image_fi, false, 0); @@ -434,7 +398,7 @@ int test_gr_obj_ctx_error_injection(struct unit_module *m, struct unit_module_test nvgpu_gr_obj_ctx_tests[] = { UNIT_TEST(gr_obj_ctx_setup, test_gr_init_setup_ready, NULL, 0), - UNIT_TEST(gr_obj_ctx_alloc_errors, test_gr_obj_ctx_error_injection, NULL, 0), + UNIT_TEST(gr_obj_ctx_alloc_errors, test_gr_obj_ctx_error_injection, NULL, 2), UNIT_TEST(gr_obj_ctx_cleanup, test_gr_init_setup_cleanup, NULL, 0), }; diff --git a/userspace/units/gr/setup/nvgpu-gr-setup.c b/userspace/units/gr/setup/nvgpu-gr-setup.c index 1f0f80ff2..2936892bf 100644 --- a/userspace/units/gr/setup/nvgpu-gr-setup.c +++ b/userspace/units/gr/setup/nvgpu-gr-setup.c @@ -720,6 +720,17 @@ int test_gr_setup_alloc_obj_ctx(struct unit_module *m, /* Set a default size for golden image */ g->gr->golden_image->size = 0x800; + err = nvgpu_gr_global_ctx_alloc_local_golden_image(g, + &g->gr->golden_image->local_golden_image, 0x800); + if (err != 0) { + unit_return_fail(m, "local golden image alloc failed\n"); + } + err = nvgpu_gr_global_ctx_alloc_local_golden_image(g, + &g->gr->golden_image->local_golden_image_copy, 0x800); + if (err != 0) { + unit_return_fail(m, "local golden image copy alloc failed\n"); + } + /* Test with channel and tsg */ err = gr_test_setup_allocate_ch_tsg(m, g); if (err != 0) {