diff options
author | Vinod G <vinodg@nvidia.com> | 2018-08-08 02:09:30 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2018-08-25 05:10:43 -0400 |
commit | bfe65407bde2b5d0776724301e215c6553c989f3 (patch) | |
tree | f68a01361052afe1c30a0c6dcd5d359b762e647a /drivers/gpu/nvgpu/gk20a | |
parent | 3bd47da0954d3486d9ccd3c396f84445918f82b4 (diff) |
gpu: nvgpu: Read sm error ioctl support for tsg
Add READ_SM_ERROR IOCTL support to TSG level.
Moved the struct to save the sm_error details
from gr to tsg as the sm_error support is context
based, not global.
Also corrected MISRA 21.1 error in header file.
nvgpu_dbg_gpu_ioctl_write_single_sm_error_state and
nvgpu_dbg_gpu_ioctl_read_single_sm_error_state
functions are modified to use the tsg struct
nvgpu_tsg_sm_error_state.
Bug 200412642
Change-Id: I9e334b059078a4bb0e360b945444cc4bf1cc56ec
Signed-off-by: Vinod G <vinodg@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1794856
Reviewed-by: svc-misra-checker <svc-misra-checker@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 30 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.h | 9 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/tsg_gk20a.c | 82 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/tsg_gk20a.h | 21 |
5 files changed, 95 insertions, 49 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index cf202f14..192f4c3e 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h | |||
@@ -396,7 +396,7 @@ struct gpu_ops { | |||
396 | u32 sm, struct channel_gk20a *fault_ch); | 396 | u32 sm, struct channel_gk20a *fault_ch); |
397 | int (*update_sm_error_state)(struct gk20a *g, | 397 | int (*update_sm_error_state)(struct gk20a *g, |
398 | struct channel_gk20a *ch, u32 sm_id, | 398 | struct channel_gk20a *ch, u32 sm_id, |
399 | struct nvgpu_gr_sm_error_state *sm_error_state); | 399 | struct nvgpu_tsg_sm_error_state *sm_error_state); |
400 | int (*clear_sm_error_state)(struct gk20a *g, | 400 | int (*clear_sm_error_state)(struct gk20a *g, |
401 | struct channel_gk20a *ch, u32 sm_id); | 401 | struct channel_gk20a *ch, u32 sm_id); |
402 | int (*suspend_contexts)(struct gk20a *g, | 402 | int (*suspend_contexts)(struct gk20a *g, |
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index f2b083d7..cdc00bbd 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c | |||
@@ -1561,19 +1561,6 @@ restore_fe_go_idle: | |||
1561 | if (err) | 1561 | if (err) |
1562 | goto clean_up; | 1562 | goto clean_up; |
1563 | 1563 | ||
1564 | nvgpu_kfree(g, gr->sm_error_states); | ||
1565 | |||
1566 | /* we need to allocate this after g->ops.gr.init_fs_state() since | ||
1567 | * we initialize gr->no_of_sm in this function | ||
1568 | */ | ||
1569 | gr->sm_error_states = nvgpu_kzalloc(g, | ||
1570 | sizeof(struct nvgpu_gr_sm_error_state) | ||
1571 | * gr->no_of_sm); | ||
1572 | if (!gr->sm_error_states) { | ||
1573 | err = -ENOMEM; | ||
1574 | goto restore_fe_go_idle; | ||
1575 | } | ||
1576 | |||
1577 | ctx_header_words = roundup(ctx_header_bytes, sizeof(u32)); | 1564 | ctx_header_words = roundup(ctx_header_bytes, sizeof(u32)); |
1578 | ctx_header_words >>= 2; | 1565 | ctx_header_words >>= 2; |
1579 | 1566 | ||
@@ -3072,7 +3059,6 @@ static void gk20a_remove_gr_support(struct gr_gk20a *gr) | |||
3072 | 3059 | ||
3073 | memset(&gr->compbit_store, 0, sizeof(struct compbit_store_desc)); | 3060 | memset(&gr->compbit_store, 0, sizeof(struct compbit_store_desc)); |
3074 | 3061 | ||
3075 | nvgpu_kfree(g, gr->sm_error_states); | ||
3076 | nvgpu_kfree(g, gr->gpc_tpc_count); | 3062 | nvgpu_kfree(g, gr->gpc_tpc_count); |
3077 | nvgpu_kfree(g, gr->gpc_zcb_count); | 3063 | nvgpu_kfree(g, gr->gpc_zcb_count); |
3078 | nvgpu_kfree(g, gr->gpc_ppc_count); | 3064 | nvgpu_kfree(g, gr->gpc_ppc_count); |
@@ -4545,22 +4531,6 @@ restore_fe_go_idle: | |||
4545 | 4531 | ||
4546 | err = gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g), | 4532 | err = gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g), |
4547 | GR_IDLE_CHECK_DEFAULT); | 4533 | GR_IDLE_CHECK_DEFAULT); |
4548 | if (err) | ||
4549 | goto out; | ||
4550 | |||
4551 | nvgpu_kfree(g, gr->sm_error_states); | ||
4552 | |||
4553 | /* we need to allocate this after g->ops.gr.init_fs_state() since | ||
4554 | * we initialize gr->no_of_sm in this function | ||
4555 | */ | ||
4556 | gr->sm_error_states = nvgpu_kzalloc(g, | ||
4557 | sizeof(struct nvgpu_gr_sm_error_state) * | ||
4558 | gr->no_of_sm); | ||
4559 | if (!gr->sm_error_states) { | ||
4560 | err = -ENOMEM; | ||
4561 | goto restore_fe_go_idle; | ||
4562 | } | ||
4563 | |||
4564 | out: | 4534 | out: |
4565 | nvgpu_log_fn(g, "done"); | 4535 | nvgpu_log_fn(g, "done"); |
4566 | return err; | 4536 | return err; |
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h index 3fc7e55f..bd5e625d 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h | |||
@@ -254,14 +254,6 @@ struct nvgpu_preemption_modes_rec { | |||
254 | u32 default_compute_preempt_mode; /* default mode */ | 254 | u32 default_compute_preempt_mode; /* default mode */ |
255 | }; | 255 | }; |
256 | 256 | ||
257 | struct nvgpu_gr_sm_error_state { | ||
258 | u32 hww_global_esr; | ||
259 | u32 hww_warp_esr; | ||
260 | u64 hww_warp_esr_pc; | ||
261 | u32 hww_global_esr_report_mask; | ||
262 | u32 hww_warp_esr_report_mask; | ||
263 | }; | ||
264 | |||
265 | struct gr_gk20a { | 257 | struct gr_gk20a { |
266 | struct gk20a *g; | 258 | struct gk20a *g; |
267 | struct { | 259 | struct { |
@@ -427,7 +419,6 @@ struct gr_gk20a { | |||
427 | u32 *fbp_rop_l2_en_mask; | 419 | u32 *fbp_rop_l2_en_mask; |
428 | u32 no_of_sm; | 420 | u32 no_of_sm; |
429 | struct sm_info *sm_to_cluster; | 421 | struct sm_info *sm_to_cluster; |
430 | struct nvgpu_gr_sm_error_state *sm_error_states; | ||
431 | 422 | ||
432 | #define NVGPU_SM_EXCEPTION_TYPE_MASK_NONE (0x0U) | 423 | #define NVGPU_SM_EXCEPTION_TYPE_MASK_NONE (0x0U) |
433 | #define NVGPU_SM_EXCEPTION_TYPE_MASK_FATAL (0x1U << 0) | 424 | #define NVGPU_SM_EXCEPTION_TYPE_MASK_FATAL (0x1U << 0) |
diff --git a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c index 62763da3..624ee1d7 100644 --- a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c | |||
@@ -275,8 +275,23 @@ struct tsg_gk20a *gk20a_tsg_open(struct gk20a *g, pid_t pid) | |||
275 | int err; | 275 | int err; |
276 | 276 | ||
277 | tsg = gk20a_tsg_acquire_unused_tsg(&g->fifo); | 277 | tsg = gk20a_tsg_acquire_unused_tsg(&g->fifo); |
278 | if (!tsg) | 278 | if (tsg == NULL) { |
279 | return NULL; | 279 | return NULL; |
280 | } | ||
281 | |||
282 | /* we need to allocate this after g->ops.gr.init_fs_state() since | ||
283 | * we initialize gr->no_of_sm in this function | ||
284 | */ | ||
285 | if (g->gr.no_of_sm == 0U) { | ||
286 | nvgpu_err(g, "no_of_sm %d not set, failed allocation", | ||
287 | g->gr.no_of_sm); | ||
288 | return NULL; | ||
289 | } | ||
290 | |||
291 | err = gk20a_tsg_alloc_sm_error_states_mem(g, tsg, g->gr.no_of_sm); | ||
292 | if (err != 0) { | ||
293 | return NULL; | ||
294 | } | ||
280 | 295 | ||
281 | tsg->g = g; | 296 | tsg->g = g; |
282 | tsg->num_active_channels = 0; | 297 | tsg->num_active_channels = 0; |
@@ -295,7 +310,7 @@ struct tsg_gk20a *gk20a_tsg_open(struct gk20a *g, pid_t pid) | |||
295 | 310 | ||
296 | if (g->ops.fifo.tsg_open) { | 311 | if (g->ops.fifo.tsg_open) { |
297 | err = g->ops.fifo.tsg_open(tsg); | 312 | err = g->ops.fifo.tsg_open(tsg); |
298 | if (err) { | 313 | if (err != 0) { |
299 | nvgpu_err(g, "tsg %d fifo open failed %d", | 314 | nvgpu_err(g, "tsg %d fifo open failed %d", |
300 | tsg->tsgid, err); | 315 | tsg->tsgid, err); |
301 | goto clean_up; | 316 | goto clean_up; |
@@ -307,6 +322,12 @@ struct tsg_gk20a *gk20a_tsg_open(struct gk20a *g, pid_t pid) | |||
307 | return tsg; | 322 | return tsg; |
308 | 323 | ||
309 | clean_up: | 324 | clean_up: |
325 | |||
326 | if(tsg->sm_error_states != NULL) { | ||
327 | nvgpu_kfree(g, tsg->sm_error_states); | ||
328 | tsg->sm_error_states = NULL; | ||
329 | } | ||
330 | |||
310 | nvgpu_ref_put(&tsg->refcount, gk20a_tsg_release); | 331 | nvgpu_ref_put(&tsg->refcount, gk20a_tsg_release); |
311 | return NULL; | 332 | return NULL; |
312 | } | 333 | } |
@@ -317,20 +338,28 @@ void gk20a_tsg_release(struct nvgpu_ref *ref) | |||
317 | struct gk20a *g = tsg->g; | 338 | struct gk20a *g = tsg->g; |
318 | struct gk20a_event_id_data *event_id_data, *event_id_data_temp; | 339 | struct gk20a_event_id_data *event_id_data, *event_id_data_temp; |
319 | 340 | ||
320 | if (g->ops.fifo.tsg_release) | 341 | if (g->ops.fifo.tsg_release != NULL) { |
321 | g->ops.fifo.tsg_release(tsg); | 342 | g->ops.fifo.tsg_release(tsg); |
343 | } | ||
322 | 344 | ||
323 | if (nvgpu_mem_is_valid(&tsg->gr_ctx.mem)) | 345 | if (nvgpu_mem_is_valid(&tsg->gr_ctx.mem)) { |
324 | gr_gk20a_free_tsg_gr_ctx(tsg); | 346 | gr_gk20a_free_tsg_gr_ctx(tsg); |
347 | } | ||
325 | 348 | ||
326 | if (g->ops.fifo.deinit_eng_method_buffers) | 349 | if (g->ops.fifo.deinit_eng_method_buffers != NULL) { |
327 | g->ops.fifo.deinit_eng_method_buffers(g, tsg); | 350 | g->ops.fifo.deinit_eng_method_buffers(g, tsg); |
351 | } | ||
328 | 352 | ||
329 | if (tsg->vm) { | 353 | if (tsg->vm != NULL) { |
330 | nvgpu_vm_put(tsg->vm); | 354 | nvgpu_vm_put(tsg->vm); |
331 | tsg->vm = NULL; | 355 | tsg->vm = NULL; |
332 | } | 356 | } |
333 | 357 | ||
358 | if(tsg->sm_error_states != NULL) { | ||
359 | nvgpu_kfree(g, tsg->sm_error_states); | ||
360 | tsg->sm_error_states = NULL; | ||
361 | } | ||
362 | |||
334 | /* unhook all events created on this TSG */ | 363 | /* unhook all events created on this TSG */ |
335 | nvgpu_mutex_acquire(&tsg->event_id_list_lock); | 364 | nvgpu_mutex_acquire(&tsg->event_id_list_lock); |
336 | nvgpu_list_for_each_entry_safe(event_id_data, event_id_data_temp, | 365 | nvgpu_list_for_each_entry_safe(event_id_data, event_id_data_temp, |
@@ -360,3 +389,44 @@ struct tsg_gk20a *tsg_gk20a_from_ch(struct channel_gk20a *ch) | |||
360 | 389 | ||
361 | return tsg; | 390 | return tsg; |
362 | } | 391 | } |
392 | |||
393 | int gk20a_tsg_alloc_sm_error_states_mem(struct gk20a *g, | ||
394 | struct tsg_gk20a *tsg, | ||
395 | u32 num_sm) | ||
396 | { | ||
397 | int err = 0; | ||
398 | |||
399 | if (tsg->sm_error_states != NULL) { | ||
400 | return err; | ||
401 | } | ||
402 | |||
403 | tsg->sm_error_states = nvgpu_kzalloc(g, | ||
404 | sizeof(struct nvgpu_tsg_sm_error_state) | ||
405 | * num_sm); | ||
406 | if (tsg->sm_error_states == NULL) { | ||
407 | nvgpu_err(g, "sm_error_states mem allocation failed"); | ||
408 | err = -ENOMEM; | ||
409 | } | ||
410 | |||
411 | return err; | ||
412 | } | ||
413 | |||
414 | void gk20a_tsg_update_sm_error_state_locked(struct tsg_gk20a *tsg, | ||
415 | u32 sm_id, | ||
416 | struct nvgpu_tsg_sm_error_state *sm_error_state) | ||
417 | { | ||
418 | struct nvgpu_tsg_sm_error_state *tsg_sm_error_states; | ||
419 | |||
420 | tsg_sm_error_states = tsg->sm_error_states + sm_id; | ||
421 | |||
422 | tsg_sm_error_states->hww_global_esr = | ||
423 | sm_error_state->hww_global_esr; | ||
424 | tsg_sm_error_states->hww_warp_esr = | ||
425 | sm_error_state->hww_warp_esr; | ||
426 | tsg_sm_error_states->hww_warp_esr_pc = | ||
427 | sm_error_state->hww_warp_esr_pc; | ||
428 | tsg_sm_error_states->hww_global_esr_report_mask = | ||
429 | sm_error_state->hww_global_esr_report_mask; | ||
430 | tsg_sm_error_states->hww_warp_esr_report_mask = | ||
431 | sm_error_state->hww_warp_esr_report_mask; | ||
432 | } | ||
diff --git a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.h b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.h index 552c3bb3..67ccb9f5 100644 --- a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.h | |||
@@ -19,8 +19,8 @@ | |||
19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
20 | * DEALINGS IN THE SOFTWARE. | 20 | * DEALINGS IN THE SOFTWARE. |
21 | */ | 21 | */ |
22 | #ifndef __TSG_GK20A_H_ | 22 | #ifndef TSG_GK20A_H |
23 | #define __TSG_GK20A_H_ | 23 | #define TSG_GK20A_H |
24 | 24 | ||
25 | #include <nvgpu/lock.h> | 25 | #include <nvgpu/lock.h> |
26 | #include <nvgpu/kref.h> | 26 | #include <nvgpu/kref.h> |
@@ -39,6 +39,14 @@ void gk20a_tsg_release(struct nvgpu_ref *ref); | |||
39 | int gk20a_init_tsg_support(struct gk20a *g, u32 tsgid); | 39 | int gk20a_init_tsg_support(struct gk20a *g, u32 tsgid); |
40 | struct tsg_gk20a *tsg_gk20a_from_ch(struct channel_gk20a *ch); | 40 | struct tsg_gk20a *tsg_gk20a_from_ch(struct channel_gk20a *ch); |
41 | 41 | ||
42 | struct nvgpu_tsg_sm_error_state { | ||
43 | u32 hww_global_esr; | ||
44 | u32 hww_warp_esr; | ||
45 | u64 hww_warp_esr_pc; | ||
46 | u32 hww_global_esr_report_mask; | ||
47 | u32 hww_warp_esr_report_mask; | ||
48 | }; | ||
49 | |||
42 | struct tsg_gk20a { | 50 | struct tsg_gk20a { |
43 | struct gk20a *g; | 51 | struct gk20a *g; |
44 | 52 | ||
@@ -69,6 +77,7 @@ struct tsg_gk20a { | |||
69 | bool tpc_num_initialized; | 77 | bool tpc_num_initialized; |
70 | bool in_use; | 78 | bool in_use; |
71 | 79 | ||
80 | struct nvgpu_tsg_sm_error_state *sm_error_states; | ||
72 | }; | 81 | }; |
73 | 82 | ||
74 | int gk20a_enable_tsg(struct tsg_gk20a *tsg); | 83 | int gk20a_enable_tsg(struct tsg_gk20a *tsg); |
@@ -84,6 +93,12 @@ int gk20a_tsg_set_timeslice(struct tsg_gk20a *tsg, u32 timeslice); | |||
84 | u32 gk20a_tsg_get_timeslice(struct tsg_gk20a *tsg); | 93 | u32 gk20a_tsg_get_timeslice(struct tsg_gk20a *tsg); |
85 | int gk20a_tsg_set_priority(struct gk20a *g, struct tsg_gk20a *tsg, | 94 | int gk20a_tsg_set_priority(struct gk20a *g, struct tsg_gk20a *tsg, |
86 | u32 priority); | 95 | u32 priority); |
96 | int gk20a_tsg_alloc_sm_error_states_mem(struct gk20a *g, | ||
97 | struct tsg_gk20a *tsg, | ||
98 | u32 num_sm); | ||
99 | void gk20a_tsg_update_sm_error_state_locked(struct tsg_gk20a *tsg, | ||
100 | u32 sm_id, | ||
101 | struct nvgpu_tsg_sm_error_state *sm_error_state); | ||
87 | 102 | ||
88 | struct gk20a_event_id_data { | 103 | struct gk20a_event_id_data { |
89 | struct gk20a *g; | 104 | struct gk20a *g; |
@@ -106,4 +121,4 @@ gk20a_event_id_data_from_event_id_node(struct nvgpu_list_node *node) | |||
106 | ((uintptr_t)node - offsetof(struct gk20a_event_id_data, event_id_node)); | 121 | ((uintptr_t)node - offsetof(struct gk20a_event_id_data, event_id_node)); |
107 | }; | 122 | }; |
108 | 123 | ||
109 | #endif /* __TSG_GK20A_H_ */ | 124 | #endif /* TSG_GK20A_H */ |