summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Nieto <dmartineznie@nvidia.com>2017-12-18 20:10:19 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2017-12-28 13:01:36 -0500
commit8fb6a8562ec033d2d1319f91377cd1782f593979 (patch)
tree07b7fe61cd9763ddf5cee2934994841fa330b90a
parentf19f22fcc8ef21b363b873c499cbd2e690af29f8 (diff)
gpu: nvgpu: gv11b: Report LTC errors per slice
Add support to report ltc ecc errors per slice (1) use new logic to detect subunits (2) store size of array and check before comparison to prevent out of bounds derefencing (3) use new hashing to prevent collisions or entries with permuted names bug 2037425 Change-Id: I63b9f0df43b9dceddc1bae17924c4723072f569e Signed-off-by: David Nieto <dmartineznie@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1620854 GVS: Gerrit_Virtual_Submit Reviewed-by: Chris Dragan <kdragan@nvidia.com> Tested-by: Chris Dragan <kdragan@nvidia.com> Reviewed-by: Nirav Patel <nipatel@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
-rw-r--r--drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c113
-rw-r--r--drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.h6
-rw-r--r--drivers/gpu/nvgpu/common/linux/platform_gv11b_tegra.c32
-rw-r--r--drivers/gpu/nvgpu/gk20a/ecc_gk20a.h1
-rw-r--r--drivers/gpu/nvgpu/gp10b/ltc_gp10b.c4
5 files changed, 125 insertions, 31 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c b/drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c
index d8bd12d2..8e4cc0a2 100644
--- a/drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c
+++ b/drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c
@@ -450,10 +450,11 @@ static struct device_attribute *dev_attr_l2_ecc_ded_count_array;
450static u32 gen_ecc_hash_key(char *str) 450static u32 gen_ecc_hash_key(char *str)
451{ 451{
452 int i = 0; 452 int i = 0;
453 u32 hash_key = 0; 453 u32 hash_key = 0x811c9dc5;
454 454
455 while (str[i]) { 455 while (str[i]) {
456 hash_key += (u32)(str[i]); 456 hash_key *= 0x1000193;
457 hash_key ^= (u32)(str[i]);
457 i++; 458 i++;
458 }; 459 };
459 460
@@ -467,10 +468,16 @@ static ssize_t ecc_stat_show(struct device *dev,
467 const char *ecc_stat_full_name = attr->attr.name; 468 const char *ecc_stat_full_name = attr->attr.name;
468 const char *ecc_stat_base_name; 469 const char *ecc_stat_base_name;
469 unsigned int hw_unit; 470 unsigned int hw_unit;
471 unsigned int subunit;
470 struct gk20a_ecc_stat *ecc_stat; 472 struct gk20a_ecc_stat *ecc_stat;
471 u32 hash_key; 473 u32 hash_key;
474 struct gk20a *g = get_gk20a(dev);
472 475
473 if (sscanf(ecc_stat_full_name, "ltc%u", &hw_unit) == 1) { 476 if (sscanf(ecc_stat_full_name, "ltc%u_lts%u", &hw_unit,
477 &subunit) == 2) {
478 ecc_stat_base_name = &(ecc_stat_full_name[strlen("ltc0_lts0_")]);
479 hw_unit = g->gr.slices_per_ltc * hw_unit + subunit;
480 } else if (sscanf(ecc_stat_full_name, "ltc%u", &hw_unit) == 1) {
474 ecc_stat_base_name = &(ecc_stat_full_name[strlen("ltc0_")]); 481 ecc_stat_base_name = &(ecc_stat_full_name[strlen("ltc0_")]);
475 } else if (sscanf(ecc_stat_full_name, "gpc0_tpc%u", &hw_unit) == 1) { 482 } else if (sscanf(ecc_stat_full_name, "gpc0_tpc%u", &hw_unit) == 1) {
476 ecc_stat_base_name = &(ecc_stat_full_name[strlen("gpc0_tpc0_")]); 483 ecc_stat_base_name = &(ecc_stat_full_name[strlen("gpc0_tpc0_")]);
@@ -485,10 +492,13 @@ static ssize_t ecc_stat_show(struct device *dev,
485 } 492 }
486 493
487 hash_key = gen_ecc_hash_key((char *)ecc_stat_base_name); 494 hash_key = gen_ecc_hash_key((char *)ecc_stat_base_name);
495
488 hash_for_each_possible(ecc_hash_table, 496 hash_for_each_possible(ecc_hash_table,
489 ecc_stat, 497 ecc_stat,
490 hash_node, 498 hash_node,
491 hash_key) { 499 hash_key) {
500 if (hw_unit >= ecc_stat->count)
501 continue;
492 if (!strcmp(ecc_stat_full_name, ecc_stat->names[hw_unit])) 502 if (!strcmp(ecc_stat_full_name, ecc_stat->names[hw_unit]))
493 return snprintf(buf, PAGE_SIZE, "%u\n", ecc_stat->counters[hw_unit]); 503 return snprintf(buf, PAGE_SIZE, "%u\n", ecc_stat->counters[hw_unit]);
494 } 504 }
@@ -505,16 +515,22 @@ int gr_gp10b_ecc_stat_create(struct device *dev,
505 struct gk20a *g = get_gk20a(dev); 515 struct gk20a *g = get_gk20a(dev);
506 char *ltc_unit_name = "ltc"; 516 char *ltc_unit_name = "ltc";
507 char *gr_unit_name = "gpc0_tpc"; 517 char *gr_unit_name = "gpc0_tpc";
518 char *lts_unit_name = "lts";
508 int num_hw_units = 0; 519 int num_hw_units = 0;
520 int num_subunits = 0;
509 521
510 if (is_l2) 522 if (is_l2 == 1)
511 num_hw_units = g->ltc_count; 523 num_hw_units = g->ltc_count;
512 else 524 else if (is_l2 == 2) {
525 num_hw_units = g->ltc_count;
526 num_subunits = g->gr.slices_per_ltc;
527 } else
513 num_hw_units = g->gr.tpc_count; 528 num_hw_units = g->gr.tpc_count;
514 529
515 530
516 return gp10b_ecc_stat_create(dev, num_hw_units, 531 return gp10b_ecc_stat_create(dev, num_hw_units, num_subunits,
517 is_l2 ? ltc_unit_name : gr_unit_name, 532 is_l2 ? ltc_unit_name : gr_unit_name,
533 num_subunits ? lts_unit_name: NULL,
518 ecc_stat_name, 534 ecc_stat_name,
519 ecc_stat, 535 ecc_stat,
520 dev_attr_array); 536 dev_attr_array);
@@ -522,7 +538,9 @@ int gr_gp10b_ecc_stat_create(struct device *dev,
522 538
523int gp10b_ecc_stat_create(struct device *dev, 539int gp10b_ecc_stat_create(struct device *dev,
524 int num_hw_units, 540 int num_hw_units,
541 int num_subunits,
525 char *ecc_unit_name, 542 char *ecc_unit_name,
543 char *ecc_subunit_name,
526 char *ecc_stat_name, 544 char *ecc_stat_name,
527 struct gk20a_ecc_stat *ecc_stat, 545 struct gk20a_ecc_stat *ecc_stat,
528 struct device_attribute **__dev_attr_array) 546 struct device_attribute **__dev_attr_array)
@@ -530,21 +548,56 @@ int gp10b_ecc_stat_create(struct device *dev,
530 int error = 0; 548 int error = 0;
531 struct gk20a *g = get_gk20a(dev); 549 struct gk20a *g = get_gk20a(dev);
532 int hw_unit = 0; 550 int hw_unit = 0;
551 int subunit = 0;
552 int element = 0;
533 u32 hash_key = 0; 553 u32 hash_key = 0;
534 struct device_attribute *dev_attr_array; 554 struct device_attribute *dev_attr_array;
535 555
556 int num_elements = num_subunits ? num_subunits*num_hw_units :
557 num_hw_units;
558
536 /* Allocate arrays */ 559 /* Allocate arrays */
537 dev_attr_array = nvgpu_kzalloc(g, sizeof(struct device_attribute) * 560 dev_attr_array = nvgpu_kzalloc(g, sizeof(struct device_attribute) *
538 num_hw_units); 561 num_elements);
539 ecc_stat->counters = nvgpu_kzalloc(g, sizeof(u32) * num_hw_units); 562 ecc_stat->counters = nvgpu_kzalloc(g, sizeof(u32) * num_elements);
540 ecc_stat->names = nvgpu_kzalloc(g, sizeof(char *) * num_hw_units); 563 ecc_stat->names = nvgpu_kzalloc(g, sizeof(char *) * num_elements);
541 for (hw_unit = 0; hw_unit < num_hw_units; hw_unit++) { 564 for (hw_unit = 0; hw_unit < num_elements; hw_unit++) {
542 ecc_stat->names[hw_unit] = nvgpu_kzalloc(g, sizeof(char) * 565 ecc_stat->names[hw_unit] = nvgpu_kzalloc(g, sizeof(char) *
543 ECC_STAT_NAME_MAX_SIZE); 566 ECC_STAT_NAME_MAX_SIZE);
544 } 567 }
568 ecc_stat->count = num_elements;
569 if (num_subunits) {
570 for (hw_unit = 0; hw_unit < num_hw_units; hw_unit++) {
571 for (subunit = 0; subunit < num_subunits; subunit++) {
572 element = hw_unit*num_subunits + subunit;
573
574 snprintf(ecc_stat->names[element],
575 ECC_STAT_NAME_MAX_SIZE,
576 "%s%d_%s%d_%s",
577 ecc_unit_name,
578 hw_unit,
579 ecc_subunit_name,
580 subunit,
581 ecc_stat_name);
582
583 sysfs_attr_init(&dev_attr_array[element].attr);
584 dev_attr_array[element].attr.name =
585 ecc_stat->names[element];
586 dev_attr_array[element].attr.mode =
587 VERIFY_OCTAL_PERMISSIONS(S_IRUGO);
588 dev_attr_array[element].show = ecc_stat_show;
589 dev_attr_array[element].store = NULL;
590
591 /* Create sysfs file */
592 error |= device_create_file(dev,
593 &dev_attr_array[element]);
594
595 }
596 }
597 } else {
598 for (hw_unit = 0; hw_unit < num_hw_units; hw_unit++) {
545 599
546 for (hw_unit = 0; hw_unit < num_hw_units; hw_unit++) { 600 /* Fill in struct device_attribute members */
547 /* Fill in struct device_attribute members */
548 snprintf(ecc_stat->names[hw_unit], 601 snprintf(ecc_stat->names[hw_unit],
549 ECC_STAT_NAME_MAX_SIZE, 602 ECC_STAT_NAME_MAX_SIZE,
550 "%s%d_%s", 603 "%s%d_%s",
@@ -552,14 +605,18 @@ int gp10b_ecc_stat_create(struct device *dev,
552 hw_unit, 605 hw_unit,
553 ecc_stat_name); 606 ecc_stat_name);
554 607
555 sysfs_attr_init(&dev_attr_array[hw_unit].attr); 608 sysfs_attr_init(&dev_attr_array[hw_unit].attr);
556 dev_attr_array[hw_unit].attr.name = ecc_stat->names[hw_unit]; 609 dev_attr_array[hw_unit].attr.name =
557 dev_attr_array[hw_unit].attr.mode = VERIFY_OCTAL_PERMISSIONS(S_IRUGO); 610 ecc_stat->names[hw_unit];
558 dev_attr_array[hw_unit].show = ecc_stat_show; 611 dev_attr_array[hw_unit].attr.mode =
559 dev_attr_array[hw_unit].store = NULL; 612 VERIFY_OCTAL_PERMISSIONS(S_IRUGO);
560 613 dev_attr_array[hw_unit].show = ecc_stat_show;
561 /* Create sysfs file */ 614 dev_attr_array[hw_unit].store = NULL;
562 error |= device_create_file(dev, &dev_attr_array[hw_unit]); 615
616 /* Create sysfs file */
617 error |= device_create_file(dev,
618 &dev_attr_array[hw_unit]);
619 }
563 } 620 }
564 621
565 /* Add hash table entry */ 622 /* Add hash table entry */
@@ -581,8 +638,10 @@ void gr_gp10b_ecc_stat_remove(struct device *dev,
581 struct gk20a *g = get_gk20a(dev); 638 struct gk20a *g = get_gk20a(dev);
582 int num_hw_units = 0; 639 int num_hw_units = 0;
583 640
584 if (is_l2) 641 if (is_l2 == 1)
585 num_hw_units = g->ltc_count; 642 num_hw_units = g->ltc_count;
643 else if (is_l2 == 2)
644 num_hw_units = g->ltc_count * g->gr.slices_per_ltc;
586 else 645 else
587 num_hw_units = g->gr.tpc_count; 646 num_hw_units = g->gr.tpc_count;
588 647
@@ -695,13 +754,13 @@ void gr_gp10b_create_sysfs(struct gk20a *g)
695 &dev_attr_tex_ecc_unique_ded_pipe1_count_array); 754 &dev_attr_tex_ecc_unique_ded_pipe1_count_array);
696 755
697 error |= gr_gp10b_ecc_stat_create(dev, 756 error |= gr_gp10b_ecc_stat_create(dev,
698 1, 757 2,
699 "lts0_ecc_sec_count", 758 "ecc_sec_count",
700 &g->ecc.ltc.l2_sec_count, 759 &g->ecc.ltc.l2_sec_count,
701 &dev_attr_l2_ecc_sec_count_array); 760 &dev_attr_l2_ecc_sec_count_array);
702 error |= gr_gp10b_ecc_stat_create(dev, 761 error |= gr_gp10b_ecc_stat_create(dev,
703 1, 762 2,
704 "lts0_ecc_ded_count", 763 "ecc_ded_count",
705 &g->ecc.ltc.l2_ded_count, 764 &g->ecc.ltc.l2_ded_count,
706 &dev_attr_l2_ecc_ded_count_array); 765 &dev_attr_l2_ecc_ded_count_array);
707 766
@@ -769,11 +828,11 @@ static void gr_gp10b_remove_sysfs(struct device *dev)
769 dev_attr_tex_ecc_unique_ded_pipe1_count_array); 828 dev_attr_tex_ecc_unique_ded_pipe1_count_array);
770 829
771 gr_gp10b_ecc_stat_remove(dev, 830 gr_gp10b_ecc_stat_remove(dev,
772 1, 831 2,
773 &g->ecc.ltc.l2_sec_count, 832 &g->ecc.ltc.l2_sec_count,
774 dev_attr_l2_ecc_sec_count_array); 833 dev_attr_l2_ecc_sec_count_array);
775 gr_gp10b_ecc_stat_remove(dev, 834 gr_gp10b_ecc_stat_remove(dev,
776 1, 835 2,
777 &g->ecc.ltc.l2_ded_count, 836 &g->ecc.ltc.l2_ded_count,
778 dev_attr_l2_ecc_ded_count_array); 837 dev_attr_l2_ecc_ded_count_array);
779} 838}
diff --git a/drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.h b/drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.h
index 74db60d1..05832e87 100644
--- a/drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.h
+++ b/drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.h
@@ -25,11 +25,13 @@ int gr_gp10b_ecc_stat_create(struct device *dev,
25 struct gk20a_ecc_stat *ecc_stat, 25 struct gk20a_ecc_stat *ecc_stat,
26 struct device_attribute **dev_attr_array); 26 struct device_attribute **dev_attr_array);
27int gp10b_ecc_stat_create(struct device *dev, 27int gp10b_ecc_stat_create(struct device *dev,
28 int hw_units, 28 int num_hw_units,
29 int num_subunits,
29 char *ecc_unit_name, 30 char *ecc_unit_name,
31 char *ecc_subunit_name,
30 char *ecc_stat_name, 32 char *ecc_stat_name,
31 struct gk20a_ecc_stat *ecc_stat, 33 struct gk20a_ecc_stat *ecc_stat,
32 struct device_attribute **dev_attr_array); 34 struct device_attribute **__dev_attr_array);
33 35
34void gr_gp10b_ecc_stat_remove(struct device *dev, 36void gr_gp10b_ecc_stat_remove(struct device *dev,
35 int is_l2, 37 int is_l2,
diff --git a/drivers/gpu/nvgpu/common/linux/platform_gv11b_tegra.c b/drivers/gpu/nvgpu/common/linux/platform_gv11b_tegra.c
index 78461b5d..4f4381a5 100644
--- a/drivers/gpu/nvgpu/common/linux/platform_gv11b_tegra.c
+++ b/drivers/gpu/nvgpu/common/linux/platform_gv11b_tegra.c
@@ -334,112 +334,144 @@ void gr_gv11b_create_sysfs(struct gk20a *g)
334 334
335 error |= gp10b_ecc_stat_create(dev, 335 error |= gp10b_ecc_stat_create(dev,
336 g->ltc_count, 336 g->ltc_count,
337 0,
337 "ltc", 338 "ltc",
339 NULL,
338 "l2_cache_uncorrected_err_count", 340 "l2_cache_uncorrected_err_count",
339 &g->ecc.ltc.t19x.l2_cache_uncorrected_err_count, 341 &g->ecc.ltc.t19x.l2_cache_uncorrected_err_count,
340 &dev_attr_l2_cache_ecc_uncorrected_err_count_array); 342 &dev_attr_l2_cache_ecc_uncorrected_err_count_array);
341 343
342 error |= gp10b_ecc_stat_create(dev, 344 error |= gp10b_ecc_stat_create(dev,
343 g->ltc_count, 345 g->ltc_count,
346 0,
344 "ltc", 347 "ltc",
348 NULL,
345 "l2_cache_corrected_err_count", 349 "l2_cache_corrected_err_count",
346 &g->ecc.ltc.t19x.l2_cache_corrected_err_count, 350 &g->ecc.ltc.t19x.l2_cache_corrected_err_count,
347 &dev_attr_l2_cache_ecc_corrected_err_count_array); 351 &dev_attr_l2_cache_ecc_corrected_err_count_array);
348 352
349 error |= gp10b_ecc_stat_create(dev, 353 error |= gp10b_ecc_stat_create(dev,
350 1, 354 1,
355 0,
351 "gpc", 356 "gpc",
357 NULL,
352 "fecs_ecc_uncorrected_err_count", 358 "fecs_ecc_uncorrected_err_count",
353 &g->ecc.gr.t19x.fecs_uncorrected_err_count, 359 &g->ecc.gr.t19x.fecs_uncorrected_err_count,
354 &dev_attr_fecs_ecc_uncorrected_err_count_array); 360 &dev_attr_fecs_ecc_uncorrected_err_count_array);
355 361
356 error |= gp10b_ecc_stat_create(dev, 362 error |= gp10b_ecc_stat_create(dev,
357 1, 363 1,
364 0,
358 "gpc", 365 "gpc",
366 NULL,
359 "fecs_ecc_corrected_err_count", 367 "fecs_ecc_corrected_err_count",
360 &g->ecc.gr.t19x.fecs_corrected_err_count, 368 &g->ecc.gr.t19x.fecs_corrected_err_count,
361 &dev_attr_fecs_ecc_corrected_err_count_array); 369 &dev_attr_fecs_ecc_corrected_err_count_array);
362 370
363 error |= gp10b_ecc_stat_create(dev, 371 error |= gp10b_ecc_stat_create(dev,
364 g->gr.gpc_count, 372 g->gr.gpc_count,
373 0,
365 "gpc", 374 "gpc",
375 NULL,
366 "gpccs_ecc_uncorrected_err_count", 376 "gpccs_ecc_uncorrected_err_count",
367 &g->ecc.gr.t19x.gpccs_uncorrected_err_count, 377 &g->ecc.gr.t19x.gpccs_uncorrected_err_count,
368 &dev_attr_gpccs_ecc_uncorrected_err_count_array); 378 &dev_attr_gpccs_ecc_uncorrected_err_count_array);
369 379
370 error |= gp10b_ecc_stat_create(dev, 380 error |= gp10b_ecc_stat_create(dev,
371 g->gr.gpc_count, 381 g->gr.gpc_count,
382 0,
372 "gpc", 383 "gpc",
384 NULL,
373 "gpccs_ecc_corrected_err_count", 385 "gpccs_ecc_corrected_err_count",
374 &g->ecc.gr.t19x.gpccs_corrected_err_count, 386 &g->ecc.gr.t19x.gpccs_corrected_err_count,
375 &dev_attr_gpccs_ecc_corrected_err_count_array); 387 &dev_attr_gpccs_ecc_corrected_err_count_array);
376 388
377 error |= gp10b_ecc_stat_create(dev, 389 error |= gp10b_ecc_stat_create(dev,
378 g->gr.gpc_count, 390 g->gr.gpc_count,
391 0,
379 "gpc", 392 "gpc",
393 NULL,
380 "mmu_l1tlb_ecc_uncorrected_err_count", 394 "mmu_l1tlb_ecc_uncorrected_err_count",
381 &g->ecc.gr.t19x.mmu_l1tlb_uncorrected_err_count, 395 &g->ecc.gr.t19x.mmu_l1tlb_uncorrected_err_count,
382 &dev_attr_mmu_l1tlb_ecc_uncorrected_err_count_array); 396 &dev_attr_mmu_l1tlb_ecc_uncorrected_err_count_array);
383 397
384 error |= gp10b_ecc_stat_create(dev, 398 error |= gp10b_ecc_stat_create(dev,
385 g->gr.gpc_count, 399 g->gr.gpc_count,
400 0,
386 "gpc", 401 "gpc",
402 NULL,
387 "mmu_l1tlb_ecc_corrected_err_count", 403 "mmu_l1tlb_ecc_corrected_err_count",
388 &g->ecc.gr.t19x.mmu_l1tlb_corrected_err_count, 404 &g->ecc.gr.t19x.mmu_l1tlb_corrected_err_count,
389 &dev_attr_mmu_l1tlb_ecc_corrected_err_count_array); 405 &dev_attr_mmu_l1tlb_ecc_corrected_err_count_array);
390 406
391 error |= gp10b_ecc_stat_create(dev, 407 error |= gp10b_ecc_stat_create(dev,
392 1, 408 1,
409 0,
393 "eng", 410 "eng",
411 NULL,
394 "mmu_l2tlb_ecc_uncorrected_err_count", 412 "mmu_l2tlb_ecc_uncorrected_err_count",
395 &g->ecc.eng.t19x.mmu_l2tlb_uncorrected_err_count, 413 &g->ecc.eng.t19x.mmu_l2tlb_uncorrected_err_count,
396 &dev_attr_mmu_l2tlb_ecc_uncorrected_err_count_array); 414 &dev_attr_mmu_l2tlb_ecc_uncorrected_err_count_array);
397 415
398 error |= gp10b_ecc_stat_create(dev, 416 error |= gp10b_ecc_stat_create(dev,
399 1, 417 1,
418 0,
400 "eng", 419 "eng",
420 NULL,
401 "mmu_l2tlb_ecc_corrected_err_count", 421 "mmu_l2tlb_ecc_corrected_err_count",
402 &g->ecc.eng.t19x.mmu_l2tlb_corrected_err_count, 422 &g->ecc.eng.t19x.mmu_l2tlb_corrected_err_count,
403 &dev_attr_mmu_l2tlb_ecc_corrected_err_count_array); 423 &dev_attr_mmu_l2tlb_ecc_corrected_err_count_array);
404 424
405 error |= gp10b_ecc_stat_create(dev, 425 error |= gp10b_ecc_stat_create(dev,
406 1, 426 1,
427 0,
407 "eng", 428 "eng",
429 NULL,
408 "mmu_hubtlb_ecc_uncorrected_err_count", 430 "mmu_hubtlb_ecc_uncorrected_err_count",
409 &g->ecc.eng.t19x.mmu_hubtlb_uncorrected_err_count, 431 &g->ecc.eng.t19x.mmu_hubtlb_uncorrected_err_count,
410 &dev_attr_mmu_hubtlb_ecc_uncorrected_err_count_array); 432 &dev_attr_mmu_hubtlb_ecc_uncorrected_err_count_array);
411 433
412 error |= gp10b_ecc_stat_create(dev, 434 error |= gp10b_ecc_stat_create(dev,
413 1, 435 1,
436 0,
414 "eng", 437 "eng",
438 NULL,
415 "mmu_hubtlb_ecc_corrected_err_count", 439 "mmu_hubtlb_ecc_corrected_err_count",
416 &g->ecc.eng.t19x.mmu_hubtlb_corrected_err_count, 440 &g->ecc.eng.t19x.mmu_hubtlb_corrected_err_count,
417 &dev_attr_mmu_hubtlb_ecc_corrected_err_count_array); 441 &dev_attr_mmu_hubtlb_ecc_corrected_err_count_array);
418 442
419 error |= gp10b_ecc_stat_create(dev, 443 error |= gp10b_ecc_stat_create(dev,
420 1, 444 1,
445 0,
421 "eng", 446 "eng",
447 NULL,
422 "mmu_fillunit_ecc_uncorrected_err_count", 448 "mmu_fillunit_ecc_uncorrected_err_count",
423 &g->ecc.eng.t19x.mmu_fillunit_uncorrected_err_count, 449 &g->ecc.eng.t19x.mmu_fillunit_uncorrected_err_count,
424 &dev_attr_mmu_fillunit_ecc_uncorrected_err_count_array); 450 &dev_attr_mmu_fillunit_ecc_uncorrected_err_count_array);
425 451
426 error |= gp10b_ecc_stat_create(dev, 452 error |= gp10b_ecc_stat_create(dev,
427 1, 453 1,
454 0,
428 "eng", 455 "eng",
456 NULL,
429 "mmu_fillunit_ecc_corrected_err_count", 457 "mmu_fillunit_ecc_corrected_err_count",
430 &g->ecc.eng.t19x.mmu_fillunit_corrected_err_count, 458 &g->ecc.eng.t19x.mmu_fillunit_corrected_err_count,
431 &dev_attr_mmu_fillunit_ecc_corrected_err_count_array); 459 &dev_attr_mmu_fillunit_ecc_corrected_err_count_array);
432 460
433 error |= gp10b_ecc_stat_create(dev, 461 error |= gp10b_ecc_stat_create(dev,
434 1, 462 1,
463 0,
435 "eng", 464 "eng",
465 NULL,
436 "pmu_ecc_uncorrected_err_count", 466 "pmu_ecc_uncorrected_err_count",
437 &g->ecc.eng.t19x.pmu_uncorrected_err_count, 467 &g->ecc.eng.t19x.pmu_uncorrected_err_count,
438 &dev_attr_pmu_ecc_uncorrected_err_count_array); 468 &dev_attr_pmu_ecc_uncorrected_err_count_array);
439 469
440 error |= gp10b_ecc_stat_create(dev, 470 error |= gp10b_ecc_stat_create(dev,
441 1, 471 1,
472 0,
442 "eng", 473 "eng",
474 NULL,
443 "pmu_ecc_corrected_err_count", 475 "pmu_ecc_corrected_err_count",
444 &g->ecc.eng.t19x.pmu_corrected_err_count, 476 &g->ecc.eng.t19x.pmu_corrected_err_count,
445 &dev_attr_pmu_ecc_corrected_err_count_array); 477 &dev_attr_pmu_ecc_corrected_err_count_array);
diff --git a/drivers/gpu/nvgpu/gk20a/ecc_gk20a.h b/drivers/gpu/nvgpu/gk20a/ecc_gk20a.h
index 0d1ed5df..57eec1e0 100644
--- a/drivers/gpu/nvgpu/gk20a/ecc_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/ecc_gk20a.h
@@ -27,6 +27,7 @@
27struct gk20a_ecc_stat { 27struct gk20a_ecc_stat {
28 char **names; 28 char **names;
29 u32 *counters; 29 u32 *counters;
30 u32 count;
30#ifdef CONFIG_SYSFS 31#ifdef CONFIG_SYSFS
31 struct hlist_node hash_node; 32 struct hlist_node hash_node;
32#endif 33#endif
diff --git a/drivers/gpu/nvgpu/gp10b/ltc_gp10b.c b/drivers/gpu/nvgpu/gp10b/ltc_gp10b.c
index 6e8a53c5..bf95f1fd 100644
--- a/drivers/gpu/nvgpu/gp10b/ltc_gp10b.c
+++ b/drivers/gpu/nvgpu/gp10b/ltc_gp10b.c
@@ -155,7 +155,7 @@ void gp10b_ltc_isr(struct gk20a *g)
155 ecc_stats_reg_val = 155 ecc_stats_reg_val =
156 gk20a_readl(g, 156 gk20a_readl(g,
157 ltc_ltc0_lts0_dstg_ecc_report_r() + offset); 157 ltc_ltc0_lts0_dstg_ecc_report_r() + offset);
158 g->ecc.ltc.l2_sec_count.counters[ltc] += 158 g->ecc.ltc.l2_sec_count.counters[ltc*g->ltc_count + slice] +=
159 ltc_ltc0_lts0_dstg_ecc_report_sec_count_v(ecc_stats_reg_val); 159 ltc_ltc0_lts0_dstg_ecc_report_sec_count_v(ecc_stats_reg_val);
160 ecc_stats_reg_val &= 160 ecc_stats_reg_val &=
161 ~(ltc_ltc0_lts0_dstg_ecc_report_sec_count_m()); 161 ~(ltc_ltc0_lts0_dstg_ecc_report_sec_count_m());
@@ -175,7 +175,7 @@ void gp10b_ltc_isr(struct gk20a *g)
175 ecc_stats_reg_val = 175 ecc_stats_reg_val =
176 gk20a_readl(g, 176 gk20a_readl(g,
177 ltc_ltc0_lts0_dstg_ecc_report_r() + offset); 177 ltc_ltc0_lts0_dstg_ecc_report_r() + offset);
178 g->ecc.ltc.l2_ded_count.counters[ltc] += 178 g->ecc.ltc.l2_ded_count.counters[ltc*g->ltc_count + slice] +=
179 ltc_ltc0_lts0_dstg_ecc_report_ded_count_v(ecc_stats_reg_val); 179 ltc_ltc0_lts0_dstg_ecc_report_ded_count_v(ecc_stats_reg_val);
180 ecc_stats_reg_val &= 180 ecc_stats_reg_val &=
181 ~(ltc_ltc0_lts0_dstg_ecc_report_ded_count_m()); 181 ~(ltc_ltc0_lts0_dstg_ecc_report_ded_count_m());