From 9b66fca1652099db305f701f866f5715a845349c Mon Sep 17 00:00:00 2001 From: Richard Zhao Date: Mon, 24 May 2021 18:21:57 -0700 Subject: [PATCH] gpu: nvgpu: move .exec_regops to only execute regops HAL .exec_regops used to first validate regops then execute it, now moving it to only execute the regops. - It helps B0CC on HV. On server side it does not track profiler object, but regops validation uses the profiler, so moving validation to client side. - The change also remove ctx_buffer_offset checking in validate_reg_op_offset. The offset already checked again whitelists which have be verified when update whitelist. Also vgpu does not have information of ctx and golden image. - Added function nvgpu_regops_exec to cover both regops validation and execution. Jira GVSCI-10351 Signed-off-by: Richard Zhao Change-Id: I434e027290e263a8a64a25a55500f7294038c9c4 Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2534252 Reviewed-by: svc-mobile-coverity Reviewed-by: svc-mobile-cert Reviewed-by: svc_kernel_abi Reviewed-by: Deepak Nibade Reviewed-by: mobile promotions GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/regops/regops.c | 72 +++++++++---------- drivers/gpu/nvgpu/common/vgpu/debugger_vgpu.c | 14 ++-- drivers/gpu/nvgpu/common/vgpu/debugger_vgpu.h | 12 ++-- .../gpu/nvgpu/include/nvgpu/gops/debugger.h | 3 +- drivers/gpu/nvgpu/include/nvgpu/regops.h | 11 ++- drivers/gpu/nvgpu/os/linux/ioctl_dbg.c | 2 +- drivers/gpu/nvgpu/os/linux/ioctl_prof.c | 2 +- 7 files changed, 58 insertions(+), 58 deletions(-) diff --git a/drivers/gpu/nvgpu/common/regops/regops.c b/drivers/gpu/nvgpu/common/regops/regops.c index 5feba5565..5502a2d2a 100644 --- a/drivers/gpu/nvgpu/common/regops/regops.c +++ b/drivers/gpu/nvgpu/common/regops/regops.c @@ -1,7 +1,7 @@ /* * Tegra GK20A GPU Debugger Driver Register Ops * - * Copyright (c) 2013-2020, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2013-2021, 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"), @@ -88,29 +88,19 @@ static bool validate_reg_ops(struct gk20a *g, int exec_regops_gk20a(struct gk20a *g, struct nvgpu_tsg *tsg, - struct nvgpu_profiler_object *prof, struct nvgpu_dbg_reg_op *ops, u32 num_ops, + u32 ctx_wr_count, + u32 ctx_rd_count, u32 *flags) { int err = 0; unsigned int i; u32 data32_lo = 0, data32_hi = 0; - u32 ctx_rd_count = 0, ctx_wr_count = 0; bool skip_read_lo, skip_read_hi; - bool ok; nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, " "); - ok = validate_reg_ops(g, prof, &ctx_rd_count, &ctx_wr_count, - ops, num_ops, tsg != NULL, flags); - if (!ok) { - nvgpu_err(g, "invalid op(s)"); - err = -EINVAL; - /* each op has its own err/status */ - goto clean_up; - } - /* be sure that ctx info is in place if there are ctx ops */ if ((ctx_wr_count | ctx_rd_count) != 0U) { if (!gr_context_info_available(g)) { @@ -226,6 +216,34 @@ int exec_regops_gk20a(struct gk20a *g, } +int nvgpu_regops_exec(struct gk20a *g, + struct nvgpu_tsg *tsg, + struct nvgpu_profiler_object *prof, + struct nvgpu_dbg_reg_op *ops, + u32 num_ops, + u32 *flags) +{ + u32 ctx_rd_count = 0, ctx_wr_count = 0; + int err = 0; + bool ok; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, " "); + + ok = validate_reg_ops(g, prof, &ctx_rd_count, &ctx_wr_count, + ops, num_ops, tsg != NULL, flags); + if (!ok) { + nvgpu_err(g, "invalid op(s)"); + return -EINVAL; + } + + err = g->ops.regops.exec_regops(g, tsg, ops, num_ops, ctx_wr_count, + ctx_rd_count, flags); + if (err != 0) { + nvgpu_warn(g, "failed to perform regops, err=%d", err); + } + + return err; +} static int validate_reg_op_info(struct nvgpu_dbg_reg_op *op) { @@ -360,8 +378,7 @@ static int validate_reg_op_offset(struct gk20a *g, struct nvgpu_dbg_reg_op *op, bool valid_ctx) { - int err; - u32 buf_offset_lo, buf_offset_addr, num_offsets, offset; + u32 offset; bool valid = false; offset = op->offset; @@ -378,31 +395,6 @@ static int validate_reg_op_offset(struct gk20a *g, valid = check_whitelists(g, op, offset + 4U, valid_ctx); } - if (valid && (op->type != REGOP(TYPE_GLOBAL))) { - err = g->ops.gr.get_ctx_buffer_offsets(g, - op->offset, - 1, - &buf_offset_lo, - &buf_offset_addr, - &num_offsets); - if (err != 0) { - err = gr_gk20a_get_pm_ctx_buffer_offsets(g, - op->offset, - 1, - &buf_offset_lo, - &buf_offset_addr, - &num_offsets); - if (err != 0) { - op->status |= REGOP(STATUS_INVALID_OFFSET); - return -EINVAL; - } - } - if (num_offsets == 0U) { - op->status |= REGOP(STATUS_INVALID_OFFSET); - return -EINVAL; - } - } - if (!valid) { nvgpu_err(g, "invalid regop offset: 0x%x", offset); op->status |= REGOP(STATUS_INVALID_OFFSET); diff --git a/drivers/gpu/nvgpu/common/vgpu/debugger_vgpu.c b/drivers/gpu/nvgpu/common/vgpu/debugger_vgpu.c index c403ca2bd..14c5c0ea5 100644 --- a/drivers/gpu/nvgpu/common/vgpu/debugger_vgpu.c +++ b/drivers/gpu/nvgpu/common/vgpu/debugger_vgpu.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -35,11 +34,12 @@ #include "common/vgpu/ivc/comm_vgpu.h" int vgpu_exec_regops(struct gk20a *g, - struct nvgpu_tsg *tsg, - struct nvgpu_profiler_object *prof, - struct nvgpu_dbg_reg_op *ops, - u32 num_ops, - u32 *flags) + struct nvgpu_tsg *tsg, + struct nvgpu_dbg_reg_op *ops, + u32 num_ops, + u32 ctx_wr_count, + u32 ctx_rd_count, + u32 *flags) { struct tegra_vgpu_cmd_msg msg; struct tegra_vgpu_reg_ops_params *p = &msg.params.reg_ops; @@ -139,4 +139,4 @@ int vgpu_tsg_set_long_timeslice(struct nvgpu_tsg *tsg, u32 timeslice_us) } return err; -} \ No newline at end of file +} diff --git a/drivers/gpu/nvgpu/common/vgpu/debugger_vgpu.h b/drivers/gpu/nvgpu/common/vgpu/debugger_vgpu.h index d0bea845d..f2fcaa651 100644 --- a/drivers/gpu/nvgpu/common/vgpu/debugger_vgpu.h +++ b/drivers/gpu/nvgpu/common/vgpu/debugger_vgpu.h @@ -25,16 +25,16 @@ struct dbg_session_gk20a; struct nvgpu_dbg_reg_op; -struct nvgpu_profiler_object; struct gk20a; struct nvgpu_channel; int vgpu_exec_regops(struct gk20a *g, - struct nvgpu_tsg *tsg, - struct nvgpu_profiler_object *prof, - struct nvgpu_dbg_reg_op *ops, - u32 num_ops, - u32 *flags); + struct nvgpu_tsg *tsg, + struct nvgpu_dbg_reg_op *ops, + u32 num_ops, + u32 ctx_wr_count, + u32 ctx_rd_count, + u32 *flags); int vgpu_dbg_set_powergate(struct dbg_session_gk20a *dbg_s, bool disable_powergate); int vgpu_tsg_set_long_timeslice(struct nvgpu_tsg *tsg, u32 timeslice_us); diff --git a/drivers/gpu/nvgpu/include/nvgpu/gops/debugger.h b/drivers/gpu/nvgpu/include/nvgpu/gops/debugger.h index 0d9ef03c8..f84491f9b 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gops/debugger.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gops/debugger.h @@ -26,9 +26,10 @@ struct gops_regops { int (*exec_regops)(struct gk20a *g, struct nvgpu_tsg *tsg, - struct nvgpu_profiler_object *prof, struct nvgpu_dbg_reg_op *ops, u32 num_ops, + u32 ctx_wr_count, + u32 ctx_rd_count, u32 *flags); const struct regop_offset_range* ( *get_global_whitelist_ranges)(void); diff --git a/drivers/gpu/nvgpu/include/nvgpu/regops.h b/drivers/gpu/nvgpu/include/nvgpu/regops.h index bd0df7b7d..a906c2e79 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/regops.h +++ b/drivers/gpu/nvgpu/include/nvgpu/regops.h @@ -1,7 +1,7 @@ /* * Tegra GK20A GPU Debugger Driver Register Ops * - * Copyright (c) 2013-2019, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2013-2021, 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"), @@ -89,10 +89,17 @@ struct regop_offset_range { int exec_regops_gk20a(struct gk20a *g, struct nvgpu_tsg *tsg, - struct nvgpu_profiler_object *prof, struct nvgpu_dbg_reg_op *ops, u32 num_ops, + u32 ctx_wr_count, + u32 ctx_rd_count, u32 *flags); +int nvgpu_regops_exec(struct gk20a *g, + struct nvgpu_tsg *tsg, + struct nvgpu_profiler_object *prof, + struct nvgpu_dbg_reg_op *ops, + u32 num_ops, + u32 *flags); /* turn seriously unwieldy names -> something shorter */ #define REGOP(x) NVGPU_DBG_REG_OP_##x diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c b/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c index 074f24f26..b8041d3b8 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c @@ -952,7 +952,7 @@ static int nvgpu_ioctl_channel_reg_ops(struct dbg_session_gk20a *dbg_s, break; err = nvgpu_gr_exec_with_err_for_instance(g, gr_instance_id, - g->ops.regops.exec_regops(g, tsg, NULL, + nvgpu_regops_exec(g, tsg, NULL, g->dbg_regops_tmp_buf, num_ops, &flags)); if (err) { diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_prof.c b/drivers/gpu/nvgpu/os/linux/ioctl_prof.c index 1d49f1087..0f2439cf1 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_prof.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_prof.c @@ -668,7 +668,7 @@ static int nvgpu_prof_ioctl_exec_reg_ops(struct nvgpu_profiler_object_priv *priv } err = nvgpu_gr_exec_with_err_for_instance(g, gr_instance_id, - g->ops.regops.exec_regops(g, tsg, prof, + nvgpu_regops_exec(g, tsg, prof, priv->regops_staging_buf, num_ops, &flags)); if (err) {