diff mbox

[RFC,16/27] ARM: cpuidle: Record the next wakeup event of the CPU

Message ID 1447799871-56374-17-git-send-email-lina.iyer@linaro.org (mailing list archive)
State New, archived
Headers show

Commit Message

Lina Iyer Nov. 17, 2015, 10:37 p.m. UTC
Reading the next wakeup of the CPU can only be realiably done only from
that CPU. In the idle enter path record the next wake up of the CPU. The
information is useful to determine the sleep time left for the CPU.

Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
---
 drivers/cpuidle/cpuidle-arm.c | 5 +++++
 1 file changed, 5 insertions(+)

Comments

Kevin Hilman Nov. 19, 2015, 11:35 p.m. UTC | #1
Lina Iyer <lina.iyer@linaro.org> writes:

> Reading the next wakeup of the CPU can only be realiably done only from
> that CPU. In the idle enter path record the next wake up of the CPU. The
> information is useful to determine the sleep time left for the CPU.
>
> Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
> ---
>  drivers/cpuidle/cpuidle-arm.c | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c
> index 8e72a23..b3133ef 100644
> --- a/drivers/cpuidle/cpuidle-arm.c
> +++ b/drivers/cpuidle/cpuidle-arm.c
> @@ -18,9 +18,11 @@
>  #include <linux/kernel.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
> +#include <linux/pm_domain.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/slab.h>
>  #include <linux/rcupdate.h>
> +#include <linux/tick.h>
>  
>  #include <asm/cpuidle.h>
>  
> @@ -49,7 +51,9 @@ static int arm_enter_idle_state(struct cpuidle_device *dev,
>  	ret = cpu_pm_enter();
>  	if (!ret) {
>  		struct device *cpu_dev = get_cpu_device(dev->cpu);
> +		struct generic_pm_domain_data *gpd = dev_gpd_data(cpu_dev);
>  
> +		gpd->td.next_wakeup = tick_nohz_get_next_wakeup();
>  		RCU_NONIDLE(pm_runtime_put_sync_suspend(cpu_dev));

Maybe set this back to zero atomicaly, after wakeup?

Checking for non-zero that might be another way for the domain goveror that there
haven't been any CPU wakeups since the CPUs have gone idle.

Kevin
Lina Iyer Nov. 20, 2015, 4:28 p.m. UTC | #2
On Thu, Nov 19 2015 at 16:35 -0700, Kevin Hilman wrote:
>Lina Iyer <lina.iyer@linaro.org> writes:
>
>> Reading the next wakeup of the CPU can only be realiably done only from
>> that CPU. In the idle enter path record the next wake up of the CPU. The
>> information is useful to determine the sleep time left for the CPU.
>>
>> Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
>> ---
>>  drivers/cpuidle/cpuidle-arm.c | 5 +++++
>>  1 file changed, 5 insertions(+)
>>
>> diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c
>> index 8e72a23..b3133ef 100644
>> --- a/drivers/cpuidle/cpuidle-arm.c
>> +++ b/drivers/cpuidle/cpuidle-arm.c
>> @@ -18,9 +18,11 @@
>>  #include <linux/kernel.h>
>>  #include <linux/module.h>
>>  #include <linux/of.h>
>> +#include <linux/pm_domain.h>
>>  #include <linux/pm_runtime.h>
>>  #include <linux/slab.h>
>>  #include <linux/rcupdate.h>
>> +#include <linux/tick.h>
>>
>>  #include <asm/cpuidle.h>
>>
>> @@ -49,7 +51,9 @@ static int arm_enter_idle_state(struct cpuidle_device *dev,
>>  	ret = cpu_pm_enter();
>>  	if (!ret) {
>>  		struct device *cpu_dev = get_cpu_device(dev->cpu);
>> +		struct generic_pm_domain_data *gpd = dev_gpd_data(cpu_dev);
>>
>> +		gpd->td.next_wakeup = tick_nohz_get_next_wakeup();
>>  		RCU_NONIDLE(pm_runtime_put_sync_suspend(cpu_dev));
>
>Maybe set this back to zero atomicaly, after wakeup?
>
>Checking for non-zero that might be another way for the domain goveror that there
>haven't been any CPU wakeups since the CPUs have gone idle.
>
I set it to 0 below.

The reference counting by the GET_PUT tells the domain if a device is
suspended. I see that as a redudant information. May be I am not getting
your point.

-- Lina
>Kevin
Kevin Hilman Nov. 24, 2015, 6:29 p.m. UTC | #3
Lina Iyer <lina.iyer@linaro.org> writes:

> On Thu, Nov 19 2015 at 16:35 -0700, Kevin Hilman wrote:
>>Lina Iyer <lina.iyer@linaro.org> writes:
>>
>>> Reading the next wakeup of the CPU can only be realiably done only from
>>> that CPU. In the idle enter path record the next wake up of the CPU. The
>>> information is useful to determine the sleep time left for the CPU.
>>>
>>> Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
>>> ---
>>>  drivers/cpuidle/cpuidle-arm.c | 5 +++++
>>>  1 file changed, 5 insertions(+)
>>>
>>> diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c
>>> index 8e72a23..b3133ef 100644
>>> --- a/drivers/cpuidle/cpuidle-arm.c
>>> +++ b/drivers/cpuidle/cpuidle-arm.c
>>> @@ -18,9 +18,11 @@
>>>  #include <linux/kernel.h>
>>>  #include <linux/module.h>
>>>  #include <linux/of.h>
>>> +#include <linux/pm_domain.h>
>>>  #include <linux/pm_runtime.h>
>>>  #include <linux/slab.h>
>>>  #include <linux/rcupdate.h>
>>> +#include <linux/tick.h>
>>>
>>>  #include <asm/cpuidle.h>
>>>
>>> @@ -49,7 +51,9 @@ static int arm_enter_idle_state(struct cpuidle_device *dev,
>>>  	ret = cpu_pm_enter();
>>>  	if (!ret) {
>>>  		struct device *cpu_dev = get_cpu_device(dev->cpu);
>>> +		struct generic_pm_domain_data *gpd = dev_gpd_data(cpu_dev);
>>>
>>> +		gpd->td.next_wakeup = tick_nohz_get_next_wakeup();
>>>  		RCU_NONIDLE(pm_runtime_put_sync_suspend(cpu_dev));
>>
>>Maybe set this back to zero atomicaly, after wakeup?
>>
>>Checking for non-zero that might be another way for the domain goveror that there
>>haven't been any CPU wakeups since the CPUs have gone idle.
>>
> I set it to 0 below.

Oops, you're right.  Not sure how I missed that.

> The reference counting by the GET_PUT tells the domain if a device is
> suspended. I see that as a redudant information. May be I am not getting
> your point.

It's redundant, but may be helpful in detecting races.  e.g. domain is
being powered off and CPU wakes up and sets this zero, but runtime PM
layers haven't been called yet so dev->power->usage_count is still zero.

Kevin
diff mbox

Patch

diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c
index 8e72a23..b3133ef 100644
--- a/drivers/cpuidle/cpuidle-arm.c
+++ b/drivers/cpuidle/cpuidle-arm.c
@@ -18,9 +18,11 @@ 
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
 #include <linux/rcupdate.h>
+#include <linux/tick.h>
 
 #include <asm/cpuidle.h>
 
@@ -49,7 +51,9 @@  static int arm_enter_idle_state(struct cpuidle_device *dev,
 	ret = cpu_pm_enter();
 	if (!ret) {
 		struct device *cpu_dev = get_cpu_device(dev->cpu);
+		struct generic_pm_domain_data *gpd = dev_gpd_data(cpu_dev);
 
+		gpd->td.next_wakeup = tick_nohz_get_next_wakeup();
 		RCU_NONIDLE(pm_runtime_put_sync_suspend(cpu_dev));
 
 		/*
@@ -60,6 +64,7 @@  static int arm_enter_idle_state(struct cpuidle_device *dev,
 		arm_cpuidle_suspend(idx);
 
 		RCU_NONIDLE(pm_runtime_get_sync(cpu_dev));
+		gpd->td.next_wakeup.tv64 = 0;
 		cpu_pm_exit();
 	}