summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a
diff options
context:
space:
mode:
authorVinod G <vinodg@nvidia.com>2018-08-08 02:09:30 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2018-08-25 05:10:43 -0400
commitbfe65407bde2b5d0776724301e215c6553c989f3 (patch)
treef68a01361052afe1c30a0c6dcd5d359b762e647a /drivers/gpu/nvgpu/gk20a
parent3bd47da0954d3486d9ccd3c396f84445918f82b4 (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.h2
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.c30
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.h9
-rw-r--r--drivers/gpu/nvgpu/gk20a/tsg_gk20a.c82
-rw-r--r--drivers/gpu/nvgpu/gk20a/tsg_gk20a.h21
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
4564out: 4534out:
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
257struct 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
265struct gr_gk20a { 257struct 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
309clean_up: 324clean_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
393int 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
414void 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);
39int gk20a_init_tsg_support(struct gk20a *g, u32 tsgid); 39int gk20a_init_tsg_support(struct gk20a *g, u32 tsgid);
40struct tsg_gk20a *tsg_gk20a_from_ch(struct channel_gk20a *ch); 40struct tsg_gk20a *tsg_gk20a_from_ch(struct channel_gk20a *ch);
41 41
42struct 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
42struct tsg_gk20a { 50struct 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
74int gk20a_enable_tsg(struct tsg_gk20a *tsg); 83int gk20a_enable_tsg(struct tsg_gk20a *tsg);
@@ -84,6 +93,12 @@ int gk20a_tsg_set_timeslice(struct tsg_gk20a *tsg, u32 timeslice);
84u32 gk20a_tsg_get_timeslice(struct tsg_gk20a *tsg); 93u32 gk20a_tsg_get_timeslice(struct tsg_gk20a *tsg);
85int gk20a_tsg_set_priority(struct gk20a *g, struct tsg_gk20a *tsg, 94int gk20a_tsg_set_priority(struct gk20a *g, struct tsg_gk20a *tsg,
86 u32 priority); 95 u32 priority);
96int gk20a_tsg_alloc_sm_error_states_mem(struct gk20a *g,
97 struct tsg_gk20a *tsg,
98 u32 num_sm);
99void 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
88struct gk20a_event_id_data { 103struct 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 */