All of lore.kernel.org
 help / color / mirror / Atom feed
From: zhuguangqing83@gmail.com
To: amit.kachhap@gmail.com, daniel.lezcano@linaro.org,
	viresh.kumar@linaro.org, javi.merino@kernel.org,
	rui.zhang@intel.com, amitk@kernel.org
Cc: linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org,
	zhuguangqing <zhuguangqing@xiaomi.com>
Subject: [PATCH] thermal/drivers/cpuidle_cooling: Change the latency limit
Date: Sat, 19 Sep 2020 12:47:25 +0800	[thread overview]
Message-ID: <20200919044725.2148-1-zhuguangqing83@gmail.com> (raw)

From: zhuguangqing <zhuguangqing@xiaomi.com>

The injected idle duration must be greater than the wake up latency
(entry + exit latency) or the idle state target residency (or  min
residency), otherwise we end up consuming more energy and potentially
invert the mitigation effect.

In function idle_inject_fn(), we call play_idle_precise() to specify
a latency limit which is finally used in find_deepest_state() to find
the deepest idle state. Although the latency limit is compared with
s->exit_latency_ns in find_deepest_state(), it should not be exit
latency, but the idle duraion minus entry latency which can ensure
that the injected idle duration is greater than the wake up latency
(entry + exit latency).

There are two timers in idle inject process, the length of the first
timer (timer_1) is idle duration, and the length of the second timer
(timer_2) is idle duration plus run duration. When timer_2 expires,
it's restarted and idle_inject_timer_fn() is called and it wakes up
idle injection tasks associated with the timer and they, in turn,
invoke play_idle_precise() to inject a specified amount (idle duration)
of CPU idle time. The major functions called are as follows:

play_idle_precise() ->
 do_idle() ->
  cpuidle_idle_call() ->
   cpuidle_find_deepest_state() ->
    find_deepest_state()

When we call find_deepest_state(), some time has been consumed from
the beginning of the idle duration which could be considered the
entry latency approximately, so the latency limit should be the idle
duraion minus entry latency which can ensure that the injected idle
duration is greater than the wake up latency (entry + exit latency).

Here are two sample scenes,
scene   entry latency(us)    exit latency(us)    idle duration(us)
1            500                     600               1000
2            500                     600               3000

In scene 1, if we use exit latency (600us) for the latency limit,
we may find a idle state which has a exit latency equal to or less
than 600us, suppose the idle state's exit latency is equal to 600us,
then the wake up latency (entry + exit latency) is greater than idle
duration.

In scene 2, if we use exit latency (600us) for the latency limit,
we may also find a idle state which has a exit latency equal to
600us. But if we use the idle duraion minus entry latency
(3000 - 500 = 2500us), we can find a deeper idle state to save
more power in idle duration.

Signed-off-by: zhuguangqing <zhuguangqing@xiaomi.com>
---
 drivers/thermal/cpuidle_cooling.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/thermal/cpuidle_cooling.c b/drivers/thermal/cpuidle_cooling.c
index 78e3e8238116..6f78c7816fcc 100644
--- a/drivers/thermal/cpuidle_cooling.c
+++ b/drivers/thermal/cpuidle_cooling.c
@@ -174,6 +174,7 @@ static int __cpuidle_cooling_register(struct device_node *np,
 	struct idle_inject_device *ii_dev;
 	struct cpuidle_cooling_device *idle_cdev;
 	struct thermal_cooling_device *cdev;
+	unsigned int entry_latency_us;
 	unsigned int idle_duration_us = TICK_USEC;
 	unsigned int latency_us = UINT_MAX;
 	char dev_name[THERMAL_NAME_LENGTH];
@@ -198,7 +199,9 @@ static int __cpuidle_cooling_register(struct device_node *np,
 	}
 
 	of_property_read_u32(np, "duration-us", &idle_duration_us);
-	of_property_read_u32(np, "exit-latency-us", &latency_us);
+	if (!of_property_read_u32(np, "entry-latency-us", &entry_latency_us) &&
+	    idle_duration_us > entry_latency_us)
+		latency_us = idle_duration_us - entry_latency_us;
 
 	idle_inject_set_duration(ii_dev, TICK_USEC, idle_duration_us);
 	idle_inject_set_latency(ii_dev, latency_us);
-- 
2.17.1


                 reply	other threads:[~2020-09-19  4:47 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200919044725.2148-1-zhuguangqing83@gmail.com \
    --to=zhuguangqing83@gmail.com \
    --cc=amit.kachhap@gmail.com \
    --cc=amitk@kernel.org \
    --cc=daniel.lezcano@linaro.org \
    --cc=javi.merino@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=rui.zhang@intel.com \
    --cc=viresh.kumar@linaro.org \
    --cc=zhuguangqing@xiaomi.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.