From 7d3ae08847075d58c6fbd5aadfded0ee9c01fe01 Mon Sep 17 00:00:00 2001 From: Aparna Das Date: Mon, 17 Jun 2019 19:09:42 -0700 Subject: [PATCH] gpu: nvgpu: vgpu: create unit fifo Move fifo related code to common/vgpu/fifo and create new child units fifo, channel, tsg, preempt, engines. Also update arch YAML to include newly created files related to fifo unit. Jira GVSCI-994 Change-Id: I79897df4e729e0506702832ba62c1694c3f42280 Signed-off-by: Aparna Das Reviewed-on: https://git-master.nvidia.com/r/2138388 Reviewed-by: Thomas Fleury Reviewed-by: Alex Waterman GVS: Gerrit_Virtual_Submit Reviewed-by: Nirav Patel Reviewed-by: mobile promotions Tested-by: mobile promotions --- arch/nvgpu-vgpu.yaml | 9 +- drivers/gpu/nvgpu/Makefile | 5 +- drivers/gpu/nvgpu/Makefile.sources | 5 +- .../gpu/nvgpu/common/vgpu/fifo/channel_vgpu.c | 197 +++++++++ .../gpu/nvgpu/common/vgpu/fifo/channel_vgpu.h | 41 ++ .../gpu/nvgpu/common/vgpu/fifo/engines_vgpu.c | 72 ++++ .../gpu/nvgpu/common/vgpu/fifo/engines_vgpu.h | 28 ++ .../gpu/nvgpu/common/vgpu/fifo/fifo_vgpu.c | 379 +----------------- .../gpu/nvgpu/common/vgpu/fifo/fifo_vgpu.h | 33 -- .../gpu/nvgpu/common/vgpu/fifo/preempt_vgpu.c | 84 ++++ .../gpu/nvgpu/common/vgpu/fifo/preempt_vgpu.h | 33 ++ .../nvgpu/common/vgpu/{ => fifo}/tsg_vgpu.c | 103 ++++- drivers/gpu/nvgpu/common/vgpu/fifo/tsg_vgpu.h | 48 +++ .../nvgpu/common/vgpu/gp10b/vgpu_hal_gp10b.c | 6 +- .../gpu/nvgpu/common/vgpu/gr/subctx_vgpu.c | 5 + .../gpu/nvgpu/common/vgpu/gr/subctx_vgpu.h | 2 + .../nvgpu/common/vgpu/gv11b/vgpu_hal_gv11b.c | 9 +- .../gpu/nvgpu/common/vgpu/intr/intr_vgpu.c | 6 +- 18 files changed, 649 insertions(+), 416 deletions(-) create mode 100644 drivers/gpu/nvgpu/common/vgpu/fifo/channel_vgpu.c create mode 100644 drivers/gpu/nvgpu/common/vgpu/fifo/channel_vgpu.h create mode 100644 drivers/gpu/nvgpu/common/vgpu/fifo/engines_vgpu.c create mode 100644 drivers/gpu/nvgpu/common/vgpu/fifo/engines_vgpu.h create mode 100644 drivers/gpu/nvgpu/common/vgpu/fifo/preempt_vgpu.c create mode 100644 drivers/gpu/nvgpu/common/vgpu/fifo/preempt_vgpu.h rename drivers/gpu/nvgpu/common/vgpu/{ => fifo}/tsg_vgpu.c (69%) create mode 100644 drivers/gpu/nvgpu/common/vgpu/fifo/tsg_vgpu.h diff --git a/arch/nvgpu-vgpu.yaml b/arch/nvgpu-vgpu.yaml index 58c6af8da..1217f4665 100644 --- a/arch/nvgpu-vgpu.yaml +++ b/arch/nvgpu-vgpu.yaml @@ -22,6 +22,14 @@ all: common/vgpu/ecc_vgpu.h, common/vgpu/fifo/fifo_vgpu.c, common/vgpu/fifo/fifo_vgpu.h, + common/vgpu/fifo/channel_vgpu.c, + common/vgpu/fifo/channel_vgpu.h, + common/vgpu/fifo/tsg_vgpu.c, + common/vgpu/fifo/tsg_vgpu.h, + common/vgpu/fifo/engines_vgpu.c, + common/vgpu/fifo/engines_vgpu.h, + common/vgpu/fifo/preempt_vgpu.c, + common/vgpu/fifo/preempt_vgpu.h, common/vgpu/fifo/ramfc_vgpu.c, common/vgpu/fifo/ramfc_vgpu.h, common/vgpu/fifo/runlist_vgpu.c, @@ -53,7 +61,6 @@ all: common/vgpu/perf/cyclestats_snapshot_vgpu.h, common/vgpu/perf/perf_vgpu.c, common/vgpu/perf/perf_vgpu.h, - common/vgpu/tsg_vgpu.c, common/vgpu/fbp/fbp_vgpu.c, common/vgpu/fbp/fbp_vgpu.h, common/vgpu/gp10b/vgpu_hal_gp10b.h, diff --git a/drivers/gpu/nvgpu/Makefile b/drivers/gpu/nvgpu/Makefile index 1842b5415..df05aa4dd 100644 --- a/drivers/gpu/nvgpu/Makefile +++ b/drivers/gpu/nvgpu/Makefile @@ -592,6 +592,10 @@ nvgpu-$(CONFIG_TEGRA_GR_VIRTUALIZATION) += \ common/vgpu/gr/ctx_vgpu.o \ common/vgpu/gr/subctx_vgpu.o \ common/vgpu/fifo/fifo_vgpu.o \ + common/vgpu/fifo/channel_vgpu.o \ + common/vgpu/fifo/tsg_vgpu.o \ + common/vgpu/fifo/engines_vgpu.o \ + common/vgpu/fifo/preempt_vgpu.o \ common/vgpu/fifo/runlist_vgpu.o \ common/vgpu/fifo/vgpu_fifo_gv11b.o \ common/vgpu/fifo/ramfc_vgpu.o \ @@ -605,7 +609,6 @@ nvgpu-$(CONFIG_TEGRA_GR_VIRTUALIZATION) += \ common/vgpu/intr/intr_vgpu.o \ common/vgpu/ptimer/ptimer_vgpu.o \ common/vgpu/debugger_vgpu.o \ - common/vgpu/tsg_vgpu.o \ common/vgpu/perf/perf_vgpu.o \ common/vgpu/ecc_vgpu.o \ common/vgpu/clk_vgpu.o \ diff --git a/drivers/gpu/nvgpu/Makefile.sources b/drivers/gpu/nvgpu/Makefile.sources index 46325deb2..02615611f 100644 --- a/drivers/gpu/nvgpu/Makefile.sources +++ b/drivers/gpu/nvgpu/Makefile.sources @@ -433,11 +433,14 @@ srcs += common/vgpu/init/init_vgpu.c \ common/vgpu/intr/intr_vgpu.c \ common/vgpu/ptimer/ptimer_vgpu.c \ common/vgpu/fifo/fifo_vgpu.c \ + common/vgpu/fifo/channel_vgpu.c \ + common/vgpu/fifo/tsg_vgpu.c \ + common/vgpu/fifo/engines_vgpu.c \ + common/vgpu/fifo/preempt_vgpu.c \ common/vgpu/fifo/runlist_vgpu.c \ common/vgpu/fifo/vgpu_fifo_gv11b.c \ common/vgpu/fifo/ramfc_vgpu.c \ common/vgpu/fifo/userd_vgpu.c \ - common/vgpu/tsg_vgpu.c \ common/vgpu/perf/perf_vgpu.c \ common/vgpu/mm/mm_vgpu.c \ common/vgpu/mm/vm_vgpu.c \ diff --git a/drivers/gpu/nvgpu/common/vgpu/fifo/channel_vgpu.c b/drivers/gpu/nvgpu/common/vgpu/fifo/channel_vgpu.c new file mode 100644 index 000000000..cdb5d2bbb --- /dev/null +++ b/drivers/gpu/nvgpu/common/vgpu/fifo/channel_vgpu.c @@ -0,0 +1,197 @@ +/* + * 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 +#include + +#include "common/vgpu/ivc/comm_vgpu.h" +#include "channel_vgpu.h" + +void vgpu_channel_bind(struct nvgpu_channel *ch) +{ + struct tegra_vgpu_cmd_msg msg; + struct tegra_vgpu_channel_config_params *p = + &msg.params.channel_config; + int err; + struct gk20a *g = ch->g; + + nvgpu_log_info(g, "bind channel %d", ch->chid); + + msg.cmd = TEGRA_VGPU_CMD_CHANNEL_BIND; + msg.handle = vgpu_get_handle(ch->g); + p->handle = ch->virt_ctx; + err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); + WARN_ON(err || msg.ret); + + nvgpu_smp_wmb(); + nvgpu_atomic_set(&ch->bound, true); +} + +void vgpu_channel_unbind(struct nvgpu_channel *ch) +{ + struct gk20a *g = ch->g; + + nvgpu_log_fn(g, " "); + + if (nvgpu_atomic_cmpxchg(&ch->bound, true, false)) { + struct tegra_vgpu_cmd_msg msg; + struct tegra_vgpu_channel_config_params *p = + &msg.params.channel_config; + int err; + + msg.cmd = TEGRA_VGPU_CMD_CHANNEL_UNBIND; + msg.handle = vgpu_get_handle(ch->g); + p->handle = ch->virt_ctx; + err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); + WARN_ON(err || msg.ret); + } + +} + +int vgpu_channel_alloc_inst(struct gk20a *g, struct nvgpu_channel *ch) +{ + struct tegra_vgpu_cmd_msg msg; + struct tegra_vgpu_channel_hwctx_params *p = &msg.params.channel_hwctx; + int err; + + nvgpu_log_fn(g, " "); + + msg.cmd = TEGRA_VGPU_CMD_CHANNEL_ALLOC_HWCTX; + msg.handle = vgpu_get_handle(g); + p->id = ch->chid; + p->pid = (u64)ch->pid; + err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); + if (err || msg.ret) { + nvgpu_err(g, "fail"); + return -ENOMEM; + } + + ch->virt_ctx = p->handle; + nvgpu_log_fn(g, "done"); + return 0; +} + +void vgpu_channel_free_inst(struct gk20a *g, struct nvgpu_channel *ch) +{ + struct tegra_vgpu_cmd_msg msg; + struct tegra_vgpu_channel_hwctx_params *p = &msg.params.channel_hwctx; + int err; + + nvgpu_log_fn(g, " "); + + msg.cmd = TEGRA_VGPU_CMD_CHANNEL_FREE_HWCTX; + msg.handle = vgpu_get_handle(g); + p->handle = ch->virt_ctx; + err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); + WARN_ON(err || msg.ret); +} + +void vgpu_channel_enable(struct nvgpu_channel *ch) +{ + struct tegra_vgpu_cmd_msg msg; + struct tegra_vgpu_channel_config_params *p = + &msg.params.channel_config; + int err; + struct gk20a *g = ch->g; + + nvgpu_log_fn(g, " "); + + msg.cmd = TEGRA_VGPU_CMD_CHANNEL_ENABLE; + msg.handle = vgpu_get_handle(ch->g); + p->handle = ch->virt_ctx; + err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); + WARN_ON(err || msg.ret); +} + +void vgpu_channel_disable(struct nvgpu_channel *ch) +{ + struct tegra_vgpu_cmd_msg msg; + struct tegra_vgpu_channel_config_params *p = + &msg.params.channel_config; + int err; + struct gk20a *g = ch->g; + + nvgpu_log_fn(g, " "); + + msg.cmd = TEGRA_VGPU_CMD_CHANNEL_DISABLE; + msg.handle = vgpu_get_handle(ch->g); + p->handle = ch->virt_ctx; + err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); + WARN_ON(err || msg.ret); +} + +u32 vgpu_channel_count(struct gk20a *g) +{ + struct vgpu_priv_data *priv = vgpu_get_priv_data(g); + + return priv->constants.num_channels; +} + +void vgpu_channel_set_ctx_mmu_error(struct gk20a *g, struct nvgpu_channel *ch) +{ + /* + * If error code is already set, this mmu fault + * was triggered as part of recovery from other + * error condition. + * Don't overwrite error flag. + */ + g->ops.channel.set_error_notifier(ch, + NVGPU_ERR_NOTIFIER_FIFO_ERROR_MMU_ERR_FLT); + + /* mark channel as faulted */ + nvgpu_channel_set_unserviceable(ch); + + /* unblock pending waits */ + nvgpu_cond_broadcast_interruptible(&ch->semaphore_wq); + nvgpu_cond_broadcast_interruptible(&ch->notifier_wq); +} + +void vgpu_channel_set_error_notifier(struct gk20a *g, + struct tegra_vgpu_channel_set_error_notifier *p) +{ + struct nvgpu_channel *ch; + + if (p->chid >= g->fifo.num_channels) { + nvgpu_err(g, "invalid chid %d", p->chid); + return; + } + + ch = &g->fifo.channel[p->chid]; + g->ops.channel.set_error_notifier(ch, p->error); +} + +void vgpu_channel_abort_cleanup(struct gk20a *g, u32 chid) +{ + struct nvgpu_channel *ch = nvgpu_channel_from_id(g, chid); + + if (ch == NULL) { + nvgpu_err(g, "invalid channel id %d", chid); + return; + } + + nvgpu_channel_set_unserviceable(ch); + g->ops.channel.abort_clean_up(ch); + nvgpu_channel_put(ch); +} diff --git a/drivers/gpu/nvgpu/common/vgpu/fifo/channel_vgpu.h b/drivers/gpu/nvgpu/common/vgpu/fifo/channel_vgpu.h new file mode 100644 index 000000000..7b3f33518 --- /dev/null +++ b/drivers/gpu/nvgpu/common/vgpu/fifo/channel_vgpu.h @@ -0,0 +1,41 @@ +/* + * 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 NVGPU_CHANNEL_VGPU_H +#define NVGPU_CHANNEL_VGPU_H + +struct gk20a; +struct nvgpu_channel; + +void vgpu_channel_bind(struct nvgpu_channel *ch); +void vgpu_channel_unbind(struct nvgpu_channel *ch); +int vgpu_channel_alloc_inst(struct gk20a *g, struct nvgpu_channel *ch); +void vgpu_channel_free_inst(struct gk20a *g, struct nvgpu_channel *ch); +void vgpu_channel_enable(struct nvgpu_channel *ch); +void vgpu_channel_disable(struct nvgpu_channel *ch); +u32 vgpu_channel_count(struct gk20a *g); +void vgpu_channel_set_ctx_mmu_error(struct gk20a *g, struct nvgpu_channel *ch); +void vgpu_channel_set_error_notifier(struct gk20a *g, + struct tegra_vgpu_channel_set_error_notifier *p); +void vgpu_channel_abort_cleanup(struct gk20a *g, u32 chid); + +#endif diff --git a/drivers/gpu/nvgpu/common/vgpu/fifo/engines_vgpu.c b/drivers/gpu/nvgpu/common/vgpu/fifo/engines_vgpu.c new file mode 100644 index 000000000..8a700cded --- /dev/null +++ b/drivers/gpu/nvgpu/common/vgpu/fifo/engines_vgpu.c @@ -0,0 +1,72 @@ +/* + * 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 + +#include "engines_vgpu.h" + +int vgpu_engine_init_info(struct nvgpu_fifo *f) +{ + struct vgpu_priv_data *priv = vgpu_get_priv_data(f->g); + struct tegra_vgpu_engines_info *engines = &priv->constants.engines_info; + u32 i; + struct gk20a *g = f->g; + + nvgpu_log_fn(g, " "); + + if (engines->num_engines > TEGRA_VGPU_MAX_ENGINES) { + nvgpu_err(f->g, "num_engines %d larger than max %d", + engines->num_engines, TEGRA_VGPU_MAX_ENGINES); + return -EINVAL; + } + + f->num_engines = engines->num_engines; + for (i = 0; i < f->num_engines; i++) { + struct nvgpu_engine_info *info = + &f->engine_info[engines->info[i].engine_id]; + + if (engines->info[i].engine_id >= f->max_engines) { + nvgpu_err(f->g, "engine id %d larger than max %d", + engines->info[i].engine_id, + f->max_engines); + return -EINVAL; + } + + info->intr_mask = engines->info[i].intr_mask; + info->reset_mask = engines->info[i].reset_mask; + info->runlist_id = engines->info[i].runlist_id; + info->pbdma_id = engines->info[i].pbdma_id; + info->inst_id = engines->info[i].inst_id; + info->pri_base = engines->info[i].pri_base; + info->engine_enum = engines->info[i].engine_enum; + info->fault_id = engines->info[i].fault_id; + f->active_engines_list[i] = engines->info[i].engine_id; + } + + nvgpu_log_fn(g, "done"); + + return 0; +} diff --git a/drivers/gpu/nvgpu/common/vgpu/fifo/engines_vgpu.h b/drivers/gpu/nvgpu/common/vgpu/fifo/engines_vgpu.h new file mode 100644 index 000000000..ebf922833 --- /dev/null +++ b/drivers/gpu/nvgpu/common/vgpu/fifo/engines_vgpu.h @@ -0,0 +1,28 @@ +/* + * 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 NVGPU_ENGINES_VGPU_H +#define NVGPU_ENGINES_VGPU_H + +int vgpu_engine_init_info(struct nvgpu_fifo *f); + +#endif diff --git a/drivers/gpu/nvgpu/common/vgpu/fifo/fifo_vgpu.c b/drivers/gpu/nvgpu/common/vgpu/fifo/fifo_vgpu.c index f62f9d76f..846b8ab6e 100644 --- a/drivers/gpu/nvgpu/common/vgpu/fifo/fifo_vgpu.c +++ b/drivers/gpu/nvgpu/common/vgpu/fifo/fifo_vgpu.c @@ -33,177 +33,20 @@ #include #include #include -#include -#include #include #include #include -#include #include #include #include +#include +#include #include #include "fifo_vgpu.h" -#include "common/vgpu/gr/subctx_vgpu.h" -#include "common/vgpu/ivc/comm_vgpu.h" - -void vgpu_channel_bind(struct nvgpu_channel *ch) -{ - struct tegra_vgpu_cmd_msg msg; - struct tegra_vgpu_channel_config_params *p = - &msg.params.channel_config; - int err; - struct gk20a *g = ch->g; - - nvgpu_log_info(g, "bind channel %d", ch->chid); - - msg.cmd = TEGRA_VGPU_CMD_CHANNEL_BIND; - msg.handle = vgpu_get_handle(ch->g); - p->handle = ch->virt_ctx; - err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); - WARN_ON(err || msg.ret); - - nvgpu_smp_wmb(); - nvgpu_atomic_set(&ch->bound, true); -} - -void vgpu_channel_unbind(struct nvgpu_channel *ch) -{ - struct gk20a *g = ch->g; - - nvgpu_log_fn(g, " "); - - if (nvgpu_atomic_cmpxchg(&ch->bound, true, false)) { - struct tegra_vgpu_cmd_msg msg; - struct tegra_vgpu_channel_config_params *p = - &msg.params.channel_config; - int err; - - msg.cmd = TEGRA_VGPU_CMD_CHANNEL_UNBIND; - msg.handle = vgpu_get_handle(ch->g); - p->handle = ch->virt_ctx; - err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); - WARN_ON(err || msg.ret); - } - -} - -int vgpu_channel_alloc_inst(struct gk20a *g, struct nvgpu_channel *ch) -{ - struct tegra_vgpu_cmd_msg msg; - struct tegra_vgpu_channel_hwctx_params *p = &msg.params.channel_hwctx; - int err; - - nvgpu_log_fn(g, " "); - - msg.cmd = TEGRA_VGPU_CMD_CHANNEL_ALLOC_HWCTX; - msg.handle = vgpu_get_handle(g); - p->id = ch->chid; - p->pid = (u64)ch->pid; - err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); - if (err || msg.ret) { - nvgpu_err(g, "fail"); - return -ENOMEM; - } - - ch->virt_ctx = p->handle; - nvgpu_log_fn(g, "done"); - return 0; -} - -void vgpu_channel_free_inst(struct gk20a *g, struct nvgpu_channel *ch) -{ - struct tegra_vgpu_cmd_msg msg; - struct tegra_vgpu_channel_hwctx_params *p = &msg.params.channel_hwctx; - int err; - - nvgpu_log_fn(g, " "); - - msg.cmd = TEGRA_VGPU_CMD_CHANNEL_FREE_HWCTX; - msg.handle = vgpu_get_handle(g); - p->handle = ch->virt_ctx; - err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); - WARN_ON(err || msg.ret); -} - -void vgpu_channel_enable(struct nvgpu_channel *ch) -{ - struct tegra_vgpu_cmd_msg msg; - struct tegra_vgpu_channel_config_params *p = - &msg.params.channel_config; - int err; - struct gk20a *g = ch->g; - - nvgpu_log_fn(g, " "); - - msg.cmd = TEGRA_VGPU_CMD_CHANNEL_ENABLE; - msg.handle = vgpu_get_handle(ch->g); - p->handle = ch->virt_ctx; - err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); - WARN_ON(err || msg.ret); -} - -void vgpu_channel_disable(struct nvgpu_channel *ch) -{ - struct tegra_vgpu_cmd_msg msg; - struct tegra_vgpu_channel_config_params *p = - &msg.params.channel_config; - int err; - struct gk20a *g = ch->g; - - nvgpu_log_fn(g, " "); - - msg.cmd = TEGRA_VGPU_CMD_CHANNEL_DISABLE; - msg.handle = vgpu_get_handle(ch->g); - p->handle = ch->virt_ctx; - err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); - WARN_ON(err || msg.ret); -} - -int vgpu_fifo_init_engine_info(struct nvgpu_fifo *f) -{ - struct vgpu_priv_data *priv = vgpu_get_priv_data(f->g); - struct tegra_vgpu_engines_info *engines = &priv->constants.engines_info; - u32 i; - struct gk20a *g = f->g; - - nvgpu_log_fn(g, " "); - - if (engines->num_engines > TEGRA_VGPU_MAX_ENGINES) { - nvgpu_err(f->g, "num_engines %d larger than max %d", - engines->num_engines, TEGRA_VGPU_MAX_ENGINES); - return -EINVAL; - } - - f->num_engines = engines->num_engines; - for (i = 0; i < f->num_engines; i++) { - struct nvgpu_engine_info *info = - &f->engine_info[engines->info[i].engine_id]; - - if (engines->info[i].engine_id >= f->max_engines) { - nvgpu_err(f->g, "engine id %d larger than max %d", - engines->info[i].engine_id, - f->max_engines); - return -EINVAL; - } - - info->intr_mask = engines->info[i].intr_mask; - info->reset_mask = engines->info[i].reset_mask; - info->runlist_id = engines->info[i].runlist_id; - info->pbdma_id = engines->info[i].pbdma_id; - info->inst_id = engines->info[i].inst_id; - info->pri_base = engines->info[i].pri_base; - info->engine_enum = engines->info[i].engine_enum; - info->fault_id = engines->info[i].fault_id; - f->active_engines_list[i] = engines->info[i].engine_id; - } - - nvgpu_log_fn(g, "done"); - - return 0; -} +#include "channel_vgpu.h" +#include "tsg_vgpu.h" void vgpu_fifo_cleanup_sw(struct gk20a *g) { @@ -308,159 +151,15 @@ int vgpu_init_fifo_setup_hw(struct gk20a *g) return 0; } -int vgpu_fifo_preempt_channel(struct gk20a *g, struct nvgpu_channel *ch) -{ - struct tegra_vgpu_cmd_msg msg; - struct tegra_vgpu_channel_config_params *p = - &msg.params.channel_config; - int err; - - nvgpu_log_fn(g, " "); - - if (!nvgpu_atomic_read(&ch->bound)) { - return 0; - } - - msg.cmd = TEGRA_VGPU_CMD_CHANNEL_PREEMPT; - msg.handle = vgpu_get_handle(g); - p->handle = ch->virt_ctx; - err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); - - if (err || msg.ret) { - nvgpu_err(g, - "preempt channel %d failed", ch->chid); - err = -ENOMEM; - } - - return err; -} - -int vgpu_fifo_preempt_tsg(struct gk20a *g, struct nvgpu_tsg *tsg) -{ - struct tegra_vgpu_cmd_msg msg; - struct tegra_vgpu_tsg_preempt_params *p = - &msg.params.tsg_preempt; - int err; - - nvgpu_log_fn(g, " "); - - msg.cmd = TEGRA_VGPU_CMD_TSG_PREEMPT; - msg.handle = vgpu_get_handle(g); - p->tsg_id = tsg->tsgid; - err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); - err = err ? err : msg.ret; - - if (err) { - nvgpu_err(g, - "preempt tsg %u failed", tsg->tsgid); - } - - return err; -} - -int vgpu_tsg_force_reset_ch(struct nvgpu_channel *ch, - u32 err_code, bool verbose) -{ - struct nvgpu_tsg *tsg = NULL; - struct nvgpu_channel *ch_tsg = NULL; - struct gk20a *g = ch->g; - struct tegra_vgpu_cmd_msg msg = {0}; - struct tegra_vgpu_channel_config_params *p = - &msg.params.channel_config; - int err; - - nvgpu_log_fn(g, " "); - - tsg = nvgpu_tsg_from_ch(ch); - if (tsg != NULL) { - nvgpu_rwsem_down_read(&tsg->ch_list_lock); - - nvgpu_list_for_each_entry(ch_tsg, &tsg->ch_list, - nvgpu_channel, ch_entry) { - if (nvgpu_channel_get(ch_tsg)) { - nvgpu_channel_set_error_notifier(g, ch_tsg, - err_code); - nvgpu_channel_set_unserviceable(ch_tsg); - nvgpu_channel_put(ch_tsg); - } - } - - nvgpu_rwsem_up_read(&tsg->ch_list_lock); - } else { - nvgpu_err(g, "chid: %d is not bound to tsg", ch->chid); - } - - msg.cmd = TEGRA_VGPU_CMD_CHANNEL_FORCE_RESET; - msg.handle = vgpu_get_handle(ch->g); - p->handle = ch->virt_ctx; - err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); - WARN_ON(err || msg.ret); - if (!err) { - nvgpu_channel_abort(ch, false); - } - return err ? err : msg.ret; -} - -static void vgpu_fifo_set_ctx_mmu_error_ch(struct gk20a *g, - struct nvgpu_channel *ch) -{ - /* - * If error code is already set, this mmu fault - * was triggered as part of recovery from other - * error condition. - * Don't overwrite error flag. - */ - nvgpu_set_error_notifier_if_empty(ch, - NVGPU_ERR_NOTIFIER_FIFO_ERROR_MMU_ERR_FLT); - - /* mark channel as faulted */ - nvgpu_channel_set_unserviceable(ch); - - /* unblock pending waits */ - nvgpu_cond_broadcast_interruptible(&ch->semaphore_wq); - nvgpu_cond_broadcast_interruptible(&ch->notifier_wq); -} - -static void vgpu_fifo_set_ctx_mmu_error_ch_tsg(struct gk20a *g, - struct nvgpu_channel *ch) -{ - struct nvgpu_tsg *tsg = NULL; - struct nvgpu_channel *ch_tsg = NULL; - - tsg = nvgpu_tsg_from_ch(ch); - if (tsg != NULL) { - nvgpu_rwsem_down_read(&tsg->ch_list_lock); - - nvgpu_list_for_each_entry(ch_tsg, &tsg->ch_list, - nvgpu_channel, ch_entry) { - if (nvgpu_channel_get(ch_tsg)) { - vgpu_fifo_set_ctx_mmu_error_ch(g, ch_tsg); - nvgpu_channel_put(ch_tsg); - } - } - - nvgpu_rwsem_up_read(&tsg->ch_list_lock); - } else { - nvgpu_err(g, "chid: %d is not bound to tsg", ch->chid); - } -} - int vgpu_fifo_isr(struct gk20a *g, struct tegra_vgpu_fifo_intr_info *info) { struct nvgpu_channel *ch = nvgpu_channel_from_id(g, info->chid); nvgpu_log_fn(g, " "); - if (!ch) { - return 0; - } nvgpu_err(g, "fifo intr (%d) on ch %u", info->type, info->chid); -#ifdef CONFIG_NVGPU_TRACE - trace_gk20a_channel_reset(ch->chid, ch->tsgid); -#endif - switch (info->type) { case TEGRA_VGPU_FIFO_INTR_PBDMA: g->ops.channel.set_error_notifier(ch, @@ -471,7 +170,7 @@ int vgpu_fifo_isr(struct gk20a *g, struct tegra_vgpu_fifo_intr_info *info) NVGPU_ERR_NOTIFIER_FIFO_ERROR_IDLE_TIMEOUT); break; case TEGRA_VGPU_FIFO_INTR_MMU_FAULT: - vgpu_fifo_set_ctx_mmu_error_ch_tsg(g, ch); + vgpu_tsg_set_ctx_mmu_error(g, info->chid); nvgpu_channel_abort(ch, false); break; default: @@ -482,71 +181,3 @@ int vgpu_fifo_isr(struct gk20a *g, struct tegra_vgpu_fifo_intr_info *info) nvgpu_channel_put(ch); return 0; } - -u32 vgpu_tsg_default_timeslice_us(struct gk20a *g) -{ - struct vgpu_priv_data *priv = vgpu_get_priv_data(g); - - return priv->constants.default_timeslice_us; -} - -u32 vgpu_channel_count(struct gk20a *g) -{ - struct vgpu_priv_data *priv = vgpu_get_priv_data(g); - - return priv->constants.num_channels; -} - -void vgpu_channel_free_ctx_header(struct nvgpu_channel *c) -{ - vgpu_free_subctx_header(c->g, c->subctx, c->vm, c->virt_ctx); -} - -void vgpu_handle_channel_event(struct gk20a *g, - struct tegra_vgpu_channel_event_info *info) -{ - struct nvgpu_tsg *tsg; - - if (!info->is_tsg) { - nvgpu_err(g, "channel event posted"); - return; - } - - if (info->id >= g->fifo.num_channels || - info->event_id >= TEGRA_VGPU_CHANNEL_EVENT_ID_MAX) { - nvgpu_err(g, "invalid channel event"); - return; - } - - tsg = &g->fifo.tsg[info->id]; - - nvgpu_tsg_post_event_id(tsg, info->event_id); -} - -void vgpu_channel_abort_cleanup(struct gk20a *g, u32 chid) -{ - struct nvgpu_channel *ch = nvgpu_channel_from_id(g, chid); - - if (ch == NULL) { - nvgpu_err(g, "invalid channel id %d", chid); - return; - } - - nvgpu_channel_set_unserviceable(ch); - g->ops.channel.abort_clean_up(ch); - nvgpu_channel_put(ch); -} - -void vgpu_set_error_notifier(struct gk20a *g, - struct tegra_vgpu_channel_set_error_notifier *p) -{ - struct nvgpu_channel *ch; - - if (p->chid >= g->fifo.num_channels) { - nvgpu_err(g, "invalid chid %d", p->chid); - return; - } - - ch = &g->fifo.channel[p->chid]; - g->ops.channel.set_error_notifier(ch, p->error); -} diff --git a/drivers/gpu/nvgpu/common/vgpu/fifo/fifo_vgpu.h b/drivers/gpu/nvgpu/common/vgpu/fifo/fifo_vgpu.h index 08ec3480f..4b1c8f026 100644 --- a/drivers/gpu/nvgpu/common/vgpu/fifo/fifo_vgpu.h +++ b/drivers/gpu/nvgpu/common/vgpu/fifo/fifo_vgpu.h @@ -26,44 +26,11 @@ #include struct gk20a; -struct nvgpu_channel; -struct nvgpu_fifo; -struct nvgpu_tsg; struct tegra_vgpu_fifo_intr_info; -struct tegra_vgpu_channel_event_info; -struct tegra_vgpu_channel_set_error_notifier; int vgpu_fifo_setup_sw(struct gk20a *g); void vgpu_fifo_cleanup_sw(struct gk20a *g); int vgpu_init_fifo_setup_hw(struct gk20a *g); -void vgpu_channel_bind(struct nvgpu_channel *ch); -void vgpu_channel_unbind(struct nvgpu_channel *ch); -int vgpu_channel_alloc_inst(struct gk20a *g, struct nvgpu_channel *ch); -void vgpu_channel_free_inst(struct gk20a *g, struct nvgpu_channel *ch); -void vgpu_channel_enable(struct nvgpu_channel *ch); -void vgpu_channel_disable(struct nvgpu_channel *ch); -u32 vgpu_channel_count(struct gk20a *g); -int vgpu_fifo_init_engine_info(struct nvgpu_fifo *f); -int vgpu_fifo_preempt_channel(struct gk20a *g, struct nvgpu_channel *ch); -int vgpu_fifo_preempt_tsg(struct gk20a *g, struct nvgpu_tsg *tsg); -int vgpu_channel_set_timeslice(struct nvgpu_channel *ch, u32 timeslice); -int vgpu_tsg_force_reset_ch(struct nvgpu_channel *ch, - u32 err_code, bool verbose); -u32 vgpu_tsg_default_timeslice_us(struct gk20a *g); -int vgpu_tsg_open(struct nvgpu_tsg *tsg); -void vgpu_tsg_release(struct nvgpu_tsg *tsg); -int vgpu_tsg_bind_channel(struct nvgpu_tsg *tsg, struct nvgpu_channel *ch); -int vgpu_tsg_unbind_channel(struct nvgpu_tsg *tsg, struct nvgpu_channel *ch); -int vgpu_tsg_set_timeslice(struct nvgpu_tsg *tsg, u32 timeslice); -int vgpu_tsg_set_interleave(struct nvgpu_tsg *tsg, u32 level); -void vgpu_tsg_enable(struct nvgpu_tsg *tsg); -int vgpu_set_sm_exception_type_mask(struct nvgpu_channel *ch, u32 mask); -void vgpu_channel_free_ctx_header(struct nvgpu_channel *c); int vgpu_fifo_isr(struct gk20a *g, struct tegra_vgpu_fifo_intr_info *info); -void vgpu_handle_channel_event(struct gk20a *g, - struct tegra_vgpu_channel_event_info *info); -void vgpu_channel_abort_cleanup(struct gk20a *g, u32 chid); -void vgpu_set_error_notifier(struct gk20a *g, - struct tegra_vgpu_channel_set_error_notifier *p); #endif /* NVGPU_FIFO_VGPU_H */ diff --git a/drivers/gpu/nvgpu/common/vgpu/fifo/preempt_vgpu.c b/drivers/gpu/nvgpu/common/vgpu/fifo/preempt_vgpu.c new file mode 100644 index 000000000..03ada501c --- /dev/null +++ b/drivers/gpu/nvgpu/common/vgpu/fifo/preempt_vgpu.c @@ -0,0 +1,84 @@ +/* + * 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 +#include +#include + +#include +#include + +#include "preempt_vgpu.h" +#include "common/vgpu/ivc/comm_vgpu.h" + +int vgpu_fifo_preempt_channel(struct gk20a *g, struct nvgpu_channel *ch) +{ + struct tegra_vgpu_cmd_msg msg; + struct tegra_vgpu_channel_config_params *p = + &msg.params.channel_config; + int err; + + nvgpu_log_fn(g, " "); + + if (!nvgpu_atomic_read(&ch->bound)) { + return 0; + } + + msg.cmd = TEGRA_VGPU_CMD_CHANNEL_PREEMPT; + msg.handle = vgpu_get_handle(g); + p->handle = ch->virt_ctx; + err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); + + if (err || msg.ret) { + nvgpu_err(g, + "preempt channel %d failed", ch->chid); + err = -ENOMEM; + } + + return err; +} + +int vgpu_fifo_preempt_tsg(struct gk20a *g, struct nvgpu_tsg *tsg) +{ + struct tegra_vgpu_cmd_msg msg; + struct tegra_vgpu_tsg_preempt_params *p = + &msg.params.tsg_preempt; + int err; + + nvgpu_log_fn(g, " "); + + msg.cmd = TEGRA_VGPU_CMD_TSG_PREEMPT; + msg.handle = vgpu_get_handle(g); + p->tsg_id = tsg->tsgid; + err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); + err = err ? err : msg.ret; + + if (err) { + nvgpu_err(g, + "preempt tsg %u failed", tsg->tsgid); + } + + return err; +} diff --git a/drivers/gpu/nvgpu/common/vgpu/fifo/preempt_vgpu.h b/drivers/gpu/nvgpu/common/vgpu/fifo/preempt_vgpu.h new file mode 100644 index 000000000..ce142d892 --- /dev/null +++ b/drivers/gpu/nvgpu/common/vgpu/fifo/preempt_vgpu.h @@ -0,0 +1,33 @@ +/* + * 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 NVGPU_PREEMPT_VGPU_H +#define NVGPU_PREEMPT_VGPU_H + +struct gk20a; +struct nvgpu_channel; +struct nvgpu_tsg; + +int vgpu_fifo_preempt_channel(struct gk20a *g, struct nvgpu_channel *ch); +int vgpu_fifo_preempt_tsg(struct gk20a *g, struct nvgpu_tsg *tsg); + +#endif diff --git a/drivers/gpu/nvgpu/common/vgpu/tsg_vgpu.c b/drivers/gpu/nvgpu/common/vgpu/fifo/tsg_vgpu.c similarity index 69% rename from drivers/gpu/nvgpu/common/vgpu/tsg_vgpu.c rename to drivers/gpu/nvgpu/common/vgpu/fifo/tsg_vgpu.c index 18fe54a89..f3e50e8d3 100644 --- a/drivers/gpu/nvgpu/common/vgpu/tsg_vgpu.c +++ b/drivers/gpu/nvgpu/common/vgpu/fifo/tsg_vgpu.c @@ -26,9 +26,11 @@ #include #include +#include #include -#include "fifo/fifo_vgpu.h" +#include "tsg_vgpu.h" +#include "channel_vgpu.h" #include "common/vgpu/ivc/comm_vgpu.h" int vgpu_tsg_open(struct nvgpu_tsg *tsg) @@ -196,3 +198,102 @@ int vgpu_tsg_set_interleave(struct nvgpu_tsg *tsg, u32 new_level) WARN_ON(err || msg.ret); return err ? err : msg.ret; } + +int vgpu_tsg_force_reset_ch(struct nvgpu_channel *ch, + u32 err_code, bool verbose) +{ + struct nvgpu_tsg *tsg = NULL; + struct nvgpu_channel *ch_tsg = NULL; + struct gk20a *g = ch->g; + struct tegra_vgpu_cmd_msg msg = {0}; + struct tegra_vgpu_channel_config_params *p = + &msg.params.channel_config; + int err; + + nvgpu_log_fn(g, " "); + + tsg = nvgpu_tsg_from_ch(ch); + if (tsg != NULL) { + nvgpu_rwsem_down_read(&tsg->ch_list_lock); + + nvgpu_list_for_each_entry(ch_tsg, &tsg->ch_list, + nvgpu_channel, ch_entry) { + if (nvgpu_channel_get(ch_tsg)) { + nvgpu_channel_set_error_notifier(g, ch_tsg, + err_code); + nvgpu_channel_set_unserviceable(ch_tsg); + nvgpu_channel_put(ch_tsg); + } + } + + nvgpu_rwsem_up_read(&tsg->ch_list_lock); + } else { + nvgpu_err(g, "chid: %d is not bound to tsg", ch->chid); + } + + msg.cmd = TEGRA_VGPU_CMD_CHANNEL_FORCE_RESET; + msg.handle = vgpu_get_handle(ch->g); + p->handle = ch->virt_ctx; + err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); + WARN_ON(err || msg.ret); + if (!err) { + nvgpu_channel_abort(ch, false); + } + return err ? err : msg.ret; +} + +u32 vgpu_tsg_default_timeslice_us(struct gk20a *g) +{ + struct vgpu_priv_data *priv = vgpu_get_priv_data(g); + + return priv->constants.default_timeslice_us; +} + +void vgpu_tsg_set_ctx_mmu_error(struct gk20a *g, u32 chid) +{ + struct nvgpu_channel *ch = nvgpu_channel_from_id(g, chid); + struct nvgpu_tsg *tsg = NULL; + + if (ch == NULL) { + return; + } + + tsg = nvgpu_tsg_from_ch(ch); + if (tsg != NULL) { + struct nvgpu_channel *ch_tsg = NULL; + + nvgpu_rwsem_down_read(&tsg->ch_list_lock); + + nvgpu_list_for_each_entry(ch_tsg, &tsg->ch_list, + nvgpu_channel, ch_entry) { + if (nvgpu_channel_get(ch_tsg)) { + vgpu_channel_set_ctx_mmu_error(g, ch_tsg); + nvgpu_channel_put(ch_tsg); + } + } + + nvgpu_rwsem_up_read(&tsg->ch_list_lock); + } else { + nvgpu_err(g, "chid: %d is not bound to tsg", ch->chid); + } +} + +void vgpu_tsg_handle_event(struct gk20a *g, + struct tegra_vgpu_channel_event_info *info) +{ + struct nvgpu_tsg *tsg; + + if (!info->is_tsg) { + nvgpu_err(g, "channel event posted"); + return; + } + + if (info->id >= g->fifo.num_channels || + info->event_id >= TEGRA_VGPU_CHANNEL_EVENT_ID_MAX) { + nvgpu_err(g, "invalid channel event"); + return; + } + + tsg = &g->fifo.tsg[info->id]; + g->ops.tsg.post_event_id(tsg, info->event_id); +} diff --git a/drivers/gpu/nvgpu/common/vgpu/fifo/tsg_vgpu.h b/drivers/gpu/nvgpu/common/vgpu/fifo/tsg_vgpu.h new file mode 100644 index 000000000..30f20c8a3 --- /dev/null +++ b/drivers/gpu/nvgpu/common/vgpu/fifo/tsg_vgpu.h @@ -0,0 +1,48 @@ +/* + * 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 NVGPU_TSG_VGPU_H +#define NVGPU_TSG_VGPU_H + +#include + +struct gk20a; +struct nvgpu_channel; +struct nvgpu_tsg; + +int vgpu_tsg_open(struct nvgpu_tsg *tsg); +void vgpu_tsg_release(struct nvgpu_tsg *tsg); +void vgpu_tsg_enable(struct nvgpu_tsg *tsg); +int vgpu_tsg_bind_channel(struct nvgpu_tsg *tsg, struct nvgpu_channel *ch); +int vgpu_tsg_unbind_channel(struct nvgpu_tsg *tsg, struct nvgpu_channel *ch); +int vgpu_tsg_set_timeslice(struct nvgpu_tsg *tsg, u32 timeslice); +int vgpu_set_sm_exception_type_mask(struct nvgpu_channel *ch, + u32 exception_mask); +int vgpu_tsg_set_interleave(struct nvgpu_tsg *tsg, u32 new_level); +int vgpu_tsg_force_reset_ch(struct nvgpu_channel *ch, + u32 err_code, bool verbose); +u32 vgpu_tsg_default_timeslice_us(struct gk20a *g); +void vgpu_tsg_set_ctx_mmu_error(struct gk20a *g, u32 chid); +void vgpu_tsg_handle_event(struct gk20a *g, + struct tegra_vgpu_channel_event_info *info); + +#endif diff --git a/drivers/gpu/nvgpu/common/vgpu/gp10b/vgpu_hal_gp10b.c b/drivers/gpu/nvgpu/common/vgpu/gp10b/vgpu_hal_gp10b.c index 56a9a9238..700c9075b 100644 --- a/drivers/gpu/nvgpu/common/vgpu/gp10b/vgpu_hal_gp10b.c +++ b/drivers/gpu/nvgpu/common/vgpu/gp10b/vgpu_hal_gp10b.c @@ -81,6 +81,10 @@ #include "common/clk_arb/clk_arb_gp10b.h" #include "common/vgpu/fifo/fifo_vgpu.h" +#include "common/vgpu/fifo/channel_vgpu.h" +#include "common/vgpu/fifo/tsg_vgpu.h" +#include "common/vgpu/fifo/engines_vgpu.h" +#include "common/vgpu/fifo/preempt_vgpu.h" #include "common/vgpu/fifo/runlist_vgpu.h" #include "common/vgpu/fifo/ramfc_vgpu.h" #include "common/vgpu/fifo/userd_vgpu.h" @@ -455,7 +459,7 @@ static const struct gpu_ops vgpu_gp10b_ops = { .engine = { .is_fault_engine_subid_gpc = gm20b_is_fault_engine_subid_gpc, .get_mask_on_id = NULL, - .init_info = vgpu_fifo_init_engine_info, + .init_info = vgpu_engine_init_info, }, .pbdma = { .setup_sw = NULL, diff --git a/drivers/gpu/nvgpu/common/vgpu/gr/subctx_vgpu.c b/drivers/gpu/nvgpu/common/vgpu/gr/subctx_vgpu.c index 0ece097bd..754119c52 100644 --- a/drivers/gpu/nvgpu/common/vgpu/gr/subctx_vgpu.c +++ b/drivers/gpu/nvgpu/common/vgpu/gr/subctx_vgpu.c @@ -103,3 +103,8 @@ void vgpu_free_subctx_header(struct gk20a *g, struct nvgpu_gr_subctx *subctx, nvgpu_kfree(g, subctx); } } + +void vgpu_gr_setup_free_subctx(struct nvgpu_channel *c) +{ + vgpu_free_subctx_header(c->g, c->subctx, c->vm, c->virt_ctx); +} diff --git a/drivers/gpu/nvgpu/common/vgpu/gr/subctx_vgpu.h b/drivers/gpu/nvgpu/common/vgpu/gr/subctx_vgpu.h index a1b60884f..c3ae21c07 100644 --- a/drivers/gpu/nvgpu/common/vgpu/gr/subctx_vgpu.h +++ b/drivers/gpu/nvgpu/common/vgpu/gr/subctx_vgpu.h @@ -26,11 +26,13 @@ struct gk20a; struct nvgpu_gr_subctx; struct vm_gk20a; +struct nvgpu_channel; int vgpu_alloc_subctx_header(struct gk20a *g, struct nvgpu_gr_subctx **gr_subctx, struct vm_gk20a *vm, u64 virt_ctx); void vgpu_free_subctx_header(struct gk20a *g, struct nvgpu_gr_subctx *subctx, struct vm_gk20a *vm, u64 virt_ctx); +void vgpu_gr_setup_free_subctx(struct nvgpu_channel *c); #endif /* NVGPU_SUBCTX_VGPU_H */ diff --git a/drivers/gpu/nvgpu/common/vgpu/gv11b/vgpu_hal_gv11b.c b/drivers/gpu/nvgpu/common/vgpu/gv11b/vgpu_hal_gv11b.c index 2ca6ca878..61918b63f 100644 --- a/drivers/gpu/nvgpu/common/vgpu/gv11b/vgpu_hal_gv11b.c +++ b/drivers/gpu/nvgpu/common/vgpu/gv11b/vgpu_hal_gv11b.c @@ -95,11 +95,16 @@ #include #include "common/vgpu/fifo/fifo_vgpu.h" +#include "common/vgpu/fifo/channel_vgpu.h" +#include "common/vgpu/fifo/tsg_vgpu.h" +#include "common/vgpu/fifo/engines_vgpu.h" +#include "common/vgpu/fifo/preempt_vgpu.h" #include "common/vgpu/fifo/runlist_vgpu.h" #include "common/vgpu/fifo/ramfc_vgpu.h" #include "common/vgpu/fifo/userd_vgpu.h" #include "common/vgpu/gr/gr_vgpu.h" #include "common/vgpu/gr/ctx_vgpu.h" +#include "common/vgpu/gr/subctx_vgpu.h" #include "common/vgpu/ltc/ltc_vgpu.h" #include "common/vgpu/mm/mm_vgpu.h" #include "common/vgpu/cbc/cbc_vgpu.h" @@ -315,7 +320,7 @@ static const struct gpu_ops vgpu_gv11b_ops = { #endif .alloc_obj_ctx = vgpu_gr_alloc_obj_ctx, .free_gr_ctx = vgpu_gr_free_gr_ctx, - .free_subctx = vgpu_channel_free_ctx_header, + .free_subctx = vgpu_gr_setup_free_subctx, .set_preemption_mode = vgpu_gr_set_preemption_mode, }, #ifdef CONFIG_NVGPU_GRAPHICS @@ -541,7 +546,7 @@ static const struct gpu_ops vgpu_gv11b_ops = { .engine = { .is_fault_engine_subid_gpc = gv11b_is_fault_engine_subid_gpc, .get_mask_on_id = NULL, - .init_info = vgpu_fifo_init_engine_info, + .init_info = vgpu_engine_init_info, }, .pbdma = { .setup_sw = NULL, diff --git a/drivers/gpu/nvgpu/common/vgpu/intr/intr_vgpu.c b/drivers/gpu/nvgpu/common/vgpu/intr/intr_vgpu.c index 2c2a4a03e..a41f8c9d4 100644 --- a/drivers/gpu/nvgpu/common/vgpu/intr/intr_vgpu.c +++ b/drivers/gpu/nvgpu/common/vgpu/intr/intr_vgpu.c @@ -28,6 +28,8 @@ #include "intr_vgpu.h" #include "common/vgpu/gr/fecs_trace_vgpu.h" #include "common/vgpu/fifo/fifo_vgpu.h" +#include "common/vgpu/fifo/channel_vgpu.h" +#include "common/vgpu/fifo/tsg_vgpu.h" #include "common/vgpu/mm/mm_vgpu.h" #include "common/vgpu/gr/gr_vgpu.h" @@ -73,7 +75,7 @@ int vgpu_intr_thread(void *dev_id) break; #endif case TEGRA_VGPU_EVENT_CHANNEL: - vgpu_handle_channel_event(g, &msg->info.channel_event); + vgpu_tsg_handle_event(g, &msg->info.channel_event); break; case TEGRA_VGPU_EVENT_SM_ESR: vgpu_gr_handle_sm_esr_event(g, &msg->info.sm_esr); @@ -87,7 +89,7 @@ int vgpu_intr_thread(void *dev_id) msg->info.ch_cleanup.chid); break; case TEGRA_VGPU_EVENT_SET_ERROR_NOTIFIER: - vgpu_set_error_notifier(g, + vgpu_channel_set_error_notifier(g, &msg->info.set_error_notifier); break; default: