From 7918cbb4f0141d475646c2086878599a6c75e444 Mon Sep 17 00:00:00 2001 From: Nicolas Benech Date: Tue, 10 Sep 2019 12:39:57 -0400 Subject: [PATCH] gpu: nvgpu: unit: unit tests for mm.as This patch adds unit testing for the mm.as unit including: - feature tests - error injection testing - 100% line coverage and 96% branches (one missing branch that cannot be tested or removed) JIRA NVGPU-917 Change-Id: I54bdac21e56554d1d960955f1a140ab98c9f3e5e Signed-off-by: Nicolas Benech Reviewed-on: https://git-master.nvidia.com/r/2194399 Reviewed-by: mobile promotions Tested-by: mobile promotions --- Makefile.umbrella.tmk | 1 + drivers/gpu/nvgpu/libnvgpu-drv_safe.export | 5 + userspace/Makefile.sources | 1 + userspace/SWUTS.h | 1 + userspace/SWUTS.sources | 1 + userspace/units/mm/as/Makefile | 26 ++ userspace/units/mm/as/Makefile.interface.tmk | 35 +++ userspace/units/mm/as/Makefile.tmk | 35 +++ userspace/units/mm/as/as.c | 275 +++++++++++++++++++ userspace/units/mm/as/as.h | 146 ++++++++++ 10 files changed, 526 insertions(+) create mode 100644 userspace/units/mm/as/Makefile create mode 100644 userspace/units/mm/as/Makefile.interface.tmk create mode 100644 userspace/units/mm/as/Makefile.tmk create mode 100644 userspace/units/mm/as/as.c create mode 100644 userspace/units/mm/as/as.h diff --git a/Makefile.umbrella.tmk b/Makefile.umbrella.tmk index f7ef2c51f..af7ce5033 100644 --- a/Makefile.umbrella.tmk +++ b/Makefile.umbrella.tmk @@ -55,6 +55,7 @@ NV_REPOSITORY_COMPONENTS += userspace/units/mm/allocators/buddy_allocator NV_REPOSITORY_COMPONENTS += userspace/units/mm/allocators/nvgpu_allocator NV_REPOSITORY_COMPONENTS += userspace/units/mm/allocators/bitmap_allocator NV_REPOSITORY_COMPONENTS += userspace/units/mm/allocators/page_allocator +NV_REPOSITORY_COMPONENTS += userspace/units/mm/as NV_REPOSITORY_COMPONENTS += userspace/units/mm/dma NV_REPOSITORY_COMPONENTS += userspace/units/mm/gmmu/pd_cache NV_REPOSITORY_COMPONENTS += userspace/units/mm/gmmu/page_table diff --git a/drivers/gpu/nvgpu/libnvgpu-drv_safe.export b/drivers/gpu/nvgpu/libnvgpu-drv_safe.export index cd4be5f79..1437ee6e6 100644 --- a/drivers/gpu/nvgpu/libnvgpu-drv_safe.export +++ b/drivers/gpu/nvgpu/libnvgpu-drv_safe.export @@ -10,9 +10,12 @@ gv11b_fb_write_mmu_fault_buffer_size find_first_bit find_first_zero_bit find_next_bit +gk20a_as_alloc_share +gk20a_as_release_share gk20a_mm_fb_flush gk20a_ramin_alloc_size gk20a_ramin_base_shift +gk20a_vm_release_share gm20b_fb_tlb_invalidate gm20b_mm_get_big_page_sizes gm20b_ramin_set_big_page_size @@ -275,6 +278,7 @@ nvgpu_mutex_destroy nvgpu_mutex_init nvgpu_mutex_release nvgpu_mutex_tryacquire +nvgpu_nvgpu_get_fault_injection nvgpu_pd_alloc nvgpu_pd_cache_fini nvgpu_pd_cache_init @@ -379,3 +383,4 @@ nvgpu_test_bit nvgpu_test_and_clear_bit nvgpu_test_and_set_bit vm_aspace_id + diff --git a/userspace/Makefile.sources b/userspace/Makefile.sources index f81f8e0e0..f50f3cff5 100644 --- a/userspace/Makefile.sources +++ b/userspace/Makefile.sources @@ -62,6 +62,7 @@ UNITS := \ $(UNIT_SRC)/mm/allocators/nvgpu_allocator \ $(UNIT_SRC)/mm/allocators/bitmap_allocator \ $(UNIT_SRC)/mm/allocators/page_allocator \ + $(UNIT_SRC)/mm/as \ $(UNIT_SRC)/mm/dma \ $(UNIT_SRC)/mm/gmmu/pd_cache \ $(UNIT_SRC)/mm/gmmu/page_table \ diff --git a/userspace/SWUTS.h b/userspace/SWUTS.h index 91ed3a12b..f5b670817 100644 --- a/userspace/SWUTS.h +++ b/userspace/SWUTS.h @@ -39,6 +39,7 @@ * - @ref SWUTS-interface-atomic * - @ref SWUTS-mm-allocators-bitmap-allocator * - @ref SWUTS-mm-allocators-buddy-allocator + * - @ref SWUTS-mm-as * - @ref SWUTS-mm-nvgpu-mem * - @ref SWUTS-mm-nvgpu-sgt * - @ref SWUTS-mm-mm diff --git a/userspace/SWUTS.sources b/userspace/SWUTS.sources index 8bc4a797c..372805f9a 100644 --- a/userspace/SWUTS.sources +++ b/userspace/SWUTS.sources @@ -12,6 +12,7 @@ INPUT += ../../../userspace/units/init/nvgpu-init.h INPUT += ../../../userspace/units/interface/atomic/atomic.h INPUT += ../../../userspace/units/mm/allocators/bitmap_allocator/bitmap_allocator.h INPUT += ../../../userspace/units/mm/allocators/buddy_allocator/buddy_allocator.h +INPUT += ../../../userspace/units/mm/as/as.h INPUT += ../../../userspace/units/mm/nvgpu_mem/nvgpu_mem.h INPUT += ../../../userspace/units/mm/nvgpu_sgt/nvgpu_sgt.h INPUT += ../../../userspace/units/mm/mm/mm.h diff --git a/userspace/units/mm/as/Makefile b/userspace/units/mm/as/Makefile new file mode 100644 index 000000000..474a1b408 --- /dev/null +++ b/userspace/units/mm/as/Makefile @@ -0,0 +1,26 @@ +# Copyright (c) 2019, 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"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. + +.SUFFIXES: + +OBJS = as.o +MODULE = as + +include ../../Makefile.units diff --git a/userspace/units/mm/as/Makefile.interface.tmk b/userspace/units/mm/as/Makefile.interface.tmk new file mode 100644 index 000000000..bcb2a2a4e --- /dev/null +++ b/userspace/units/mm/as/Makefile.interface.tmk @@ -0,0 +1,35 @@ +################################### tell Emacs this is a -*- makefile-gmake -*- +# +# Copyright (c) 2019, 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"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# +# tmake for SW Mobile component makefile +# +############################################################################### + +NVGPU_UNIT_NAME=as + +include $(NV_COMPONENT_DIR)/../../Makefile.units.common.interface.tmk + +# Local Variables: +# indent-tabs-mode: t +# tab-width: 8 +# End: +# vi: set tabstop=8 noexpandtab: diff --git a/userspace/units/mm/as/Makefile.tmk b/userspace/units/mm/as/Makefile.tmk new file mode 100644 index 000000000..1c2726ae1 --- /dev/null +++ b/userspace/units/mm/as/Makefile.tmk @@ -0,0 +1,35 @@ +################################### tell Emacs this is a -*- makefile-gmake -*- +# +# Copyright (c) 2019, 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"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# +# tmake for SW Mobile component makefile +# +############################################################################### + +NVGPU_UNIT_NAME=as + +include $(NV_COMPONENT_DIR)/../../Makefile.units.common.tmk + +# Local Variables: +# indent-tabs-mode: t +# tab-width: 8 +# End: +# vi: set tabstop=8 noexpandtab: diff --git a/userspace/units/mm/as/as.c b/userspace/units/mm/as/as.c new file mode 100644 index 000000000..037f838de --- /dev/null +++ b/userspace/units/mm/as/as.c @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2019, 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"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include "as.h" + +#include +#include "os/posix/os_posix.h" + +#include "hal/mm/mm_gp10b.h" +#include "hal/mm/mm_gv11b.h" +#include "hal/mm/cache/flush_gk20a.h" +#include "hal/mm/cache/flush_gv11b.h" +#include "hal/mm/gmmu/gmmu_gp10b.h" +#include "hal/mm/gmmu/gmmu_gv11b.h" +#include "hal/mm/mmu_fault/mmu_fault_gv11b.h" +#include "hal/fb/fb_gm20b.h" +#include "hal/fb/fb_gv11b.h" +#include "hal/fb/fb_mmu_fault_gv11b.h" +#include "hal/fb/intr/fb_intr_gv11b.h" +#include "hal/fifo/ramin_gk20a.h" +#include "hal/fifo/ramin_gp10b.h" +#include +#include +#include +#include +#include + +/* + * Each allocated as_share gets a unique, incrementing, global_id. Use the + * following global static to track the global_id and ensure they are + * correct. + */ +static int global_id_count; + +/* Parameters to test standard cases of allocation */ +static struct test_parameters test_64k_user_managed = { + .big_page_size = SZ_64K, + .flags = NVGPU_AS_ALLOC_USERSPACE_MANAGED, + .expected_error = 0 +}; + +static struct test_parameters test_0k_user_managed = { + .big_page_size = 0, + .flags = NVGPU_AS_ALLOC_USERSPACE_MANAGED, + .expected_error = 0 +}; + +static struct test_parameters test_64k_unified_va = { + .big_page_size = SZ_64K, + .flags = NVGPU_AS_ALLOC_UNIFIED_VA, + .expected_error = 0 +}; + +static struct test_parameters test_64k_unified_va_enabled = { + .big_page_size = SZ_64K, + .flags = 0, + .expected_error = 0, + .unify_address_spaces_flag = true +}; + +static struct test_parameters test_einval_user_managed = { + .big_page_size = 1, + .flags = NVGPU_AS_ALLOC_USERSPACE_MANAGED, + .expected_error = -EINVAL +}; + +static struct test_parameters test_notp2_user_managed = { + .big_page_size = SZ_64K-1, + .flags = NVGPU_AS_ALLOC_USERSPACE_MANAGED, + .expected_error = -EINVAL +}; + +/* Parameters to test corner cases and error handling */ +static struct test_parameters test_64k_user_managed_as_fail = { + .big_page_size = SZ_64K, + .flags = 0, + .expected_error = -ENOMEM, + .special_case = SPECIAL_CASE_AS_MALLOC_FAIL +}; + +static struct test_parameters test_64k_user_managed_vm_fail = { + .big_page_size = SZ_64K, + .flags = 0, + .expected_error = -ENOMEM, + .special_case = SPECIAL_CASE_VM_INIT_FAIL +}; + +static struct test_parameters test_64k_user_managed_busy_fail_1 = { + .big_page_size = SZ_64K, + .flags = 0, + .expected_error = -ENODEV, + .special_case = SPECIAL_CASE_GK20A_BUSY_ALLOC +}; + +static struct test_parameters test_64k_user_managed_busy_fail_2 = { + .big_page_size = SZ_64K, + .flags = 0, + .expected_error = 0, + .special_case = SPECIAL_CASE_GK20A_BUSY_RELEASE +}; + +/* + * Init the minimum set of HALs to use DMA amd GMMU features, then call the + * init_mm base function. + */ +int test_init_mm(struct unit_module *m, struct gk20a *g, void *args) +{ + int err; + struct nvgpu_os_posix *p = nvgpu_os_posix_from_gk20a(g); + + p->mm_is_iommuable = true; + + g->ops.mm.gmmu.get_default_big_page_size = + gp10b_mm_get_default_big_page_size; + g->ops.mm.gmmu.get_mmu_levels = gp10b_mm_get_mmu_levels; + g->ops.mm.init_inst_block = gv11b_mm_init_inst_block; + g->ops.mm.gmmu.map = nvgpu_gmmu_map_locked; + g->ops.mm.gmmu.unmap = nvgpu_gmmu_unmap_locked; + g->ops.mm.gmmu.gpu_phys_addr = gv11b_gpu_phys_addr; + g->ops.mm.is_bar1_supported = gv11b_mm_is_bar1_supported; + g->ops.mm.cache.l2_flush = gv11b_mm_l2_flush; + g->ops.mm.cache.fb_flush = gk20a_mm_fb_flush; +#ifdef CONFIG_NVGPU_DGPU + g->ops.fb.compression_page_size = gp10b_fb_compression_page_size; +#endif + g->ops.fb.tlb_invalidate = gm20b_fb_tlb_invalidate; + g->ops.ramin.init_pdb = gp10b_ramin_init_pdb; + g->ops.ramin.alloc_size = gk20a_ramin_alloc_size; + g->ops.fb.is_fault_buf_enabled = gv11b_fb_is_fault_buf_enabled; + g->ops.fb.read_mmu_fault_buffer_size = + gv11b_fb_read_mmu_fault_buffer_size; + g->ops.fb.init_hw = gv11b_fb_init_hw; + g->ops.fb.intr.enable = gv11b_fb_intr_enable; + + err = nvgpu_init_mm_support(g); + if (err != 0) { + unit_return_fail(m, "nvgpu_init_mm_support failed err=%d\n", + err); + } + + /* + * Before ref_init calls to gk20a_as_alloc_share should immediately + * fail. + */ + err = gk20a_as_alloc_share(g, 0, 0, NULL); + if (err != -ENODEV) { + unit_return_fail(m, "gk20a_as_alloc_share did not fail as expected err=%d\n", + err); + } + + nvgpu_ref_init(&g->refcount); + + return UNIT_SUCCESS; +} + +int test_as_alloc_share(struct unit_module *m, struct gk20a *g, void *args) +{ + struct gk20a_as_share *out; + int err; + struct nvgpu_posix_fault_inj *kmem_fi = + nvgpu_kmem_get_fault_injection(); + struct nvgpu_posix_fault_inj *nvgpu_fi = + nvgpu_nvgpu_get_fault_injection(); + struct test_parameters *params = (struct test_parameters *) args; + + global_id_count++; + + if (params->unify_address_spaces_flag) { + nvgpu_set_enabled(g, NVGPU_MM_UNIFY_ADDRESS_SPACES, true); + } + + if (params->special_case == SPECIAL_CASE_AS_MALLOC_FAIL) { + nvgpu_posix_enable_fault_injection(kmem_fi, true, 0); + } + + if (params->special_case == SPECIAL_CASE_VM_INIT_FAIL) { + nvgpu_posix_enable_fault_injection(kmem_fi, true, 1); + } + + if (params->special_case == SPECIAL_CASE_GK20A_BUSY_ALLOC) { + nvgpu_posix_enable_fault_injection(nvgpu_fi, true, 0); + } + + err = gk20a_as_alloc_share(g, params->big_page_size, + params->flags, &out); + + if (params->unify_address_spaces_flag) { + nvgpu_set_enabled(g, NVGPU_MM_UNIFY_ADDRESS_SPACES, false); + } + + if (params->special_case == SPECIAL_CASE_AS_MALLOC_FAIL) { + /* The failure will cause the global_id not to be incremented */ + global_id_count--; + } + + nvgpu_posix_enable_fault_injection(kmem_fi, false, 0); + nvgpu_posix_enable_fault_injection(nvgpu_fi, false, 0); + + if (err != params->expected_error) { + unit_return_fail(m, "gk20a_as_alloc_share failed err=%d\n", + err); + } else if (err != 0) { + /* We got the expected error, no cleanup needed */ + return UNIT_SUCCESS; + } + + if (out->id != global_id_count) { + unit_return_fail(m, "unexpected out->id (%d)\n", out->id); + } + + if (params->special_case == SPECIAL_CASE_GK20A_BUSY_RELEASE) { + nvgpu_posix_enable_fault_injection(nvgpu_fi, true, 0); + } + + err = gk20a_as_release_share(out); + + if (params->special_case == SPECIAL_CASE_GK20A_BUSY_RELEASE) { + nvgpu_posix_enable_fault_injection(nvgpu_fi, false, 0); + if (err != -ENODEV) { + unit_return_fail(m, "gk20a_as_release_share did not fail as expected err=%d\n", err); + } + } else if (err != 0) { + unit_return_fail(m, "gk20a_as_release_share failed err=%d\n", + err); + } + return UNIT_SUCCESS; +} + +struct unit_module_test nvgpu_mm_as_tests[] = { + UNIT_TEST(init, test_init_mm, NULL, 0), + UNIT_TEST(as_alloc_share_64k_um_as_fail, test_as_alloc_share, + (void *) &test_64k_user_managed_as_fail, 0), + UNIT_TEST(as_alloc_share_64k_um_vm_fail, test_as_alloc_share, + (void *) &test_64k_user_managed_vm_fail, 0), + UNIT_TEST(as_alloc_share_64k_um_busy_fail_1, test_as_alloc_share, + (void *) &test_64k_user_managed_busy_fail_1, 0), + UNIT_TEST(as_alloc_share_64k_um_busy_fail_2, test_as_alloc_share, + (void *) &test_64k_user_managed_busy_fail_2, 0), + UNIT_TEST(as_alloc_share_64k_um, test_as_alloc_share, + (void *) &test_64k_user_managed, 0), + UNIT_TEST(as_alloc_share_0k_um, test_as_alloc_share, + (void *) &test_0k_user_managed, 0), + UNIT_TEST(as_alloc_share_einval_um, test_as_alloc_share, + (void *) &test_einval_user_managed, 0), + UNIT_TEST(as_alloc_share_notp2_um, test_as_alloc_share, + (void *) &test_notp2_user_managed, 0), + UNIT_TEST(as_alloc_share_uva, test_as_alloc_share, + (void *) &test_64k_unified_va, 0), + UNIT_TEST(as_alloc_share_uva_enabled, test_as_alloc_share, + (void *) &test_64k_unified_va_enabled, 0) +}; + +UNIT_MODULE(mm.as, nvgpu_mm_as_tests, UNIT_PRIO_NVGPU_TEST); diff --git a/userspace/units/mm/as/as.h b/userspace/units/mm/as/as.h new file mode 100644 index 000000000..3ccf2a764 --- /dev/null +++ b/userspace/units/mm/as/as.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2019, 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"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef UNIT_MM_AS_H +#define UNIT_MM_AS_H + +struct gk20a; +struct unit_module; + +/** @addtogroup SWUTS-mm-as + * @{ + * + * Software Unit Test Specification for mm.as + */ + +/** Special case to cause the gk20a_as_share malloc to fail */ +#define SPECIAL_CASE_AS_MALLOC_FAIL 1 +/** Special case to cause the VM init to fail */ +#define SPECIAL_CASE_VM_INIT_FAIL 2 +/** + * Special case to cause the call to gk20a_busy to fail in gk20a_as_alloc_share + */ +#define SPECIAL_CASE_GK20A_BUSY_ALLOC 3 +/** + * Special case to cause the call to gk20a_busy to fail in + * gk20a_as_release_share + */ +#define SPECIAL_CASE_GK20A_BUSY_RELEASE 4 + +/** + * Structure to hold various parameters for the test_as_alloc_share function. + */ +struct test_parameters { + /** + * Size of big pages + */ + int big_page_size; + + /** + * Flags to use when calling gk20a_as_alloc_share. Should be one of the + * NVGPU_AS_ALLOC_* flag defined in as.h. + */ + int flags; + + /** + * The expected error code from gk20a_as_alloc_share. Typically 0 if + * the test is expecting success, or a specific error value if it is + * expecting failure. + */ + int expected_error; + + /** + * If true, enable NVGPU_MM_UNIFY_ADDRESS_SPACES before running + * gk20a_as_alloc_share (and disable it afterwards). + */ + bool unify_address_spaces_flag; + + /** + * One of the SPECIAL_CASE_* values defined above, to trigger special + * corner cases. No special case if set to 0. + */ + int special_case; +}; + +/** + * Test specification for: test_init_mm + * + * Description: Test to initialize the mm.as environment. + * + * Test Type: Other (Init) + * + * Input: None + * + * Steps: + * - Set all the minimum HAL needed for the mm.as unit. + * - Call nvgpu_init_mm_support to initialize the mm subsystem and check the + * return code to ensure success. + * - Call gk20a_as_alloc_share with zeroed parameters and ensure that it + * returns -ENODEV as expected since g->refcount has not been initialized. + * - Initialize g->refcount. + * + * Output: Returns PASS if the steps above were executed successfully. FAIL + * otherwise. + */ +int test_init_mm(struct unit_module *m, struct gk20a *g, void *args); + +/** + * Test specification for: test_as_alloc_share + * + * Description: The AS unit shall be able to allocate address spaces based on + * required flags, or report appropriate error codes in case of failures. + * + * Test Type: Feature based + * + * Input: + * - The test_init_mm must have been executed + * - The args argument points to an instance of struct test_parameters that + * contains the flags to be used, any special cases if needed and the expected + * return value from gk20a_as_alloc_share. + * + * Steps: + * - Increment a global id counter used to track the allocations made later by + * calls to gk20a_as_alloc_share. + * - Test if a special case is requested in the arguments and act accordingly + * by either: + * - enabling the NVGPU_MM_UNIFY_ADDRESS_SPACES flag + * - enabling KMEM fault injection + * - enabling nvgpu fault injection (for gk20a_busy) + * - Call the gk20a_as_alloc_share with the flags and page size set in the + * arguments. + * - If needed disable the NVGPU_MM_UNIFY_ADDRESS_SPACES. + * - Disable all fault injection mechanisms. + * - Compare the return code of gk20a_as_alloc_share with the one expected from + * the test arguments. + * - If the call to gk20a_as_alloc_share was expected to succeed, compare the + * id of the allocated as with the global id counter to ensure they match. + * - Enable nvgpu fault injection if a special case is enabled. + * - Call the gk20a_as_release_share on the allocated as and collect its + * return value. Check the return value either for success or for an expected + * failure if fault injection was enabled. + * + * Output: Returns PASS if the steps above were executed successfully. FAIL + * otherwise. + */ +int test_as_alloc_share(struct unit_module *m, struct gk20a *g, void *args); + +#endif /* UNIT_MM_AS_H */