From 58ee7561f72653aea8acece9f5d33ff8fe6fb99d Mon Sep 17 00:00:00 2001 From: Debarshi Dutta Date: Wed, 7 Aug 2019 11:57:28 +0530 Subject: gpu: nvgpu: Add CHANNEL_SETUP_BIND IOCTL For a long time now, the ALLOC_GPFIFO_EX channel IOCTL has done much more than just gpfifo allocation, and its signature does not match support that's needed soon. Add a new one called SETUP_BIND to hopefully cover our future needs and deprecate ALLOC_GPFIFO_EX. Change nvgpu internals to match this new naming as well. Bug 200145225 Bug 200541476 Change-Id: I766f9283a064e140656f6004b2b766db70bd6cad Signed-off-by: Konsta Holtta Reviewed-on: https://git-master.nvidia.com/r/1835186 Signed-off-by: Debarshi Dutta (cherry-picked from e0c8a16c8d474eac6723fea3980833873ab921a6 in dev-main) Reviewed-on: https://git-master.nvidia.com/r/2169882 GVS: Gerrit_Virtual_Submit Reviewed-by: Bibek Basu Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/fifo/channel.c | 28 +++++----- drivers/gpu/nvgpu/gk20a/ce2_gk20a.c | 12 ++--- drivers/gpu/nvgpu/gv11b/fifo_gv11b.c | 2 +- drivers/gpu/nvgpu/include/nvgpu/channel.h | 18 +++---- drivers/gpu/nvgpu/include/nvgpu/gk20a.h | 4 +- drivers/gpu/nvgpu/os/linux/cde.c | 19 ++++--- drivers/gpu/nvgpu/os/linux/ioctl_channel.c | 86 ++++++++++++++++++++++-------- 7 files changed, 103 insertions(+), 66 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/nvgpu/common/fifo/channel.c b/drivers/gpu/nvgpu/common/fifo/channel.c index fefd90d8..adb59ac4 100644 --- a/drivers/gpu/nvgpu/common/fifo/channel.c +++ b/drivers/gpu/nvgpu/common/fifo/channel.c @@ -1131,8 +1131,8 @@ static void channel_gk20a_free_prealloc_resources(struct channel_gk20a *c) c->joblist.pre_alloc.enabled = false; } -int gk20a_channel_alloc_gpfifo(struct channel_gk20a *c, - struct nvgpu_gpfifo_args *gpfifo_args) +int nvgpu_channel_setup_bind(struct channel_gk20a *c, + struct nvgpu_setup_bind_args *args) { struct gk20a *g = c->g; struct vm_gk20a *ch_vm; @@ -1141,14 +1141,14 @@ int gk20a_channel_alloc_gpfifo(struct channel_gk20a *c, int err = 0; unsigned long acquire_timeout; - gpfifo_size = gpfifo_args->num_entries; + gpfifo_size = args->num_gpfifo_entries; gpfifo_entry_size = nvgpu_get_gpfifo_entry_size(); - if (gpfifo_args->flags & NVGPU_GPFIFO_FLAGS_SUPPORT_VPR) { + if (args->flags & NVGPU_SETUP_BIND_FLAGS_SUPPORT_VPR) { c->vpr = true; } - if (gpfifo_args->flags & NVGPU_GPFIFO_FLAGS_SUPPORT_DETERMINISTIC) { + if (args->flags & NVGPU_SETUP_BIND_FLAGS_SUPPORT_DETERMINISTIC) { nvgpu_rwsem_down_read(&g->deterministic_busy); /* * Railgating isn't deterministic; instead of disallowing @@ -1172,8 +1172,7 @@ int gk20a_channel_alloc_gpfifo(struct channel_gk20a *c, /* an address space needs to have been bound at this point. */ if (!gk20a_channel_as_bound(c)) { nvgpu_err(g, - "not bound to an address space at time of gpfifo" - " allocation."); + "not bound to an address space at time of setup_bind"); err = -EINVAL; goto clean_up_idle; } @@ -1187,10 +1186,9 @@ int gk20a_channel_alloc_gpfifo(struct channel_gk20a *c, goto clean_up_idle; } - if (gpfifo_args->flags & NVGPU_GPFIFO_FLAGS_USERMODE_SUPPORT) { + if (args->flags & NVGPU_SETUP_BIND_FLAGS_USERMODE_SUPPORT) { if (g->os_channel.alloc_usermode_buffers) { - err = g->os_channel.alloc_usermode_buffers(c, - gpfifo_args); + err = g->os_channel.alloc_usermode_buffers(c, args); if (err) { nvgpu_err(g, "Usermode buffer alloc failed"); goto clean_up; @@ -1258,23 +1256,23 @@ int gk20a_channel_alloc_gpfifo(struct channel_gk20a *c, err = g->ops.fifo.setup_ramfc(c, gpfifo_gpu_va, c->gpfifo.entry_num, - acquire_timeout, gpfifo_args->flags); + acquire_timeout, args->flags); if (err) { goto clean_up_sync; } /* TBD: setup engine contexts */ - if (c->deterministic && gpfifo_args->num_inflight_jobs != 0U) { + if (c->deterministic && args->num_inflight_jobs != 0U) { err = channel_gk20a_prealloc_resources(c, - gpfifo_args->num_inflight_jobs); + args->num_inflight_jobs); if (err) { goto clean_up_sync; } } err = channel_gk20a_alloc_priv_cmdbuf(c, - gpfifo_args->num_inflight_jobs); + args->num_inflight_jobs); if (err) { goto clean_up_prealloc; } @@ -1292,7 +1290,7 @@ int gk20a_channel_alloc_gpfifo(struct channel_gk20a *c, clean_up_priv_cmd: channel_gk20a_free_priv_cmdbuf(c); clean_up_prealloc: - if (c->deterministic && gpfifo_args->num_inflight_jobs != 0U) { + if (c->deterministic && args->num_inflight_jobs != 0U) { channel_gk20a_free_prealloc_resources(c); } clean_up_sync: diff --git a/drivers/gpu/nvgpu/gk20a/ce2_gk20a.c b/drivers/gpu/nvgpu/gk20a/ce2_gk20a.c index 5052fc35..9dcba25a 100644 --- a/drivers/gpu/nvgpu/gk20a/ce2_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/ce2_gk20a.c @@ -420,7 +420,7 @@ u32 gk20a_ce_create_context(struct gk20a *g, { struct gk20a_gpu_ctx *ce_ctx; struct gk20a_ce_app *ce_app = &g->ce_app; - struct nvgpu_gpfifo_args gpfifo_args; + struct nvgpu_setup_bind_args setup_bind_args; u32 ctx_id = ~0; int err = 0; @@ -476,13 +476,13 @@ u32 gk20a_ce_create_context(struct gk20a *g, goto end; } - gpfifo_args.num_entries = 1024; - gpfifo_args.num_inflight_jobs = 0; - gpfifo_args.flags = 0; + setup_bind_args.num_gpfifo_entries = 1024; + setup_bind_args.num_inflight_jobs = 0; + setup_bind_args.flags = 0; /* allocate gpfifo (1024 should be more than enough) */ - err = gk20a_channel_alloc_gpfifo(ce_ctx->ch, &gpfifo_args); + err = nvgpu_channel_setup_bind(ce_ctx->ch, &setup_bind_args); if (err) { - nvgpu_err(g, "ce: unable to allocate gpfifo"); + nvgpu_err(g, "ce: unable to setup and bind channel"); goto end; } diff --git a/drivers/gpu/nvgpu/gv11b/fifo_gv11b.c b/drivers/gpu/nvgpu/gv11b/fifo_gv11b.c index 3c2de4f2..36cb5306 100644 --- a/drivers/gpu/nvgpu/gv11b/fifo_gv11b.c +++ b/drivers/gpu/nvgpu/gv11b/fifo_gv11b.c @@ -150,7 +150,7 @@ int channel_gv11b_setup_ramfc(struct channel_gk20a *c, nvgpu_memset(g, mem, 0, 0, ram_fc_size_val_v()); - if ((flags & NVGPU_GPFIFO_FLAGS_REPLAYABLE_FAULTS_ENABLE) != 0) { + if ((flags & NVGPU_SETUP_BIND_FLAGS_REPLAYABLE_FAULTS_ENABLE) != 0) { replayable = true; } gv11b_init_subcontext_pdb(c->vm, mem, replayable); diff --git a/drivers/gpu/nvgpu/include/nvgpu/channel.h b/drivers/gpu/nvgpu/include/nvgpu/channel.h index ba3d548e..d7bf7816 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/channel.h +++ b/drivers/gpu/nvgpu/include/nvgpu/channel.h @@ -38,11 +38,11 @@ struct fifo_profile_gk20a; struct nvgpu_channel_sync; struct nvgpu_gpfifo_userdata; -/* Flags to be passed to gk20a_channel_alloc_gpfifo() */ -#define NVGPU_GPFIFO_FLAGS_SUPPORT_VPR (1U << 0U) -#define NVGPU_GPFIFO_FLAGS_SUPPORT_DETERMINISTIC (1U << 1U) -#define NVGPU_GPFIFO_FLAGS_REPLAYABLE_FAULTS_ENABLE (1U << 2U) -#define NVGPU_GPFIFO_FLAGS_USERMODE_SUPPORT (1U << 3U) +/* Flags to be passed to nvgpu_channel_setup_bind() */ +#define NVGPU_SETUP_BIND_FLAGS_SUPPORT_VPR (1U << 0U) +#define NVGPU_SETUP_BIND_FLAGS_SUPPORT_DETERMINISTIC (1U << 1U) +#define NVGPU_SETUP_BIND_FLAGS_REPLAYABLE_FAULTS_ENABLE (1U << 2U) +#define NVGPU_SETUP_BIND_FLAGS_USERMODE_SUPPORT (1U << 3U) /* Flags to be passed to nvgpu_submit_channel_gpfifo() */ #define NVGPU_SUBMIT_FLAGS_FENCE_WAIT (1U << 0U) @@ -91,8 +91,8 @@ struct gpfifo_desc { void *pipe; }; -struct nvgpu_gpfifo_args { - u32 num_entries; +struct nvgpu_setup_bind_args { + u32 num_gpfifo_entries; u32 num_inflight_jobs; u32 userd_dmabuf_fd; u32 gpfifo_dmabuf_fd; @@ -407,8 +407,8 @@ struct channel_gk20a *gk20a_open_new_channel(struct gk20a *g, bool is_privileged_channel, pid_t pid, pid_t tid); -int gk20a_channel_alloc_gpfifo(struct channel_gk20a *c, - struct nvgpu_gpfifo_args *gpfifo_args); +int nvgpu_channel_setup_bind(struct channel_gk20a *c, + struct nvgpu_setup_bind_args *args); void gk20a_channel_timeout_restart_all_channels(struct gk20a *g); diff --git a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h index c9002f47..d523cf5f 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h @@ -47,7 +47,7 @@ struct nvgpu_clk_arb; struct nvgpu_gpu_ctxsw_trace_filter; #endif struct priv_cmd_entry; -struct nvgpu_gpfifo_args; +struct nvgpu_setup_bind_args; #ifdef __KERNEL__ #include @@ -1604,7 +1604,7 @@ struct gk20a { struct nvgpu_gpfifo_userdata userdata, u32 start, u32 length); int (*alloc_usermode_buffers)(struct channel_gk20a *c, - struct nvgpu_gpfifo_args *gpfifo_args); + struct nvgpu_setup_bind_args *gpfifo_args); } os_channel; struct gk20a_scale_profile *scale_profile; diff --git a/drivers/gpu/nvgpu/os/linux/cde.c b/drivers/gpu/nvgpu/os/linux/cde.c index 7b2cba7d..715513c9 100644 --- a/drivers/gpu/nvgpu/os/linux/cde.c +++ b/drivers/gpu/nvgpu/os/linux/cde.c @@ -1312,7 +1312,7 @@ static int gk20a_cde_load(struct gk20a_cde_ctx *cde_ctx) struct channel_gk20a *ch; struct tsg_gk20a *tsg; struct gr_gk20a *gr = &g->gr; - struct nvgpu_gpfifo_args gpfifo_args; + struct nvgpu_setup_bind_args setup_bind_args; int err = 0; u64 vaddr; @@ -1351,17 +1351,16 @@ static int gk20a_cde_load(struct gk20a_cde_ctx *cde_ctx) err = gk20a_tsg_bind_channel(tsg, ch); if (err) { nvgpu_err(g, "cde: unable to bind to tsg"); - goto err_alloc_gpfifo; + goto err_setup_bind; } - gpfifo_args.num_entries = 1024; - gpfifo_args.num_inflight_jobs = 0; - gpfifo_args.flags = 0; - /* allocate gpfifo (1024 should be more than enough) */ - err = gk20a_channel_alloc_gpfifo(ch, &gpfifo_args); + setup_bind_args.num_gpfifo_entries = 1024; + setup_bind_args.num_inflight_jobs = 0; + setup_bind_args.flags = 0; + err = nvgpu_channel_setup_bind(ch, &setup_bind_args); if (err) { - nvgpu_warn(g, "cde: unable to allocate gpfifo"); - goto err_alloc_gpfifo; + nvgpu_warn(g, "cde: unable to setup channel"); + goto err_setup_bind; } /* map backing store to gpu virtual space */ @@ -1399,7 +1398,7 @@ static int gk20a_cde_load(struct gk20a_cde_ctx *cde_ctx) err_init_cde_img: nvgpu_gmmu_unmap(ch->vm, &g->gr.compbit_store.mem, vaddr); err_map_backingstore: -err_alloc_gpfifo: +err_setup_bind: nvgpu_vm_put(ch->vm); err_commit_va: err_get_gk20a_channel: diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_channel.c b/drivers/gpu/nvgpu/os/linux/ioctl_channel.c index d0d4b1af..d243c425 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_channel.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_channel.c @@ -577,45 +577,59 @@ clean_up: return err; } -static u32 nvgpu_gpfifo_user_flags_to_common_flags(u32 user_flags) +static u32 nvgpu_setup_bind_user_flags_to_common_flags(u32 user_flags) { u32 flags = 0; - if (user_flags & NVGPU_ALLOC_GPFIFO_EX_FLAGS_VPR_ENABLED) - flags |= NVGPU_GPFIFO_FLAGS_SUPPORT_VPR; + if (user_flags & NVGPU_CHANNEL_SETUP_BIND_FLAGS_VPR_ENABLED) + flags |= NVGPU_SETUP_BIND_FLAGS_SUPPORT_VPR; - if (user_flags & NVGPU_ALLOC_GPFIFO_EX_FLAGS_DETERMINISTIC) - flags |= NVGPU_GPFIFO_FLAGS_SUPPORT_DETERMINISTIC; + if (user_flags & NVGPU_CHANNEL_SETUP_BIND_FLAGS_DETERMINISTIC) + flags |= NVGPU_SETUP_BIND_FLAGS_SUPPORT_DETERMINISTIC; - if (user_flags & NVGPU_ALLOC_GPFIFO_FLAGS_REPLAYABLE_FAULTS_ENABLE) - flags |= NVGPU_GPFIFO_FLAGS_REPLAYABLE_FAULTS_ENABLE; + if (user_flags & NVGPU_CHANNEL_SETUP_BIND_FLAGS_REPLAYABLE_FAULTS_ENABLE) + flags |= NVGPU_SETUP_BIND_FLAGS_REPLAYABLE_FAULTS_ENABLE; return flags; } +static void nvgpu_get_setup_bind_args( + struct nvgpu_channel_setup_bind_args *channel_setup_bind_args, + struct nvgpu_setup_bind_args *setup_bind_args) +{ + setup_bind_args->num_gpfifo_entries = + channel_setup_bind_args->num_gpfifo_entries; + setup_bind_args->num_inflight_jobs = + channel_setup_bind_args->num_inflight_jobs; + setup_bind_args->flags = nvgpu_setup_bind_user_flags_to_common_flags( + channel_setup_bind_args->flags); +} + static void nvgpu_get_gpfifo_ex_args( struct nvgpu_alloc_gpfifo_ex_args *alloc_gpfifo_ex_args, - struct nvgpu_gpfifo_args *gpfifo_args) + struct nvgpu_setup_bind_args *setup_bind_args) { - gpfifo_args->num_entries = alloc_gpfifo_ex_args->num_entries; - gpfifo_args->num_inflight_jobs = alloc_gpfifo_ex_args->num_inflight_jobs; - gpfifo_args->flags = nvgpu_gpfifo_user_flags_to_common_flags( - alloc_gpfifo_ex_args->flags); + setup_bind_args->num_gpfifo_entries = alloc_gpfifo_ex_args->num_entries; + setup_bind_args->num_inflight_jobs = + alloc_gpfifo_ex_args->num_inflight_jobs; + setup_bind_args->flags = nvgpu_setup_bind_user_flags_to_common_flags( + alloc_gpfifo_ex_args->flags); } static void nvgpu_get_gpfifo_args( struct nvgpu_alloc_gpfifo_args *alloc_gpfifo_args, - struct nvgpu_gpfifo_args *gpfifo_args) + struct nvgpu_setup_bind_args *setup_bind_args) { /* * Kernel can insert one extra gpfifo entry before user * submitted gpfifos and another one after, for internal usage. * Triple the requested size. */ - gpfifo_args->num_entries = alloc_gpfifo_args->num_entries * 3; - gpfifo_args->num_inflight_jobs = 0; - gpfifo_args->flags = nvgpu_gpfifo_user_flags_to_common_flags( - alloc_gpfifo_args->flags); + setup_bind_args->num_gpfifo_entries = + alloc_gpfifo_args->num_entries * 3; + setup_bind_args->num_inflight_jobs = 0; + setup_bind_args->flags = nvgpu_setup_bind_user_flags_to_common_flags( + alloc_gpfifo_args->flags); } static void nvgpu_get_fence_args( @@ -1119,13 +1133,39 @@ long gk20a_channel_ioctl(struct file *filp, gk20a_idle(ch->g); break; } + case NVGPU_IOCTL_CHANNEL_SETUP_BIND: + { + struct nvgpu_channel_setup_bind_args *channel_setup_bind_args = + (struct nvgpu_channel_setup_bind_args *)buf; + struct nvgpu_setup_bind_args setup_bind_args; + + nvgpu_get_setup_bind_args(channel_setup_bind_args, + &setup_bind_args); + + err = gk20a_busy(ch->g); + if (err) { + dev_err(dev, + "%s: failed to host gk20a for ioctl cmd: 0x%x", + __func__, cmd); + break; + } + + if (!is_power_of_2(setup_bind_args.num_gpfifo_entries)) { + err = -EINVAL; + gk20a_idle(ch->g); + break; + } + err = nvgpu_channel_setup_bind(ch, &setup_bind_args); + gk20a_idle(ch->g); + break; + } case NVGPU_IOCTL_CHANNEL_ALLOC_GPFIFO_EX: { struct nvgpu_alloc_gpfifo_ex_args *alloc_gpfifo_ex_args = (struct nvgpu_alloc_gpfifo_ex_args *)buf; - struct nvgpu_gpfifo_args gpfifo_args; + struct nvgpu_setup_bind_args setup_bind_args; - nvgpu_get_gpfifo_ex_args(alloc_gpfifo_ex_args, &gpfifo_args); + nvgpu_get_gpfifo_ex_args(alloc_gpfifo_ex_args, &setup_bind_args); err = gk20a_busy(ch->g); if (err) { @@ -1140,7 +1180,7 @@ long gk20a_channel_ioctl(struct file *filp, gk20a_idle(ch->g); break; } - err = gk20a_channel_alloc_gpfifo(ch, &gpfifo_args); + err = nvgpu_channel_setup_bind(ch, &setup_bind_args); gk20a_idle(ch->g); break; } @@ -1148,9 +1188,9 @@ long gk20a_channel_ioctl(struct file *filp, { struct nvgpu_alloc_gpfifo_args *alloc_gpfifo_args = (struct nvgpu_alloc_gpfifo_args *)buf; - struct nvgpu_gpfifo_args gpfifo_args; + struct nvgpu_setup_bind_args setup_bind_args; - nvgpu_get_gpfifo_args(alloc_gpfifo_args, &gpfifo_args); + nvgpu_get_gpfifo_args(alloc_gpfifo_args, &setup_bind_args); err = gk20a_busy(ch->g); if (err) { @@ -1160,7 +1200,7 @@ long gk20a_channel_ioctl(struct file *filp, break; } - err = gk20a_channel_alloc_gpfifo(ch, &gpfifo_args); + err = nvgpu_channel_setup_bind(ch, &setup_bind_args); gk20a_idle(ch->g); break; } -- cgit v1.2.2