[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