Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drivers: arch_topology: use __free attribute instead of of_node_put()

Introduce the __free attribute for scope-based resource management.
Resources allocated with __free are automatically released at the end of
the scope. This enhancement aims to mitigate memory management issues
associated with forgetting to release resources by utilizing __free
instead of of_node_put().

The declaration of the device_node used within the do-while loops is
moved directly within the loop so that the resource is automatically
freed at the end of each iteration.

Acked-by: Sudeep Holla <sudeep.holla@arm.com>
Suggested-by: Julia Lawall <julia.lawall@inria.fr>
Signed-off-by: Vincenzo Mezzela <vincenzo.mezzela@gmail.com>
Link: https://lore.kernel.org/r/20240607163350.392971-3-vincenzo.mezzela@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Vincenzo Mezzela and committed by
Greg Kroah-Hartman
880f5f58 97b19745

+26 -30
+26 -30
drivers/base/arch_topology.c
··· 8 8 9 9 #include <linux/acpi.h> 10 10 #include <linux/cacheinfo.h> 11 + #include <linux/cleanup.h> 11 12 #include <linux/cpu.h> 12 13 #include <linux/cpufreq.h> 13 14 #include <linux/device.h> ··· 514 513 */ 515 514 static int __init get_cpu_for_node(struct device_node *node) 516 515 { 517 - struct device_node *cpu_node; 518 516 int cpu; 517 + struct device_node *cpu_node __free(device_node) = 518 + of_parse_phandle(node, "cpu", 0); 519 519 520 - cpu_node = of_parse_phandle(node, "cpu", 0); 521 520 if (!cpu_node) 522 521 return -1; 523 522 ··· 528 527 pr_info("CPU node for %pOF exist but the possible cpu range is :%*pbl\n", 529 528 cpu_node, cpumask_pr_args(cpu_possible_mask)); 530 529 531 - of_node_put(cpu_node); 532 530 return cpu; 533 531 } 534 532 ··· 538 538 bool leaf = true; 539 539 int i = 0; 540 540 int cpu; 541 - struct device_node *t; 542 541 543 542 do { 544 543 snprintf(name, sizeof(name), "thread%d", i); 545 - t = of_get_child_by_name(core, name); 544 + struct device_node *t __free(device_node) = 545 + of_get_child_by_name(core, name); 546 + 546 547 if (!t) 547 548 break; 548 549 ··· 556 555 cpu_topology[cpu].thread_id = i; 557 556 } else if (cpu != -ENODEV) { 558 557 pr_err("%pOF: Can't get CPU for thread\n", t); 559 - of_node_put(t); 560 558 return -EINVAL; 561 559 } 562 - of_node_put(t); 563 560 i++; 564 561 } while (1); 565 562 ··· 586 587 char name[20]; 587 588 bool leaf = true; 588 589 bool has_cores = false; 589 - struct device_node *c; 590 590 int core_id = 0; 591 591 int i, ret; 592 592 ··· 597 599 i = 0; 598 600 do { 599 601 snprintf(name, sizeof(name), "cluster%d", i); 600 - c = of_get_child_by_name(cluster, name); 602 + struct device_node *c __free(device_node) = 603 + of_get_child_by_name(cluster, name); 604 + 601 605 if (!c) 602 606 break; 603 607 ··· 607 607 ret = parse_cluster(c, package_id, i, depth + 1); 608 608 if (depth > 0) 609 609 pr_warn("Topology for clusters of clusters not yet supported\n"); 610 - of_node_put(c); 611 610 if (ret != 0) 612 611 return ret; 613 612 i++; ··· 616 617 i = 0; 617 618 do { 618 619 snprintf(name, sizeof(name), "core%d", i); 619 - c = of_get_child_by_name(cluster, name); 620 + struct device_node *c __free(device_node) = 621 + of_get_child_by_name(cluster, name); 622 + 620 623 if (!c) 621 624 break; 622 625 ··· 626 625 627 626 if (depth == 0) { 628 627 pr_err("%pOF: cpu-map children should be clusters\n", c); 629 - of_node_put(c); 630 628 return -EINVAL; 631 629 } 632 630 633 631 if (leaf) { 634 632 ret = parse_core(c, package_id, cluster_id, core_id++); 633 + if (ret != 0) 634 + return ret; 635 635 } else { 636 636 pr_err("%pOF: Non-leaf cluster with core %s\n", 637 637 cluster, name); 638 - ret = -EINVAL; 638 + return -EINVAL; 639 639 } 640 640 641 - of_node_put(c); 642 - if (ret != 0) 643 - return ret; 644 641 i++; 645 642 } while (1); 646 643 ··· 651 652 static int __init parse_socket(struct device_node *socket) 652 653 { 653 654 char name[20]; 654 - struct device_node *c; 655 655 bool has_socket = false; 656 656 int package_id = 0, ret; 657 657 658 658 do { 659 659 snprintf(name, sizeof(name), "socket%d", package_id); 660 - c = of_get_child_by_name(socket, name); 660 + struct device_node *c __free(device_node) = 661 + of_get_child_by_name(socket, name); 662 + 661 663 if (!c) 662 664 break; 663 665 664 666 has_socket = true; 665 667 ret = parse_cluster(c, package_id, -1, 0); 666 - of_node_put(c); 667 668 if (ret != 0) 668 669 return ret; 669 670 ··· 678 679 679 680 static int __init parse_dt_topology(void) 680 681 { 681 - struct device_node *cn, *map; 682 682 int ret = 0; 683 683 int cpu; 684 + struct device_node *cn __free(device_node) = 685 + of_find_node_by_path("/cpus"); 684 686 685 - cn = of_find_node_by_path("/cpus"); 686 687 if (!cn) { 687 688 pr_err("No CPU information found in DT\n"); 688 689 return 0; ··· 692 693 * When topology is provided cpu-map is essentially a root 693 694 * cluster with restricted subnodes. 694 695 */ 695 - map = of_get_child_by_name(cn, "cpu-map"); 696 + struct device_node *map __free(device_node) = 697 + of_get_child_by_name(cn, "cpu-map"); 698 + 696 699 if (!map) 697 - goto out; 700 + return ret; 698 701 699 702 ret = parse_socket(map); 700 703 if (ret != 0) 701 - goto out_map; 704 + return ret; 702 705 703 706 topology_normalize_cpu_scale(); 704 707 ··· 710 709 */ 711 710 for_each_possible_cpu(cpu) 712 711 if (cpu_topology[cpu].package_id < 0) { 713 - ret = -EINVAL; 714 - break; 712 + return -EINVAL; 715 713 } 716 714 717 - out_map: 718 - of_node_put(map); 719 - out: 720 - of_node_put(cn); 721 715 return ret; 722 716 } 723 717 #endif