gpu: nvgpu: re-arrange parity counters

(1) Re-arrange the structure for parity counters reporting so multiple
units can be managed

JIRA: GPUT19X-84

Change-Id: If59a883dfe22d5a1d91a6d0ed2f5a6254434ffcb
Signed-off-by: David Nieto <dmartineznie@nvidia.com>
Reviewed-on: http://git-master/r/1485276
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
David Nieto
2017-05-18 16:50:57 -07:00
committed by mobile promotions
parent 94226c9c1e
commit 05388ad24a
10 changed files with 211 additions and 93 deletions

View File

@@ -0,0 +1,20 @@
/*
* NVIDIA T18x ECC
*
* Copyright (c) 2017, 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,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#ifndef _NVGPU_ECC_T18X_H_
#define _NVGPU_ECC_T18X_H_
#include "gp10b/ecc_gp10b.h"
#endif

View File

@@ -0,0 +1,48 @@
/*
* GK20A ECC
*
* Copyright (c) 2017, 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,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ECC_GK20A_H
#define ECC_GK20A_H
#include <uapi/linux/nvgpu.h>
struct gk20a_ecc_stat {
char **names;
u32 *counters;
struct hlist_node hash_node;
};
#ifdef CONFIG_ARCH_TEGRA_18x_SOC
#include "ecc_t18x.h"
#endif
#ifdef CONFIG_TEGRA_19x_GPU
#include "ecc_t19x.h"
#endif
struct ecc_gk20a {
/* Stats per engine */
struct {
#ifdef CONFIG_ARCH_TEGRA_18x_SOC
struct ecc_gr_t18x t18x;
#endif
#ifdef CONFIG_TEGRA_19x_GPU
struct ecc_gr_t19x t19x;
#endif
} gr;
};
#endif /*__ECC_GK20A_H__*/

View File

@@ -29,6 +29,7 @@ struct gk20a_ctxsw_trace;
struct acr_desc; struct acr_desc;
struct nvgpu_mem_alloc_tracker; struct nvgpu_mem_alloc_tracker;
struct dbg_profiler_object_data; struct dbg_profiler_object_data;
struct ecc_gk20a;
#include <linux/sched.h> #include <linux/sched.h>
#include <nvgpu/lock.h> #include <nvgpu/lock.h>
@@ -69,6 +70,7 @@ struct dbg_profiler_object_data;
#include "pmgr/pmgr.h" #include "pmgr/pmgr.h"
#include "therm/thrm.h" #include "therm/thrm.h"
#endif #endif
#include "ecc_gk20a.h"
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0) #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0)
#define WRITE_ONCE(x, val) \ #define WRITE_ONCE(x, val) \
@@ -991,6 +993,7 @@ struct gk20a {
struct mm_gk20a mm; struct mm_gk20a mm;
struct pmu_gk20a pmu; struct pmu_gk20a pmu;
struct acr_desc acr; struct acr_desc acr;
struct ecc_gk20a ecc;
struct cooling_device_gk20a gk20a_cdev; struct cooling_device_gk20a gk20a_cdev;
#ifdef CONFIG_ARCH_TEGRA_18x_SOC #ifdef CONFIG_ARCH_TEGRA_18x_SOC
struct clk_pmupstate clk_pmu; struct clk_pmupstate clk_pmu;

View File

@@ -374,9 +374,6 @@ struct gr_gk20a {
#ifdef CONFIG_ARCH_TEGRA_18x_SOC #ifdef CONFIG_ARCH_TEGRA_18x_SOC
struct gr_t18x t18x; struct gr_t18x t18x;
#endif #endif
#ifdef CONFIG_TEGRA_19x_GPU
struct gr_t19x t19x;
#endif
u32 fbp_en_mask; u32 fbp_en_mask;
u32 *fbp_rop_l2_en_mask; u32 *fbp_rop_l2_en_mask;

View File

@@ -0,0 +1,41 @@
/*
* GP10B ECC
*
* Copyright (c) 2015-2017, 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,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#ifndef _NVGPU_ECC_GP10B_H_
#define _NVGPU_ECC_GP10B_H_
#include <linux/version.h>
struct ecc_gr_t18x {
struct gk20a_ecc_stat sm_lrf_single_err_count;
struct gk20a_ecc_stat sm_lrf_double_err_count;
struct gk20a_ecc_stat sm_shm_sec_count;
struct gk20a_ecc_stat sm_shm_sed_count;
struct gk20a_ecc_stat sm_shm_ded_count;
struct gk20a_ecc_stat tex_total_sec_pipe0_count;
struct gk20a_ecc_stat tex_total_ded_pipe0_count;
struct gk20a_ecc_stat tex_unique_sec_pipe0_count;
struct gk20a_ecc_stat tex_unique_ded_pipe0_count;
struct gk20a_ecc_stat tex_total_sec_pipe1_count;
struct gk20a_ecc_stat tex_total_ded_pipe1_count;
struct gk20a_ecc_stat tex_unique_sec_pipe1_count;
struct gk20a_ecc_stat tex_unique_ded_pipe1_count;
struct gk20a_ecc_stat l2_sec_count;
struct gk20a_ecc_stat l2_ded_count;
};
#endif

View File

@@ -169,7 +169,7 @@ static int gr_gp10b_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc,
lrf_ecc_ded_status, lrf_ecc_ded_status,
&lrf_single_count_delta, &lrf_single_count_delta,
lrf_double_count_delta); lrf_double_count_delta);
g->gr.t18x.ecc_stats.sm_lrf_single_err_count.counters[tpc] += g->ecc.gr.t18x.sm_lrf_single_err_count.counters[tpc] +=
lrf_single_count_delta; lrf_single_count_delta;
} }
if (lrf_ecc_ded_status) { if (lrf_ecc_ded_status) {
@@ -181,7 +181,7 @@ static int gr_gp10b_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc,
lrf_ecc_ded_status, lrf_ecc_ded_status,
&lrf_double_count_delta, &lrf_double_count_delta,
lrf_single_count_delta); lrf_single_count_delta);
g->gr.t18x.ecc_stats.sm_lrf_double_err_count.counters[tpc] += g->ecc.gr.t18x.sm_lrf_double_err_count.counters[tpc] +=
lrf_double_count_delta; lrf_double_count_delta;
} }
gk20a_writel(g, gr_pri_gpc0_tpc0_sm_lrf_ecc_status_r() + offset, gk20a_writel(g, gr_pri_gpc0_tpc0_sm_lrf_ecc_status_r() + offset,
@@ -206,9 +206,9 @@ static int gr_gp10b_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc,
ecc_stats_reg_val = ecc_stats_reg_val =
gk20a_readl(g, gk20a_readl(g,
gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_r() + offset); gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_r() + offset);
g->gr.t18x.ecc_stats.sm_shm_sec_count.counters[tpc] += g->ecc.gr.t18x.sm_shm_sec_count.counters[tpc] +=
gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_single_corrected_v(ecc_stats_reg_val); gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_single_corrected_v(ecc_stats_reg_val);
g->gr.t18x.ecc_stats.sm_shm_sed_count.counters[tpc] += g->ecc.gr.t18x.sm_shm_sed_count.counters[tpc] +=
gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_single_detected_v(ecc_stats_reg_val); gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_single_detected_v(ecc_stats_reg_val);
ecc_stats_reg_val &= ~(gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_single_corrected_m() | ecc_stats_reg_val &= ~(gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_single_corrected_m() |
gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_single_detected_m()); gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_single_detected_m());
@@ -228,7 +228,7 @@ static int gr_gp10b_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc,
ecc_stats_reg_val = ecc_stats_reg_val =
gk20a_readl(g, gk20a_readl(g,
gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_r() + offset); gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_r() + offset);
g->gr.t18x.ecc_stats.sm_shm_ded_count.counters[tpc] += g->ecc.gr.t18x.sm_shm_ded_count.counters[tpc] +=
gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_double_detected_v(ecc_stats_reg_val); gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_double_detected_v(ecc_stats_reg_val);
ecc_stats_reg_val &= ~(gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_double_detected_m()); ecc_stats_reg_val &= ~(gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_double_detected_m());
gk20a_writel(g, gk20a_writel(g,
@@ -269,7 +269,7 @@ static int gr_gp10b_handle_tex_exception(struct gk20a *g, u32 gpc, u32 tpc,
ecc_stats_reg_val = gk20a_readl(g, ecc_stats_reg_val = gk20a_readl(g,
gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_r() + offset); gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_r() + offset);
g->gr.t18x.ecc_stats.tex_total_sec_pipe0_count.counters[tpc] += g->ecc.gr.t18x.tex_total_sec_pipe0_count.counters[tpc] +=
gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_sec_v(ecc_stats_reg_val); gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_sec_v(ecc_stats_reg_val);
ecc_stats_reg_val &= ~gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_sec_m(); ecc_stats_reg_val &= ~gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_sec_m();
gk20a_writel(g, gk20a_writel(g,
@@ -278,7 +278,7 @@ static int gr_gp10b_handle_tex_exception(struct gk20a *g, u32 gpc, u32 tpc,
ecc_stats_reg_val = gk20a_readl(g, ecc_stats_reg_val = gk20a_readl(g,
gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_r() + offset); gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_r() + offset);
g->gr.t18x.ecc_stats.tex_unique_sec_pipe0_count.counters[tpc] += g->ecc.gr.t18x.tex_unique_sec_pipe0_count.counters[tpc] +=
gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_sec_v(ecc_stats_reg_val); gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_sec_v(ecc_stats_reg_val);
ecc_stats_reg_val &= ~gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_sec_m(); ecc_stats_reg_val &= ~gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_sec_m();
gk20a_writel(g, gk20a_writel(g,
@@ -293,7 +293,7 @@ static int gr_gp10b_handle_tex_exception(struct gk20a *g, u32 gpc, u32 tpc,
ecc_stats_reg_val = gk20a_readl(g, ecc_stats_reg_val = gk20a_readl(g,
gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_r() + offset); gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_r() + offset);
g->gr.t18x.ecc_stats.tex_total_sec_pipe1_count.counters[tpc] += g->ecc.gr.t18x.tex_total_sec_pipe1_count.counters[tpc] +=
gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_sec_v(ecc_stats_reg_val); gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_sec_v(ecc_stats_reg_val);
ecc_stats_reg_val &= ~gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_sec_m(); ecc_stats_reg_val &= ~gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_sec_m();
gk20a_writel(g, gk20a_writel(g,
@@ -302,7 +302,7 @@ static int gr_gp10b_handle_tex_exception(struct gk20a *g, u32 gpc, u32 tpc,
ecc_stats_reg_val = gk20a_readl(g, ecc_stats_reg_val = gk20a_readl(g,
gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_r() + offset); gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_r() + offset);
g->gr.t18x.ecc_stats.tex_unique_sec_pipe1_count.counters[tpc] += g->ecc.gr.t18x.tex_unique_sec_pipe1_count.counters[tpc] +=
gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_sec_v(ecc_stats_reg_val); gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_sec_v(ecc_stats_reg_val);
ecc_stats_reg_val &= ~gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_sec_m(); ecc_stats_reg_val &= ~gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_sec_m();
gk20a_writel(g, gk20a_writel(g,
@@ -325,7 +325,7 @@ static int gr_gp10b_handle_tex_exception(struct gk20a *g, u32 gpc, u32 tpc,
ecc_stats_reg_val = gk20a_readl(g, ecc_stats_reg_val = gk20a_readl(g,
gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_r() + offset); gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_r() + offset);
g->gr.t18x.ecc_stats.tex_total_ded_pipe0_count.counters[tpc] += g->ecc.gr.t18x.tex_total_ded_pipe0_count.counters[tpc] +=
gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_ded_v(ecc_stats_reg_val); gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_ded_v(ecc_stats_reg_val);
ecc_stats_reg_val &= ~gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_ded_m(); ecc_stats_reg_val &= ~gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_ded_m();
gk20a_writel(g, gk20a_writel(g,
@@ -334,7 +334,7 @@ static int gr_gp10b_handle_tex_exception(struct gk20a *g, u32 gpc, u32 tpc,
ecc_stats_reg_val = gk20a_readl(g, ecc_stats_reg_val = gk20a_readl(g,
gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_r() + offset); gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_r() + offset);
g->gr.t18x.ecc_stats.tex_unique_ded_pipe0_count.counters[tpc] += g->ecc.gr.t18x.tex_unique_ded_pipe0_count.counters[tpc] +=
gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_ded_v(ecc_stats_reg_val); gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_ded_v(ecc_stats_reg_val);
ecc_stats_reg_val &= ~gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_ded_m(); ecc_stats_reg_val &= ~gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_ded_m();
gk20a_writel(g, gk20a_writel(g,
@@ -349,7 +349,7 @@ static int gr_gp10b_handle_tex_exception(struct gk20a *g, u32 gpc, u32 tpc,
ecc_stats_reg_val = gk20a_readl(g, ecc_stats_reg_val = gk20a_readl(g,
gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_r() + offset); gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_r() + offset);
g->gr.t18x.ecc_stats.tex_total_ded_pipe1_count.counters[tpc] += g->ecc.gr.t18x.tex_total_ded_pipe1_count.counters[tpc] +=
gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_ded_v(ecc_stats_reg_val); gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_ded_v(ecc_stats_reg_val);
ecc_stats_reg_val &= ~gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_ded_m(); ecc_stats_reg_val &= ~gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_ded_m();
gk20a_writel(g, gk20a_writel(g,
@@ -358,7 +358,7 @@ static int gr_gp10b_handle_tex_exception(struct gk20a *g, u32 gpc, u32 tpc,
ecc_stats_reg_val = gk20a_readl(g, ecc_stats_reg_val = gk20a_readl(g,
gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_r() + offset); gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_r() + offset);
g->gr.t18x.ecc_stats.tex_unique_ded_pipe1_count.counters[tpc] += g->ecc.gr.t18x.tex_unique_ded_pipe1_count.counters[tpc] +=
gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_ded_v(ecc_stats_reg_val); gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_ded_v(ecc_stats_reg_val);
ecc_stats_reg_val &= ~gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_ded_m(); ecc_stats_reg_val &= ~gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_ded_m();
gk20a_writel(g, gk20a_writel(g,

View File

@@ -22,12 +22,6 @@
struct gpu_ops; struct gpu_ops;
struct gr_gp10b_ecc_stat {
char **names;
u32 *counters;
struct hlist_node hash_node;
};
enum { enum {
PASCAL_CHANNEL_GPFIFO_A = 0xC06F, PASCAL_CHANNEL_GPFIFO_A = 0xC06F,
PASCAL_A = 0xC097, PASCAL_A = 0xC097,
@@ -68,27 +62,6 @@ struct gr_t18x {
struct dentry *debugfs_dump_ctxsw_stats; struct dentry *debugfs_dump_ctxsw_stats;
} ctx_vars; } ctx_vars;
struct {
struct gr_gp10b_ecc_stat sm_lrf_single_err_count;
struct gr_gp10b_ecc_stat sm_lrf_double_err_count;
struct gr_gp10b_ecc_stat sm_shm_sec_count;
struct gr_gp10b_ecc_stat sm_shm_sed_count;
struct gr_gp10b_ecc_stat sm_shm_ded_count;
struct gr_gp10b_ecc_stat tex_total_sec_pipe0_count;
struct gr_gp10b_ecc_stat tex_total_ded_pipe0_count;
struct gr_gp10b_ecc_stat tex_unique_sec_pipe0_count;
struct gr_gp10b_ecc_stat tex_unique_ded_pipe0_count;
struct gr_gp10b_ecc_stat tex_total_sec_pipe1_count;
struct gr_gp10b_ecc_stat tex_total_ded_pipe1_count;
struct gr_gp10b_ecc_stat tex_unique_sec_pipe1_count;
struct gr_gp10b_ecc_stat tex_unique_ded_pipe1_count;
struct gr_gp10b_ecc_stat l2_sec_count;
struct gr_gp10b_ecc_stat l2_ded_count;
} ecc_stats;
u32 fecs_feature_override_ecc_val; u32 fecs_feature_override_ecc_val;
int cilp_preempt_pending_chid; int cilp_preempt_pending_chid;

View File

@@ -149,7 +149,7 @@ static void gp10b_ltc_isr(struct gk20a *g)
ecc_stats_reg_val = ecc_stats_reg_val =
gk20a_readl(g, gk20a_readl(g,
ltc_ltc0_lts0_dstg_ecc_report_r() + offset); ltc_ltc0_lts0_dstg_ecc_report_r() + offset);
g->gr.t18x.ecc_stats.l2_sec_count.counters[ltc] += g->ecc.gr.t18x.l2_sec_count.counters[ltc] +=
ltc_ltc0_lts0_dstg_ecc_report_sec_count_v(ecc_stats_reg_val); ltc_ltc0_lts0_dstg_ecc_report_sec_count_v(ecc_stats_reg_val);
ecc_stats_reg_val &= ecc_stats_reg_val &=
~(ltc_ltc0_lts0_dstg_ecc_report_sec_count_m()); ~(ltc_ltc0_lts0_dstg_ecc_report_sec_count_m());
@@ -169,7 +169,7 @@ static void gp10b_ltc_isr(struct gk20a *g)
ecc_stats_reg_val = ecc_stats_reg_val =
gk20a_readl(g, gk20a_readl(g,
ltc_ltc0_lts0_dstg_ecc_report_r() + offset); ltc_ltc0_lts0_dstg_ecc_report_r() + offset);
g->gr.t18x.ecc_stats.l2_ded_count.counters[ltc] += g->ecc.gr.t18x.l2_ded_count.counters[ltc] +=
ltc_ltc0_lts0_dstg_ecc_report_ded_count_v(ecc_stats_reg_val); ltc_ltc0_lts0_dstg_ecc_report_ded_count_v(ecc_stats_reg_val);
ecc_stats_reg_val &= ecc_stats_reg_val &=
~(ltc_ltc0_lts0_dstg_ecc_report_ded_count_m()); ~(ltc_ltc0_lts0_dstg_ecc_report_ded_count_m());

View File

@@ -484,13 +484,15 @@ static ssize_t ecc_stat_show(struct device *dev,
const char *ecc_stat_full_name = attr->attr.name; const char *ecc_stat_full_name = attr->attr.name;
const char *ecc_stat_base_name; const char *ecc_stat_base_name;
unsigned int hw_unit; unsigned int hw_unit;
struct gr_gp10b_ecc_stat *ecc_stat; struct gk20a_ecc_stat *ecc_stat;
u32 hash_key; u32 hash_key;
if (sscanf(ecc_stat_full_name, "ltc%u", &hw_unit) == 1) { if (sscanf(ecc_stat_full_name, "ltc%u", &hw_unit) == 1) {
ecc_stat_base_name = &(ecc_stat_full_name[strlen("ltc0_")]); ecc_stat_base_name = &(ecc_stat_full_name[strlen("ltc0_")]);
} else if (sscanf(ecc_stat_full_name, "gpc0_tpc%u", &hw_unit) == 1) { } else if (sscanf(ecc_stat_full_name, "gpc0_tpc%u", &hw_unit) == 1) {
ecc_stat_base_name = &(ecc_stat_full_name[strlen("gpc0_tpc0_")]); ecc_stat_base_name = &(ecc_stat_full_name[strlen("gpc0_tpc0_")]);
} else if (sscanf(ecc_stat_full_name, "gpc%u", &hw_unit) == 1) {
ecc_stat_base_name = &(ecc_stat_full_name[strlen("gpc0_")]);
} else { } else {
return snprintf(buf, return snprintf(buf,
PAGE_SIZE, PAGE_SIZE,
@@ -512,20 +514,39 @@ static ssize_t ecc_stat_show(struct device *dev,
int gr_gp10b_ecc_stat_create(struct device *dev, int gr_gp10b_ecc_stat_create(struct device *dev,
int is_l2, int is_l2,
char *ecc_stat_name, char *ecc_stat_name,
struct gr_gp10b_ecc_stat *ecc_stat, struct gk20a_ecc_stat *ecc_stat,
struct device_attribute *dev_attr_array) struct device_attribute *dev_attr_array)
{ {
int error = 0;
struct gk20a *g = get_gk20a(dev); struct gk20a *g = get_gk20a(dev);
char *ltc_unit_name = "ltc";
char *gr_unit_name = "gpc0_tpc";
int num_hw_units = 0; int num_hw_units = 0;
int hw_unit = 0;
u32 hash_key = 0;
if (is_l2) if (is_l2)
num_hw_units = g->ltc_count; num_hw_units = g->ltc_count;
else else
num_hw_units = g->gr.tpc_count; num_hw_units = g->gr.tpc_count;
return gp10b_ecc_stat_create(dev, num_hw_units,
is_l2 ? ltc_unit_name : gr_unit_name,
ecc_stat_name,
ecc_stat,
dev_attr_array);
}
int gp10b_ecc_stat_create(struct device *dev,
int num_hw_units,
char *ecc_unit_name,
char *ecc_stat_name,
struct gk20a_ecc_stat *ecc_stat,
struct device_attribute *dev_attr_array)
{
int error = 0;
struct gk20a *g = get_gk20a(dev);
int hw_unit = 0;
u32 hash_key = 0;
/* Allocate arrays */ /* Allocate arrays */
dev_attr_array = nvgpu_kzalloc(g, sizeof(struct device_attribute) * dev_attr_array = nvgpu_kzalloc(g, sizeof(struct device_attribute) *
num_hw_units); num_hw_units);
@@ -538,16 +559,10 @@ int gr_gp10b_ecc_stat_create(struct device *dev,
for (hw_unit = 0; hw_unit < num_hw_units; hw_unit++) { for (hw_unit = 0; hw_unit < num_hw_units; hw_unit++) {
/* Fill in struct device_attribute members */ /* Fill in struct device_attribute members */
if (is_l2)
snprintf(ecc_stat->names[hw_unit], snprintf(ecc_stat->names[hw_unit],
ECC_STAT_NAME_MAX_SIZE, ECC_STAT_NAME_MAX_SIZE,
"ltc%d_%s", "%s%d_%s",
hw_unit, ecc_unit_name,
ecc_stat_name);
else
snprintf(ecc_stat->names[hw_unit],
ECC_STAT_NAME_MAX_SIZE,
"gpc0_tpc%d_%s",
hw_unit, hw_unit,
ecc_stat_name); ecc_stat_name);
@@ -572,18 +587,28 @@ int gr_gp10b_ecc_stat_create(struct device *dev,
void gr_gp10b_ecc_stat_remove(struct device *dev, void gr_gp10b_ecc_stat_remove(struct device *dev,
int is_l2, int is_l2,
struct gr_gp10b_ecc_stat *ecc_stat, struct gk20a_ecc_stat *ecc_stat,
struct device_attribute *dev_attr_array) struct device_attribute *dev_attr_array)
{ {
struct gk20a *g = get_gk20a(dev); struct gk20a *g = get_gk20a(dev);
int num_hw_units = 0; int num_hw_units = 0;
int hw_unit = 0;
if (is_l2) if (is_l2)
num_hw_units = g->ltc_count; num_hw_units = g->ltc_count;
else else
num_hw_units = g->gr.tpc_count; num_hw_units = g->gr.tpc_count;
gp10b_ecc_stat_remove(dev, num_hw_units, ecc_stat, dev_attr_array);
}
void gp10b_ecc_stat_remove(struct device *dev,
int num_hw_units,
struct gk20a_ecc_stat *ecc_stat,
struct device_attribute *dev_attr_array)
{
struct gk20a *g = get_gk20a(dev);
int hw_unit = 0;
/* Remove sysfs files */ /* Remove sysfs files */
for (hw_unit = 0; hw_unit < num_hw_units; hw_unit++) { for (hw_unit = 0; hw_unit < num_hw_units; hw_unit++) {
device_remove_file(dev, &dev_attr_array[hw_unit]); device_remove_file(dev, &dev_attr_array[hw_unit]);
@@ -610,86 +635,86 @@ void gr_gp10b_create_sysfs(struct device *dev)
initialized multiple times but we only need to create the ECC initialized multiple times but we only need to create the ECC
stats once. Therefore, add the following check to avoid stats once. Therefore, add the following check to avoid
creating duplicate stat sysfs nodes. */ creating duplicate stat sysfs nodes. */
if (g->gr.t18x.ecc_stats.sm_lrf_single_err_count.counters != NULL) if (g->ecc.gr.t18x.sm_lrf_single_err_count.counters != NULL)
return; return;
error |= gr_gp10b_ecc_stat_create(dev, error |= gr_gp10b_ecc_stat_create(dev,
0, 0,
"sm_lrf_ecc_single_err_count", "sm_lrf_ecc_single_err_count",
&g->gr.t18x.ecc_stats.sm_lrf_single_err_count, &g->ecc.gr.t18x.sm_lrf_single_err_count,
dev_attr_sm_lrf_ecc_single_err_count_array); dev_attr_sm_lrf_ecc_single_err_count_array);
error |= gr_gp10b_ecc_stat_create(dev, error |= gr_gp10b_ecc_stat_create(dev,
0, 0,
"sm_lrf_ecc_double_err_count", "sm_lrf_ecc_double_err_count",
&g->gr.t18x.ecc_stats.sm_lrf_double_err_count, &g->ecc.gr.t18x.sm_lrf_double_err_count,
dev_attr_sm_lrf_ecc_double_err_count_array); dev_attr_sm_lrf_ecc_double_err_count_array);
error |= gr_gp10b_ecc_stat_create(dev, error |= gr_gp10b_ecc_stat_create(dev,
0, 0,
"sm_shm_ecc_sec_count", "sm_shm_ecc_sec_count",
&g->gr.t18x.ecc_stats.sm_shm_sec_count, &g->ecc.gr.t18x.sm_shm_sec_count,
dev_attr_sm_shm_ecc_sec_count_array); dev_attr_sm_shm_ecc_sec_count_array);
error |= gr_gp10b_ecc_stat_create(dev, error |= gr_gp10b_ecc_stat_create(dev,
0, 0,
"sm_shm_ecc_sed_count", "sm_shm_ecc_sed_count",
&g->gr.t18x.ecc_stats.sm_shm_sed_count, &g->ecc.gr.t18x.sm_shm_sed_count,
dev_attr_sm_shm_ecc_sed_count_array); dev_attr_sm_shm_ecc_sed_count_array);
error |= gr_gp10b_ecc_stat_create(dev, error |= gr_gp10b_ecc_stat_create(dev,
0, 0,
"sm_shm_ecc_ded_count", "sm_shm_ecc_ded_count",
&g->gr.t18x.ecc_stats.sm_shm_ded_count, &g->ecc.gr.t18x.sm_shm_ded_count,
dev_attr_sm_shm_ecc_ded_count_array); dev_attr_sm_shm_ecc_ded_count_array);
error |= gr_gp10b_ecc_stat_create(dev, error |= gr_gp10b_ecc_stat_create(dev,
0, 0,
"tex_ecc_total_sec_pipe0_count", "tex_ecc_total_sec_pipe0_count",
&g->gr.t18x.ecc_stats.tex_total_sec_pipe0_count, &g->ecc.gr.t18x.tex_total_sec_pipe0_count,
dev_attr_tex_ecc_total_sec_pipe0_count_array); dev_attr_tex_ecc_total_sec_pipe0_count_array);
error |= gr_gp10b_ecc_stat_create(dev, error |= gr_gp10b_ecc_stat_create(dev,
0, 0,
"tex_ecc_total_ded_pipe0_count", "tex_ecc_total_ded_pipe0_count",
&g->gr.t18x.ecc_stats.tex_total_ded_pipe0_count, &g->ecc.gr.t18x.tex_total_ded_pipe0_count,
dev_attr_tex_ecc_total_ded_pipe0_count_array); dev_attr_tex_ecc_total_ded_pipe0_count_array);
error |= gr_gp10b_ecc_stat_create(dev, error |= gr_gp10b_ecc_stat_create(dev,
0, 0,
"tex_ecc_unique_sec_pipe0_count", "tex_ecc_unique_sec_pipe0_count",
&g->gr.t18x.ecc_stats.tex_unique_sec_pipe0_count, &g->ecc.gr.t18x.tex_unique_sec_pipe0_count,
dev_attr_tex_ecc_unique_sec_pipe0_count_array); dev_attr_tex_ecc_unique_sec_pipe0_count_array);
error |= gr_gp10b_ecc_stat_create(dev, error |= gr_gp10b_ecc_stat_create(dev,
0, 0,
"tex_ecc_unique_ded_pipe0_count", "tex_ecc_unique_ded_pipe0_count",
&g->gr.t18x.ecc_stats.tex_unique_ded_pipe0_count, &g->ecc.gr.t18x.tex_unique_ded_pipe0_count,
dev_attr_tex_ecc_unique_ded_pipe0_count_array); dev_attr_tex_ecc_unique_ded_pipe0_count_array);
error |= gr_gp10b_ecc_stat_create(dev, error |= gr_gp10b_ecc_stat_create(dev,
0, 0,
"tex_ecc_total_sec_pipe1_count", "tex_ecc_total_sec_pipe1_count",
&g->gr.t18x.ecc_stats.tex_total_sec_pipe1_count, &g->ecc.gr.t18x.tex_total_sec_pipe1_count,
dev_attr_tex_ecc_total_sec_pipe1_count_array); dev_attr_tex_ecc_total_sec_pipe1_count_array);
error |= gr_gp10b_ecc_stat_create(dev, error |= gr_gp10b_ecc_stat_create(dev,
0, 0,
"tex_ecc_total_ded_pipe1_count", "tex_ecc_total_ded_pipe1_count",
&g->gr.t18x.ecc_stats.tex_total_ded_pipe1_count, &g->ecc.gr.t18x.tex_total_ded_pipe1_count,
dev_attr_tex_ecc_total_ded_pipe1_count_array); dev_attr_tex_ecc_total_ded_pipe1_count_array);
error |= gr_gp10b_ecc_stat_create(dev, error |= gr_gp10b_ecc_stat_create(dev,
0, 0,
"tex_ecc_unique_sec_pipe1_count", "tex_ecc_unique_sec_pipe1_count",
&g->gr.t18x.ecc_stats.tex_unique_sec_pipe1_count, &g->ecc.gr.t18x.tex_unique_sec_pipe1_count,
dev_attr_tex_ecc_unique_sec_pipe1_count_array); dev_attr_tex_ecc_unique_sec_pipe1_count_array);
error |= gr_gp10b_ecc_stat_create(dev, error |= gr_gp10b_ecc_stat_create(dev,
0, 0,
"tex_ecc_unique_ded_pipe1_count", "tex_ecc_unique_ded_pipe1_count",
&g->gr.t18x.ecc_stats.tex_unique_ded_pipe1_count, &g->ecc.gr.t18x.tex_unique_ded_pipe1_count,
dev_attr_tex_ecc_unique_ded_pipe1_count_array); dev_attr_tex_ecc_unique_ded_pipe1_count_array);
error |= gr_gp10b_ecc_stat_create(dev, error |= gr_gp10b_ecc_stat_create(dev,
1, 1,
"lts0_ecc_sec_count", "lts0_ecc_sec_count",
&g->gr.t18x.ecc_stats.l2_sec_count, &g->ecc.gr.t18x.l2_sec_count,
dev_attr_l2_ecc_sec_count_array); dev_attr_l2_ecc_sec_count_array);
error |= gr_gp10b_ecc_stat_create(dev, error |= gr_gp10b_ecc_stat_create(dev,
1, 1,
"lts0_ecc_ded_count", "lts0_ecc_ded_count",
&g->gr.t18x.ecc_stats.l2_ded_count, &g->ecc.gr.t18x.l2_ded_count,
dev_attr_l2_ecc_ded_count_array); dev_attr_l2_ecc_ded_count_array);
if (error) if (error)
@@ -702,65 +727,65 @@ static void gr_gp10b_remove_sysfs(struct device *dev)
gr_gp10b_ecc_stat_remove(dev, gr_gp10b_ecc_stat_remove(dev,
0, 0,
&g->gr.t18x.ecc_stats.sm_lrf_single_err_count, &g->ecc.gr.t18x.sm_lrf_single_err_count,
dev_attr_sm_lrf_ecc_single_err_count_array); dev_attr_sm_lrf_ecc_single_err_count_array);
gr_gp10b_ecc_stat_remove(dev, gr_gp10b_ecc_stat_remove(dev,
0, 0,
&g->gr.t18x.ecc_stats.sm_lrf_double_err_count, &g->ecc.gr.t18x.sm_lrf_double_err_count,
dev_attr_sm_lrf_ecc_double_err_count_array); dev_attr_sm_lrf_ecc_double_err_count_array);
gr_gp10b_ecc_stat_remove(dev, gr_gp10b_ecc_stat_remove(dev,
0, 0,
&g->gr.t18x.ecc_stats.sm_shm_sec_count, &g->ecc.gr.t18x.sm_shm_sec_count,
dev_attr_sm_shm_ecc_sec_count_array); dev_attr_sm_shm_ecc_sec_count_array);
gr_gp10b_ecc_stat_remove(dev, gr_gp10b_ecc_stat_remove(dev,
0, 0,
&g->gr.t18x.ecc_stats.sm_shm_sed_count, &g->ecc.gr.t18x.sm_shm_sed_count,
dev_attr_sm_shm_ecc_sed_count_array); dev_attr_sm_shm_ecc_sed_count_array);
gr_gp10b_ecc_stat_remove(dev, gr_gp10b_ecc_stat_remove(dev,
0, 0,
&g->gr.t18x.ecc_stats.sm_shm_ded_count, &g->ecc.gr.t18x.sm_shm_ded_count,
dev_attr_sm_shm_ecc_ded_count_array); dev_attr_sm_shm_ecc_ded_count_array);
gr_gp10b_ecc_stat_remove(dev, gr_gp10b_ecc_stat_remove(dev,
0, 0,
&g->gr.t18x.ecc_stats.tex_total_sec_pipe0_count, &g->ecc.gr.t18x.tex_total_sec_pipe0_count,
dev_attr_tex_ecc_total_sec_pipe0_count_array); dev_attr_tex_ecc_total_sec_pipe0_count_array);
gr_gp10b_ecc_stat_remove(dev, gr_gp10b_ecc_stat_remove(dev,
0, 0,
&g->gr.t18x.ecc_stats.tex_total_ded_pipe0_count, &g->ecc.gr.t18x.tex_total_ded_pipe0_count,
dev_attr_tex_ecc_total_ded_pipe0_count_array); dev_attr_tex_ecc_total_ded_pipe0_count_array);
gr_gp10b_ecc_stat_remove(dev, gr_gp10b_ecc_stat_remove(dev,
0, 0,
&g->gr.t18x.ecc_stats.tex_unique_sec_pipe0_count, &g->ecc.gr.t18x.tex_unique_sec_pipe0_count,
dev_attr_tex_ecc_unique_sec_pipe0_count_array); dev_attr_tex_ecc_unique_sec_pipe0_count_array);
gr_gp10b_ecc_stat_remove(dev, gr_gp10b_ecc_stat_remove(dev,
0, 0,
&g->gr.t18x.ecc_stats.tex_unique_ded_pipe0_count, &g->ecc.gr.t18x.tex_unique_ded_pipe0_count,
dev_attr_tex_ecc_unique_ded_pipe0_count_array); dev_attr_tex_ecc_unique_ded_pipe0_count_array);
gr_gp10b_ecc_stat_remove(dev, gr_gp10b_ecc_stat_remove(dev,
0, 0,
&g->gr.t18x.ecc_stats.tex_total_sec_pipe1_count, &g->ecc.gr.t18x.tex_total_sec_pipe1_count,
dev_attr_tex_ecc_total_sec_pipe1_count_array); dev_attr_tex_ecc_total_sec_pipe1_count_array);
gr_gp10b_ecc_stat_remove(dev, gr_gp10b_ecc_stat_remove(dev,
0, 0,
&g->gr.t18x.ecc_stats.tex_total_ded_pipe1_count, &g->ecc.gr.t18x.tex_total_ded_pipe1_count,
dev_attr_tex_ecc_total_ded_pipe1_count_array); dev_attr_tex_ecc_total_ded_pipe1_count_array);
gr_gp10b_ecc_stat_remove(dev, gr_gp10b_ecc_stat_remove(dev,
0, 0,
&g->gr.t18x.ecc_stats.tex_unique_sec_pipe1_count, &g->ecc.gr.t18x.tex_unique_sec_pipe1_count,
dev_attr_tex_ecc_unique_sec_pipe1_count_array); dev_attr_tex_ecc_unique_sec_pipe1_count_array);
gr_gp10b_ecc_stat_remove(dev, gr_gp10b_ecc_stat_remove(dev,
0, 0,
&g->gr.t18x.ecc_stats.tex_unique_ded_pipe1_count, &g->ecc.gr.t18x.tex_unique_ded_pipe1_count,
dev_attr_tex_ecc_unique_ded_pipe1_count_array); dev_attr_tex_ecc_unique_ded_pipe1_count_array);
gr_gp10b_ecc_stat_remove(dev, gr_gp10b_ecc_stat_remove(dev,
1, 1,
&g->gr.t18x.ecc_stats.l2_sec_count, &g->ecc.gr.t18x.l2_sec_count,
dev_attr_l2_ecc_sec_count_array); dev_attr_l2_ecc_sec_count_array);
gr_gp10b_ecc_stat_remove(dev, gr_gp10b_ecc_stat_remove(dev,
1, 1,
&g->gr.t18x.ecc_stats.l2_ded_count, &g->ecc.gr.t18x.l2_ded_count,
dev_attr_l2_ecc_ded_count_array); dev_attr_l2_ecc_ded_count_array);
} }

View File

@@ -22,12 +22,23 @@
int gr_gp10b_ecc_stat_create(struct device *dev, int gr_gp10b_ecc_stat_create(struct device *dev,
int is_l2, int is_l2,
char *ecc_stat_name, char *ecc_stat_name,
struct gr_gp10b_ecc_stat *ecc_stat, struct gk20a_ecc_stat *ecc_stat,
struct device_attribute *dev_attr_array);
int gp10b_ecc_stat_create(struct device *dev,
int hw_units,
char *ecc_unit_name,
char *ecc_stat_name,
struct gk20a_ecc_stat *ecc_stat,
struct device_attribute *dev_attr_array); struct device_attribute *dev_attr_array);
void gr_gp10b_ecc_stat_remove(struct device *dev, void gr_gp10b_ecc_stat_remove(struct device *dev,
int is_l2, int is_l2,
struct gr_gp10b_ecc_stat *ecc_stat, struct gk20a_ecc_stat *ecc_stat,
struct device_attribute *dev_attr_array);
void gp10b_ecc_stat_remove(struct device *dev,
int hw_units,
struct gk20a_ecc_stat *ecc_stat,
struct device_attribute *dev_attr_array); struct device_attribute *dev_attr_array);
int gp10b_tegra_remove(struct device *dev); int gp10b_tegra_remove(struct device *dev);