summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a
diff options
context:
space:
mode:
authorDeepak Nibade <dnibade@nvidia.com>2016-08-01 07:32:31 -0400
committerTerje Bergstrom <tbergstrom@nvidia.com>2016-08-12 12:51:23 -0400
commit33ff34887f560449828e79170a2a36a97496eeec (patch)
tree89fbc068163ab18b46487bd8f0ee70b82b6c9c95 /drivers/gpu/nvgpu/gk20a
parent1b216d778a7938072aa2a68ebef38bb954418257 (diff)
gpu: nvgpu: fix deferred engine reset sequence
We currently store fault_id into fifo.deferred_fault_engines and use that in gk20a_fifo_reset_engine() which is incorrect Also, in deferred engine reset path during channel close, we do not check if channel is loaded on engine or not fix this with below - store engine_id bits into fifo.deferred_fault_engines - define new API gk20a_fifo_deferred_reset() to perform deferred engine reset - get all engines on which channel is loaded with gk20a_fifo_engines_on_id() - for each set bit/engine_id in fifo.deferred_fault_engines, check if channel is loaded on that engine, and if yes, reset the engine Bug 1791696 Change-Id: I1b8b1a9e3aa538fe6903a352aa732b47c95ec7d5 Signed-off-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-on: http://git-master/r/1195087 Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a')
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c5
-rw-r--r--drivers/gpu/nvgpu/gk20a/fifo_gk20a.c39
-rw-r--r--drivers/gpu/nvgpu/gk20a/fifo_gk20a.h4
3 files changed, 42 insertions, 6 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index eae2bdae..a8a39302 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -910,11 +910,8 @@ static void gk20a_free_channel(struct channel_gk20a *ch)
910 /* if lock is already taken, a reset is taking place 910 /* if lock is already taken, a reset is taking place
911 so no need to repeat */ 911 so no need to repeat */
912 if (!was_reset) 912 if (!was_reset)
913 gk20a_fifo_reset_engine(g, 913 gk20a_fifo_deferred_reset(g, ch);
914 g->fifo.deferred_fault_engines);
915 mutex_unlock(&g->fifo.gr_reset_mutex); 914 mutex_unlock(&g->fifo.gr_reset_mutex);
916 g->fifo.deferred_fault_engines = 0;
917 g->fifo.deferred_reset_pending = false;
918 } 915 }
919 mutex_unlock(&f->deferred_reset_mutex); 916 mutex_unlock(&f->deferred_reset_mutex);
920 917
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
index 23a014d7..b025f4d6 100644
--- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
@@ -39,6 +39,7 @@
39static int gk20a_fifo_update_runlist_locked(struct gk20a *g, u32 runlist_id, 39static int gk20a_fifo_update_runlist_locked(struct gk20a *g, u32 runlist_id,
40 u32 hw_chid, bool add, 40 u32 hw_chid, bool add,
41 bool wait_for_finish); 41 bool wait_for_finish);
42static u32 gk20a_fifo_engines_on_id(struct gk20a *g, u32 id, bool is_tsg);
42 43
43u32 gk20a_fifo_get_engine_ids(struct gk20a *g, 44u32 gk20a_fifo_get_engine_ids(struct gk20a *g,
44 u32 engine_id[], u32 engine_id_sz, 45 u32 engine_id[], u32 engine_id_sz,
@@ -1269,6 +1270,42 @@ void gk20a_fifo_abort_tsg(struct gk20a *g, u32 tsgid, bool preempt)
1269 mutex_unlock(&tsg->ch_list_lock); 1270 mutex_unlock(&tsg->ch_list_lock);
1270} 1271}
1271 1272
1273int gk20a_fifo_deferred_reset(struct gk20a *g, struct channel_gk20a *ch)
1274{
1275 u32 engine_id, engines;
1276
1277 mutex_lock(&g->dbg_sessions_lock);
1278 gr_gk20a_disable_ctxsw(g);
1279
1280 if (!g->fifo.deferred_reset_pending)
1281 goto clean_up;
1282
1283 if (gk20a_is_channel_marked_as_tsg(ch))
1284 engines = gk20a_fifo_engines_on_id(g, ch->tsgid, true);
1285 else
1286 engines = gk20a_fifo_engines_on_id(g, ch->hw_chid, false);
1287 if (!engines)
1288 goto clean_up;
1289
1290 /*
1291 * If deferred reset is set for an engine, and channel is running
1292 * on that engine, reset it
1293 */
1294 for_each_set_bit(engine_id, &g->fifo.deferred_fault_engines, 32) {
1295 if (BIT(engine_id) & engines)
1296 gk20a_fifo_reset_engine(g, engine_id);
1297 }
1298
1299 g->fifo.deferred_fault_engines = 0;
1300 g->fifo.deferred_reset_pending = false;
1301
1302clean_up:
1303 gr_gk20a_enable_ctxsw(g);
1304 mutex_unlock(&g->dbg_sessions_lock);
1305
1306 return 0;
1307}
1308
1272static bool gk20a_fifo_handle_mmu_fault( 1309static bool gk20a_fifo_handle_mmu_fault(
1273 struct gk20a *g, 1310 struct gk20a *g,
1274 u32 mmu_fault_engines, /* queried from HW if 0 */ 1311 u32 mmu_fault_engines, /* queried from HW if 0 */
@@ -1403,7 +1440,7 @@ static bool gk20a_fifo_handle_mmu_fault(
1403 /* check if engine reset should be deferred */ 1440 /* check if engine reset should be deferred */
1404 if ((ch || tsg) && gk20a_fifo_should_defer_engine_reset(g, 1441 if ((ch || tsg) && gk20a_fifo_should_defer_engine_reset(g,
1405 engine_id, &f, fake_fault)) { 1442 engine_id, &f, fake_fault)) {
1406 g->fifo.deferred_fault_engines = fault_id; 1443 g->fifo.deferred_fault_engines |= BIT(engine_id);
1407 1444
1408 /* handled during channel free */ 1445 /* handled during channel free */
1409 g->fifo.deferred_reset_pending = true; 1446 g->fifo.deferred_reset_pending = true;
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h
index 33d6d39c..f5a73a12 100644
--- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h
@@ -142,7 +142,7 @@ struct fifo_gk20a {
142 142
143 } intr; 143 } intr;
144 144
145 u32 deferred_fault_engines; 145 unsigned long deferred_fault_engines;
146 bool deferred_reset_pending; 146 bool deferred_reset_pending;
147 struct mutex deferred_reset_mutex; 147 struct mutex deferred_reset_mutex;
148}; 148};
@@ -242,6 +242,8 @@ bool gk20a_fifo_is_valid_engine_id(struct gk20a *g, u32 engine_id);
242 242
243u32 gk20a_fifo_get_gr_engine_id(struct gk20a *g); 243u32 gk20a_fifo_get_gr_engine_id(struct gk20a *g);
244 244
245int gk20a_fifo_deferred_reset(struct gk20a *g, struct channel_gk20a *ch);
246
245u32 gk20a_fifo_get_all_ce_engine_reset_mask(struct gk20a *g); 247u32 gk20a_fifo_get_all_ce_engine_reset_mask(struct gk20a *g);
246 248
247u32 gk20a_fifo_get_fast_ce_runlist_id(struct gk20a *g); 249u32 gk20a_fifo_get_fast_ce_runlist_id(struct gk20a *g);