diff options
Diffstat (limited to 'drivers/powercap/intel_rapl.c')
| -rw-r--r-- | drivers/powercap/intel_rapl.c | 48 |
1 files changed, 25 insertions, 23 deletions
diff --git a/drivers/powercap/intel_rapl.c b/drivers/powercap/intel_rapl.c index 3c6768378a9..b1cda6ffdbc 100644 --- a/drivers/powercap/intel_rapl.c +++ b/drivers/powercap/intel_rapl.c @@ -834,7 +834,7 @@ static int rapl_write_data_raw(struct rapl_domain *rd, } static const struct x86_cpu_id energy_unit_quirk_ids[] = { - { X86_VENDOR_INTEL, 6, 0x37},/* VLV */ + { X86_VENDOR_INTEL, 6, 0x37},/* Valleyview */ {} }; @@ -947,11 +947,13 @@ static void package_power_limit_irq_restore(int package_id) } static const struct x86_cpu_id rapl_ids[] = { - { X86_VENDOR_INTEL, 6, 0x2a},/* SNB */ - { X86_VENDOR_INTEL, 6, 0x2d},/* SNB EP */ - { X86_VENDOR_INTEL, 6, 0x37},/* VLV */ - { X86_VENDOR_INTEL, 6, 0x3a},/* IVB */ - { X86_VENDOR_INTEL, 6, 0x45},/* HSW */ + { X86_VENDOR_INTEL, 6, 0x2a},/* Sandy Bridge */ + { X86_VENDOR_INTEL, 6, 0x2d},/* Sandy Bridge EP */ + { X86_VENDOR_INTEL, 6, 0x37},/* Valleyview */ + { X86_VENDOR_INTEL, 6, 0x3a},/* Ivy Bridge */ + { X86_VENDOR_INTEL, 6, 0x3c},/* Haswell */ + { X86_VENDOR_INTEL, 6, 0x3d},/* Broadwell */ + { X86_VENDOR_INTEL, 6, 0x45},/* Haswell ULT */ /* TODO: Add more CPU IDs after testing */ {} }; @@ -1124,8 +1126,7 @@ err_cleanup_package: static int rapl_check_domain(int cpu, int domain) { unsigned msr; - u64 val1, val2 = 0; - int retry = 0; + u64 val = 0; switch (domain) { case RAPL_DOMAIN_PACKAGE: @@ -1144,21 +1145,13 @@ static int rapl_check_domain(int cpu, int domain) pr_err("invalid domain id %d\n", domain); return -EINVAL; } - if (rdmsrl_safe_on_cpu(cpu, msr, &val1)) + /* make sure domain counters are available and contains non-zero + * values, otherwise skip it. + */ + if (rdmsrl_safe_on_cpu(cpu, msr, &val) || !val) return -ENODEV; - /* energy counters roll slowly on some domains */ - while (++retry < 10) { - usleep_range(10000, 15000); - rdmsrl_safe_on_cpu(cpu, msr, &val2); - if ((val1 & ENERGY_STATUS_MASK) != (val2 & ENERGY_STATUS_MASK)) - return 0; - } - /* if energy counter does not change, report as bad domain */ - pr_info("domain %s energy ctr %llu:%llu not working, skip\n", - rapl_domain_names[domain], val1, val2); - - return -ENODEV; + return 0; } /* Detect active and valid domains for the given CPU, caller must @@ -1175,6 +1168,9 @@ static int rapl_detect_domains(struct rapl_package *rp, int cpu) /* use physical package id to read counters */ if (!rapl_check_domain(cpu, i)) rp->domain_map |= 1 << i; + else + pr_warn("RAPL domain %s detection failed\n", + rapl_domain_names[i]); } rp->nr_domains = bitmap_weight(&rp->domain_map, RAPL_DOMAIN_MAX); if (!rp->nr_domains) { @@ -1369,6 +1365,9 @@ static int __init rapl_init(void) return -ENODEV; } + + cpu_notifier_register_begin(); + /* prevent CPU hotplug during detection */ get_online_cpus(); ret = rapl_detect_topology(); @@ -1380,20 +1379,23 @@ static int __init rapl_init(void) ret = -ENODEV; goto done; } - register_hotcpu_notifier(&rapl_cpu_notifier); + __register_hotcpu_notifier(&rapl_cpu_notifier); done: put_online_cpus(); + cpu_notifier_register_done(); return ret; } static void __exit rapl_exit(void) { + cpu_notifier_register_begin(); get_online_cpus(); - unregister_hotcpu_notifier(&rapl_cpu_notifier); + __unregister_hotcpu_notifier(&rapl_cpu_notifier); rapl_unregister_powercap(); rapl_cleanup_data(); put_online_cpus(); + cpu_notifier_register_done(); } module_init(rapl_init); |
