unsigned int time_unit;
struct rapl_domain *domains; /* array of domains, sized at runtime */
struct powercap_zone *power_zone; /* keep track of parent zone */
- int nr_cpus; /* active cpus on the package, topology info is lost during
- * cpu hotplug. so we have to track ourselves.
- */
unsigned long power_limit_irq; /* keep track of package power limit
* notify interrupt enable status.
*/
struct list_head plist;
int lead_cpu; /* one active cpu per package for access */
+ /* Track active cpus */
+ struct cpumask cpumask;
};
struct rapl_defaults {
}
/* called from CPU hotplug notifier, hotplug lock held */
-static int rapl_add_package(int cpu)
+static struct rapl_package *rapl_add_package(int cpu, int pkgid)
{
struct rapl_package *rp;
- int ret, phy_package_id;
+ int ret;
- phy_package_id = topology_physical_package_id(cpu);
rp = kzalloc(sizeof(struct rapl_package), GFP_KERNEL);
if (!rp)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
/* add the new package to the list */
- rp->id = phy_package_id;
- rp->nr_cpus = 1;
+ rp->id = pkgid;
rp->lead_cpu = cpu;
/* check if the package contains valid domains */
if (!ret) {
INIT_LIST_HEAD(&rp->plist);
list_add(&rp->plist, &rapl_packages);
- return 0;
+ return rp;
}
err_free_package:
kfree(rp->domains);
kfree(rp);
-
- return ret;
+ return ERR_PTR(ret);
}
/* Handles CPU hotplug on multi-socket systems.
*/
static int rapl_cpu_online(unsigned int cpu)
{
+ int pkgid = topology_physical_package_id(cpu);
struct rapl_package *rp;
- int phy_package_id;
-
- phy_package_id = topology_physical_package_id(cpu);
- rp = find_package_by_id(phy_package_id);
- if (rp) {
- rp->nr_cpus++;
- return 0;
+ rp = find_package_by_id(pkgid);
+ if (!rp) {
+ rp = rapl_add_package(cpu, pkgid);
+ if (IS_ERR(rp))
+ return PTR_ERR(rp);
}
- return rapl_add_package(cpu);
+ cpumask_set_cpu(cpu, &rp->cpumask);
+ return 0;
}
static int rapl_cpu_down_prep(unsigned int cpu)
{
- int phy_package_id;
+ int pkgid = topology_physical_package_id(cpu);
struct rapl_package *rp;
int lead_cpu;
- phy_package_id = topology_physical_package_id(cpu);
- rp = find_package_by_id(phy_package_id);
+ rp = find_package_by_id(pkgid);
if (!rp)
return 0;
- if (--rp->nr_cpus == 0) {
+
+ cpumask_clear_cpu(cpu, &rp->cpumask);
+ lead_cpu = cpumask_first(&rp->cpumask);
+ if (lead_cpu >= nr_cpu_ids)
rapl_remove_package(rp);
- } else if (cpu == rp->lead_cpu) {
- /* choose another active cpu in the package */
- lead_cpu = cpumask_any_but(topology_core_cpumask(cpu), cpu);
- if (lead_cpu < nr_cpu_ids) {
- rp->lead_cpu = lead_cpu;
- } else {
- /* should never go here */
- pr_err("no active cpu available for package %d\n",
- phy_package_id);
- }
- }
+ else if (rp->lead_cpu == cpu)
+ rp->lead_cpu = lead_cpu;
return 0;
}