[Skiboot] [PATCH v2] SLW: Provide cpuidle state description in device tree
ppaidipe
ppaidipe at linux.vnet.ibm.com
Mon Jun 4 18:49:33 AEST 2018
On 2018-06-04 13:35, Abhishek Goel wrote:
> This patch adds description for every cpuidle state and expose it
> through device tree. Up until now, name was being used for description
> as no description was provided for cpuidle states.
> The description for idle states in case of POWER can be printed
> using "cpupower monitor -l" or "cpupower idle-info".
>
> Signed-off-by: Abhishek Goel <huntbag at linux.vnet.ibm.com>
> ---
> doc/device-tree/ibm,opal/power-mgt.rst | 5 ++++
> hw/slw.c | 49
> +++++++++++++++++++++++++++++-----
> 2 files changed, 48 insertions(+), 6 deletions(-)
>
> diff --git a/doc/device-tree/ibm,opal/power-mgt.rst
> b/doc/device-tree/ibm,opal/power-mgt.rst
> index b326a24b..598f8651 100644
> --- a/doc/device-tree/ibm,opal/power-mgt.rst
> +++ b/doc/device-tree/ibm,opal/power-mgt.rst
> @@ -10,6 +10,10 @@ ibm,opal/power-mgt device tree entries
>
>
> All available CPU idle states are listed in ibm,cpu-idle-state-names
> +The description field for cpuidle states describes the impact of that
> +idle state. It describes about the power management steps taken to
> save
> +power in that idle state and also whether its impact is
> thread/core/quad
> +domain.
>
> For example:
>
> @@ -17,6 +21,7 @@ For example:
>
> power-mgt {
> ibm,cpu-idle-state-names = "nap", "fastsleep_", "winkle";
> + ibm,cpu-idle-state-descs = "stop processor execution", "Core and
> L2 clock gating", "core and L3 power gating";
Hi
Can you make the description for all the states uniform start either
starts with
small or capital letters. That makes cpupower output nicer way.
Thanks
Pridhiviraj
> ibm,cpu-idle-state-residency-ns = <0x1 0x2 0x3>;
> ibm,cpu-idle-state-latencies-ns = <0x1 0x2 0x3>;
> };
> diff --git a/hw/slw.c b/hw/slw.c
> index 49bcd839..b0f6955e 100644
> --- a/hw/slw.c
> +++ b/hw/slw.c
> @@ -414,8 +414,10 @@ static bool idle_prepare_core(struct proc_chip
> *chip, struct cpu_thread *c)
>
> /* Define device-tree fields */
> #define MAX_NAME_LEN 16
> +#define MAX_DESC_LEN 60
> struct cpu_idle_states {
> char name[MAX_NAME_LEN];
> + char desc[MAX_DESC_LEN];
> u32 latency_ns;
> u32 residency_ns;
> /*
> @@ -430,6 +432,7 @@ struct cpu_idle_states {
> static struct cpu_idle_states power7_cpu_idle_states[] = {
> { /* nap */
> .name = "nap",
> + .desc = "stop processor execution",
> .latency_ns = 4000,
> .residency_ns = 100000,
> .flags = 0*OPAL_PM_DEC_STOP \
> @@ -448,6 +451,7 @@ static struct cpu_idle_states
> power7_cpu_idle_states[] = {
> static struct cpu_idle_states power8_cpu_idle_states[] = {
> { /* nap */
> .name = "nap",
> + .desc = "stop processor execution",
> .latency_ns = 4000,
> .residency_ns = 100000,
> .flags = 0*OPAL_PM_DEC_STOP \
> @@ -461,6 +465,7 @@ static struct cpu_idle_states
> power8_cpu_idle_states[] = {
> .pm_ctrl_reg_mask = 0 },
> { /* fast sleep (with workaround) */
> .name = "fastsleep_",
> + .desc = "Core and L2 clock gating",
> .latency_ns = 40000,
> .residency_ns = 300000000,
> .flags = 1*OPAL_PM_DEC_STOP \
> @@ -475,6 +480,7 @@ static struct cpu_idle_states
> power8_cpu_idle_states[] = {
> .pm_ctrl_reg_mask = OPAL_PM_SLEEP_PMICR_MASK },
> { /* Winkle */
> .name = "winkle",
> + .desc = "core and L3 power gating",
> .latency_ns = 10000000,
> .residency_ns = 1000000000, /* Educated guess (not measured).
> * Winkle is not currently used by
> @@ -503,6 +509,7 @@ static struct cpu_idle_states
> power8_cpu_idle_states[] = {
> static struct cpu_idle_states power9_cpu_idle_states[] = {
> {
> .name = "stop0_lite", /* Enter stop0 with no state loss */
> + .desc = "thread level stop instruction dispatch",
> .latency_ns = 1000,
> .residency_ns = 10000,
> .flags = 0*OPAL_PM_DEC_STOP \
> @@ -517,6 +524,7 @@ static struct cpu_idle_states
> power9_cpu_idle_states[] = {
> .pm_ctrl_reg_mask = OPAL_PM_PSSCR_MASK },
> {
> .name = "stop0",
> + .desc = "low latency SMT switching",
> .latency_ns = 2000,
> .residency_ns = 20000,
> .flags = 0*OPAL_PM_DEC_STOP \
> @@ -536,6 +544,7 @@ static struct cpu_idle_states
> power9_cpu_idle_states[] = {
>
> {
> .name = "stop1",
> + .desc = "SMT switching with basic clock gating",
> .latency_ns = 5000,
> .residency_ns = 50000,
> .flags = 0*OPAL_PM_DEC_STOP \
> @@ -557,6 +566,7 @@ static struct cpu_idle_states
> power9_cpu_idle_states[] = {
>
> {
> .name = "stop2",
> + .desc = "core level clock gating",
> .latency_ns = 10000,
> .residency_ns = 100000,
> .flags = 0*OPAL_PM_DEC_STOP \
> @@ -573,6 +583,7 @@ static struct cpu_idle_states
> power9_cpu_idle_states[] = {
> .pm_ctrl_reg_mask = OPAL_PM_PSSCR_MASK },
> {
> .name = "stop4",
> + .desc = "core level power gating",
> .latency_ns = 100000,
> .residency_ns = 10000000,
> .flags = 0*OPAL_PM_DEC_STOP \
> @@ -589,6 +600,7 @@ static struct cpu_idle_states
> power9_cpu_idle_states[] = {
> .pm_ctrl_reg_mask = OPAL_PM_PSSCR_MASK },
> {
> .name = "stop5",
> + .desc = "core level power gating and turbo boost benefit",
> .latency_ns = 200000,
> .residency_ns = 20000000,
> .flags = 0*OPAL_PM_DEC_STOP \
> @@ -606,6 +618,7 @@ static struct cpu_idle_states
> power9_cpu_idle_states[] = {
>
> {
> .name = "stop8",
> + .desc = "core power gating and L2 clock gating",
> .latency_ns = 2000000,
> .residency_ns = 20000000,
> .flags = 1*OPAL_PM_DEC_STOP \
> @@ -623,6 +636,7 @@ static struct cpu_idle_states
> power9_cpu_idle_states[] = {
>
> {
> .name = "stop11",
> + .desc = "quad level core and cache power gating",
> .latency_ns = 10000000,
> .residency_ns = 100000000,
> .flags = 1*OPAL_PM_DEC_STOP \
> @@ -647,6 +661,7 @@ static struct cpu_idle_states
> power9_cpu_idle_states[] = {
> static struct cpu_idle_states power9_mambo_cpu_idle_states[] = {
> {
> .name = "stop0",
> + .desc = "low latency SMT switching",
> .latency_ns = 2000,
> .residency_ns = 20000,
> .flags = 0*OPAL_PM_DEC_STOP \
> @@ -663,6 +678,7 @@ static struct cpu_idle_states
> power9_mambo_cpu_idle_states[] = {
> .pm_ctrl_reg_mask = OPAL_PM_PSSCR_MASK },
> {
> .name = "stop1",
> + .desc = "SMT switching with basic clock gating",
> .latency_ns = 5000,
> .residency_ns = 50000,
> .flags = 0*OPAL_PM_DEC_STOP \
> @@ -679,6 +695,7 @@ static struct cpu_idle_states
> power9_mambo_cpu_idle_states[] = {
> .pm_ctrl_reg_mask = OPAL_PM_PSSCR_MASK },
> {
> .name = "stop2",
> + .desc = "core level clock gating",
> .latency_ns = 10000,
> .residency_ns = 100000,
> .flags = 0*OPAL_PM_DEC_STOP \
> @@ -695,6 +712,7 @@ static struct cpu_idle_states
> power9_mambo_cpu_idle_states[] = {
> .pm_ctrl_reg_mask = OPAL_PM_PSSCR_MASK },
> {
> .name = "stop4",
> + .desc = "core level power gating",
> .latency_ns = 100000,
> .residency_ns = 1000000,
> .flags = 1*OPAL_PM_DEC_STOP \
> @@ -712,6 +730,7 @@ static struct cpu_idle_states
> power9_mambo_cpu_idle_states[] = {
>
> {
> .name = "stop8",
> + .desc = "core power gating and L2 clock gating",
> .latency_ns = 2000000,
> .residency_ns = 20000000,
> .flags = 1*OPAL_PM_DEC_STOP \
> @@ -729,6 +748,7 @@ static struct cpu_idle_states
> power9_mambo_cpu_idle_states[] = {
>
> {
> .name = "stop11",
> + .desc = "quad level core and cache power gating",
> .latency_ns = 10000000,
> .residency_ns = 100000000,
> .flags = 1*OPAL_PM_DEC_STOP \
> @@ -750,6 +770,7 @@ static struct cpu_idle_states
> power9_mambo_cpu_idle_states[] = {
> static struct cpu_idle_states power9_ndd1_cpu_idle_states[] = {
> {
> .name = "stop0_lite",
> + .desc = "thread level stop instruction dispatch",
> .latency_ns = 1000,
> .residency_ns = 10000,
> .flags = 0*OPAL_PM_DEC_STOP \
> @@ -764,6 +785,7 @@ static struct cpu_idle_states
> power9_ndd1_cpu_idle_states[] = {
> .pm_ctrl_reg_mask = OPAL_PM_PSSCR_MASK },
> {
> .name = "stop1_lite",
> + .desc = "functional unit clock gating no SMT switching",
> .latency_ns = 4900,
> .residency_ns = 49000,
> .flags = 0*OPAL_PM_DEC_STOP \
> @@ -778,6 +800,7 @@ static struct cpu_idle_states
> power9_ndd1_cpu_idle_states[] = {
> .pm_ctrl_reg_mask = OPAL_PM_PSSCR_MASK },
> {
> .name = "stop1",
> + .desc = "SMT switching with basic clock gating",
> .latency_ns = 2050000,
> .residency_ns = 50000,
> .flags = 0*OPAL_PM_DEC_STOP \
> @@ -840,10 +863,12 @@ void add_cpu_idle_state_properties(void)
>
> /* Variables to track buffer length */
> u8 name_buf_len;
> + u32 desc_buf_len;
> u8 num_supported_idle_states;
>
> /* Buffers to hold idle state properties */
> char *name_buf, *alloced_name_buf;
> + char *desc_buf, *alloced_desc_buf;
> u32 *latency_ns_buf;
> u32 *residency_ns_buf;
> u32 *flags_buf;
> @@ -949,15 +974,18 @@ void add_cpu_idle_state_properties(void)
> */
>
> /* Allocate memory to idle state property buffers. */
> - alloced_name_buf= malloc(nr_states * sizeof(char) * MAX_NAME_LEN);
> + alloced_name_buf = malloc(nr_states * sizeof(char) * MAX_NAME_LEN);
> name_buf = alloced_name_buf;
> + alloced_desc_buf = malloc(nr_states * sizeof(char) * MAX_DESC_LEN);
> + desc_buf = alloced_desc_buf;
> latency_ns_buf = malloc(nr_states * sizeof(u32));
> - residency_ns_buf= malloc(nr_states * sizeof(u32));
> - flags_buf = malloc(nr_states * sizeof(u32));
> - pm_ctrl_reg_val_buf = malloc(nr_states * sizeof(u64));
> - pm_ctrl_reg_mask_buf = malloc(nr_states * sizeof(u64));
> + residency_ns_buf = malloc(nr_states * sizeof(u32));
> + flags_buf = malloc(nr_states * sizeof(u32));
> + pm_ctrl_reg_val_buf = malloc(nr_states * sizeof(u64));
> + pm_ctrl_reg_mask_buf = malloc(nr_states * sizeof(u64));
>
> name_buf_len = 0;
> + desc_buf_len = 0;
> num_supported_idle_states = 0;
>
> /*
> @@ -1021,6 +1049,9 @@ void add_cpu_idle_state_properties(void)
> strncpy(name_buf, states[i].name, MAX_NAME_LEN);
> name_buf = name_buf + strlen(states[i].name) + 1;
>
> + strncpy(desc_buf, states[i].desc, MAX_DESC_LEN);
> + desc_buf = desc_buf + strlen(states[i].desc) + 1;
> +
> *latency_ns_buf = cpu_to_fdt32(states[i].latency_ns);
> latency_ns_buf++;
>
> @@ -1038,12 +1069,14 @@ void add_cpu_idle_state_properties(void)
>
> /* Increment buffer length trackers */
> name_buf_len += strlen(states[i].name) + 1;
> + desc_buf_len += strlen(states[i].name) + 1;
> num_supported_idle_states++;
>
> }
>
> /* Point buffer pointers back to beginning of the buffer */
> name_buf -= name_buf_len;
> + desc_buf -= desc_buf_len;
> latency_ns_buf -= num_supported_idle_states;
> residency_ns_buf -= num_supported_idle_states;
> flags_buf -= num_supported_idle_states;
> @@ -1051,7 +1084,9 @@ void add_cpu_idle_state_properties(void)
> pm_ctrl_reg_mask_buf -= num_supported_idle_states;
> /* Create dt properties with the buffer content */
> dt_add_property(power_mgt, "ibm,cpu-idle-state-names", name_buf,
> - name_buf_len* sizeof(char));
> + name_buf_len * sizeof(char));
> + dt_add_property(power_mgt, "ibm,cpu-idle-state-descs", desc_buf,
> + desc_buf_len * sizeof(char));
> dt_add_property(power_mgt, "ibm,cpu-idle-state-latencies-ns",
> latency_ns_buf, num_supported_idle_states * sizeof(u32));
> dt_add_property(power_mgt, "ibm,cpu-idle-state-residency-ns",
> @@ -1075,7 +1110,9 @@ void add_cpu_idle_state_properties(void)
> num_supported_idle_states * sizeof(u64));
> }
> assert(alloced_name_buf == name_buf);
> + assert(alloced_desc_buf == desc_buf);
> free(alloced_name_buf);
> + free(alloced_desc_buf);
> free(latency_ns_buf);
> free(residency_ns_buf);
> free(flags_buf);
More information about the Skiboot
mailing list