summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu
diff options
context:
space:
mode:
authorThomas Fleury <tfleury@nvidia.com>2016-08-24 18:12:35 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2016-08-29 19:14:40 -0400
commitfba43012c092b7566a1e83d140e0c5f170de62f0 (patch)
tree4e893772b571b4c96b8284c8a7118faea31f129e /drivers/gpu/nvgpu
parent7298414969ff659241f4fe1d8111bc54ae335d5e (diff)
gpu: nvgpu: do not flush FECS record on engine reset
Flushing timestamp record method can fail in case FECS is not processing the main method queue. In particular, this occurs in case of ctxsw timeout, where we process fifo sched interrupts from the host, but FECS is still waiting for idle (grWFI). In such scenario, this adds huge delay in fifo recovery procedure (timeout on FECS method). Since flushing the last (incomplete) record from FECS would only be useful in that case (context switch ongoing), remove flush operation on engine reset. Note that an explicit ENGINE_RESET event (with pid) is inserted in user-facing ctxsw buffer on engine reset. Bug 200228310 Change-Id: I885525f8f197f81266b50db161bb511867fc74f4 Signed-off-by: Thomas Fleury <tfleury@nvidia.com> Reviewed-on: http://git-master/r/1207305 (cherry picked from commit 44391b6204fd648949295f90481b0c424d9a5ddf) Reviewed-on: http://git-master/r/1208414 GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu')
-rw-r--r--drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c22
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h1
-rw-r--r--drivers/gpu/nvgpu/vgpu/fecs_trace_vgpu.c13
3 files changed, 31 insertions, 5 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c b/drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c
index abf1cc55..4bfbf503 100644
--- a/drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c
@@ -651,9 +651,11 @@ static int gk20a_fecs_trace_unbind_channel(struct gk20a *g, struct channel_gk20a
651 gk20a_dbg(gpu_dbg_fn|gpu_dbg_ctxsw, 651 gk20a_dbg(gpu_dbg_fn|gpu_dbg_ctxsw,
652 "ch=%p context_ptr=%x", ch, context_ptr); 652 "ch=%p context_ptr=%x", ch, context_ptr);
653 653
654 if (g->ops.fecs_trace.flush) 654 if (g->ops.fecs_trace.is_enabled(g)) {
655 g->ops.fecs_trace.flush(g); 655 if (g->ops.fecs_trace.flush)
656 gk20a_fecs_trace_poll(g); 656 g->ops.fecs_trace.flush(g);
657 gk20a_fecs_trace_poll(g);
658 }
657 gk20a_fecs_trace_hash_del(g, context_ptr); 659 gk20a_fecs_trace_hash_del(g, context_ptr);
658 return 0; 660 return 0;
659} 661}
@@ -662,8 +664,9 @@ static int gk20a_fecs_trace_reset(struct gk20a *g)
662{ 664{
663 gk20a_dbg(gpu_dbg_fn|gpu_dbg_ctxsw, ""); 665 gk20a_dbg(gpu_dbg_fn|gpu_dbg_ctxsw, "");
664 666
665 if (g->ops.fecs_trace.flush) 667 if (!g->ops.fecs_trace.is_enabled(g))
666 g->ops.fecs_trace.flush(g); 668 return 0;
669
667 gk20a_fecs_trace_poll(g); 670 gk20a_fecs_trace_poll(g);
668 return gk20a_fecs_trace_set_read_index(g, 0); 671 return gk20a_fecs_trace_set_read_index(g, 0);
669} 672}
@@ -725,6 +728,14 @@ static int gk20a_fecs_trace_disable(struct gk20a *g)
725 return -EPERM; 728 return -EPERM;
726} 729}
727 730
731static bool gk20a_fecs_trace_is_enabled(struct gk20a *g)
732{
733 struct gk20a_fecs_trace *trace = g->fecs_trace;
734
735 return (trace && trace->poll_task);
736}
737
738
728void gk20a_init_fecs_trace_ops(struct gpu_ops *ops) 739void gk20a_init_fecs_trace_ops(struct gpu_ops *ops)
729{ 740{
730 gk20a_ctxsw_trace_init_ops(ops); 741 gk20a_ctxsw_trace_init_ops(ops);
@@ -732,6 +743,7 @@ void gk20a_init_fecs_trace_ops(struct gpu_ops *ops)
732 ops->fecs_trace.deinit = gk20a_fecs_trace_deinit; 743 ops->fecs_trace.deinit = gk20a_fecs_trace_deinit;
733 ops->fecs_trace.enable = gk20a_fecs_trace_enable; 744 ops->fecs_trace.enable = gk20a_fecs_trace_enable;
734 ops->fecs_trace.disable = gk20a_fecs_trace_disable; 745 ops->fecs_trace.disable = gk20a_fecs_trace_disable;
746 ops->fecs_trace.is_enabled = gk20a_fecs_trace_is_enabled;
735 ops->fecs_trace.reset = gk20a_fecs_trace_reset; 747 ops->fecs_trace.reset = gk20a_fecs_trace_reset;
736 ops->fecs_trace.flush = NULL; 748 ops->fecs_trace.flush = NULL;
737 ops->fecs_trace.poll = gk20a_fecs_trace_poll; 749 ops->fecs_trace.poll = gk20a_fecs_trace_poll;
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index 463317e3..2b348677 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -484,6 +484,7 @@ struct gpu_ops {
484 int (*poll)(struct gk20a *g); 484 int (*poll)(struct gk20a *g);
485 int (*enable)(struct gk20a *g); 485 int (*enable)(struct gk20a *g);
486 int (*disable)(struct gk20a *g); 486 int (*disable)(struct gk20a *g);
487 bool (*is_enabled)(struct gk20a *g);
487 int (*reset)(struct gk20a *g); 488 int (*reset)(struct gk20a *g);
488 int (*bind_channel)(struct gk20a *, struct channel_gk20a *); 489 int (*bind_channel)(struct gk20a *, struct channel_gk20a *);
489 int (*unbind_channel)(struct gk20a *, struct channel_gk20a *); 490 int (*unbind_channel)(struct gk20a *, struct channel_gk20a *);
diff --git a/drivers/gpu/nvgpu/vgpu/fecs_trace_vgpu.c b/drivers/gpu/nvgpu/vgpu/fecs_trace_vgpu.c
index 634932b7..c80da26d 100644
--- a/drivers/gpu/nvgpu/vgpu/fecs_trace_vgpu.c
+++ b/drivers/gpu/nvgpu/vgpu/fecs_trace_vgpu.c
@@ -26,6 +26,7 @@ struct vgpu_fecs_trace {
26 struct nvgpu_ctxsw_ring_header *header; 26 struct nvgpu_ctxsw_ring_header *header;
27 struct nvgpu_ctxsw_trace_entry *entries; 27 struct nvgpu_ctxsw_trace_entry *entries;
28 int num_entries; 28 int num_entries;
29 bool enabled;
29 void *buf; 30 void *buf;
30}; 31};
31 32
@@ -104,6 +105,7 @@ static int vgpu_fecs_trace_deinit(struct gk20a *g)
104 105
105static int vgpu_fecs_trace_enable(struct gk20a *g) 106static int vgpu_fecs_trace_enable(struct gk20a *g)
106{ 107{
108 struct vgpu_fecs_trace *vcst = (struct vgpu_fecs_trace *)g->fecs_trace;
107 struct tegra_vgpu_cmd_msg msg = { 109 struct tegra_vgpu_cmd_msg msg = {
108 .cmd = TEGRA_VGPU_CMD_FECS_TRACE_ENABLE, 110 .cmd = TEGRA_VGPU_CMD_FECS_TRACE_ENABLE,
109 .handle = vgpu_get_handle(g), 111 .handle = vgpu_get_handle(g),
@@ -113,23 +115,33 @@ static int vgpu_fecs_trace_enable(struct gk20a *g)
113 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); 115 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
114 err = err ? err : msg.ret; 116 err = err ? err : msg.ret;
115 WARN_ON(err); 117 WARN_ON(err);
118 vcst->enabled = !err;
116 return err; 119 return err;
117} 120}
118 121
119static int vgpu_fecs_trace_disable(struct gk20a *g) 122static int vgpu_fecs_trace_disable(struct gk20a *g)
120{ 123{
124 struct vgpu_fecs_trace *vcst = (struct vgpu_fecs_trace *)g->fecs_trace;
121 struct tegra_vgpu_cmd_msg msg = { 125 struct tegra_vgpu_cmd_msg msg = {
122 .cmd = TEGRA_VGPU_CMD_FECS_TRACE_DISABLE, 126 .cmd = TEGRA_VGPU_CMD_FECS_TRACE_DISABLE,
123 .handle = vgpu_get_handle(g), 127 .handle = vgpu_get_handle(g),
124 }; 128 };
125 int err; 129 int err;
126 130
131 vcst->enabled = false;
127 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); 132 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
128 err = err ? err : msg.ret; 133 err = err ? err : msg.ret;
129 WARN_ON(err); 134 WARN_ON(err);
130 return err; 135 return err;
131} 136}
132 137
138static bool vpgpu_fecs_trace_is_enabled(struct gk20a *g)
139{
140 struct vgpu_fecs_trace *vcst = (struct vgpu_fecs_trace *)g->fecs_trace;
141
142 return (vcst && vcst->enabled);
143}
144
133static int vgpu_fecs_trace_poll(struct gk20a *g) 145static int vgpu_fecs_trace_poll(struct gk20a *g)
134{ 146{
135 struct tegra_vgpu_cmd_msg msg = { 147 struct tegra_vgpu_cmd_msg msg = {
@@ -208,6 +220,7 @@ void vgpu_init_fecs_trace_ops(struct gpu_ops *ops)
208 ops->fecs_trace.deinit = vgpu_fecs_trace_deinit; 220 ops->fecs_trace.deinit = vgpu_fecs_trace_deinit;
209 ops->fecs_trace.enable = vgpu_fecs_trace_enable; 221 ops->fecs_trace.enable = vgpu_fecs_trace_enable;
210 ops->fecs_trace.disable = vgpu_fecs_trace_disable; 222 ops->fecs_trace.disable = vgpu_fecs_trace_disable;
223 ops->fecs_trace.is_enabled = vpgpu_fecs_trace_is_enabled;
211 ops->fecs_trace.reset = NULL; 224 ops->fecs_trace.reset = NULL;
212 ops->fecs_trace.flush = NULL; 225 ops->fecs_trace.flush = NULL;
213 ops->fecs_trace.poll = vgpu_fecs_trace_poll; 226 ops->fecs_trace.poll = vgpu_fecs_trace_poll;