gpu: nvgpu: add ctxsw channel reset event

Generate a ctxsw channel reset when engine needs to be reset.
This event is generated by the driver, while other events are
generated by FECS.

JIRA ELVR-314

Change-Id: I7791cf3e538782464c37c442c871acb177484566
Signed-off-by: Thomas Fleury <tfleury@nvidia.com>
Reviewed-on: http://git-master/r/1129029
(cherry picked from commit 114038a1a5d9e8941bc53f3e95115b01dd1f8c6e)
Reviewed-on: http://git-master/r/1134379
(cherry picked from commit 15fa2a7b48a0937dfd449ca0c4ed5ad3a863d6bf)
Reviewed-on: http://git-master/r/1123916
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
This commit is contained in:
Thomas Fleury
2016-04-11 17:06:20 -07:00
committed by Terje Bergstrom
parent a21dcf0bc6
commit 4df6cd4a34
6 changed files with 55 additions and 6 deletions

View File

@@ -886,7 +886,7 @@ static void gk20a_free_channel(struct channel_gk20a *ch)
/* if lock is already taken, a reset is taking place /* if lock is already taken, a reset is taking place
so no need to repeat */ so no need to repeat */
if (!was_reset) { if (!was_reset) {
trace_gk20a_channel_reset(ch->hw_chid, ch->tsgid); gk20a_ctxsw_trace_channel_reset(g, ch);
gk20a_fifo_reset_engine(g, gk20a_fifo_reset_engine(g,
g->fifo.deferred_fault_engines); g->fifo.deferred_fault_engines);
} }

View File

@@ -23,6 +23,7 @@
#include <linux/hashtable.h> #include <linux/hashtable.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/log2.h> #include <linux/log2.h>
#include <trace/events/gk20a.h>
#include <uapi/linux/nvgpu.h> #include <uapi/linux/nvgpu.h>
#include "ctxsw_trace_gk20a.h" #include "ctxsw_trace_gk20a.h"
#include "gk20a.h" #include "gk20a.h"
@@ -620,6 +621,47 @@ void gk20a_ctxsw_trace_wake_up(struct gk20a *g, int vmid)
wake_up_interruptible(&dev->readout_wq); wake_up_interruptible(&dev->readout_wq);
} }
void gk20a_ctxsw_trace_channel_reset(struct gk20a *g, struct channel_gk20a *ch)
{
#ifdef CONFIG_GK20A_CTXSW_TRACE
struct nvgpu_ctxsw_trace_entry entry = {
.vmid = 0,
.tag = NVGPU_CTXSW_TAG_RESET,
.timestamp = gk20a_read_ptimer(g),
.context_id = 0,
.pid = ch->pid,
};
gk20a_ctxsw_trace_write(g, &entry);
#endif
trace_gk20a_channel_reset(ch->hw_chid, ch->tsgid);
gk20a_ctxsw_trace_wake_up(g, 0);
}
void gk20a_ctxsw_trace_tsg_reset(struct gk20a *g, struct tsg_gk20a *tsg)
{
#ifdef CONFIG_GK20A_CTXSW_TRACE
struct nvgpu_ctxsw_trace_entry entry = {
.vmid = 0,
.tag = NVGPU_CTXSW_TAG_RESET,
.timestamp = gk20a_read_ptimer(g),
.context_id = 0,
.pid = 0,
};
struct channel_gk20a *ch;
mutex_lock(&tsg->ch_list_lock);
ch = list_entry(&tsg->ch_list, struct channel_gk20a, ch_entry);
mutex_unlock(&tsg->ch_list_lock);
entry.pid = ch->pid;
gk20a_ctxsw_trace_write(g, &entry);
#endif
trace_gk20a_channel_reset(~0, tsg->tsgid);
gk20a_ctxsw_trace_wake_up(g, 0);
}
void gk20a_ctxsw_trace_init_ops(struct gpu_ops *ops) void gk20a_ctxsw_trace_init_ops(struct gpu_ops *ops)
{ {
ops->fecs_trace.alloc_user_buffer = gk20a_ctxsw_dev_ring_alloc; ops->fecs_trace.alloc_user_buffer = gk20a_ctxsw_dev_ring_alloc;

View File

@@ -23,6 +23,7 @@ struct channel_gk20a;
struct channel_ctx_gk20a; struct channel_ctx_gk20a;
struct gk20a_ctxsw_dev; struct gk20a_ctxsw_dev;
struct gk20a_fecs_trace; struct gk20a_fecs_trace;
struct tsg_gk20a;
int gk20a_ctxsw_dev_release(struct inode *inode, struct file *filp); int gk20a_ctxsw_dev_release(struct inode *inode, struct file *filp);
@@ -40,4 +41,8 @@ int gk20a_ctxsw_trace_write(struct gk20a *, struct nvgpu_ctxsw_trace_entry *);
void gk20a_ctxsw_trace_wake_up(struct gk20a *g, int vmid); void gk20a_ctxsw_trace_wake_up(struct gk20a *g, int vmid);
void gk20a_ctxsw_trace_init_ops(struct gpu_ops *ops); void gk20a_ctxsw_trace_init_ops(struct gpu_ops *ops);
void gk20a_ctxsw_trace_channel_reset(struct gk20a *g, struct channel_gk20a *ch);
void gk20a_ctxsw_trace_tsg_reset(struct gk20a *g, struct tsg_gk20a *tsg);
#endif /* __CTXSW_TRACE_GK20A_H */ #endif /* __CTXSW_TRACE_GK20A_H */

View File

@@ -1083,10 +1083,10 @@ static bool gk20a_fifo_handle_mmu_fault(
/* if lock is already taken, a reset is taking place /* if lock is already taken, a reset is taking place
so no need to repeat */ so no need to repeat */
if (!was_reset) { if (!was_reset) {
trace_gk20a_channel_reset( if (ch)
ch ? ch->hw_chid : ~0, gk20a_ctxsw_trace_channel_reset(g, ch);
tsg ? tsg->tsgid : else
NVGPU_INVALID_TSG_ID); gk20a_ctxsw_trace_tsg_reset(g, tsg);
gk20a_fifo_reset_engine(g, engine_id); gk20a_fifo_reset_engine(g, engine_id);
} }
mutex_unlock(&g->fifo.gr_reset_mutex); mutex_unlock(&g->fifo.gr_reset_mutex);

View File

@@ -17,6 +17,7 @@
#include <trace/events/gk20a.h> #include <trace/events/gk20a.h>
#include "vgpu/vgpu.h" #include "vgpu/vgpu.h"
#include "gk20a/ctxsw_trace_gk20a.h"
#include "gk20a/hw_fifo_gk20a.h" #include "gk20a/hw_fifo_gk20a.h"
#include "gk20a/hw_ram_gk20a.h" #include "gk20a/hw_ram_gk20a.h"
@@ -629,7 +630,7 @@ int vgpu_fifo_isr(struct gk20a *g, struct tegra_vgpu_fifo_intr_info *info)
gk20a_err(dev_from_gk20a(g), "fifo intr (%d) on ch %u", gk20a_err(dev_from_gk20a(g), "fifo intr (%d) on ch %u",
info->type, info->chid); info->type, info->chid);
trace_gk20a_channel_reset(ch->hw_chid, ch->tsgid); gk20a_ctxsw_trace_channel_reset(g, ch);
switch (info->type) { switch (info->type) {
case TEGRA_VGPU_FIFO_INTR_PBDMA: case TEGRA_VGPU_FIFO_INTR_PBDMA:

View File

@@ -1367,6 +1367,7 @@ struct nvgpu_as_map_buffer_batch_args {
#define NVGPU_CTXSW_TAG_SAVE_END 0x03 #define NVGPU_CTXSW_TAG_SAVE_END 0x03
#define NVGPU_CTXSW_TAG_RESTORE_START 0x04 #define NVGPU_CTXSW_TAG_RESTORE_START 0x04
#define NVGPU_CTXSW_TAG_CONTEXT_START 0x05 #define NVGPU_CTXSW_TAG_CONTEXT_START 0x05
#define NVGPU_CTXSW_TAG_RESET 0xfe
#define NVGPU_CTXSW_TAG_INVALID_TIMESTAMP 0xff #define NVGPU_CTXSW_TAG_INVALID_TIMESTAMP 0xff
#define NVGPU_CTXSW_TAG_LAST \ #define NVGPU_CTXSW_TAG_LAST \
NVGPU_CTXSW_TAG_INVALID_TIMESTAMP NVGPU_CTXSW_TAG_INVALID_TIMESTAMP