From d2d79224112845d464d17711c6d0b0edaff165e2 Mon Sep 17 00:00:00 2001 From: Thomas Fleury Date: Thu, 23 May 2019 14:11:23 -0700 Subject: [PATCH] gpu: nvgpu: unit: add channel setup_sw/cleanup_sw Add unit test for: - nvgpu_channel_setup_sw - nvgpu_channel_cleanup_sw Jira NVGPU-3480 Change-Id: Ic691b7fa17f97022fd7d4905377f9a348d8ecae8 Signed-off-by: Thomas Fleury Reviewed-on: https://git-master.nvidia.com/r/2129722 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/libnvgpu-drv_safe.export | 2 + userspace/units/fifo/channel/nvgpu-channel.c | 111 ++++++++++++++++++- userspace/units/fifo/nvgpu-fifo.c | 41 +++++++ userspace/units/fifo/nvgpu-fifo.h | 3 + 4 files changed, 155 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/nvgpu/libnvgpu-drv_safe.export b/drivers/gpu/nvgpu/libnvgpu-drv_safe.export index da525fccb..25c72d6a5 100644 --- a/drivers/gpu/nvgpu/libnvgpu-drv_safe.export +++ b/drivers/gpu/nvgpu/libnvgpu-drv_safe.export @@ -63,7 +63,9 @@ nvgpu_aperture_mask nvgpu_bar1_readl nvgpu_bar1_writel nvgpu_bsearch +nvgpu_channel_cleanup_sw nvgpu_channel_close +nvgpu_channel_setup_sw nvgpu_dma_alloc nvgpu_dma_alloc_get_fault_injection nvgpu_dma_alloc_vid_at diff --git a/userspace/units/fifo/channel/nvgpu-channel.c b/userspace/units/fifo/channel/nvgpu-channel.c index 8c08c02e5..2353b326f 100644 --- a/userspace/units/fifo/channel/nvgpu-channel.c +++ b/userspace/units/fifo/channel/nvgpu-channel.c @@ -19,13 +19,120 @@ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ +#include +#include +#include + +#include #include +#include +#include +#include +#include + +#include + #include "../nvgpu-fifo.h" + +struct stub_ctx stub[MAX_STUB]; + +struct channel_unit_ctx { + u32 branches; +}; + +static struct channel_unit_ctx unit_ctx; + +static void subtest_setup(u32 branches) +{ + unit_ctx.branches = branches; + memset(stub, 0, sizeof(stub)); + for (i = 0; i < MAX_STUB; i++) { + stub[i].chid = NVGPU_INVALID_CHANNEL_ID; + } +} + +#define subtest_pruned test_fifo_subtest_pruned +#define branches_str test_fifo_flags_str + +#define assert(cond) unit_assert(cond, goto done) + +#define F_CHANNEL_SETUP_SW_VZALLOC_FAIL BIT(0) +#define F_CHANNEL_SETUP_SW_LAST BIT(1) + +/* TODO: nvgpu_cond_init failure, not testable yet */ +#define F_CHANNEL_SETUP_SW_INIT_SUPPORT_FAIL_COND_INIT + +static const char *f_channel_setup_sw[] = { + "vzalloc_fail", +}; + +static u32 stub_channel_count(struct gk20a *g) +{ + return 32; +} + +static int test_channel_setup_sw(struct unit_module *m, + struct gk20a *g, void *args) +{ + struct gpu_ops gops = g->ops; + struct nvgpu_fifo *f = &g->fifo; + struct nvgpu_posix_fault_inj *kmem_fi; + u32 branches; + int rc = UNIT_FAIL; + int err; + u32 fail = F_CHANNEL_SETUP_SW_VZALLOC_FAIL; + + u32 prune = fail; + + kmem_fi = nvgpu_kmem_get_fault_injection(); + + g->ops.channel.count = stub_channel_count; + + for (branches = 0U; branches < F_CHANNEL_SETUP_SW_LAST; branches++) { + + if (subtest_pruned(branches, prune)) { + unit_verbose(m, "%s branches=%s (pruned)\n", + __func__, + branches_str(branches, f_channel_setup_sw)); + continue; + } + subtest_setup(branches); + + nvgpu_posix_enable_fault_injection(kmem_fi, + branches & F_CHANNEL_SETUP_SW_VZALLOC_FAIL ? + true : false, 0); + + unit_verbose(m, "%s branches=%s\n", __func__, + branches_str(branches, f_channel_setup_sw)); + + err = nvgpu_channel_setup_sw(g); + + if (branches & fail) { + assert(err != 0); + assert(f->channel == NULL); + } else { + assert(err == 0); + nvgpu_channel_cleanup_sw(g); + } + } + + rc = UNIT_SUCCESS; +done: + nvgpu_posix_enable_fault_injection(kmem_fi, false, 0); + if (rc != UNIT_SUCCESS) { + unit_err(m, "%s branches=%s\n", __func__, + branches_str(branches, f_channel_setup_sw)); + } + g->ops = gops; + return rc; +} + struct unit_module_test nvgpu_channel_tests[] = { - UNIT_TEST(init_support, test_fifo_init_support, NULL, 0), - UNIT_TEST(remove_support, test_fifo_remove_support, NULL, 0), + UNIT_TEST(setup_sw, test_channel_setup_sw, &unit_ctx, 0), + UNIT_TEST(init_support, test_fifo_init_support, &unit_ctx, 0), + UNIT_TEST(remove_support, test_fifo_remove_support, &unit_ctx, 0), }; UNIT_MODULE(nvgpu_channel, nvgpu_channel_tests, UNIT_PRIO_NVGPU_TEST); diff --git a/userspace/units/fifo/nvgpu-fifo.c b/userspace/units/fifo/nvgpu-fifo.c index cc6b088e4..eaf6e36ee 100644 --- a/userspace/units/fifo/nvgpu-fifo.c +++ b/userspace/units/fifo/nvgpu-fifo.c @@ -36,6 +36,47 @@ #include "nvgpu-fifo.h" #include "nvgpu-fifo-gv11b.h" +bool test_fifo_subtest_pruned(u32 branches, u32 final_branches) +{ + u32 match = branches & final_branches; + int bit; + + if (match == 0U) { + return false; + } + bit = ffs(match) - 1; + + return (branches > BIT(bit)); +} + +static int test_fifo_flags_strn(char *dst, size_t size, + const char *labels[], u32 flags) +{ + int i; + char *p = dst; + int len; + + for (i = 0; i < 32; i++) { + if (flags & BIT(i)) { + len = snprintf(p, size, "%s ", labels[i]); + size -= len; + p += len; + } + } + + return (p - dst); +} + +/* not MT-safe */ +char *test_fifo_flags_str(u32 flags, const char *labels[]) +{ + static char buf[256]; + + memset(buf, 0, sizeof(buf)); + test_fifo_flags_strn(buf, sizeof(buf), labels, flags); + return buf; +} + static u32 stub_gv11b_gr_init_get_no_of_sm(struct gk20a *g) { return 8; diff --git a/userspace/units/fifo/nvgpu-fifo.h b/userspace/units/fifo/nvgpu-fifo.h index 57aa66b3a..21b72330c 100644 --- a/userspace/units/fifo/nvgpu-fifo.h +++ b/userspace/units/fifo/nvgpu-fifo.h @@ -40,4 +40,7 @@ int test_fifo_init_support(struct unit_module *m, int test_fifo_remove_support(struct unit_module *m, struct gk20a *g, void *args); +bool test_fifo_subtest_pruned(u32 branches, u32 final_branches); +char *test_fifo_flags_str(u32 flags, const char *labels[]); + #endif /* UNIT_NVGPU_FIFO_H */