diff options
-rw-r--r-- | drivers/powercap/intel_rapl.c | 94 |
1 files changed, 49 insertions, 45 deletions
diff --git a/drivers/powercap/intel_rapl.c b/drivers/powercap/intel_rapl.c index 79b1e041f2ec..de5cf22371f5 100644 --- a/drivers/powercap/intel_rapl.c +++ b/drivers/powercap/intel_rapl.c | |||
@@ -1603,50 +1603,48 @@ err_free_package: | |||
1603 | * associated domains. Cooling devices are handled accordingly at | 1603 | * associated domains. Cooling devices are handled accordingly at |
1604 | * per-domain level. | 1604 | * per-domain level. |
1605 | */ | 1605 | */ |
1606 | static int rapl_cpu_callback(struct notifier_block *nfb, | 1606 | static int rapl_cpu_online(unsigned int cpu) |
1607 | unsigned long action, void *hcpu) | 1607 | { |
1608 | struct rapl_package *rp; | ||
1609 | int phy_package_id; | ||
1610 | |||
1611 | phy_package_id = topology_physical_package_id(cpu); | ||
1612 | |||
1613 | rp = find_package_by_id(phy_package_id); | ||
1614 | if (rp) | ||
1615 | rp->nr_cpus++; | ||
1616 | else | ||
1617 | rapl_add_package(cpu); | ||
1618 | return 0; | ||
1619 | } | ||
1620 | |||
1621 | static int rapl_cpu_down_prep(unsigned int cpu) | ||
1608 | { | 1622 | { |
1609 | unsigned long cpu = (unsigned long)hcpu; | ||
1610 | int phy_package_id; | 1623 | int phy_package_id; |
1611 | struct rapl_package *rp; | 1624 | struct rapl_package *rp; |
1612 | int lead_cpu; | 1625 | int lead_cpu; |
1613 | 1626 | ||
1614 | phy_package_id = topology_physical_package_id(cpu); | 1627 | phy_package_id = topology_physical_package_id(cpu); |
1615 | switch (action) { | 1628 | rp = find_package_by_id(phy_package_id); |
1616 | case CPU_ONLINE: | 1629 | if (!rp) |
1617 | case CPU_ONLINE_FROZEN: | 1630 | return 0; |
1618 | case CPU_DOWN_FAILED: | 1631 | if (--rp->nr_cpus == 0) { |
1619 | case CPU_DOWN_FAILED_FROZEN: | 1632 | rapl_remove_package(rp); |
1620 | rp = find_package_by_id(phy_package_id); | 1633 | } else if (cpu == rp->lead_cpu) { |
1621 | if (rp) | 1634 | /* choose another active cpu in the package */ |
1622 | ++rp->nr_cpus; | 1635 | lead_cpu = cpumask_any_but(topology_core_cpumask(cpu), cpu); |
1623 | else | 1636 | if (lead_cpu < nr_cpu_ids) { |
1624 | rapl_add_package(cpu); | 1637 | rp->lead_cpu = lead_cpu; |
1625 | break; | 1638 | } else { |
1626 | case CPU_DOWN_PREPARE: | 1639 | /* should never go here */ |
1627 | case CPU_DOWN_PREPARE_FROZEN: | 1640 | pr_err("no active cpu available for package %d\n", |
1628 | rp = find_package_by_id(phy_package_id); | 1641 | phy_package_id); |
1629 | if (!rp) | ||
1630 | break; | ||
1631 | if (--rp->nr_cpus == 0) | ||
1632 | rapl_remove_package(rp); | ||
1633 | else if (cpu == rp->lead_cpu) { | ||
1634 | /* choose another active cpu in the package */ | ||
1635 | lead_cpu = cpumask_any_but(topology_core_cpumask(cpu), cpu); | ||
1636 | if (lead_cpu < nr_cpu_ids) | ||
1637 | rp->lead_cpu = lead_cpu; | ||
1638 | else /* should never go here */ | ||
1639 | pr_err("no active cpu available for package %d\n", | ||
1640 | phy_package_id); | ||
1641 | } | 1642 | } |
1642 | } | 1643 | } |
1643 | 1644 | return 0; | |
1644 | return NOTIFY_OK; | ||
1645 | } | 1645 | } |
1646 | 1646 | ||
1647 | static struct notifier_block rapl_cpu_notifier = { | 1647 | static enum cpuhp_state pcap_rapl_online; |
1648 | .notifier_call = rapl_cpu_callback, | ||
1649 | }; | ||
1650 | 1648 | ||
1651 | static int __init rapl_init(void) | 1649 | static int __init rapl_init(void) |
1652 | { | 1650 | { |
@@ -1663,36 +1661,42 @@ static int __init rapl_init(void) | |||
1663 | 1661 | ||
1664 | rapl_defaults = (struct rapl_defaults *)id->driver_data; | 1662 | rapl_defaults = (struct rapl_defaults *)id->driver_data; |
1665 | 1663 | ||
1666 | cpu_notifier_register_begin(); | ||
1667 | |||
1668 | /* prevent CPU hotplug during detection */ | 1664 | /* prevent CPU hotplug during detection */ |
1669 | get_online_cpus(); | 1665 | get_online_cpus(); |
1670 | ret = rapl_detect_topology(); | 1666 | ret = rapl_detect_topology(); |
1671 | if (ret) | 1667 | if (ret) |
1672 | goto done; | 1668 | goto err; |
1673 | 1669 | ||
1674 | if (rapl_register_powercap()) { | 1670 | if (rapl_register_powercap()) { |
1675 | rapl_cleanup_data(); | ||
1676 | ret = -ENODEV; | 1671 | ret = -ENODEV; |
1677 | goto done; | 1672 | goto err_cleanup; |
1678 | } | 1673 | } |
1679 | __register_hotcpu_notifier(&rapl_cpu_notifier); | 1674 | ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, |
1680 | done: | 1675 | "powercap/rapl:online", |
1676 | rapl_cpu_online, rapl_cpu_down_prep); | ||
1677 | if (ret < 0) | ||
1678 | goto err_unreg; | ||
1679 | pcap_rapl_online = ret; | ||
1681 | put_online_cpus(); | 1680 | put_online_cpus(); |
1682 | cpu_notifier_register_done(); | 1681 | return 0; |
1682 | |||
1683 | err_unreg: | ||
1684 | rapl_unregister_powercap(); | ||
1683 | 1685 | ||
1686 | err_cleanup: | ||
1687 | rapl_cleanup_data(); | ||
1688 | err: | ||
1689 | put_online_cpus(); | ||
1684 | return ret; | 1690 | return ret; |
1685 | } | 1691 | } |
1686 | 1692 | ||
1687 | static void __exit rapl_exit(void) | 1693 | static void __exit rapl_exit(void) |
1688 | { | 1694 | { |
1689 | cpu_notifier_register_begin(); | ||
1690 | get_online_cpus(); | 1695 | get_online_cpus(); |
1691 | __unregister_hotcpu_notifier(&rapl_cpu_notifier); | 1696 | cpuhp_remove_state(pcap_rapl_online); |
1692 | rapl_unregister_powercap(); | 1697 | rapl_unregister_powercap(); |
1693 | rapl_cleanup_data(); | 1698 | rapl_cleanup_data(); |
1694 | put_online_cpus(); | 1699 | put_online_cpus(); |
1695 | cpu_notifier_register_done(); | ||
1696 | } | 1700 | } |
1697 | 1701 | ||
1698 | module_init(rapl_init); | 1702 | module_init(rapl_init); |