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 | |
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')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 5 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 39 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.h | 4 |
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 @@ | |||
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; |
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 | ||
243 | u32 gk20a_fifo_get_gr_engine_id(struct gk20a *g); | 243 | u32 gk20a_fifo_get_gr_engine_id(struct gk20a *g); |
244 | 244 | ||
245 | int gk20a_fifo_deferred_reset(struct gk20a *g, struct channel_gk20a *ch); | ||
246 | |||
245 | u32 gk20a_fifo_get_all_ce_engine_reset_mask(struct gk20a *g); | 247 | u32 gk20a_fifo_get_all_ce_engine_reset_mask(struct gk20a *g); |
246 | 248 | ||
247 | u32 gk20a_fifo_get_fast_ce_runlist_id(struct gk20a *g); | 249 | u32 gk20a_fifo_get_fast_ce_runlist_id(struct gk20a *g); |