diff options
author | Deepak Nibade <dnibade@nvidia.com> | 2016-08-01 07:32:31 -0400 |
---|---|---|
committer | Terje Bergstrom <tbergstrom@nvidia.com> | 2016-08-12 12:51:23 -0400 |
commit | 33ff34887f560449828e79170a2a36a97496eeec (patch) | |
tree | 89fbc068163ab18b46487bd8f0ee70b82b6c9c95 /drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | |
parent | 1b216d778a7938072aa2a68ebef38bb954418257 (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/fifo_gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 39 |
1 files changed, 38 insertions, 1 deletions
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 @@ | |||
39 | static int gk20a_fifo_update_runlist_locked(struct gk20a *g, u32 runlist_id, | 39 | static 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); |
42 | static u32 gk20a_fifo_engines_on_id(struct gk20a *g, u32 id, bool is_tsg); | ||
42 | 43 | ||
43 | u32 gk20a_fifo_get_engine_ids(struct gk20a *g, | 44 | u32 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 | ||
1273 | int 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 | |||
1302 | clean_up: | ||
1303 | gr_gk20a_enable_ctxsw(g); | ||
1304 | mutex_unlock(&g->dbg_sessions_lock); | ||
1305 | |||
1306 | return 0; | ||
1307 | } | ||
1308 | |||
1272 | static bool gk20a_fifo_handle_mmu_fault( | 1309 | static 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; |