From 0b4ccc72473ba51c51a631ead70386aaf14ae056 Mon Sep 17 00:00:00 2001 From: shashank singh Date: Fri, 24 Jan 2020 14:09:11 +0530 Subject: [PATCH] gpu: nvgpu: ignore deterministic submit flag for safety Safety only supports usermode submits so there is no need to process DETERMINISTIC submit flag. For safety, while processing DETERMINISTIC submit flag we are only setting deterministic field of struct channel_gk20a and taking power reference with gk20a_busy(). On qnx safety deterministic field is just used to check the syncpoint allocation and taking power reference is a noop. Jira NVGPU-4378 Change-Id: I1dc256db7d9fab93bef8fcc42bdb36f611b3ef40 Signed-off-by: shashank singh Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2284644 Reviewed-by: svc-mobile-coverity Reviewed-by: svc-mobile-misra Reviewed-by: Konsta Holtta Reviewed-by: Thomas Fleury Reviewed-by: Vaibhav Kachore Reviewed-by: mobile promotions GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/fifo/channel.c | 14 ++++++++++++++ drivers/gpu/nvgpu/hal/fifo/channel_gv11b_fusa.c | 10 +++++++++- drivers/gpu/nvgpu/include/nvgpu/channel.h | 4 ++++ drivers/gpu/nvgpu/libnvgpu-drv_safe.export | 2 -- userspace/required_tests.json | 6 ------ .../fifo/channel/gv11b/nvgpu-channel-gv11b.c | 2 ++ userspace/units/fifo/channel/nvgpu-channel.c | 16 ++++++++++++++++ 7 files changed, 45 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/nvgpu/common/fifo/channel.c b/drivers/gpu/nvgpu/common/fifo/channel.c index db02b060a..b434995e4 100644 --- a/drivers/gpu/nvgpu/common/fifo/channel.c +++ b/drivers/gpu/nvgpu/common/fifo/channel.c @@ -674,6 +674,7 @@ out: return err; } +#ifdef CONFIG_NVGPU_KERNEL_MODE_SUBMIT static int channel_setup_kernelmode(struct nvgpu_channel *c, struct nvgpu_setup_bind_args *args) { @@ -783,6 +784,7 @@ clean_up: return err; } +#endif /* Update with this periodically to determine how the gpfifo is draining. */ static inline u32 channel_update_gpfifo_get(struct gk20a *g, @@ -1694,6 +1696,7 @@ static void channel_free_wait_for_refs(struct nvgpu_channel *ch, } +#ifdef CONFIG_NVGPU_IOCTL_NON_FUSA static void channel_free_put_deterministic_ref_from_init( struct nvgpu_channel *ch) { @@ -1711,6 +1714,7 @@ static void channel_free_put_deterministic_ref_from_init( nvgpu_rwsem_up_read(&g->deterministic_busy); } } +#endif /* call ONLY when no references to the channel exist: after the last put */ static void channel_free(struct nvgpu_channel *ch, bool force) @@ -1830,7 +1834,9 @@ unbind: g->ops.channel.unbind(ch); g->ops.channel.free_inst(g, ch); +#ifdef CONFIG_NVGPU_IOCTL_NON_FUSA channel_free_put_deterministic_ref_from_init(ch); +#endif ch->vpr = false; ch->vm = NULL; @@ -2270,6 +2276,7 @@ int nvgpu_channel_setup_bind(struct nvgpu_channel *c, c->vpr = false; #endif +#ifdef CONFIG_NVGPU_IOCTL_NON_FUSA if ((args->flags & NVGPU_SETUP_BIND_FLAGS_SUPPORT_DETERMINISTIC) != 0U) { nvgpu_rwsem_down_read(&g->deterministic_busy); /* @@ -2290,6 +2297,7 @@ int nvgpu_channel_setup_bind(struct nvgpu_channel *c, c->deterministic = true; nvgpu_rwsem_up_read(&g->deterministic_busy); } +#endif if ((args->flags & NVGPU_SETUP_BIND_FLAGS_USERMODE_SUPPORT) != 0U) { err = nvgpu_channel_setup_usermode(c, args); @@ -2314,12 +2322,14 @@ int nvgpu_channel_setup_bind(struct nvgpu_channel *c, return 0; clean_up_idle: +#ifdef CONFIG_NVGPU_IOCTL_NON_FUSA if (c->deterministic) { nvgpu_rwsem_down_read(&g->deterministic_busy); gk20a_idle(g); c->deterministic = false; nvgpu_rwsem_up_read(&g->deterministic_busy); } +#endif fail: nvgpu_err(g, "fail"); return err; @@ -2400,6 +2410,7 @@ void nvgpu_channel_sw_quiesce(struct gk20a *g) } #endif +#ifdef CONFIG_NVGPU_IOCTL_NON_FUSA /* * Stop deterministic channel activity for do_idle() when power needs to go off * momentarily but deterministic channels keep power refs for potentially a @@ -2482,6 +2493,7 @@ void nvgpu_channel_deterministic_unidle(struct gk20a *g) /* Release submits, new deterministic channels and frees */ nvgpu_rwsem_up_write(&g->deterministic_busy); } +#endif static void nvgpu_channel_destroy(struct nvgpu_channel *c) { @@ -2869,7 +2881,9 @@ void nvgpu_channel_debug_dump_all(struct gk20a *g, info->tsgid = ch->tsgid; info->pid = ch->pid; info->refs = nvgpu_atomic_read(&ch->ref_count); +#ifdef CONFIG_NVGPU_IOCTL_NON_FUSA info->deterministic = ch->deterministic; +#endif #ifdef CONFIG_NVGPU_SW_SEMAPHORE if (hw_sema != NULL) { diff --git a/drivers/gpu/nvgpu/hal/fifo/channel_gv11b_fusa.c b/drivers/gpu/nvgpu/hal/fifo/channel_gv11b_fusa.c index d5854e6af..c3f2f900d 100644 --- a/drivers/gpu/nvgpu/hal/fifo/channel_gv11b_fusa.c +++ b/drivers/gpu/nvgpu/hal/fifo/channel_gv11b_fusa.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2016-2020, 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"), @@ -85,13 +85,21 @@ void gv11b_channel_debug_dump(struct gk20a *g, struct nvgpu_debug_context *o, struct nvgpu_channel_dump_info *info) { +#ifdef CONFIG_NVGPU_IOCTL_NON_FUSA gk20a_debug_output(o, "%d-%s, TSG: %u, pid %d, refs: %d%s: ", +#else + gk20a_debug_output(o, "%d-%s, TSG: %u, pid %d, refs: %d: ", +#endif info->chid, g->name, info->tsgid, info->pid, +#ifdef CONFIG_NVGPU_IOCTL_NON_FUSA info->refs, info->deterministic ? ", deterministic" : ""); +#else + info->refs); +#endif gk20a_debug_output(o, "channel status: %s in use %s %s\n", info->hw_state.enabled ? "" : "not", info->hw_state.status_string, diff --git a/drivers/gpu/nvgpu/include/nvgpu/channel.h b/drivers/gpu/nvgpu/include/nvgpu/channel.h index b9dd6bf17..ef4d08ec1 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/channel.h +++ b/drivers/gpu/nvgpu/include/nvgpu/channel.h @@ -183,8 +183,10 @@ struct nvgpu_channel_dump_info { int pid; /** Number of references to this channel. */ int refs; +#ifdef CONFIG_NVGPU_IOCTL_NON_FUSA /** Channel uses deterministic submit (kernel submit only). */ bool deterministic; +#endif /** Channel H/W state */ struct nvgpu_channel_hw_state hw_state; /** Snaphsot of channel instance fields. */ @@ -560,6 +562,7 @@ struct nvgpu_channel { bool referenceable; /** True if VPR support was requested during setup bind */ bool vpr; +#ifdef CONFIG_NVGPU_IOCTL_NON_FUSA /** * Channel shall exhibit deterministic behavior in the submit path. * Submit latency shall be consistent (and low). Submits that may cause @@ -567,6 +570,7 @@ struct nvgpu_channel { * sync fds or mapped buffer refcounting are not deterministic). */ bool deterministic; +#endif /** Deterministic, but explicitly idle and submits disallowed. */ bool deterministic_railgate_allowed; /** Channel uses Color Decompression Engine. */ diff --git a/drivers/gpu/nvgpu/libnvgpu-drv_safe.export b/drivers/gpu/nvgpu/libnvgpu-drv_safe.export index 3d594b319..f7d31c272 100644 --- a/drivers/gpu/nvgpu/libnvgpu-drv_safe.export +++ b/drivers/gpu/nvgpu/libnvgpu-drv_safe.export @@ -307,8 +307,6 @@ nvgpu_channel_cleanup_sw nvgpu_channel_close nvgpu_channel_commit_va nvgpu_channel_debug_dump_all -nvgpu_channel_deterministic_idle -nvgpu_channel_deterministic_unidle nvgpu_channel_disable_tsg nvgpu_channel_enable_tsg nvgpu_channel_free_inst diff --git a/userspace/required_tests.json b/userspace/required_tests.json index d4b3e80c3..6e1e4ff82 100644 --- a/userspace/required_tests.json +++ b/userspace/required_tests.json @@ -2147,12 +2147,6 @@ "unit": "nvgpu_channel", "test_level": 0 }, - { - "test": "test_channel_deterministic_idle_unidle", - "case": "idle_unidle", - "unit": "nvgpu_channel", - "test_level": 0 - }, { "test": "test_fifo_init_support", "case": "init_support", diff --git a/userspace/units/fifo/channel/gv11b/nvgpu-channel-gv11b.c b/userspace/units/fifo/channel/gv11b/nvgpu-channel-gv11b.c index 87061bec4..bbf70cf05 100644 --- a/userspace/units/fifo/channel/gv11b/nvgpu-channel-gv11b.c +++ b/userspace/units/fifo/channel/gv11b/nvgpu-channel-gv11b.c @@ -284,7 +284,9 @@ int test_gv11b_channel_debug_dump(struct unit_module *m, info->tsgid = ch->tsgid; info->pid = ch->pid; info->refs = nvgpu_atomic_read(&ch->ref_count); +#ifdef CONFIG_NVGPU_IOCTL_NON_FUSA info->deterministic = (branches & F_CHANNEL_DUMP_DETERMINISTIC) != 0; +#endif info->hw_state.enabled = (branches & F_CHANNEL_DUMP_ENABLED) != 0; info->hw_state.busy = (branches & F_CHANNEL_DUMP_BUSY) != 0; info->hw_state.status_string = "fake"; diff --git a/userspace/units/fifo/channel/nvgpu-channel.c b/userspace/units/fifo/channel/nvgpu-channel.c index d3ed22022..9149a89f1 100644 --- a/userspace/units/fifo/channel/nvgpu-channel.c +++ b/userspace/units/fifo/channel/nvgpu-channel.c @@ -497,6 +497,7 @@ int test_channel_close(struct unit_module *m, struct gk20a *g, void *vargs) ch->vm = NULL; } +#ifdef CONFIG_NVGPU_IOCTL_NON_FUSA if (branches & F_CHANNEL_CLOSE_DETERMINISTIC) { /* Compensate for atomic dec in gk20a_idle() */ nvgpu_atomic_set(&g->usage_count, 1); @@ -507,6 +508,7 @@ int test_channel_close(struct unit_module *m, struct gk20a *g, void *vargs) ch->deterministic = true; ch->deterministic_railgate_allowed = true; } +#endif g->ops.gr.setup.free_subctx = branches & F_CHANNEL_CLOSE_FREE_SUBCTX ? @@ -601,7 +603,9 @@ int test_channel_close(struct unit_module *m, struct gk20a *g, void *vargs) ch->subctx = NULL; } +#ifdef CONFIG_NVGPU_IOCTL_NON_FUSA ch->deterministic = false; +#endif ch->deterministic_railgate_allowed = false; unit_assert(ch->usermode_submit_enabled == false, goto done); @@ -819,6 +823,7 @@ int test_channel_setup_bind(struct unit_module *m, struct gk20a *g, void *vargs) stub_os_channel_alloc_usermode_buffers_ENOMEM; } +#ifdef CONFIG_NVGPU_IOCTL_NON_FUSA if (branches & F_CHANNEL_SETUP_BIND_USERMODE_SUPPORT_DETERMINISTIC) { bind_args.flags |= @@ -833,6 +838,7 @@ int test_channel_setup_bind(struct unit_module *m, struct gk20a *g, void *vargs) nvgpu_posix_enable_fault_injection(l_nvgpu_fi, true, 0); } +#endif if (branches & F_CHANNEL_SETUP_BIND_NON_USERMODE_DETERMINISTIC) { bind_args.flags |= @@ -895,7 +901,9 @@ int test_channel_setup_bind(struct unit_module *m, struct gk20a *g, void *vargs) nvgpu_dma_free(g, &ch->usermode_userd); nvgpu_dma_free(g, &ch->usermode_gpfifo); ch->userd_iova = 0U; +#ifdef CONFIG_NVGPU_IOCTL_NON_FUSA ch->deterministic = false; +#endif nvgpu_atomic_set(&ch->bound, false); } bind_args.flags &= @@ -1307,6 +1315,7 @@ done: #define F_CHANNEL_DETERMINISTIC_UNIDLE_GK20ABUSY_FAIL BIT(2) #define F_CHANNEL_DETERMINISTIC_IDLE_LAST BIT(3) +#ifdef CONFIG_NVGPU_IOCTL_NON_FUSA static const char *f_channel_deterministic_idle_unidle[] = { "deterministic_channel", "determinstic_railgate_allowed", @@ -1440,6 +1449,7 @@ done: return ret; } +#endif #define F_CHANNEL_SUSPEND_RESUME_UNSERVICEABLE_CH BIT(0) #define F_CHANNEL_SUSPEND_RESUME_INVALID_TSGID BIT(1) @@ -1748,9 +1758,11 @@ int test_channel_semaphore_wakeup(struct unit_module *m, unit_verbose(m, "%s branches=%s\n", __func__, branches_str(branches, f_channel_semaphore_wakeup)); +#ifdef CONFIG_NVGPU_IOCTL_NON_FUSA if (branches & F_CHANNEL_SEMAPHORRE_WAKEUP_DETERMINISTIC_CH) { ch->deterministic = true; } +#endif ch->semaphore_wq.initialized = branches & F_CHANNEL_SEMAPHORRE_WAKEUP_COND_BROADCAST_FAIL ? @@ -1765,7 +1777,9 @@ int test_channel_semaphore_wakeup(struct unit_module *m, nvgpu_channel_semaphore_wakeup(g, false); unit_assert(stub[0].count == (global_count - 1U), goto done); +#ifdef CONFIG_NVGPU_IOCTL_NON_FUSA ch->deterministic = false; +#endif } ret = UNIT_SUCCESS; @@ -1993,7 +2007,9 @@ struct unit_module_test nvgpu_channel_tests[] = { UNIT_TEST(ch_abort, test_channel_abort, &unit_ctx, 0), UNIT_TEST(mark_error, test_channel_mark_error, &unit_ctx, 0), UNIT_TEST(sw_quiesce, test_channel_sw_quiesce, &unit_ctx, 0), +#ifdef CONFIG_NVGPU_IOCTL_NON_FUSA UNIT_TEST(idle_unidle, test_channel_deterministic_idle_unidle, &unit_ctx, 0), +#endif UNIT_TEST(suspend_resume, test_channel_suspend_resume_serviceable_chs, &unit_ctx, 0), UNIT_TEST(debug_dump, test_channel_debug_dump, &unit_ctx, 0), UNIT_TEST(semaphore_wakeup, test_channel_semaphore_wakeup, &unit_ctx, 0),