gpu: nvgpu: use mmu_fault_info struct for legacy gpu chips

Removed fifo_mmu_fault_info_gk20a struct to use
new mmu_fault_info struct

JIRA GPUT19X-7
JIRA GPUT19X-12

Change-Id: I1987ff1b07e7dbdbee58d7e5f585faacf4846e54
Signed-off-by: Seema Khowala <seemaj@nvidia.com>
Reviewed-on: http://git-master/r/1487240
Reviewed-by: svccoveritychecker <svccoveritychecker@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
This commit is contained in:
Seema Khowala
2017-05-22 10:39:52 -07:00
committed by mobile promotions
parent e8f4e52efe
commit c3192b5acc
5 changed files with 127 additions and 97 deletions

View File

@@ -36,6 +36,7 @@
#include "gk20a.h" #include "gk20a.h"
#include "debug_gk20a.h" #include "debug_gk20a.h"
#include "ctxsw_trace_gk20a.h" #include "ctxsw_trace_gk20a.h"
#include "mm_gk20a.h"
#include <nvgpu/hw/gk20a/hw_fifo_gk20a.h> #include <nvgpu/hw/gk20a/hw_fifo_gk20a.h>
#include <nvgpu/hw/gk20a/hw_pbdma_gk20a.h> #include <nvgpu/hw/gk20a/hw_pbdma_gk20a.h>
@@ -1160,51 +1161,78 @@ static const char * const gpc_client_descs[] = {
"rgg utlb", "rgg utlb",
}; };
static const char * const does_not_exist[] = {
"does not exist"
};
/* reads info from hardware and fills in mmu fault info record */ /* reads info from hardware and fills in mmu fault info record */
static inline void get_exception_mmu_fault_info( static void get_exception_mmu_fault_info(
struct gk20a *g, u32 engine_id, struct gk20a *g, u32 mmu_fault_id,
struct fifo_mmu_fault_info_gk20a *f) struct mmu_fault_info *mmfault)
{ {
u32 fault_info_v; u32 fault_info;
u32 addr_lo, addr_hi;
gk20a_dbg_fn("engine_id %d", engine_id); gk20a_dbg_fn("mmu_fault_id %d", mmu_fault_id);
memset(f, 0, sizeof(*f)); memset(mmfault, 0, sizeof(*mmfault));
f->fault_info_v = fault_info_v = gk20a_readl(g, fault_info = gk20a_readl(g,
fifo_intr_mmu_fault_info_r(engine_id)); fifo_intr_mmu_fault_info_r(mmu_fault_id));
f->fault_type_v = mmfault->fault_type =
fifo_intr_mmu_fault_info_type_v(fault_info_v); fifo_intr_mmu_fault_info_type_v(fault_info);
f->engine_subid_v = mmfault->access_type =
fifo_intr_mmu_fault_info_engine_subid_v(fault_info_v); fifo_intr_mmu_fault_info_write_v(fault_info);
f->client_v = fifo_intr_mmu_fault_info_client_v(fault_info_v); mmfault->client_type =
fifo_intr_mmu_fault_info_engine_subid_v(fault_info);
mmfault->client_id =
fifo_intr_mmu_fault_info_client_v(fault_info);
BUG_ON(f->fault_type_v >= ARRAY_SIZE(fault_type_descs)); if (mmfault->fault_type >= ARRAY_SIZE(fault_type_descs)) {
f->fault_type_desc = fault_type_descs[f->fault_type_v]; WARN_ON(mmfault->fault_type >= ARRAY_SIZE(fault_type_descs));
mmfault->fault_type_desc = does_not_exist[0];
BUG_ON(f->engine_subid_v >= ARRAY_SIZE(engine_subid_descs));
f->engine_subid_desc = engine_subid_descs[f->engine_subid_v];
if (f->engine_subid_v ==
fifo_intr_mmu_fault_info_engine_subid_hub_v()) {
BUG_ON(f->client_v >= ARRAY_SIZE(hub_client_descs));
f->client_desc = hub_client_descs[f->client_v];
} else if (f->engine_subid_v ==
fifo_intr_mmu_fault_info_engine_subid_gpc_v()) {
BUG_ON(f->client_v >= ARRAY_SIZE(gpc_client_descs));
f->client_desc = gpc_client_descs[f->client_v];
} else { } else {
BUG_ON(1); mmfault->fault_type_desc =
fault_type_descs[mmfault->fault_type];
} }
f->fault_hi_v = gk20a_readl(g, fifo_intr_mmu_fault_hi_r(engine_id)); if (mmfault->client_type >= ARRAY_SIZE(engine_subid_descs)) {
f->fault_lo_v = gk20a_readl(g, fifo_intr_mmu_fault_lo_r(engine_id)); WARN_ON(mmfault->client_type >= ARRAY_SIZE(engine_subid_descs));
mmfault->client_type_desc = does_not_exist[0];
} else {
mmfault->client_type_desc =
engine_subid_descs[mmfault->client_type];
}
mmfault->client_id_desc = does_not_exist[0];
if (mmfault->client_type ==
fifo_intr_mmu_fault_info_engine_subid_hub_v()) {
if (mmfault->client_id >=
ARRAY_SIZE(hub_client_descs))
WARN_ON(mmfault->client_id >=
ARRAY_SIZE(hub_client_descs));
else
mmfault->client_id_desc =
hub_client_descs[mmfault->client_id];
} else if (mmfault->client_type ==
fifo_intr_mmu_fault_info_engine_subid_gpc_v()) {
if (mmfault->client_id >= ARRAY_SIZE(gpc_client_descs))
WARN_ON(mmfault->client_id >=
ARRAY_SIZE(gpc_client_descs));
else
mmfault->client_id_desc =
gpc_client_descs[mmfault->client_id];
}
addr_lo = gk20a_readl(g, fifo_intr_mmu_fault_lo_r(mmu_fault_id));
addr_hi = gk20a_readl(g, fifo_intr_mmu_fault_hi_r(mmu_fault_id));
mmfault->fault_addr = hi32_lo32_to_u64(addr_hi, addr_lo);
/* note:ignoring aperture on gk20a... */ /* note:ignoring aperture on gk20a... */
f->inst_ptr = fifo_intr_mmu_fault_inst_ptr_v( mmfault->inst_ptr = fifo_intr_mmu_fault_inst_ptr_v(
gk20a_readl(g, fifo_intr_mmu_fault_inst_r(engine_id))); gk20a_readl(g, fifo_intr_mmu_fault_inst_r(mmu_fault_id)));
/* note: inst_ptr is a 40b phys addr. */ /* note: inst_ptr is a 40b phys addr. */
f->inst_ptr <<= fifo_intr_mmu_fault_inst_ptr_align_shift_v(); mmfault->inst_ptr <<= fifo_intr_mmu_fault_inst_ptr_align_shift_v();
} }
void gk20a_fifo_reset_engine(struct gk20a *g, u32 engine_id) void gk20a_fifo_reset_engine(struct gk20a *g, u32 engine_id)
@@ -1519,7 +1547,7 @@ static bool gk20a_fifo_handle_mmu_fault(
* engines. Convert engine_mmu_id to engine_id */ * engines. Convert engine_mmu_id to engine_id */
u32 engine_id = gk20a_mmu_id_to_engine_id(g, u32 engine_id = gk20a_mmu_id_to_engine_id(g,
engine_mmu_fault_id); engine_mmu_fault_id);
struct fifo_mmu_fault_info_gk20a f; struct mmu_fault_info mmfault_info;
struct channel_gk20a *ch = NULL; struct channel_gk20a *ch = NULL;
struct tsg_gk20a *tsg = NULL; struct tsg_gk20a *tsg = NULL;
struct channel_gk20a *refch = NULL; struct channel_gk20a *refch = NULL;
@@ -1533,26 +1561,29 @@ static bool gk20a_fifo_handle_mmu_fault(
|| ctx_status == || ctx_status ==
fifo_engine_status_ctx_status_ctxsw_load_v()); fifo_engine_status_ctx_status_ctxsw_load_v());
get_exception_mmu_fault_info(g, engine_mmu_fault_id, &f); get_exception_mmu_fault_info(g, engine_mmu_fault_id,
trace_gk20a_mmu_fault(f.fault_hi_v, &mmfault_info);
f.fault_lo_v, trace_gk20a_mmu_fault(mmfault_info.fault_addr,
f.fault_info_v, mmfault_info.fault_type,
f.inst_ptr, mmfault_info.access_type,
mmfault_info.inst_ptr,
engine_id, engine_id,
f.engine_subid_desc, mmfault_info.client_type_desc,
f.client_desc, mmfault_info.client_id_desc,
f.fault_type_desc); mmfault_info.fault_type_desc);
nvgpu_err(g, "%s mmu fault on engine %d, " nvgpu_err(g, "%s mmu fault on engine %d, "
"engine subid %d (%s), client %d (%s), " "engine subid %d (%s), client %d (%s), "
"addr 0x%08x:0x%08x, type %d (%s), info 0x%08x," "addr 0x%llx, type %d (%s), access_type 0x%08x,"
"inst_ptr 0x%llx", "inst_ptr 0x%llx\n",
fake_fault ? "fake" : "", fake_fault ? "fake" : "",
engine_id, engine_id,
f.engine_subid_v, f.engine_subid_desc, mmfault_info.client_type,
f.client_v, f.client_desc, mmfault_info.client_type_desc,
f.fault_hi_v, f.fault_lo_v, mmfault_info.client_id, mmfault_info.client_id_desc,
f.fault_type_v, f.fault_type_desc, mmfault_info.fault_addr,
f.fault_info_v, f.inst_ptr); mmfault_info.fault_type,
mmfault_info.fault_type_desc,
mmfault_info.access_type, mmfault_info.inst_ptr);
if (ctxsw) { if (ctxsw) {
gk20a_fecs_dump_falcon_stats(g); gk20a_fecs_dump_falcon_stats(g);
@@ -1589,7 +1620,8 @@ static bool gk20a_fifo_handle_mmu_fault(
} }
} else { } else {
/* read channel based on instruction pointer */ /* read channel based on instruction pointer */
ch = gk20a_refch_from_inst_ptr(g, f.inst_ptr); ch = gk20a_refch_from_inst_ptr(g,
mmfault_info.inst_ptr);
refch = ch; refch = ch;
} }
@@ -1599,8 +1631,8 @@ static bool gk20a_fifo_handle_mmu_fault(
/* check if engine reset should be deferred */ /* check if engine reset should be deferred */
if (engine_id != FIFO_INVAL_ENGINE_ID) { if (engine_id != FIFO_INVAL_ENGINE_ID) {
bool defer = gk20a_fifo_should_defer_engine_reset(g, bool defer = gk20a_fifo_should_defer_engine_reset(g,
engine_id, f.engine_subid_v, engine_id, mmfault_info.client_type,
fake_fault); fake_fault);
if ((ch || tsg) && defer) { if ((ch || tsg) && defer) {
g->fifo.deferred_fault_engines |= BIT(engine_id); g->fifo.deferred_fault_engines |= BIT(engine_id);
@@ -1656,10 +1688,10 @@ static bool gk20a_fifo_handle_mmu_fault(
"mmu error in freed channel %d", "mmu error in freed channel %d",
ch->hw_chid); ch->hw_chid);
} }
} else if (f.inst_ptr == } else if (mmfault_info.inst_ptr ==
gk20a_mm_inst_block_addr(g, &g->mm.bar1.inst_block)) { gk20a_mm_inst_block_addr(g, &g->mm.bar1.inst_block)) {
nvgpu_err(g, "mmu fault from bar1"); nvgpu_err(g, "mmu fault from bar1");
} else if (f.inst_ptr == } else if (mmfault_info.inst_ptr ==
gk20a_mm_inst_block_addr(g, &g->mm.pmu.inst_block)) { gk20a_mm_inst_block_addr(g, &g->mm.pmu.inst_block)) {
nvgpu_err(g, "mmu fault from pmu"); nvgpu_err(g, "mmu fault from pmu");
} else } else

View File

@@ -104,19 +104,6 @@ struct fifo_engine_exception_info_gk20a {
bool faulted, idle, ctxsw_in_progress; bool faulted, idle, ctxsw_in_progress;
}; };
struct fifo_mmu_fault_info_gk20a {
u32 fault_info_v;
u32 fault_type_v;
u32 engine_subid_v;
u32 client_v;
u32 fault_hi_v;
u32 fault_lo_v;
u64 inst_ptr;
const char *fault_type_desc;
const char *engine_subid_desc;
const char *client_desc;
};
struct fifo_engine_info_gk20a { struct fifo_engine_info_gk20a {
u32 engine_id; u32 engine_id;
u32 runlist_id; u32 runlist_id;
@@ -129,8 +116,6 @@ struct fifo_engine_info_gk20a {
u32 engine_enum; u32 engine_enum;
struct fifo_pbdma_exception_info_gk20a pbdma_exception_info; struct fifo_pbdma_exception_info_gk20a pbdma_exception_info;
struct fifo_engine_exception_info_gk20a engine_exception_info; struct fifo_engine_exception_info_gk20a engine_exception_info;
struct fifo_mmu_fault_info_gk20a mmu_fault_info;
}; };
enum { enum {

View File

@@ -173,8 +173,12 @@ struct mmu_fault_info {
u32 valid; u32 valid;
u32 faulted_pbdma; u32 faulted_pbdma;
u32 faulted_engine; u32 faulted_engine;
u32 faulted_subid;
u32 hw_chid; u32 hw_chid;
struct channel_gk20a *refch; struct channel_gk20a *refch;
const char *client_type_desc;
const char *fault_type_desc;
const char *client_id_desc;
}; };
struct mm_gk20a { struct mm_gk20a {

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012-2016, NVIDIA CORPORATION. All rights reserved. * Copyright (c) 2012-2017, NVIDIA CORPORATION. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -338,6 +338,10 @@ static inline u32 fifo_intr_mmu_fault_info_type_v(u32 r)
{ {
return (r >> 0) & 0xf; return (r >> 0) & 0xf;
} }
static inline u32 fifo_intr_mmu_fault_info_write_v(u32 r)
{
return (r >> 7) & 0x1;
}
static inline u32 fifo_intr_mmu_fault_info_engine_subid_v(u32 r) static inline u32 fifo_intr_mmu_fault_info_engine_subid_v(u32 r)
{ {
return (r >> 6) & 0x1; return (r >> 6) & 0x1;

View File

@@ -463,39 +463,44 @@ TRACE_EVENT(gk20a_as_ioctl_get_va_regions,
); );
TRACE_EVENT(gk20a_mmu_fault, TRACE_EVENT(gk20a_mmu_fault,
TP_PROTO(u32 fault_hi, u32 fault_lo, TP_PROTO(u64 fault_addr,
u32 fault_info, u32 fault_type,
u64 instance, u32 access_type,
u64 inst_ptr,
u32 engine_id, u32 engine_id,
const char *engine, const char *client_type_desc,
const char *client, const char *client_id_desc,
const char *fault_type), const char *fault_type_desc),
TP_ARGS(fault_hi, fault_lo, fault_info, TP_ARGS(fault_addr, fault_type, access_type,
instance, engine_id, engine, client, fault_type), inst_ptr, engine_id, client_type_desc,
client_id_desc, fault_type_desc),
TP_STRUCT__entry( TP_STRUCT__entry(
__field(u32, fault_hi) __field(u64, fault_addr)
__field(u32, fault_lo) __field(u32, fault_type)
__field(u32, fault_info) __field(u32, access_type)
__field(u64, instance) __field(u64, inst_ptr)
__field(u32, engine_id) __field(u32, engine_id)
__field(const char *, engine) __field(const char *, client_type_desc)
__field(const char *, client) __field(const char *, client_id_desc)
__field(const char *, fault_type) __field(const char *, fault_type_desc)
), ),
TP_fast_assign( TP_fast_assign(
__entry->fault_hi = fault_hi; __entry->fault_addr = fault_addr;
__entry->fault_lo = fault_lo;
__entry->fault_info = fault_info;
__entry->instance = instance;
__entry->engine_id = engine_id;
__entry->engine = engine;
__entry->client = client;
__entry->fault_type = fault_type; __entry->fault_type = fault_type;
__entry->access_type = access_type;
__entry->inst_ptr = inst_ptr;
__entry->engine_id = engine_id;
__entry->client_type_desc = client_type_desc;
__entry->client_id_desc = client_id_desc;
__entry->fault_type_desc = fault_type_desc;
), ),
TP_printk("fault=0x%x,%08x info=0x%x instance=0x%llx engine_id=%d engine=%s client=%s type=%s", TP_printk("fault addr=0x%llx type=0x%x access_type=0x%x "
__entry->fault_hi, __entry->fault_lo, "instance=0x%llx engine_id=%d client_type=%s "
__entry->fault_info, __entry->instance, __entry->engine_id, "client_id=%s fault type=%s",
__entry->engine, __entry->client, __entry->fault_type) __entry->fault_addr, __entry->fault_type,
__entry->access_type, __entry->inst_ptr,
__entry->engine_id, __entry->client_type_desc,
__entry->client_id_desc, __entry->fault_type_desc)
); );
TRACE_EVENT(gk20a_ltc_cbc_ctrl_start, TRACE_EVENT(gk20a_ltc_cbc_ctrl_start,