diff options
author | David Nieto <dmartineznie@nvidia.com> | 2017-12-18 20:10:19 -0500 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2017-12-28 13:01:36 -0500 |
commit | 8fb6a8562ec033d2d1319f91377cd1782f593979 (patch) | |
tree | 07b7fe61cd9763ddf5cee2934994841fa330b90a /drivers/gpu/nvgpu/common/linux | |
parent | f19f22fcc8ef21b363b873c499cbd2e690af29f8 (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>
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux')
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c | 113 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.h | 6 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/platform_gv11b_tegra.c | 32 |
3 files changed, 122 insertions, 29 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; | |||
450 | static u32 gen_ecc_hash_key(char *str) | 450 | static 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 | ||
523 | int gp10b_ecc_stat_create(struct device *dev, | 539 | int 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); |
27 | int gp10b_ecc_stat_create(struct device *dev, | 27 | int 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 | ||
34 | void gr_gp10b_ecc_stat_remove(struct device *dev, | 36 | void 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); |