Loading drivers/powercap/intel_rapl.c +80 −25 Original line number Diff line number Diff line Loading @@ -336,14 +336,14 @@ static int release_zone(struct powercap_zone *power_zone) static int find_nr_power_limit(struct rapl_domain *rd) { int i; int i, nr_pl = 0; for (i = 0; i < NR_POWER_LIMITS; i++) { if (rd->rpl[i].name == NULL) break; if (rd->rpl[i].name) nr_pl++; } return i; return nr_pl; } static int set_domain_enable(struct powercap_zone *power_zone, bool mode) Loading Loading @@ -426,15 +426,38 @@ static const struct powercap_zone_ops zone_ops[] = { }, }; static int set_power_limit(struct powercap_zone *power_zone, int id, /* * Constraint index used by powercap can be different than power limit (PL) * index in that some PLs maybe missing due to non-existant MSRs. So we * need to convert here by finding the valid PLs only (name populated). */ static int contraint_to_pl(struct rapl_domain *rd, int cid) { int i, j; for (i = 0, j = 0; i < NR_POWER_LIMITS; i++) { if ((rd->rpl[i].name) && j++ == cid) { pr_debug("%s: index %d\n", __func__, i); return i; } } return -EINVAL; } static int set_power_limit(struct powercap_zone *power_zone, int cid, u64 power_limit) { struct rapl_domain *rd; struct rapl_package *rp; int ret = 0; int id; get_online_cpus(); rd = power_zone_to_rapl_domain(power_zone); id = contraint_to_pl(rd, cid); rp = rd->rp; if (rd->state & DOMAIN_STATE_BIOS_LOCKED) { Loading @@ -461,16 +484,18 @@ static int set_power_limit(struct powercap_zone *power_zone, int id, return ret; } static int get_current_power_limit(struct powercap_zone *power_zone, int id, static int get_current_power_limit(struct powercap_zone *power_zone, int cid, u64 *data) { struct rapl_domain *rd; u64 val; int prim; int ret = 0; int id; get_online_cpus(); rd = power_zone_to_rapl_domain(power_zone); id = contraint_to_pl(rd, cid); switch (rd->rpl[id].prim_id) { case PL1_ENABLE: prim = POWER_LIMIT1; Loading @@ -492,14 +517,17 @@ static int get_current_power_limit(struct powercap_zone *power_zone, int id, return ret; } static int set_time_window(struct powercap_zone *power_zone, int id, static int set_time_window(struct powercap_zone *power_zone, int cid, u64 window) { struct rapl_domain *rd; int ret = 0; int id; get_online_cpus(); rd = power_zone_to_rapl_domain(power_zone); id = contraint_to_pl(rd, cid); switch (rd->rpl[id].prim_id) { case PL1_ENABLE: rapl_write_data_raw(rd, TIME_WINDOW1, window); Loading @@ -514,14 +542,17 @@ static int set_time_window(struct powercap_zone *power_zone, int id, return ret; } static int get_time_window(struct powercap_zone *power_zone, int id, u64 *data) static int get_time_window(struct powercap_zone *power_zone, int cid, u64 *data) { struct rapl_domain *rd; u64 val; int ret = 0; int id; get_online_cpus(); rd = power_zone_to_rapl_domain(power_zone); id = contraint_to_pl(rd, cid); switch (rd->rpl[id].prim_id) { case PL1_ENABLE: ret = rapl_read_data_raw(rd, TIME_WINDOW1, true, &val); Loading @@ -540,15 +571,17 @@ static int get_time_window(struct powercap_zone *power_zone, int id, u64 *data) return ret; } static const char *get_constraint_name(struct powercap_zone *power_zone, int id) static const char *get_constraint_name(struct powercap_zone *power_zone, int cid) { struct rapl_power_limit *rpl; struct rapl_domain *rd; int id; rd = power_zone_to_rapl_domain(power_zone); rpl = (struct rapl_power_limit *) &rd->rpl[id]; id = contraint_to_pl(rd, cid); if (id >= 0) return rd->rpl[id].name; return rpl->name; return NULL; } Loading Loading @@ -1381,6 +1414,37 @@ static int rapl_check_domain(int cpu, int domain) return 0; } /* * Check if power limits are available. Two cases when they are not available: * 1. Locked by BIOS, in this case we still provide read-only access so that * users can see what limit is set by the BIOS. * 2. Some CPUs make some domains monitoring only which means PLx MSRs may not * exist at all. In this case, we do not show the contraints in powercap. * * Called after domains are detected and initialized. */ static void rapl_detect_powerlimit(struct rapl_domain *rd) { u64 val64; int i; /* check if the domain is locked by BIOS, ignore if MSR doesn't exist */ if (!rapl_read_data_raw(rd, FW_LOCK, false, &val64)) { if (val64) { pr_info("RAPL package %d domain %s locked by BIOS\n", rd->rp->id, rd->name); rd->state |= DOMAIN_STATE_BIOS_LOCKED; } } /* check if power limit MSRs exists, otherwise domain is monitoring only */ for (i = 0; i < NR_POWER_LIMITS; i++) { int prim = rd->rpl[i].prim_id; if (rapl_read_data_raw(rd, prim, false, &val64)) rd->rpl[i].name = NULL; } } /* Detect active and valid domains for the given CPU, caller must * ensure the CPU belongs to the targeted package and CPU hotlug is disabled. */ Loading @@ -1389,7 +1453,6 @@ static int rapl_detect_domains(struct rapl_package *rp, int cpu) int i; int ret = 0; struct rapl_domain *rd; u64 locked; for (i = 0; i < RAPL_DOMAIN_MAX; i++) { /* use physical package id to read counters */ Loading @@ -1400,7 +1463,7 @@ static int rapl_detect_domains(struct rapl_package *rp, int cpu) } rp->nr_domains = bitmap_weight(&rp->domain_map, RAPL_DOMAIN_MAX); if (!rp->nr_domains) { pr_err("no valid rapl domains found in package %d\n", rp->id); pr_debug("no valid rapl domains found in package %d\n", rp->id); ret = -ENODEV; goto done; } Loading @@ -1414,17 +1477,9 @@ static int rapl_detect_domains(struct rapl_package *rp, int cpu) } rapl_init_domains(rp); for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++) { /* check if the domain is locked by BIOS */ ret = rapl_read_data_raw(rd, FW_LOCK, false, &locked); if (ret) return ret; if (locked) { pr_info("RAPL package %d domain %s locked by BIOS\n", rp->id, rd->name); rd->state |= DOMAIN_STATE_BIOS_LOCKED; } } for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++) rapl_detect_powerlimit(rd); done: Loading Loading
drivers/powercap/intel_rapl.c +80 −25 Original line number Diff line number Diff line Loading @@ -336,14 +336,14 @@ static int release_zone(struct powercap_zone *power_zone) static int find_nr_power_limit(struct rapl_domain *rd) { int i; int i, nr_pl = 0; for (i = 0; i < NR_POWER_LIMITS; i++) { if (rd->rpl[i].name == NULL) break; if (rd->rpl[i].name) nr_pl++; } return i; return nr_pl; } static int set_domain_enable(struct powercap_zone *power_zone, bool mode) Loading Loading @@ -426,15 +426,38 @@ static const struct powercap_zone_ops zone_ops[] = { }, }; static int set_power_limit(struct powercap_zone *power_zone, int id, /* * Constraint index used by powercap can be different than power limit (PL) * index in that some PLs maybe missing due to non-existant MSRs. So we * need to convert here by finding the valid PLs only (name populated). */ static int contraint_to_pl(struct rapl_domain *rd, int cid) { int i, j; for (i = 0, j = 0; i < NR_POWER_LIMITS; i++) { if ((rd->rpl[i].name) && j++ == cid) { pr_debug("%s: index %d\n", __func__, i); return i; } } return -EINVAL; } static int set_power_limit(struct powercap_zone *power_zone, int cid, u64 power_limit) { struct rapl_domain *rd; struct rapl_package *rp; int ret = 0; int id; get_online_cpus(); rd = power_zone_to_rapl_domain(power_zone); id = contraint_to_pl(rd, cid); rp = rd->rp; if (rd->state & DOMAIN_STATE_BIOS_LOCKED) { Loading @@ -461,16 +484,18 @@ static int set_power_limit(struct powercap_zone *power_zone, int id, return ret; } static int get_current_power_limit(struct powercap_zone *power_zone, int id, static int get_current_power_limit(struct powercap_zone *power_zone, int cid, u64 *data) { struct rapl_domain *rd; u64 val; int prim; int ret = 0; int id; get_online_cpus(); rd = power_zone_to_rapl_domain(power_zone); id = contraint_to_pl(rd, cid); switch (rd->rpl[id].prim_id) { case PL1_ENABLE: prim = POWER_LIMIT1; Loading @@ -492,14 +517,17 @@ static int get_current_power_limit(struct powercap_zone *power_zone, int id, return ret; } static int set_time_window(struct powercap_zone *power_zone, int id, static int set_time_window(struct powercap_zone *power_zone, int cid, u64 window) { struct rapl_domain *rd; int ret = 0; int id; get_online_cpus(); rd = power_zone_to_rapl_domain(power_zone); id = contraint_to_pl(rd, cid); switch (rd->rpl[id].prim_id) { case PL1_ENABLE: rapl_write_data_raw(rd, TIME_WINDOW1, window); Loading @@ -514,14 +542,17 @@ static int set_time_window(struct powercap_zone *power_zone, int id, return ret; } static int get_time_window(struct powercap_zone *power_zone, int id, u64 *data) static int get_time_window(struct powercap_zone *power_zone, int cid, u64 *data) { struct rapl_domain *rd; u64 val; int ret = 0; int id; get_online_cpus(); rd = power_zone_to_rapl_domain(power_zone); id = contraint_to_pl(rd, cid); switch (rd->rpl[id].prim_id) { case PL1_ENABLE: ret = rapl_read_data_raw(rd, TIME_WINDOW1, true, &val); Loading @@ -540,15 +571,17 @@ static int get_time_window(struct powercap_zone *power_zone, int id, u64 *data) return ret; } static const char *get_constraint_name(struct powercap_zone *power_zone, int id) static const char *get_constraint_name(struct powercap_zone *power_zone, int cid) { struct rapl_power_limit *rpl; struct rapl_domain *rd; int id; rd = power_zone_to_rapl_domain(power_zone); rpl = (struct rapl_power_limit *) &rd->rpl[id]; id = contraint_to_pl(rd, cid); if (id >= 0) return rd->rpl[id].name; return rpl->name; return NULL; } Loading Loading @@ -1381,6 +1414,37 @@ static int rapl_check_domain(int cpu, int domain) return 0; } /* * Check if power limits are available. Two cases when they are not available: * 1. Locked by BIOS, in this case we still provide read-only access so that * users can see what limit is set by the BIOS. * 2. Some CPUs make some domains monitoring only which means PLx MSRs may not * exist at all. In this case, we do not show the contraints in powercap. * * Called after domains are detected and initialized. */ static void rapl_detect_powerlimit(struct rapl_domain *rd) { u64 val64; int i; /* check if the domain is locked by BIOS, ignore if MSR doesn't exist */ if (!rapl_read_data_raw(rd, FW_LOCK, false, &val64)) { if (val64) { pr_info("RAPL package %d domain %s locked by BIOS\n", rd->rp->id, rd->name); rd->state |= DOMAIN_STATE_BIOS_LOCKED; } } /* check if power limit MSRs exists, otherwise domain is monitoring only */ for (i = 0; i < NR_POWER_LIMITS; i++) { int prim = rd->rpl[i].prim_id; if (rapl_read_data_raw(rd, prim, false, &val64)) rd->rpl[i].name = NULL; } } /* Detect active and valid domains for the given CPU, caller must * ensure the CPU belongs to the targeted package and CPU hotlug is disabled. */ Loading @@ -1389,7 +1453,6 @@ static int rapl_detect_domains(struct rapl_package *rp, int cpu) int i; int ret = 0; struct rapl_domain *rd; u64 locked; for (i = 0; i < RAPL_DOMAIN_MAX; i++) { /* use physical package id to read counters */ Loading @@ -1400,7 +1463,7 @@ static int rapl_detect_domains(struct rapl_package *rp, int cpu) } rp->nr_domains = bitmap_weight(&rp->domain_map, RAPL_DOMAIN_MAX); if (!rp->nr_domains) { pr_err("no valid rapl domains found in package %d\n", rp->id); pr_debug("no valid rapl domains found in package %d\n", rp->id); ret = -ENODEV; goto done; } Loading @@ -1414,17 +1477,9 @@ static int rapl_detect_domains(struct rapl_package *rp, int cpu) } rapl_init_domains(rp); for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++) { /* check if the domain is locked by BIOS */ ret = rapl_read_data_raw(rd, FW_LOCK, false, &locked); if (ret) return ret; if (locked) { pr_info("RAPL package %d domain %s locked by BIOS\n", rp->id, rd->name); rd->state |= DOMAIN_STATE_BIOS_LOCKED; } } for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++) rapl_detect_powerlimit(rd); done: Loading