aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/powercap/intel_rapl.c94
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 */
1606static int rapl_cpu_callback(struct notifier_block *nfb, 1606static 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
1621static 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
1647static struct notifier_block rapl_cpu_notifier = { 1647static enum cpuhp_state pcap_rapl_online;
1648 .notifier_call = rapl_cpu_callback,
1649};
1650 1648
1651static int __init rapl_init(void) 1649static 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,
1680done: 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
1683err_unreg:
1684 rapl_unregister_powercap();
1683 1685
1686err_cleanup:
1687 rapl_cleanup_data();
1688err:
1689 put_online_cpus();
1684 return ret; 1690 return ret;
1685} 1691}
1686 1692
1687static void __exit rapl_exit(void) 1693static 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
1698module_init(rapl_init); 1702module_init(rapl_init);