mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +03:00
gpu: nvgpu: remove debugger include from regops
Regops does not depend on debug session logically We right now include debugger.h in regops_gk20a.c to extract channel pointer from debug session and to check if session is for profiling or not Update exec_regops_gk20a() to receive channel pointer and profiler flag directly as parameters, and remove dbg_session_gk20a from parameter list Remove ((!dbg_s->is_profiler) && (ch != NULL)) checks from check_whitelists(). Caller of exec_regops_gk20a() already ensures that we have context bound for debug session Use only is_profiler boolean flag in this case which should be sufficient Remove (ch == NULL) check in check_whitelists() if regops is of type gr_ctx. Instead move this check to earlier function call in validate_reg_ops(). If we have non-zero context operation on a profiler session, return error from validate_reg_ops() Update all subsequent calls with appropriate parameter list Remove debugger.h include from regops_gk20a.c Jira NVGPU-620 Change-Id: If857c21da1a43a2230c1f7ef2cc2ad6640ff48d9 Signed-off-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1997868 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
0ff5a49f45
commit
b3b87cf303
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Tegra GK20A GPU Debugger Driver Register Ops
|
||||
*
|
||||
* Copyright (c) 2013-2018, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2013-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"),
|
||||
@@ -25,7 +25,6 @@
|
||||
#include "gr_gk20a.h"
|
||||
#include "regops_gk20a.h"
|
||||
|
||||
#include <nvgpu/debugger.h>
|
||||
#include <nvgpu/log.h>
|
||||
#include <nvgpu/bsearch.h>
|
||||
#include <nvgpu/bug.h>
|
||||
@@ -82,22 +81,21 @@ static bool gr_context_info_available(struct gr_gk20a *gr)
|
||||
|
||||
}
|
||||
|
||||
static bool validate_reg_ops(struct dbg_session_gk20a *dbg_s,
|
||||
u32 *ctx_rd_count, u32 *ctx_wr_count,
|
||||
struct nvgpu_dbg_reg_op *ops,
|
||||
u32 op_count);
|
||||
static bool validate_reg_ops(struct gk20a *g,
|
||||
u32 *ctx_rd_count, u32 *ctx_wr_count,
|
||||
struct nvgpu_dbg_reg_op *ops,
|
||||
u32 op_count,
|
||||
bool is_profiler);
|
||||
|
||||
|
||||
int exec_regops_gk20a(struct dbg_session_gk20a *dbg_s,
|
||||
int exec_regops_gk20a(struct gk20a *g,
|
||||
struct channel_gk20a *ch,
|
||||
struct nvgpu_dbg_reg_op *ops,
|
||||
u64 num_ops,
|
||||
bool is_profiler,
|
||||
bool *is_current_ctx)
|
||||
{
|
||||
int err = 0;
|
||||
unsigned int i;
|
||||
struct channel_gk20a *ch = NULL;
|
||||
struct gk20a *g = dbg_s->g;
|
||||
/*struct gr_gk20a *gr = &g->gr;*/
|
||||
u32 data32_lo = 0, data32_hi = 0;
|
||||
u32 ctx_rd_count = 0, ctx_wr_count = 0;
|
||||
bool skip_read_lo, skip_read_hi;
|
||||
@@ -105,8 +103,6 @@ int exec_regops_gk20a(struct dbg_session_gk20a *dbg_s,
|
||||
|
||||
nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, " ");
|
||||
|
||||
ch = nvgpu_dbg_gpu_get_session_channel(dbg_s);
|
||||
|
||||
/* For vgpu, the regops routines need to be handled in the
|
||||
* context of the server and support for that does not exist.
|
||||
*
|
||||
@@ -119,9 +115,8 @@ int exec_regops_gk20a(struct dbg_session_gk20a *dbg_s,
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
ok = validate_reg_ops(dbg_s,
|
||||
&ctx_rd_count, &ctx_wr_count,
|
||||
ops, num_ops);
|
||||
ok = validate_reg_ops(g, &ctx_rd_count, &ctx_wr_count,
|
||||
ops, num_ops, is_profiler);
|
||||
if (!ok) {
|
||||
nvgpu_err(g, "invalid op(s)");
|
||||
err = -EINVAL;
|
||||
@@ -236,8 +231,7 @@ int exec_regops_gk20a(struct dbg_session_gk20a *dbg_s,
|
||||
}
|
||||
|
||||
|
||||
static int validate_reg_op_info(struct dbg_session_gk20a *dbg_s,
|
||||
struct nvgpu_dbg_reg_op *op)
|
||||
static int validate_reg_op_info(struct nvgpu_dbg_reg_op *op)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
@@ -276,14 +270,12 @@ static int validate_reg_op_info(struct dbg_session_gk20a *dbg_s,
|
||||
return err;
|
||||
}
|
||||
|
||||
static bool check_whitelists(struct dbg_session_gk20a *dbg_s,
|
||||
struct nvgpu_dbg_reg_op *op, u32 offset)
|
||||
static bool check_whitelists(struct gk20a *g,
|
||||
struct nvgpu_dbg_reg_op *op,
|
||||
u32 offset,
|
||||
bool is_profiler)
|
||||
{
|
||||
struct gk20a *g = dbg_s->g;
|
||||
bool valid = false;
|
||||
struct channel_gk20a *ch;
|
||||
|
||||
ch = nvgpu_dbg_gpu_get_session_channel(dbg_s);
|
||||
|
||||
if (op->type == REGOP(TYPE_GLOBAL)) {
|
||||
/* search global list */
|
||||
@@ -294,8 +286,8 @@ static bool check_whitelists(struct dbg_session_gk20a *dbg_s,
|
||||
sizeof(*g->ops.regops.get_global_whitelist_ranges()),
|
||||
regop_bsearch_range_cmp) != NULL);
|
||||
|
||||
/* if debug session and channel is bound search context list */
|
||||
if ((!valid) && (!dbg_s->is_profiler) && (ch != NULL)) {
|
||||
/* if debug session, search context list */
|
||||
if ((!valid) && (!is_profiler)) {
|
||||
/* binary search context list */
|
||||
valid = (g->ops.regops.get_context_whitelist_ranges != NULL) &&
|
||||
(bsearch(&offset,
|
||||
@@ -305,21 +297,14 @@ static bool check_whitelists(struct dbg_session_gk20a *dbg_s,
|
||||
regop_bsearch_range_cmp) != NULL);
|
||||
}
|
||||
|
||||
/* if debug session and channel is bound search runcontrol list */
|
||||
if ((!valid) && (!dbg_s->is_profiler) && (ch != NULL)) {
|
||||
/* if debug session, search runcontrol list */
|
||||
if ((!valid) && (!is_profiler)) {
|
||||
valid = (g->ops.regops.get_runcontrol_whitelist != NULL) &&
|
||||
linear_search(offset,
|
||||
g->ops.regops.get_runcontrol_whitelist(),
|
||||
g->ops.regops.get_runcontrol_whitelist_count());
|
||||
}
|
||||
} else if (op->type == REGOP(TYPE_GR_CTX)) {
|
||||
/* it's a context-relative op */
|
||||
if (ch == NULL) {
|
||||
nvgpu_err(dbg_s->g, "can't perform ctx regop unless bound");
|
||||
op->status = REGOP(STATUS_UNSUPPORTED_OP);
|
||||
return valid;
|
||||
}
|
||||
|
||||
/* binary search context list */
|
||||
valid = (g->ops.regops.get_context_whitelist_ranges != NULL) &&
|
||||
(bsearch(&offset,
|
||||
@@ -328,8 +313,8 @@ static bool check_whitelists(struct dbg_session_gk20a *dbg_s,
|
||||
sizeof(*g->ops.regops.get_context_whitelist_ranges()),
|
||||
regop_bsearch_range_cmp) != NULL);
|
||||
|
||||
/* if debug session and channel is bound search runcontrol list */
|
||||
if ((!valid) && (!dbg_s->is_profiler) && (ch != NULL)) {
|
||||
/* if debug session, search runcontrol list */
|
||||
if ((!valid) && (!is_profiler)) {
|
||||
valid = (g->ops.regops.get_runcontrol_whitelist != NULL) &&
|
||||
linear_search(offset,
|
||||
g->ops.regops.get_runcontrol_whitelist(),
|
||||
@@ -347,8 +332,9 @@ static bool check_whitelists(struct dbg_session_gk20a *dbg_s,
|
||||
}
|
||||
|
||||
/* note: the op here has already been through validate_reg_op_info */
|
||||
static int validate_reg_op_offset(struct dbg_session_gk20a *dbg_s,
|
||||
struct nvgpu_dbg_reg_op *op)
|
||||
static int validate_reg_op_offset(struct gk20a *g,
|
||||
struct nvgpu_dbg_reg_op *op,
|
||||
bool is_profiler)
|
||||
{
|
||||
int err;
|
||||
u32 buf_offset_lo, buf_offset_addr, num_offsets, offset;
|
||||
@@ -359,18 +345,18 @@ static int validate_reg_op_offset(struct dbg_session_gk20a *dbg_s,
|
||||
|
||||
/* support only 24-bit 4-byte aligned offsets */
|
||||
if ((offset & 0xFF000003U) != 0U) {
|
||||
nvgpu_err(dbg_s->g, "invalid regop offset: 0x%x", offset);
|
||||
nvgpu_err(g, "invalid regop offset: 0x%x", offset);
|
||||
op->status |= REGOP(STATUS_INVALID_OFFSET);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
valid = check_whitelists(dbg_s, op, offset);
|
||||
valid = check_whitelists(g, op, offset, is_profiler);
|
||||
if ((op->op == REGOP(READ_64) || op->op == REGOP(WRITE_64)) && valid) {
|
||||
valid = check_whitelists(dbg_s, op, offset + 4U);
|
||||
valid = check_whitelists(g, op, offset + 4U, is_profiler);
|
||||
}
|
||||
|
||||
if (valid && (op->type != REGOP(TYPE_GLOBAL))) {
|
||||
err = gr_gk20a_get_ctx_buffer_offsets(dbg_s->g,
|
||||
err = gr_gk20a_get_ctx_buffer_offsets(g,
|
||||
op->offset,
|
||||
1,
|
||||
&buf_offset_lo,
|
||||
@@ -379,13 +365,12 @@ static int validate_reg_op_offset(struct dbg_session_gk20a *dbg_s,
|
||||
op->type == REGOP(TYPE_GR_CTX_QUAD),
|
||||
op->quad);
|
||||
if (err != 0) {
|
||||
err = gr_gk20a_get_pm_ctx_buffer_offsets(dbg_s->g,
|
||||
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;
|
||||
@@ -398,7 +383,7 @@ static int validate_reg_op_offset(struct dbg_session_gk20a *dbg_s,
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
nvgpu_err(dbg_s->g, "invalid regop offset: 0x%x", offset);
|
||||
nvgpu_err(g, "invalid regop offset: 0x%x", offset);
|
||||
op->status |= REGOP(STATUS_INVALID_OFFSET);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -406,21 +391,23 @@ static int validate_reg_op_offset(struct dbg_session_gk20a *dbg_s,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool validate_reg_ops(struct dbg_session_gk20a *dbg_s,
|
||||
static bool validate_reg_ops(struct gk20a *g,
|
||||
u32 *ctx_rd_count, u32 *ctx_wr_count,
|
||||
struct nvgpu_dbg_reg_op *ops,
|
||||
u32 op_count)
|
||||
u32 op_count,
|
||||
bool is_profiler)
|
||||
{
|
||||
u32 i;
|
||||
bool ok = true;
|
||||
struct gk20a *g = dbg_s->g;
|
||||
bool gr_ctx_ops = false;
|
||||
|
||||
/* keep going until the end so every op can get
|
||||
* a separate error code if needed */
|
||||
for (i = 0; i < op_count; i++) {
|
||||
|
||||
if (validate_reg_op_info(dbg_s, &ops[i]) != 0) {
|
||||
if (validate_reg_op_info(&ops[i]) != 0) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (reg_op_is_gr_ctx(ops[i].type)) {
|
||||
@@ -429,18 +416,30 @@ static bool validate_reg_ops(struct dbg_session_gk20a *dbg_s,
|
||||
} else {
|
||||
(*ctx_wr_count)++;
|
||||
}
|
||||
|
||||
gr_ctx_ops = true;
|
||||
}
|
||||
|
||||
/* context operations are not valid on profiler session */
|
||||
if (gr_ctx_ops && is_profiler) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
|
||||
/* if "allow_all" flag enabled, dont validate offset */
|
||||
if (!g->allow_all) {
|
||||
if (validate_reg_op_offset(dbg_s, &ops[i]) != 0) {
|
||||
if (validate_reg_op_offset(g, &ops[i],
|
||||
is_profiler) != 0) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nvgpu_log(g, gpu_dbg_gpu_dbg, "ctx_wrs:%d ctx_rds:%d",
|
||||
*ctx_wr_count, *ctx_rd_count);
|
||||
if (ok) {
|
||||
nvgpu_log(g, gpu_dbg_gpu_dbg, "ctx_wrs:%d ctx_rds:%d",
|
||||
*ctx_wr_count, *ctx_rd_count);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Tegra GK20A GPU Debugger Driver Register Ops
|
||||
*
|
||||
* Copyright (c) 2013-2018, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2013-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"),
|
||||
@@ -75,9 +75,11 @@ struct regop_offset_range {
|
||||
u32 count:8;
|
||||
};
|
||||
|
||||
int exec_regops_gk20a(struct dbg_session_gk20a *dbg_s,
|
||||
int exec_regops_gk20a(struct gk20a *g,
|
||||
struct channel_gk20a *ch,
|
||||
struct nvgpu_dbg_reg_op *ops,
|
||||
u64 num_ops,
|
||||
bool is_profiler,
|
||||
bool *is_current_ctx);
|
||||
|
||||
/* turn seriously unwieldy names -> something shorter */
|
||||
|
||||
@@ -1284,9 +1284,11 @@ struct gpu_ops {
|
||||
bool support_vfe;
|
||||
} pmu_perf;
|
||||
struct {
|
||||
int (*exec_regops)(struct dbg_session_gk20a *dbg_s,
|
||||
int (*exec_regops)(struct gk20a *g,
|
||||
struct channel_gk20a *ch,
|
||||
struct nvgpu_dbg_reg_op *ops,
|
||||
u64 num_ops,
|
||||
bool is_profiler,
|
||||
bool *is_current_ctx);
|
||||
const struct regop_offset_range* (
|
||||
*get_global_whitelist_ranges)(void);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Tegra GK20A GPU Debugger/Profiler Driver
|
||||
*
|
||||
* Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2017-2019, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -882,8 +882,9 @@ static int nvgpu_ioctl_channel_reg_ops(struct dbg_session_gk20a *dbg_s,
|
||||
if (err)
|
||||
break;
|
||||
|
||||
err = g->ops.regops.exec_regops(
|
||||
dbg_s, g->dbg_regops_tmp_buf, num_ops, &is_current_ctx);
|
||||
err = g->ops.regops.exec_regops(g, ch,
|
||||
g->dbg_regops_tmp_buf, num_ops,
|
||||
dbg_s->is_profiler, &is_current_ctx);
|
||||
|
||||
if (err) {
|
||||
break;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2018, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2015-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"),
|
||||
@@ -32,19 +32,19 @@
|
||||
#include "gk20a/regops_gk20a.h"
|
||||
#include "dbg_vgpu.h"
|
||||
|
||||
int vgpu_exec_regops(struct dbg_session_gk20a *dbg_s,
|
||||
struct nvgpu_dbg_reg_op *ops,
|
||||
u64 num_ops,
|
||||
bool *is_current_ctx)
|
||||
int vgpu_exec_regops(struct gk20a *g,
|
||||
struct channel_gk20a *ch,
|
||||
struct nvgpu_dbg_reg_op *ops,
|
||||
u64 num_ops,
|
||||
bool is_profiler,
|
||||
bool *is_current_ctx)
|
||||
{
|
||||
struct channel_gk20a *ch;
|
||||
struct tegra_vgpu_cmd_msg msg;
|
||||
struct tegra_vgpu_reg_ops_params *p = &msg.params.reg_ops;
|
||||
void *oob;
|
||||
size_t oob_size, ops_size;
|
||||
void *handle = NULL;
|
||||
int err = 0;
|
||||
struct gk20a *g = dbg_s->g;
|
||||
|
||||
nvgpu_log_fn(g, " ");
|
||||
BUG_ON(sizeof(*ops) != sizeof(struct tegra_vgpu_reg_op));
|
||||
@@ -64,11 +64,10 @@ int vgpu_exec_regops(struct dbg_session_gk20a *dbg_s,
|
||||
nvgpu_memcpy((u8 *)oob, (u8 *)ops, ops_size);
|
||||
|
||||
msg.cmd = TEGRA_VGPU_CMD_REG_OPS;
|
||||
msg.handle = vgpu_get_handle(dbg_s->g);
|
||||
ch = nvgpu_dbg_gpu_get_session_channel(dbg_s);
|
||||
msg.handle = vgpu_get_handle(g);
|
||||
p->handle = ch ? ch->virt_ctx : 0;
|
||||
p->num_ops = num_ops;
|
||||
p->is_profiler = dbg_s->is_profiler;
|
||||
p->is_profiler = is_profiler;
|
||||
err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
|
||||
err = err ? err : msg.ret;
|
||||
if (err == 0) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2017-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"),
|
||||
@@ -27,11 +27,14 @@ struct dbg_session_gk20a;
|
||||
struct nvgpu_dbg_reg_op;
|
||||
struct dbg_profiler_object_data;
|
||||
struct gk20a;
|
||||
struct channel_gk20a;
|
||||
|
||||
int vgpu_exec_regops(struct dbg_session_gk20a *dbg_s,
|
||||
struct nvgpu_dbg_reg_op *ops,
|
||||
u64 num_ops,
|
||||
bool *is_current_ctx);
|
||||
int vgpu_exec_regops(struct gk20a *g,
|
||||
struct channel_gk20a *ch,
|
||||
struct nvgpu_dbg_reg_op *ops,
|
||||
u64 num_ops,
|
||||
bool is_profiler,
|
||||
bool *is_current_ctx);
|
||||
int vgpu_dbg_set_powergate(struct dbg_session_gk20a *dbg_s, bool disable_powergate);
|
||||
bool vgpu_check_and_set_global_reservation(
|
||||
struct dbg_session_gk20a *dbg_s,
|
||||
|
||||
Reference in New Issue
Block a user