Commit 9050a9cd authored by Zhang Rui's avatar Zhang Rui Committed by Rafael J. Wysocki

powercap: intel_rapl: Cleanup Power Limits support

The same set of operations are shared by different Powert Limits,
including Power Limit get/set, Power Limit enable/disable, clamping
enable/disable, time window get/set, and max power get/set, etc.

But the same operation for different Power Limit has different
primitives because they use different registers/register bits.

A lot of dirty/duplicate code was introduced to handle this difference.

Introduce a universal way to issue Power Limit operations.
Instead of using hardcoded primitive name directly, use Power Limit id
+ operation type, and hide all the Power Limit difference details in a
central place, get_pl_prim(). Two helpers, rapl_read_pl_data() and
rapl_write_pl_data(), are introduced at the same time to simplify the
code for issuing Power Limit operations.
Signed-off-by: default avatarZhang Rui <rui.zhang@intel.com>
Tested-by: default avatarWang Wendy <wendy.wang@intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent a38f300b
...@@ -96,9 +96,67 @@ enum unit_type { ...@@ -96,9 +96,67 @@ enum unit_type {
#define DOMAIN_STATE_POWER_LIMIT_SET BIT(1) #define DOMAIN_STATE_POWER_LIMIT_SET BIT(1)
#define DOMAIN_STATE_BIOS_LOCKED BIT(2) #define DOMAIN_STATE_BIOS_LOCKED BIT(2)
static const char pl1_name[] = "long_term"; static const char *pl_names[NR_POWER_LIMITS] = {
static const char pl2_name[] = "short_term"; [POWER_LIMIT1] = "long_term",
static const char pl4_name[] = "peak_power"; [POWER_LIMIT2] = "short_term",
[POWER_LIMIT4] = "peak_power",
};
enum pl_prims {
PL_ENABLE,
PL_CLAMP,
PL_LIMIT,
PL_TIME_WINDOW,
PL_MAX_POWER,
};
static bool is_pl_valid(struct rapl_domain *rd, int pl)
{
if (pl < POWER_LIMIT1 || pl > POWER_LIMIT4)
return false;
return rd->rpl[pl].name ? true : false;
}
static int get_pl_prim(int pl, enum pl_prims prim)
{
switch (pl) {
case POWER_LIMIT1:
if (prim == PL_ENABLE)
return PL1_ENABLE;
if (prim == PL_CLAMP)
return PL1_CLAMP;
if (prim == PL_LIMIT)
return POWER_LIMIT1;
if (prim == PL_TIME_WINDOW)
return TIME_WINDOW1;
if (prim == PL_MAX_POWER)
return THERMAL_SPEC_POWER;
return -EINVAL;
case POWER_LIMIT2:
if (prim == PL_ENABLE)
return PL2_ENABLE;
if (prim == PL_CLAMP)
return PL2_CLAMP;
if (prim == PL_LIMIT)
return POWER_LIMIT2;
if (prim == PL_TIME_WINDOW)
return TIME_WINDOW2;
if (prim == PL_MAX_POWER)
return MAX_POWER;
return -EINVAL;
case POWER_LIMIT4:
if (prim == PL_LIMIT)
return POWER_LIMIT4;
if (prim == PL_ENABLE)
return PL4_ENABLE;
/* PL4 would be around two times PL2, use same prim as PL2. */
if (prim == PL_MAX_POWER)
return MAX_POWER;
return -EINVAL;
default:
return -EINVAL;
}
}
#define power_zone_to_rapl_domain(_zone) \ #define power_zone_to_rapl_domain(_zone) \
container_of(_zone, struct rapl_domain, power_zone) container_of(_zone, struct rapl_domain, power_zone)
...@@ -155,6 +213,12 @@ static int rapl_read_data_raw(struct rapl_domain *rd, ...@@ -155,6 +213,12 @@ static int rapl_read_data_raw(struct rapl_domain *rd,
static int rapl_write_data_raw(struct rapl_domain *rd, static int rapl_write_data_raw(struct rapl_domain *rd,
enum rapl_primitives prim, enum rapl_primitives prim,
unsigned long long value); unsigned long long value);
static int rapl_read_pl_data(struct rapl_domain *rd, int pl,
enum pl_prims pl_prim,
bool xlate, u64 *data);
static int rapl_write_pl_data(struct rapl_domain *rd, int pl,
enum pl_prims pl_prim,
unsigned long long value);
static u64 rapl_unit_xlate(struct rapl_domain *rd, static u64 rapl_unit_xlate(struct rapl_domain *rd,
enum unit_type type, u64 value, int to_raw); enum unit_type type, u64 value, int to_raw);
static void package_power_limit_irq_save(struct rapl_package *rp); static void package_power_limit_irq_save(struct rapl_package *rp);
...@@ -222,7 +286,7 @@ static int find_nr_power_limit(struct rapl_domain *rd) ...@@ -222,7 +286,7 @@ static int find_nr_power_limit(struct rapl_domain *rd)
int i, nr_pl = 0; int i, nr_pl = 0;
for (i = 0; i < NR_POWER_LIMITS; i++) { for (i = 0; i < NR_POWER_LIMITS; i++) {
if (rd->rpl[i].name) if (is_pl_valid(rd, i))
nr_pl++; nr_pl++;
} }
...@@ -233,37 +297,34 @@ static int set_domain_enable(struct powercap_zone *power_zone, bool mode) ...@@ -233,37 +297,34 @@ static int set_domain_enable(struct powercap_zone *power_zone, bool mode)
{ {
struct rapl_domain *rd = power_zone_to_rapl_domain(power_zone); struct rapl_domain *rd = power_zone_to_rapl_domain(power_zone);
struct rapl_defaults *defaults = get_defaults(rd->rp); struct rapl_defaults *defaults = get_defaults(rd->rp);
int ret;
if (rd->state & DOMAIN_STATE_BIOS_LOCKED)
return -EACCES;
cpus_read_lock(); cpus_read_lock();
rapl_write_data_raw(rd, PL1_ENABLE, mode); ret = rapl_write_pl_data(rd, POWER_LIMIT1, PL_ENABLE, mode);
if (defaults->set_floor_freq) if (!ret && defaults->set_floor_freq)
defaults->set_floor_freq(rd, mode); defaults->set_floor_freq(rd, mode);
cpus_read_unlock(); cpus_read_unlock();
return 0; return ret;
} }
static int get_domain_enable(struct powercap_zone *power_zone, bool *mode) static int get_domain_enable(struct powercap_zone *power_zone, bool *mode)
{ {
struct rapl_domain *rd = power_zone_to_rapl_domain(power_zone); struct rapl_domain *rd = power_zone_to_rapl_domain(power_zone);
u64 val; u64 val;
int ret;
if (rd->state & DOMAIN_STATE_BIOS_LOCKED) { if (rd->state & DOMAIN_STATE_BIOS_LOCKED) {
*mode = false; *mode = false;
return 0; return 0;
} }
cpus_read_lock(); cpus_read_lock();
if (rapl_read_data_raw(rd, PL1_ENABLE, true, &val)) { ret = rapl_read_pl_data(rd, POWER_LIMIT1, PL_ENABLE, true, &val);
cpus_read_unlock(); if (!ret)
return -EIO;
}
*mode = val; *mode = val;
cpus_read_unlock(); cpus_read_unlock();
return 0; return ret;
} }
/* per RAPL domain ops, in the order of rapl_domain_type */ /* per RAPL domain ops, in the order of rapl_domain_type */
...@@ -319,8 +380,8 @@ static int contraint_to_pl(struct rapl_domain *rd, int cid) ...@@ -319,8 +380,8 @@ static int contraint_to_pl(struct rapl_domain *rd, int cid)
{ {
int i, j; int i, j;
for (i = 0, j = 0; i < NR_POWER_LIMITS; i++) { for (i = POWER_LIMIT1, j = 0; i < NR_POWER_LIMITS; i++) {
if ((rd->rpl[i].name) && j++ == cid) { if (is_pl_valid(rd, i) && j++ == cid) {
pr_debug("%s: index %d\n", __func__, i); pr_debug("%s: index %d\n", __func__, i);
return i; return i;
} }
...@@ -341,36 +402,11 @@ static int set_power_limit(struct powercap_zone *power_zone, int cid, ...@@ -341,36 +402,11 @@ static int set_power_limit(struct powercap_zone *power_zone, int cid,
cpus_read_lock(); cpus_read_lock();
rd = power_zone_to_rapl_domain(power_zone); rd = power_zone_to_rapl_domain(power_zone);
id = contraint_to_pl(rd, cid); id = contraint_to_pl(rd, cid);
if (id < 0) {
ret = id;
goto set_exit;
}
rp = rd->rp; rp = rd->rp;
if (rd->state & DOMAIN_STATE_BIOS_LOCKED) { ret = rapl_write_pl_data(rd, id, PL_LIMIT, power_limit);
dev_warn(&power_zone->dev,
"%s locked by BIOS, monitoring only\n", rd->name);
ret = -EACCES;
goto set_exit;
}
switch (rd->rpl[id].prim_id) {
case PL1_ENABLE:
rapl_write_data_raw(rd, POWER_LIMIT1, power_limit);
break;
case PL2_ENABLE:
rapl_write_data_raw(rd, POWER_LIMIT2, power_limit);
break;
case PL4_ENABLE:
rapl_write_data_raw(rd, POWER_LIMIT4, power_limit);
break;
default:
ret = -EINVAL;
}
if (!ret) if (!ret)
package_power_limit_irq_save(rp); package_power_limit_irq_save(rp);
set_exit:
cpus_read_unlock(); cpus_read_unlock();
return ret; return ret;
} }
...@@ -380,38 +416,17 @@ static int get_current_power_limit(struct powercap_zone *power_zone, int cid, ...@@ -380,38 +416,17 @@ static int get_current_power_limit(struct powercap_zone *power_zone, int cid,
{ {
struct rapl_domain *rd; struct rapl_domain *rd;
u64 val; u64 val;
int prim;
int ret = 0; int ret = 0;
int id; int id;
cpus_read_lock(); cpus_read_lock();
rd = power_zone_to_rapl_domain(power_zone); rd = power_zone_to_rapl_domain(power_zone);
id = contraint_to_pl(rd, cid); id = contraint_to_pl(rd, cid);
if (id < 0) {
ret = id;
goto get_exit;
}
switch (rd->rpl[id].prim_id) { ret = rapl_read_pl_data(rd, id, PL_LIMIT, true, &val);
case PL1_ENABLE: if (!ret)
prim = POWER_LIMIT1;
break;
case PL2_ENABLE:
prim = POWER_LIMIT2;
break;
case PL4_ENABLE:
prim = POWER_LIMIT4;
break;
default:
cpus_read_unlock();
return -EINVAL;
}
if (rapl_read_data_raw(rd, prim, true, &val))
ret = -EIO;
else
*data = val; *data = val;
get_exit:
cpus_read_unlock(); cpus_read_unlock();
return ret; return ret;
...@@ -427,23 +442,9 @@ static int set_time_window(struct powercap_zone *power_zone, int cid, ...@@ -427,23 +442,9 @@ static int set_time_window(struct powercap_zone *power_zone, int cid,
cpus_read_lock(); cpus_read_lock();
rd = power_zone_to_rapl_domain(power_zone); rd = power_zone_to_rapl_domain(power_zone);
id = contraint_to_pl(rd, cid); id = contraint_to_pl(rd, cid);
if (id < 0) {
ret = id;
goto set_time_exit;
}
switch (rd->rpl[id].prim_id) { ret = rapl_write_pl_data(rd, id, PL_TIME_WINDOW, window);
case PL1_ENABLE:
rapl_write_data_raw(rd, TIME_WINDOW1, window);
break;
case PL2_ENABLE:
rapl_write_data_raw(rd, TIME_WINDOW2, window);
break;
default:
ret = -EINVAL;
}
set_time_exit:
cpus_read_unlock(); cpus_read_unlock();
return ret; return ret;
} }
...@@ -459,33 +460,11 @@ static int get_time_window(struct powercap_zone *power_zone, int cid, ...@@ -459,33 +460,11 @@ static int get_time_window(struct powercap_zone *power_zone, int cid,
cpus_read_lock(); cpus_read_lock();
rd = power_zone_to_rapl_domain(power_zone); rd = power_zone_to_rapl_domain(power_zone);
id = contraint_to_pl(rd, cid); id = contraint_to_pl(rd, cid);
if (id < 0) {
ret = id;
goto get_time_exit;
}
switch (rd->rpl[id].prim_id) { ret = rapl_read_pl_data(rd, id, PL_TIME_WINDOW, true, &val);
case PL1_ENABLE:
ret = rapl_read_data_raw(rd, TIME_WINDOW1, true, &val);
break;
case PL2_ENABLE:
ret = rapl_read_data_raw(rd, TIME_WINDOW2, true, &val);
break;
case PL4_ENABLE:
/*
* Time window parameter is not applicable for PL4 entry
* so assigining '0' as default value.
*/
val = 0;
break;
default:
cpus_read_unlock();
return -EINVAL;
}
if (!ret) if (!ret)
*data = val; *data = val;
get_time_exit:
cpus_read_unlock(); cpus_read_unlock();
return ret; return ret;
...@@ -505,36 +484,23 @@ static const char *get_constraint_name(struct powercap_zone *power_zone, ...@@ -505,36 +484,23 @@ static const char *get_constraint_name(struct powercap_zone *power_zone,
return NULL; return NULL;
} }
static int get_max_power(struct powercap_zone *power_zone, int id, u64 *data) static int get_max_power(struct powercap_zone *power_zone, int cid, u64 *data)
{ {
struct rapl_domain *rd; struct rapl_domain *rd;
u64 val; u64 val;
int prim;
int ret = 0; int ret = 0;
int id;
cpus_read_lock(); cpus_read_lock();
rd = power_zone_to_rapl_domain(power_zone); rd = power_zone_to_rapl_domain(power_zone);
switch (rd->rpl[id].prim_id) { id = contraint_to_pl(rd, cid);
case PL1_ENABLE:
prim = THERMAL_SPEC_POWER; ret = rapl_read_pl_data(rd, id, PL_MAX_POWER, true, &val);
break; if (!ret)
case PL2_ENABLE:
prim = MAX_POWER;
break;
case PL4_ENABLE:
prim = MAX_POWER;
break;
default:
cpus_read_unlock();
return -EINVAL;
}
if (rapl_read_data_raw(rd, prim, true, &val))
ret = -EIO;
else
*data = val; *data = val;
/* As a generalization rule, PL4 would be around two times PL2. */ /* As a generalization rule, PL4 would be around two times PL2. */
if (rd->rpl[id].prim_id == PL4_ENABLE) if (id == POWER_LIMIT4)
*data = *data * 2; *data = *data * 2;
cpus_read_unlock(); cpus_read_unlock();
...@@ -560,6 +526,7 @@ static void rapl_init_domains(struct rapl_package *rp) ...@@ -560,6 +526,7 @@ static void rapl_init_domains(struct rapl_package *rp)
for (i = 0; i < RAPL_DOMAIN_MAX; i++) { for (i = 0; i < RAPL_DOMAIN_MAX; i++) {
unsigned int mask = rp->domain_map & (1 << i); unsigned int mask = rp->domain_map & (1 << i);
int t;
if (!mask) if (!mask)
continue; continue;
...@@ -577,17 +544,10 @@ static void rapl_init_domains(struct rapl_package *rp) ...@@ -577,17 +544,10 @@ static void rapl_init_domains(struct rapl_package *rp)
/* PL1 is supported by default */ /* PL1 is supported by default */
rp->priv->limits[i] |= BIT(POWER_LIMIT1); rp->priv->limits[i] |= BIT(POWER_LIMIT1);
rd->rpl[0].prim_id = PL1_ENABLE;
rd->rpl[0].name = pl1_name;
if (rp->priv->limits[i] & BIT(POWER_LIMIT2)) { for (t = POWER_LIMIT1; t < NR_POWER_LIMITS; t++) {
rd->rpl[1].prim_id = PL2_ENABLE; if (rp->priv->limits[i] & BIT(t))
rd->rpl[1].name = pl2_name; rd->rpl[t].name = pl_names[t];
}
if (rp->priv->limits[i] & BIT(POWER_LIMIT4)) {
rd->rpl[2].prim_id = PL4_ENABLE;
rd->rpl[2].name = pl4_name;
} }
for (j = 0; j < RAPL_DOMAIN_REG_MAX; j++) for (j = 0; j < RAPL_DOMAIN_REG_MAX; j++)
...@@ -818,6 +778,33 @@ static int rapl_write_data_raw(struct rapl_domain *rd, ...@@ -818,6 +778,33 @@ static int rapl_write_data_raw(struct rapl_domain *rd,
return ret; return ret;
} }
static int rapl_read_pl_data(struct rapl_domain *rd, int pl,
enum pl_prims pl_prim, bool xlate, u64 *data)
{
enum rapl_primitives prim = get_pl_prim(pl, pl_prim);
if (!is_pl_valid(rd, pl))
return -EINVAL;
return rapl_read_data_raw(rd, prim, xlate, data);
}
static int rapl_write_pl_data(struct rapl_domain *rd, int pl,
enum pl_prims pl_prim,
unsigned long long value)
{
enum rapl_primitives prim = get_pl_prim(pl, pl_prim);
if (!is_pl_valid(rd, pl))
return -EINVAL;
if (rd->state & DOMAIN_STATE_BIOS_LOCKED) {
pr_warn("%s:%s:%s locked by BIOS\n", rd->rp->name, rd->name, pl_names[pl]);
return -EACCES;
}
return rapl_write_data_raw(rd, prim, value);
}
/* /*
* Raw RAPL data stored in MSRs are in certain scales. We need to * Raw RAPL data stored in MSRs are in certain scales. We need to
* convert them into standard units based on the units reported in * convert them into standard units based on the units reported in
...@@ -945,17 +932,16 @@ static void package_power_limit_irq_restore(struct rapl_package *rp) ...@@ -945,17 +932,16 @@ static void package_power_limit_irq_restore(struct rapl_package *rp)
static void set_floor_freq_default(struct rapl_domain *rd, bool mode) static void set_floor_freq_default(struct rapl_domain *rd, bool mode)
{ {
int nr_powerlimit = find_nr_power_limit(rd); int i;
/* always enable clamp such that p-state can go below OS requested /* always enable clamp such that p-state can go below OS requested
* range. power capping priority over guranteed frequency. * range. power capping priority over guranteed frequency.
*/ */
rapl_write_data_raw(rd, PL1_CLAMP, mode); rapl_write_pl_data(rd, POWER_LIMIT1, PL_CLAMP, mode);
/* some domains have pl2 */ for (i = POWER_LIMIT2; i < NR_POWER_LIMITS; i++) {
if (nr_powerlimit > 1) { rapl_write_pl_data(rd, i, PL_ENABLE, mode);
rapl_write_data_raw(rd, PL2_ENABLE, mode); rapl_write_pl_data(rd, i, PL_CLAMP, mode);
rapl_write_data_raw(rd, PL2_CLAMP, mode);
} }
} }
...@@ -1327,11 +1313,10 @@ static void rapl_detect_powerlimit(struct rapl_domain *rd) ...@@ -1327,11 +1313,10 @@ static void rapl_detect_powerlimit(struct rapl_domain *rd)
rd->state |= DOMAIN_STATE_BIOS_LOCKED; rd->state |= DOMAIN_STATE_BIOS_LOCKED;
} }
} }
/* check if power limit MSR 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)) /* check if power limit exists, otherwise domain is monitoring only */
for (i = POWER_LIMIT1; i < NR_POWER_LIMITS; i++) {
if (rapl_read_pl_data(rd, i, PL_ENABLE, false, &val64))
rd->rpl[i].name = NULL; rd->rpl[i].name = NULL;
} }
} }
...@@ -1381,13 +1366,13 @@ void rapl_remove_package(struct rapl_package *rp) ...@@ -1381,13 +1366,13 @@ void rapl_remove_package(struct rapl_package *rp)
package_power_limit_irq_restore(rp); package_power_limit_irq_restore(rp);
for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++) { for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++) {
rapl_write_data_raw(rd, PL1_ENABLE, 0); int i;
rapl_write_data_raw(rd, PL1_CLAMP, 0);
if (find_nr_power_limit(rd) > 1) { for (i = POWER_LIMIT1; i < NR_POWER_LIMITS; i++) {
rapl_write_data_raw(rd, PL2_ENABLE, 0); rapl_write_pl_data(rd, i, PL_ENABLE, 0);
rapl_write_data_raw(rd, PL2_CLAMP, 0); rapl_write_pl_data(rd, i, PL_CLAMP, 0);
rapl_write_data_raw(rd, PL4_ENABLE, 0);
} }
if (rd->id == RAPL_DOMAIN_PACKAGE) { if (rd->id == RAPL_DOMAIN_PACKAGE) {
rd_package = rd; rd_package = rd;
continue; continue;
...@@ -1472,38 +1457,18 @@ static void power_limit_state_save(void) ...@@ -1472,38 +1457,18 @@ static void power_limit_state_save(void)
{ {
struct rapl_package *rp; struct rapl_package *rp;
struct rapl_domain *rd; struct rapl_domain *rd;
int nr_pl, ret, i; int ret, i;
cpus_read_lock(); cpus_read_lock();
list_for_each_entry(rp, &rapl_packages, plist) { list_for_each_entry(rp, &rapl_packages, plist) {
if (!rp->power_zone) if (!rp->power_zone)
continue; continue;
rd = power_zone_to_rapl_domain(rp->power_zone); rd = power_zone_to_rapl_domain(rp->power_zone);
nr_pl = find_nr_power_limit(rd); for (i = POWER_LIMIT1; i < NR_POWER_LIMITS; i++) {
for (i = 0; i < nr_pl; i++) { ret = rapl_read_pl_data(rd, i, PL_LIMIT, true,
switch (rd->rpl[i].prim_id) {
case PL1_ENABLE:
ret = rapl_read_data_raw(rd,
POWER_LIMIT1, true,
&rd->rpl[i].last_power_limit);
if (ret)
rd->rpl[i].last_power_limit = 0;
break;
case PL2_ENABLE:
ret = rapl_read_data_raw(rd,
POWER_LIMIT2, true,
&rd->rpl[i].last_power_limit);
if (ret)
rd->rpl[i].last_power_limit = 0;
break;
case PL4_ENABLE:
ret = rapl_read_data_raw(rd,
POWER_LIMIT4, true,
&rd->rpl[i].last_power_limit); &rd->rpl[i].last_power_limit);
if (ret) if (ret)
rd->rpl[i].last_power_limit = 0; rd->rpl[i].last_power_limit = 0;
break;
}
} }
} }
cpus_read_unlock(); cpus_read_unlock();
...@@ -1513,33 +1478,17 @@ static void power_limit_state_restore(void) ...@@ -1513,33 +1478,17 @@ static void power_limit_state_restore(void)
{ {
struct rapl_package *rp; struct rapl_package *rp;
struct rapl_domain *rd; struct rapl_domain *rd;
int nr_pl, i; int i;
cpus_read_lock(); cpus_read_lock();
list_for_each_entry(rp, &rapl_packages, plist) { list_for_each_entry(rp, &rapl_packages, plist) {
if (!rp->power_zone) if (!rp->power_zone)
continue; continue;
rd = power_zone_to_rapl_domain(rp->power_zone); rd = power_zone_to_rapl_domain(rp->power_zone);
nr_pl = find_nr_power_limit(rd); for (i = POWER_LIMIT1; i < NR_POWER_LIMITS; i++)
for (i = 0; i < nr_pl; i++) {
switch (rd->rpl[i].prim_id) {
case PL1_ENABLE:
if (rd->rpl[i].last_power_limit) if (rd->rpl[i].last_power_limit)
rapl_write_data_raw(rd, POWER_LIMIT1, rapl_write_pl_data(rd, i, PL_LIMIT,
rd->rpl[i].last_power_limit); rd->rpl[i].last_power_limit);
break;
case PL2_ENABLE:
if (rd->rpl[i].last_power_limit)
rapl_write_data_raw(rd, POWER_LIMIT2,
rd->rpl[i].last_power_limit);
break;
case PL4_ENABLE:
if (rd->rpl[i].last_power_limit)
rapl_write_data_raw(rd, POWER_LIMIT4,
rd->rpl[i].last_power_limit);
break;
}
}
} }
cpus_read_unlock(); cpus_read_unlock();
} }
......
...@@ -79,7 +79,6 @@ struct rapl_domain_data { ...@@ -79,7 +79,6 @@ struct rapl_domain_data {
struct rapl_power_limit { struct rapl_power_limit {
struct powercap_zone_constraint *constraint; struct powercap_zone_constraint *constraint;
int prim_id; /* primitive ID used to enable */
struct rapl_domain *domain; struct rapl_domain *domain;
const char *name; const char *name;
u64 last_power_limit; u64 last_power_limit;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment