aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/powercap/intel_rapl.c107
1 files changed, 82 insertions, 25 deletions
diff --git a/drivers/powercap/intel_rapl.c b/drivers/powercap/intel_rapl.c
index 2e8f2be5b6f9..fbab29dfa793 100644
--- a/drivers/powercap/intel_rapl.c
+++ b/drivers/powercap/intel_rapl.c
@@ -336,14 +336,14 @@ static int release_zone(struct powercap_zone *power_zone)
336 336
337static int find_nr_power_limit(struct rapl_domain *rd) 337static int find_nr_power_limit(struct rapl_domain *rd)
338{ 338{
339 int i; 339 int i, nr_pl = 0;
340 340
341 for (i = 0; i < NR_POWER_LIMITS; i++) { 341 for (i = 0; i < NR_POWER_LIMITS; i++) {
342 if (rd->rpl[i].name == NULL) 342 if (rd->rpl[i].name)
343 break; 343 nr_pl++;
344 } 344 }
345 345
346 return i; 346 return nr_pl;
347} 347}
348 348
349static int set_domain_enable(struct powercap_zone *power_zone, bool mode) 349static int set_domain_enable(struct powercap_zone *power_zone, bool mode)
@@ -426,15 +426,38 @@ static const struct powercap_zone_ops zone_ops[] = {
426 }, 426 },
427}; 427};
428 428
429static int set_power_limit(struct powercap_zone *power_zone, int id, 429
430/*
431 * Constraint index used by powercap can be different than power limit (PL)
432 * index in that some PLs maybe missing due to non-existant MSRs. So we
433 * need to convert here by finding the valid PLs only (name populated).
434 */
435static int contraint_to_pl(struct rapl_domain *rd, int cid)
436{
437 int i, j;
438
439 for (i = 0, j = 0; i < NR_POWER_LIMITS; i++) {
440 if ((rd->rpl[i].name) && j++ == cid) {
441 pr_debug("%s: index %d\n", __func__, i);
442 return i;
443 }
444 }
445
446 return -EINVAL;
447}
448
449static int set_power_limit(struct powercap_zone *power_zone, int cid,
430 u64 power_limit) 450 u64 power_limit)
431{ 451{
432 struct rapl_domain *rd; 452 struct rapl_domain *rd;
433 struct rapl_package *rp; 453 struct rapl_package *rp;
434 int ret = 0; 454 int ret = 0;
455 int id;
435 456
436 get_online_cpus(); 457 get_online_cpus();
437 rd = power_zone_to_rapl_domain(power_zone); 458 rd = power_zone_to_rapl_domain(power_zone);
459 id = contraint_to_pl(rd, cid);
460
438 rp = rd->rp; 461 rp = rd->rp;
439 462
440 if (rd->state & DOMAIN_STATE_BIOS_LOCKED) { 463 if (rd->state & DOMAIN_STATE_BIOS_LOCKED) {
@@ -461,16 +484,18 @@ set_exit:
461 return ret; 484 return ret;
462} 485}
463 486
464static int get_current_power_limit(struct powercap_zone *power_zone, int id, 487static int get_current_power_limit(struct powercap_zone *power_zone, int cid,
465 u64 *data) 488 u64 *data)
466{ 489{
467 struct rapl_domain *rd; 490 struct rapl_domain *rd;
468 u64 val; 491 u64 val;
469 int prim; 492 int prim;
470 int ret = 0; 493 int ret = 0;
494 int id;
471 495
472 get_online_cpus(); 496 get_online_cpus();
473 rd = power_zone_to_rapl_domain(power_zone); 497 rd = power_zone_to_rapl_domain(power_zone);
498 id = contraint_to_pl(rd, cid);
474 switch (rd->rpl[id].prim_id) { 499 switch (rd->rpl[id].prim_id) {
475 case PL1_ENABLE: 500 case PL1_ENABLE:
476 prim = POWER_LIMIT1; 501 prim = POWER_LIMIT1;
@@ -492,14 +517,17 @@ static int get_current_power_limit(struct powercap_zone *power_zone, int id,
492 return ret; 517 return ret;
493} 518}
494 519
495static int set_time_window(struct powercap_zone *power_zone, int id, 520static int set_time_window(struct powercap_zone *power_zone, int cid,
496 u64 window) 521 u64 window)
497{ 522{
498 struct rapl_domain *rd; 523 struct rapl_domain *rd;
499 int ret = 0; 524 int ret = 0;
525 int id;
500 526
501 get_online_cpus(); 527 get_online_cpus();
502 rd = power_zone_to_rapl_domain(power_zone); 528 rd = power_zone_to_rapl_domain(power_zone);
529 id = contraint_to_pl(rd, cid);
530
503 switch (rd->rpl[id].prim_id) { 531 switch (rd->rpl[id].prim_id) {
504 case PL1_ENABLE: 532 case PL1_ENABLE:
505 rapl_write_data_raw(rd, TIME_WINDOW1, window); 533 rapl_write_data_raw(rd, TIME_WINDOW1, window);
@@ -514,14 +542,17 @@ static int set_time_window(struct powercap_zone *power_zone, int id,
514 return ret; 542 return ret;
515} 543}
516 544
517static int get_time_window(struct powercap_zone *power_zone, int id, u64 *data) 545static int get_time_window(struct powercap_zone *power_zone, int cid, u64 *data)
518{ 546{
519 struct rapl_domain *rd; 547 struct rapl_domain *rd;
520 u64 val; 548 u64 val;
521 int ret = 0; 549 int ret = 0;
550 int id;
522 551
523 get_online_cpus(); 552 get_online_cpus();
524 rd = power_zone_to_rapl_domain(power_zone); 553 rd = power_zone_to_rapl_domain(power_zone);
554 id = contraint_to_pl(rd, cid);
555
525 switch (rd->rpl[id].prim_id) { 556 switch (rd->rpl[id].prim_id) {
526 case PL1_ENABLE: 557 case PL1_ENABLE:
527 ret = rapl_read_data_raw(rd, TIME_WINDOW1, true, &val); 558 ret = rapl_read_data_raw(rd, TIME_WINDOW1, true, &val);
@@ -540,15 +571,17 @@ static int get_time_window(struct powercap_zone *power_zone, int id, u64 *data)
540 return ret; 571 return ret;
541} 572}
542 573
543static const char *get_constraint_name(struct powercap_zone *power_zone, int id) 574static const char *get_constraint_name(struct powercap_zone *power_zone, int cid)
544{ 575{
545 struct rapl_power_limit *rpl;
546 struct rapl_domain *rd; 576 struct rapl_domain *rd;
577 int id;
547 578
548 rd = power_zone_to_rapl_domain(power_zone); 579 rd = power_zone_to_rapl_domain(power_zone);
549 rpl = (struct rapl_power_limit *) &rd->rpl[id]; 580 id = contraint_to_pl(rd, cid);
581 if (id >= 0)
582 return rd->rpl[id].name;
550 583
551 return rpl->name; 584 return NULL;
552} 585}
553 586
554 587
@@ -1101,6 +1134,7 @@ static const struct x86_cpu_id rapl_ids[] __initconst = {
1101 RAPL_CPU(INTEL_FAM6_SANDYBRIDGE_X, rapl_defaults_core), 1134 RAPL_CPU(INTEL_FAM6_SANDYBRIDGE_X, rapl_defaults_core),
1102 1135
1103 RAPL_CPU(INTEL_FAM6_IVYBRIDGE, rapl_defaults_core), 1136 RAPL_CPU(INTEL_FAM6_IVYBRIDGE, rapl_defaults_core),
1137 RAPL_CPU(INTEL_FAM6_IVYBRIDGE_X, rapl_defaults_core),
1104 1138
1105 RAPL_CPU(INTEL_FAM6_HASWELL_CORE, rapl_defaults_core), 1139 RAPL_CPU(INTEL_FAM6_HASWELL_CORE, rapl_defaults_core),
1106 RAPL_CPU(INTEL_FAM6_HASWELL_ULT, rapl_defaults_core), 1140 RAPL_CPU(INTEL_FAM6_HASWELL_ULT, rapl_defaults_core),
@@ -1123,6 +1157,7 @@ static const struct x86_cpu_id rapl_ids[] __initconst = {
1123 RAPL_CPU(INTEL_FAM6_ATOM_MERRIFIELD1, rapl_defaults_tng), 1157 RAPL_CPU(INTEL_FAM6_ATOM_MERRIFIELD1, rapl_defaults_tng),
1124 RAPL_CPU(INTEL_FAM6_ATOM_MERRIFIELD2, rapl_defaults_ann), 1158 RAPL_CPU(INTEL_FAM6_ATOM_MERRIFIELD2, rapl_defaults_ann),
1125 RAPL_CPU(INTEL_FAM6_ATOM_GOLDMONT, rapl_defaults_core), 1159 RAPL_CPU(INTEL_FAM6_ATOM_GOLDMONT, rapl_defaults_core),
1160 RAPL_CPU(INTEL_FAM6_ATOM_DENVERTON, rapl_defaults_core),
1126 1161
1127 RAPL_CPU(INTEL_FAM6_XEON_PHI_KNL, rapl_defaults_hsw_server), 1162 RAPL_CPU(INTEL_FAM6_XEON_PHI_KNL, rapl_defaults_hsw_server),
1128 {} 1163 {}
@@ -1381,6 +1416,37 @@ static int rapl_check_domain(int cpu, int domain)
1381 return 0; 1416 return 0;
1382} 1417}
1383 1418
1419
1420/*
1421 * Check if power limits are available. Two cases when they are not available:
1422 * 1. Locked by BIOS, in this case we still provide read-only access so that
1423 * users can see what limit is set by the BIOS.
1424 * 2. Some CPUs make some domains monitoring only which means PLx MSRs may not
1425 * exist at all. In this case, we do not show the contraints in powercap.
1426 *
1427 * Called after domains are detected and initialized.
1428 */
1429static void rapl_detect_powerlimit(struct rapl_domain *rd)
1430{
1431 u64 val64;
1432 int i;
1433
1434 /* check if the domain is locked by BIOS, ignore if MSR doesn't exist */
1435 if (!rapl_read_data_raw(rd, FW_LOCK, false, &val64)) {
1436 if (val64) {
1437 pr_info("RAPL package %d domain %s locked by BIOS\n",
1438 rd->rp->id, rd->name);
1439 rd->state |= DOMAIN_STATE_BIOS_LOCKED;
1440 }
1441 }
1442 /* check if power limit MSRs exists, otherwise domain is monitoring only */
1443 for (i = 0; i < NR_POWER_LIMITS; i++) {
1444 int prim = rd->rpl[i].prim_id;
1445 if (rapl_read_data_raw(rd, prim, false, &val64))
1446 rd->rpl[i].name = NULL;
1447 }
1448}
1449
1384/* Detect active and valid domains for the given CPU, caller must 1450/* Detect active and valid domains for the given CPU, caller must
1385 * ensure the CPU belongs to the targeted package and CPU hotlug is disabled. 1451 * ensure the CPU belongs to the targeted package and CPU hotlug is disabled.
1386 */ 1452 */
@@ -1389,7 +1455,6 @@ static int rapl_detect_domains(struct rapl_package *rp, int cpu)
1389 int i; 1455 int i;
1390 int ret = 0; 1456 int ret = 0;
1391 struct rapl_domain *rd; 1457 struct rapl_domain *rd;
1392 u64 locked;
1393 1458
1394 for (i = 0; i < RAPL_DOMAIN_MAX; i++) { 1459 for (i = 0; i < RAPL_DOMAIN_MAX; i++) {
1395 /* use physical package id to read counters */ 1460 /* use physical package id to read counters */
@@ -1400,7 +1465,7 @@ static int rapl_detect_domains(struct rapl_package *rp, int cpu)
1400 } 1465 }
1401 rp->nr_domains = bitmap_weight(&rp->domain_map, RAPL_DOMAIN_MAX); 1466 rp->nr_domains = bitmap_weight(&rp->domain_map, RAPL_DOMAIN_MAX);
1402 if (!rp->nr_domains) { 1467 if (!rp->nr_domains) {
1403 pr_err("no valid rapl domains found in package %d\n", rp->id); 1468 pr_debug("no valid rapl domains found in package %d\n", rp->id);
1404 ret = -ENODEV; 1469 ret = -ENODEV;
1405 goto done; 1470 goto done;
1406 } 1471 }
@@ -1414,17 +1479,9 @@ static int rapl_detect_domains(struct rapl_package *rp, int cpu)
1414 } 1479 }
1415 rapl_init_domains(rp); 1480 rapl_init_domains(rp);
1416 1481
1417 for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++) { 1482 for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++)
1418 /* check if the domain is locked by BIOS */ 1483 rapl_detect_powerlimit(rd);
1419 ret = rapl_read_data_raw(rd, FW_LOCK, false, &locked); 1484
1420 if (ret)
1421 return ret;
1422 if (locked) {
1423 pr_info("RAPL package %d domain %s locked by BIOS\n",
1424 rp->id, rd->name);
1425 rd->state |= DOMAIN_STATE_BIOS_LOCKED;
1426 }
1427 }
1428 1485
1429 1486
1430done: 1487done: