* [PATCH 1/2] cpuidle: add hotplug support to initialize the timer broadcast
@ 2013-07-30 13:54 Daniel Lezcano
2013-07-30 13:54 ` [PATCH 2/2] x86: cpuidle: remove broadcast timer initialization Daniel Lezcano
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Daniel Lezcano @ 2013-07-30 13:54 UTC (permalink / raw)
To: rjw, lenb; +Cc: linux-pm, patches, linaro-kernel
Commit 89878baa73f0f1c679355006bd8632e5d78f96c2 introduced the flag
CPUIDLE_FLAG_TIMER_STOP where we specify a specific idle state stops the local
timer.
Commit a06df062a189a8d5588babb8bf0bb78672497798 introduced the initialization
of the timer broadcast framework depending of the flag presence.
If a system is booted with some cpus offline, by setting for example, maxcpus=1
in the kernel command line, and then they are set online, the timer broadcast
won't be setup automatically.
Fix this by adding the cpu hotplug notifier and enable/disable the timer
broadcast automatically. So no need to handle that at the arch specific driver
level like eg. intel_idle does.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
drivers/cpuidle/driver.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c
index 3ac499d..e976994 100644
--- a/drivers/cpuidle/driver.c
+++ b/drivers/cpuidle/driver.c
@@ -10,6 +10,7 @@
#include <linux/mutex.h>
#include <linux/module.h>
+#include <linux/cpu.h>
#include <linux/cpuidle.h>
#include <linux/cpumask.h>
#include <linux/clockchips.h>
@@ -147,6 +148,48 @@ static void cpuidle_setup_broadcast_timer(void *arg)
}
/**
+ * cpuidle_hotplug_notify: notifier callback when a cpu is onlined/offlined
+ * @n: the notifier block
+ * @action: an unsigned long giving the event related to the notification
+ * @hcpu: a void pointer but used as the cpu number which the event is related
+ *
+ * The kernel can boot with some cpus offline, we have to init the timer
+ * broadcast for these cpus when they are onlined. Also we have to disable
+ * the timer broadcast when the cpu is down.
+ *
+ * Returns NOTIFY_OK
+ */
+static int cpuidle_hotplug_notify(struct notifier_block *n,
+ unsigned long action, void *hcpu)
+{
+ int cpu = (unsigned long)hcpu;
+ struct cpuidle_driver *drv;
+
+ drv = __cpuidle_get_cpu_driver(cpu);
+ if (!drv || !drv->bctimer)
+ goto out;
+
+ switch (action & 0xf) {
+ case CPU_ONLINE:
+ smp_call_function_single(cpu, cpuidle_setup_broadcast_timer,
+ (void *)CLOCK_EVT_NOTIFY_BROADCAST_ON,
+ 1);
+ break;
+ case CPU_DEAD:
+ smp_call_function_single(cpu, cpuidle_setup_broadcast_timer,
+ (void *)CLOCK_EVT_NOTIFY_BROADCAST_OFF,
+ 1);
+ break;
+ }
+out:
+ return NOTIFY_OK;
+}
+
+static struct notifier_block cpuidle_hotplug_notifier = {
+ .notifier_call = cpuidle_hotplug_notify,
+};
+
+/**
* __cpuidle_driver_init - initialize the driver's internal data
* @drv: a valid pointer to a struct cpuidle_driver
*
@@ -262,6 +305,9 @@ int cpuidle_register_driver(struct cpuidle_driver *drv)
ret = __cpuidle_register_driver(drv);
spin_unlock(&cpuidle_driver_lock);
+ if (!ret)
+ ret = register_cpu_notifier(&cpuidle_hotplug_notifier);
+
return ret;
}
EXPORT_SYMBOL_GPL(cpuidle_register_driver);
@@ -276,6 +322,8 @@ EXPORT_SYMBOL_GPL(cpuidle_register_driver);
*/
void cpuidle_unregister_driver(struct cpuidle_driver *drv)
{
+ unregister_cpu_notifier(&cpuidle_hotplug_notifier);
+
spin_lock(&cpuidle_driver_lock);
__cpuidle_unregister_driver(drv);
spin_unlock(&cpuidle_driver_lock);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/2] x86: cpuidle: remove broadcast timer initialization
2013-07-30 13:54 [PATCH 1/2] cpuidle: add hotplug support to initialize the timer broadcast Daniel Lezcano
@ 2013-07-30 13:54 ` Daniel Lezcano
2013-08-20 14:11 ` Rafael J. Wysocki
2013-08-06 8:36 ` [PATCH 1/2] cpuidle: add hotplug support to initialize the timer broadcast Daniel Lezcano
2013-08-20 14:07 ` Rafael J. Wysocki
2 siblings, 1 reply; 9+ messages in thread
From: Daniel Lezcano @ 2013-07-30 13:54 UTC (permalink / raw)
To: rjw, lenb; +Cc: linux-pm, patches, linaro-kernel
Commit 89878baa73f0f1c679355006bd8632e5d78f96c2 introduced the flag
CPUIDLE_FLAG_TIMER_STOP where we specify a specific idle state stops the local
timer.
Commit a06df062a189a8d5588babb8bf0bb78672497798 introduced the initialization
of the timer broadcast framework depending of the flag presence.
We have now a way to set a flag for a specific state to tell if the local timer
will be down in deep idle state or not and we have cpu hotplug support to setup
the broadcast timer.
Remove the timer broadcast initialization from init and at the cpu hotplug
time.
Remove the timer broadcast activation in the idle loop.
Remove the bitmap LAPIC_TIMER_ALWAYS_RELIABLE.
Set the CPUIDLE_FLAG_TIMER_STOP on the states when they are greater than C1 and
the cpu has not X86_FEATURE_ARAT.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
drivers/idle/intel_idle.c | 41 ++++-------------------------------------
1 file changed, 4 insertions(+), 37 deletions(-)
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index fa6964d..a975868 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -55,7 +55,6 @@
#include <linux/kernel.h>
#include <linux/cpuidle.h>
-#include <linux/clockchips.h>
#include <trace/events/power.h>
#include <linux/sched.h>
#include <linux/notifier.h>
@@ -77,10 +76,6 @@ static int max_cstate = CPUIDLE_STATE_MAX - 1;
static unsigned int mwait_substates;
-#define LAPIC_TIMER_ALWAYS_RELIABLE 0xFFFFFFFF
-/* Reliable LAPIC Timer States, bit 1 for C1 etc. */
-static unsigned int lapic_timer_reliable_states = (1 << 1); /* Default to only C1 */
-
struct idle_cpu {
struct cpuidle_state *state_table;
@@ -356,9 +351,6 @@ static int intel_idle(struct cpuidle_device *dev,
if (state->flags & CPUIDLE_FLAG_TLB_FLUSHED)
leave_mm(cpu);
- if (!(lapic_timer_reliable_states & (1 << (cstate))))
- clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
-
if (!need_resched()) {
__monitor((void *)¤t_thread_info()->flags, 0, 0);
@@ -367,23 +359,9 @@ static int intel_idle(struct cpuidle_device *dev,
__mwait(eax, ecx);
}
- if (!(lapic_timer_reliable_states & (1 << (cstate))))
- clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
-
return index;
}
-static void __setup_broadcast_timer(void *arg)
-{
- unsigned long reason = (unsigned long)arg;
- int cpu = smp_processor_id();
-
- reason = reason ?
- CLOCK_EVT_NOTIFY_BROADCAST_ON : CLOCK_EVT_NOTIFY_BROADCAST_OFF;
-
- clockevents_notify(reason, &cpu);
-}
-
static int cpu_hotplug_notify(struct notifier_block *n,
unsigned long action, void *hcpu)
{
@@ -393,10 +371,6 @@ static int cpu_hotplug_notify(struct notifier_block *n,
switch (action & 0xf) {
case CPU_ONLINE:
- if (lapic_timer_reliable_states != LAPIC_TIMER_ALWAYS_RELIABLE)
- smp_call_function_single(hotcpu, __setup_broadcast_timer,
- (void *)true, 1);
-
/*
* Some systems can hotplug a cpu at runtime after
* the kernel has booted, we have to initialize the
@@ -524,16 +498,9 @@ static int intel_idle_probe(void)
icpu = (const struct idle_cpu *)id->driver_data;
cpuidle_state_table = icpu->state_table;
- if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */
- lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE;
- else
- on_each_cpu(__setup_broadcast_timer, (void *)true, 1);
-
pr_debug(PREFIX "v" INTEL_IDLE_VERSION
" model 0x%X\n", boot_cpu_data.x86_model);
- pr_debug(PREFIX "lapic_timer_reliable_states 0x%x\n",
- lapic_timer_reliable_states);
return 0;
}
@@ -594,6 +561,10 @@ static int intel_idle_cpuidle_driver_init(void)
mark_tsc_unstable("TSC halts in idle"
" states deeper than C2");
+ if (cstate > 1 && !boot_cpu_has(X86_FEATURE_ARAT))
+ cpuidle_state_table[cstate].flags |=
+ CPUIDLE_FLAG_TIMER_STOP;
+
drv->states[drv->state_count] = /* structure copy */
cpuidle_state_table[cstate];
@@ -705,10 +676,6 @@ static void __exit intel_idle_exit(void)
{
intel_idle_cpuidle_devices_uninit();
cpuidle_unregister_driver(&intel_idle_driver);
-
-
- if (lapic_timer_reliable_states != LAPIC_TIMER_ALWAYS_RELIABLE)
- on_each_cpu(__setup_broadcast_timer, (void *)false, 1);
unregister_cpu_notifier(&cpu_hotplug_notifier);
return;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] cpuidle: add hotplug support to initialize the timer broadcast
2013-07-30 13:54 [PATCH 1/2] cpuidle: add hotplug support to initialize the timer broadcast Daniel Lezcano
2013-07-30 13:54 ` [PATCH 2/2] x86: cpuidle: remove broadcast timer initialization Daniel Lezcano
@ 2013-08-06 8:36 ` Daniel Lezcano
2013-08-06 14:10 ` Rafael J. Wysocki
2013-08-20 14:07 ` Rafael J. Wysocki
2 siblings, 1 reply; 9+ messages in thread
From: Daniel Lezcano @ 2013-08-06 8:36 UTC (permalink / raw)
To: rjw@sisk.pl, lenb; +Cc: linux-pm, patches, linaro-kernel, Rafael J. Wysocki
On 07/30/2013 03:54 PM, Daniel Lezcano wrote:
> Commit 89878baa73f0f1c679355006bd8632e5d78f96c2 introduced the flag
> CPUIDLE_FLAG_TIMER_STOP where we specify a specific idle state stops the local
> timer.
>
> Commit a06df062a189a8d5588babb8bf0bb78672497798 introduced the initialization
> of the timer broadcast framework depending of the flag presence.
>
> If a system is booted with some cpus offline, by setting for example, maxcpus=1
> in the kernel command line, and then they are set online, the timer broadcast
> won't be setup automatically.
>
> Fix this by adding the cpu hotplug notifier and enable/disable the timer
> broadcast automatically. So no need to handle that at the arch specific driver
> level like eg. intel_idle does.
>
> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> ---
Len, Rafael,
any comment on these two patches ?
Thanks
-- Daniel
> drivers/cpuidle/driver.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 48 insertions(+)
>
> diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c
> index 3ac499d..e976994 100644
> --- a/drivers/cpuidle/driver.c
> +++ b/drivers/cpuidle/driver.c
> @@ -10,6 +10,7 @@
>
> #include <linux/mutex.h>
> #include <linux/module.h>
> +#include <linux/cpu.h>
> #include <linux/cpuidle.h>
> #include <linux/cpumask.h>
> #include <linux/clockchips.h>
> @@ -147,6 +148,48 @@ static void cpuidle_setup_broadcast_timer(void *arg)
> }
>
> /**
> + * cpuidle_hotplug_notify: notifier callback when a cpu is onlined/offlined
> + * @n: the notifier block
> + * @action: an unsigned long giving the event related to the notification
> + * @hcpu: a void pointer but used as the cpu number which the event is related
> + *
> + * The kernel can boot with some cpus offline, we have to init the timer
> + * broadcast for these cpus when they are onlined. Also we have to disable
> + * the timer broadcast when the cpu is down.
> + *
> + * Returns NOTIFY_OK
> + */
> +static int cpuidle_hotplug_notify(struct notifier_block *n,
> + unsigned long action, void *hcpu)
> +{
> + int cpu = (unsigned long)hcpu;
> + struct cpuidle_driver *drv;
> +
> + drv = __cpuidle_get_cpu_driver(cpu);
> + if (!drv || !drv->bctimer)
> + goto out;
> +
> + switch (action & 0xf) {
> + case CPU_ONLINE:
> + smp_call_function_single(cpu, cpuidle_setup_broadcast_timer,
> + (void *)CLOCK_EVT_NOTIFY_BROADCAST_ON,
> + 1);
> + break;
> + case CPU_DEAD:
> + smp_call_function_single(cpu, cpuidle_setup_broadcast_timer,
> + (void *)CLOCK_EVT_NOTIFY_BROADCAST_OFF,
> + 1);
> + break;
> + }
> +out:
> + return NOTIFY_OK;
> +}
> +
> +static struct notifier_block cpuidle_hotplug_notifier = {
> + .notifier_call = cpuidle_hotplug_notify,
> +};
> +
> +/**
> * __cpuidle_driver_init - initialize the driver's internal data
> * @drv: a valid pointer to a struct cpuidle_driver
> *
> @@ -262,6 +305,9 @@ int cpuidle_register_driver(struct cpuidle_driver *drv)
> ret = __cpuidle_register_driver(drv);
> spin_unlock(&cpuidle_driver_lock);
>
> + if (!ret)
> + ret = register_cpu_notifier(&cpuidle_hotplug_notifier);
> +
> return ret;
> }
> EXPORT_SYMBOL_GPL(cpuidle_register_driver);
> @@ -276,6 +322,8 @@ EXPORT_SYMBOL_GPL(cpuidle_register_driver);
> */
> void cpuidle_unregister_driver(struct cpuidle_driver *drv)
> {
> + unregister_cpu_notifier(&cpuidle_hotplug_notifier);
> +
> spin_lock(&cpuidle_driver_lock);
> __cpuidle_unregister_driver(drv);
> spin_unlock(&cpuidle_driver_lock);
>
--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] cpuidle: add hotplug support to initialize the timer broadcast
2013-08-06 8:36 ` [PATCH 1/2] cpuidle: add hotplug support to initialize the timer broadcast Daniel Lezcano
@ 2013-08-06 14:10 ` Rafael J. Wysocki
2013-08-06 14:11 ` Daniel Lezcano
0 siblings, 1 reply; 9+ messages in thread
From: Rafael J. Wysocki @ 2013-08-06 14:10 UTC (permalink / raw)
To: Daniel Lezcano; +Cc: lenb, linux-pm, patches, linaro-kernel
On Tuesday, August 06, 2013 10:36:21 AM Daniel Lezcano wrote:
> On 07/30/2013 03:54 PM, Daniel Lezcano wrote:
> > Commit 89878baa73f0f1c679355006bd8632e5d78f96c2 introduced the flag
> > CPUIDLE_FLAG_TIMER_STOP where we specify a specific idle state stops the local
> > timer.
> >
> > Commit a06df062a189a8d5588babb8bf0bb78672497798 introduced the initialization
> > of the timer broadcast framework depending of the flag presence.
> >
> > If a system is booted with some cpus offline, by setting for example, maxcpus=1
> > in the kernel command line, and then they are set online, the timer broadcast
> > won't be setup automatically.
> >
> > Fix this by adding the cpu hotplug notifier and enable/disable the timer
> > broadcast automatically. So no need to handle that at the arch specific driver
> > level like eg. intel_idle does.
> >
> > Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> > ---
>
> Len, Rafael,
>
> any comment on these two patches ?
Honestly, I didn't have the time to look into that and Len is on vacation.
It's on my todo list, however.
Thanks,
Rafael
> > drivers/cpuidle/driver.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 48 insertions(+)
> >
> > diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c
> > index 3ac499d..e976994 100644
> > --- a/drivers/cpuidle/driver.c
> > +++ b/drivers/cpuidle/driver.c
> > @@ -10,6 +10,7 @@
> >
> > #include <linux/mutex.h>
> > #include <linux/module.h>
> > +#include <linux/cpu.h>
> > #include <linux/cpuidle.h>
> > #include <linux/cpumask.h>
> > #include <linux/clockchips.h>
> > @@ -147,6 +148,48 @@ static void cpuidle_setup_broadcast_timer(void *arg)
> > }
> >
> > /**
> > + * cpuidle_hotplug_notify: notifier callback when a cpu is onlined/offlined
> > + * @n: the notifier block
> > + * @action: an unsigned long giving the event related to the notification
> > + * @hcpu: a void pointer but used as the cpu number which the event is related
> > + *
> > + * The kernel can boot with some cpus offline, we have to init the timer
> > + * broadcast for these cpus when they are onlined. Also we have to disable
> > + * the timer broadcast when the cpu is down.
> > + *
> > + * Returns NOTIFY_OK
> > + */
> > +static int cpuidle_hotplug_notify(struct notifier_block *n,
> > + unsigned long action, void *hcpu)
> > +{
> > + int cpu = (unsigned long)hcpu;
> > + struct cpuidle_driver *drv;
> > +
> > + drv = __cpuidle_get_cpu_driver(cpu);
> > + if (!drv || !drv->bctimer)
> > + goto out;
> > +
> > + switch (action & 0xf) {
> > + case CPU_ONLINE:
> > + smp_call_function_single(cpu, cpuidle_setup_broadcast_timer,
> > + (void *)CLOCK_EVT_NOTIFY_BROADCAST_ON,
> > + 1);
> > + break;
> > + case CPU_DEAD:
> > + smp_call_function_single(cpu, cpuidle_setup_broadcast_timer,
> > + (void *)CLOCK_EVT_NOTIFY_BROADCAST_OFF,
> > + 1);
> > + break;
> > + }
> > +out:
> > + return NOTIFY_OK;
> > +}
> > +
> > +static struct notifier_block cpuidle_hotplug_notifier = {
> > + .notifier_call = cpuidle_hotplug_notify,
> > +};
> > +
> > +/**
> > * __cpuidle_driver_init - initialize the driver's internal data
> > * @drv: a valid pointer to a struct cpuidle_driver
> > *
> > @@ -262,6 +305,9 @@ int cpuidle_register_driver(struct cpuidle_driver *drv)
> > ret = __cpuidle_register_driver(drv);
> > spin_unlock(&cpuidle_driver_lock);
> >
> > + if (!ret)
> > + ret = register_cpu_notifier(&cpuidle_hotplug_notifier);
> > +
> > return ret;
> > }
> > EXPORT_SYMBOL_GPL(cpuidle_register_driver);
> > @@ -276,6 +322,8 @@ EXPORT_SYMBOL_GPL(cpuidle_register_driver);
> > */
> > void cpuidle_unregister_driver(struct cpuidle_driver *drv)
> > {
> > + unregister_cpu_notifier(&cpuidle_hotplug_notifier);
> > +
> > spin_lock(&cpuidle_driver_lock);
> > __cpuidle_unregister_driver(drv);
> > spin_unlock(&cpuidle_driver_lock);
> >
>
>
>
--
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] cpuidle: add hotplug support to initialize the timer broadcast
2013-08-06 14:10 ` Rafael J. Wysocki
@ 2013-08-06 14:11 ` Daniel Lezcano
0 siblings, 0 replies; 9+ messages in thread
From: Daniel Lezcano @ 2013-08-06 14:11 UTC (permalink / raw)
To: Rafael J. Wysocki; +Cc: lenb, linux-pm, patches, linaro-kernel
On 08/06/2013 04:10 PM, Rafael J. Wysocki wrote:
> On Tuesday, August 06, 2013 10:36:21 AM Daniel Lezcano wrote:
>> On 07/30/2013 03:54 PM, Daniel Lezcano wrote:
>>> Commit 89878baa73f0f1c679355006bd8632e5d78f96c2 introduced the flag
>>> CPUIDLE_FLAG_TIMER_STOP where we specify a specific idle state stops the local
>>> timer.
>>>
>>> Commit a06df062a189a8d5588babb8bf0bb78672497798 introduced the initialization
>>> of the timer broadcast framework depending of the flag presence.
>>>
>>> If a system is booted with some cpus offline, by setting for example, maxcpus=1
>>> in the kernel command line, and then they are set online, the timer broadcast
>>> won't be setup automatically.
>>>
>>> Fix this by adding the cpu hotplug notifier and enable/disable the timer
>>> broadcast automatically. So no need to handle that at the arch specific driver
>>> level like eg. intel_idle does.
>>>
>>> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
>>> ---
>>
>> Len, Rafael,
>>
>> any comment on these two patches ?
>
> Honestly, I didn't have the time to look into that and Len is on vacation.
>
> It's on my todo list, however.
Ah, ok. Thanks.
-- Daniel
>>> drivers/cpuidle/driver.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++
>>> 1 file changed, 48 insertions(+)
>>>
>>> diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c
>>> index 3ac499d..e976994 100644
>>> --- a/drivers/cpuidle/driver.c
>>> +++ b/drivers/cpuidle/driver.c
>>> @@ -10,6 +10,7 @@
>>>
>>> #include <linux/mutex.h>
>>> #include <linux/module.h>
>>> +#include <linux/cpu.h>
>>> #include <linux/cpuidle.h>
>>> #include <linux/cpumask.h>
>>> #include <linux/clockchips.h>
>>> @@ -147,6 +148,48 @@ static void cpuidle_setup_broadcast_timer(void *arg)
>>> }
>>>
>>> /**
>>> + * cpuidle_hotplug_notify: notifier callback when a cpu is onlined/offlined
>>> + * @n: the notifier block
>>> + * @action: an unsigned long giving the event related to the notification
>>> + * @hcpu: a void pointer but used as the cpu number which the event is related
>>> + *
>>> + * The kernel can boot with some cpus offline, we have to init the timer
>>> + * broadcast for these cpus when they are onlined. Also we have to disable
>>> + * the timer broadcast when the cpu is down.
>>> + *
>>> + * Returns NOTIFY_OK
>>> + */
>>> +static int cpuidle_hotplug_notify(struct notifier_block *n,
>>> + unsigned long action, void *hcpu)
>>> +{
>>> + int cpu = (unsigned long)hcpu;
>>> + struct cpuidle_driver *drv;
>>> +
>>> + drv = __cpuidle_get_cpu_driver(cpu);
>>> + if (!drv || !drv->bctimer)
>>> + goto out;
>>> +
>>> + switch (action & 0xf) {
>>> + case CPU_ONLINE:
>>> + smp_call_function_single(cpu, cpuidle_setup_broadcast_timer,
>>> + (void *)CLOCK_EVT_NOTIFY_BROADCAST_ON,
>>> + 1);
>>> + break;
>>> + case CPU_DEAD:
>>> + smp_call_function_single(cpu, cpuidle_setup_broadcast_timer,
>>> + (void *)CLOCK_EVT_NOTIFY_BROADCAST_OFF,
>>> + 1);
>>> + break;
>>> + }
>>> +out:
>>> + return NOTIFY_OK;
>>> +}
>>> +
>>> +static struct notifier_block cpuidle_hotplug_notifier = {
>>> + .notifier_call = cpuidle_hotplug_notify,
>>> +};
>>> +
>>> +/**
>>> * __cpuidle_driver_init - initialize the driver's internal data
>>> * @drv: a valid pointer to a struct cpuidle_driver
>>> *
>>> @@ -262,6 +305,9 @@ int cpuidle_register_driver(struct cpuidle_driver *drv)
>>> ret = __cpuidle_register_driver(drv);
>>> spin_unlock(&cpuidle_driver_lock);
>>>
>>> + if (!ret)
>>> + ret = register_cpu_notifier(&cpuidle_hotplug_notifier);
>>> +
>>> return ret;
>>> }
>>> EXPORT_SYMBOL_GPL(cpuidle_register_driver);
>>> @@ -276,6 +322,8 @@ EXPORT_SYMBOL_GPL(cpuidle_register_driver);
>>> */
>>> void cpuidle_unregister_driver(struct cpuidle_driver *drv)
>>> {
>>> + unregister_cpu_notifier(&cpuidle_hotplug_notifier);
>>> +
>>> spin_lock(&cpuidle_driver_lock);
>>> __cpuidle_unregister_driver(drv);
>>> spin_unlock(&cpuidle_driver_lock);
>>>
>>
>>
>>
--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] cpuidle: add hotplug support to initialize the timer broadcast
2013-07-30 13:54 [PATCH 1/2] cpuidle: add hotplug support to initialize the timer broadcast Daniel Lezcano
2013-07-30 13:54 ` [PATCH 2/2] x86: cpuidle: remove broadcast timer initialization Daniel Lezcano
2013-08-06 8:36 ` [PATCH 1/2] cpuidle: add hotplug support to initialize the timer broadcast Daniel Lezcano
@ 2013-08-20 14:07 ` Rafael J. Wysocki
2013-09-02 13:29 ` Daniel Lezcano
2 siblings, 1 reply; 9+ messages in thread
From: Rafael J. Wysocki @ 2013-08-20 14:07 UTC (permalink / raw)
To: Daniel Lezcano; +Cc: lenb, linux-pm, patches, linaro-kernel
On Tuesday, July 30, 2013 03:54:27 PM Daniel Lezcano wrote:
> Commit 89878baa73f0f1c679355006bd8632e5d78f96c2 introduced the flag
> CPUIDLE_FLAG_TIMER_STOP where we specify a specific idle state stops the local
> timer.
>
> Commit a06df062a189a8d5588babb8bf0bb78672497798 introduced the initialization
> of the timer broadcast framework depending of the flag presence.
>
> If a system is booted with some cpus offline, by setting for example, maxcpus=1
> in the kernel command line, and then they are set online, the timer broadcast
> won't be setup automatically.
>
> Fix this by adding the cpu hotplug notifier and enable/disable the timer
> broadcast automatically. So no need to handle that at the arch specific driver
> level like eg. intel_idle does.
>
> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> ---
> drivers/cpuidle/driver.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 48 insertions(+)
>
> diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c
> index 3ac499d..e976994 100644
> --- a/drivers/cpuidle/driver.c
> +++ b/drivers/cpuidle/driver.c
> @@ -10,6 +10,7 @@
>
> #include <linux/mutex.h>
> #include <linux/module.h>
> +#include <linux/cpu.h>
> #include <linux/cpuidle.h>
> #include <linux/cpumask.h>
> #include <linux/clockchips.h>
> @@ -147,6 +148,48 @@ static void cpuidle_setup_broadcast_timer(void *arg)
> }
>
> /**
> + * cpuidle_hotplug_notify: notifier callback when a cpu is onlined/offlined
> + * @n: the notifier block
> + * @action: an unsigned long giving the event related to the notification
> + * @hcpu: a void pointer but used as the cpu number which the event is related
> + *
> + * The kernel can boot with some cpus offline, we have to init the timer
> + * broadcast for these cpus when they are onlined. Also we have to disable
> + * the timer broadcast when the cpu is down.
> + *
> + * Returns NOTIFY_OK
> + */
> +static int cpuidle_hotplug_notify(struct notifier_block *n,
> + unsigned long action, void *hcpu)
> +{
> + int cpu = (unsigned long)hcpu;
> + struct cpuidle_driver *drv;
> +
> + drv = __cpuidle_get_cpu_driver(cpu);
> + if (!drv || !drv->bctimer)
> + goto out;
> +
> + switch (action & 0xf) {
What does the 0xf stand for?
Please always use the defined symbols in such situations.
> + case CPU_ONLINE:
> + smp_call_function_single(cpu, cpuidle_setup_broadcast_timer,
> + (void *)CLOCK_EVT_NOTIFY_BROADCAST_ON,
> + 1);
> + break;
> + case CPU_DEAD:
> + smp_call_function_single(cpu, cpuidle_setup_broadcast_timer,
> + (void *)CLOCK_EVT_NOTIFY_BROADCAST_OFF,
> + 1);
> + break;
This code is going to be run during every system suspend and resume.
Is this intentional and if so, are you confident that it covers all of the
cases that can happen then?
> + }
> +out:
> + return NOTIFY_OK;
> +}
> +
> +static struct notifier_block cpuidle_hotplug_notifier = {
> + .notifier_call = cpuidle_hotplug_notify,
> +};
> +
> +/**
> * __cpuidle_driver_init - initialize the driver's internal data
> * @drv: a valid pointer to a struct cpuidle_driver
> *
> @@ -262,6 +305,9 @@ int cpuidle_register_driver(struct cpuidle_driver *drv)
> ret = __cpuidle_register_driver(drv);
> spin_unlock(&cpuidle_driver_lock);
>
> + if (!ret)
> + ret = register_cpu_notifier(&cpuidle_hotplug_notifier);
> +
> return ret;
> }
> EXPORT_SYMBOL_GPL(cpuidle_register_driver);
> @@ -276,6 +322,8 @@ EXPORT_SYMBOL_GPL(cpuidle_register_driver);
> */
> void cpuidle_unregister_driver(struct cpuidle_driver *drv)
> {
> + unregister_cpu_notifier(&cpuidle_hotplug_notifier);
> +
> spin_lock(&cpuidle_driver_lock);
> __cpuidle_unregister_driver(drv);
> spin_unlock(&cpuidle_driver_lock);
>
Thanks,
Rafael
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] x86: cpuidle: remove broadcast timer initialization
2013-07-30 13:54 ` [PATCH 2/2] x86: cpuidle: remove broadcast timer initialization Daniel Lezcano
@ 2013-08-20 14:11 ` Rafael J. Wysocki
2013-09-02 14:02 ` Daniel Lezcano
0 siblings, 1 reply; 9+ messages in thread
From: Rafael J. Wysocki @ 2013-08-20 14:11 UTC (permalink / raw)
To: Daniel Lezcano; +Cc: lenb, linux-pm, patches, linaro-kernel, Len Brown
On Tuesday, July 30, 2013 03:54:28 PM Daniel Lezcano wrote:
> Commit 89878baa73f0f1c679355006bd8632e5d78f96c2 introduced the flag
> CPUIDLE_FLAG_TIMER_STOP where we specify a specific idle state stops the local
> timer.
>
> Commit a06df062a189a8d5588babb8bf0bb78672497798 introduced the initialization
> of the timer broadcast framework depending of the flag presence.
>
> We have now a way to set a flag for a specific state to tell if the local timer
> will be down in deep idle state or not and we have cpu hotplug support to setup
> the broadcast timer.
So this depends on [1/2], right?
> Remove the timer broadcast initialization from init and at the cpu hotplug
> time.
>
> Remove the timer broadcast activation in the idle loop.
>
> Remove the bitmap LAPIC_TIMER_ALWAYS_RELIABLE.
>
> Set the CPUIDLE_FLAG_TIMER_STOP on the states when they are greater than C1 and
> the cpu has not X86_FEATURE_ARAT.
>
> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
I generally like the changes made by this patch, but I wonder how much it
has been tested?
The subject is slightly misleading too, because it's about the intel_idle
driver. Please put intel_idle in the subject.
Thanks,
Rafael
> ---
> drivers/idle/intel_idle.c | 41 ++++-------------------------------------
> 1 file changed, 4 insertions(+), 37 deletions(-)
>
> diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
> index fa6964d..a975868 100644
> --- a/drivers/idle/intel_idle.c
> +++ b/drivers/idle/intel_idle.c
> @@ -55,7 +55,6 @@
>
> #include <linux/kernel.h>
> #include <linux/cpuidle.h>
> -#include <linux/clockchips.h>
> #include <trace/events/power.h>
> #include <linux/sched.h>
> #include <linux/notifier.h>
> @@ -77,10 +76,6 @@ static int max_cstate = CPUIDLE_STATE_MAX - 1;
>
> static unsigned int mwait_substates;
>
> -#define LAPIC_TIMER_ALWAYS_RELIABLE 0xFFFFFFFF
> -/* Reliable LAPIC Timer States, bit 1 for C1 etc. */
> -static unsigned int lapic_timer_reliable_states = (1 << 1); /* Default to only C1 */
> -
> struct idle_cpu {
> struct cpuidle_state *state_table;
>
> @@ -356,9 +351,6 @@ static int intel_idle(struct cpuidle_device *dev,
> if (state->flags & CPUIDLE_FLAG_TLB_FLUSHED)
> leave_mm(cpu);
>
> - if (!(lapic_timer_reliable_states & (1 << (cstate))))
> - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
> -
> if (!need_resched()) {
>
> __monitor((void *)¤t_thread_info()->flags, 0, 0);
> @@ -367,23 +359,9 @@ static int intel_idle(struct cpuidle_device *dev,
> __mwait(eax, ecx);
> }
>
> - if (!(lapic_timer_reliable_states & (1 << (cstate))))
> - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
> -
> return index;
> }
>
> -static void __setup_broadcast_timer(void *arg)
> -{
> - unsigned long reason = (unsigned long)arg;
> - int cpu = smp_processor_id();
> -
> - reason = reason ?
> - CLOCK_EVT_NOTIFY_BROADCAST_ON : CLOCK_EVT_NOTIFY_BROADCAST_OFF;
> -
> - clockevents_notify(reason, &cpu);
> -}
> -
> static int cpu_hotplug_notify(struct notifier_block *n,
> unsigned long action, void *hcpu)
> {
> @@ -393,10 +371,6 @@ static int cpu_hotplug_notify(struct notifier_block *n,
> switch (action & 0xf) {
> case CPU_ONLINE:
>
> - if (lapic_timer_reliable_states != LAPIC_TIMER_ALWAYS_RELIABLE)
> - smp_call_function_single(hotcpu, __setup_broadcast_timer,
> - (void *)true, 1);
> -
> /*
> * Some systems can hotplug a cpu at runtime after
> * the kernel has booted, we have to initialize the
> @@ -524,16 +498,9 @@ static int intel_idle_probe(void)
> icpu = (const struct idle_cpu *)id->driver_data;
> cpuidle_state_table = icpu->state_table;
>
> - if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */
> - lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE;
> - else
> - on_each_cpu(__setup_broadcast_timer, (void *)true, 1);
> -
> pr_debug(PREFIX "v" INTEL_IDLE_VERSION
> " model 0x%X\n", boot_cpu_data.x86_model);
>
> - pr_debug(PREFIX "lapic_timer_reliable_states 0x%x\n",
> - lapic_timer_reliable_states);
> return 0;
> }
>
> @@ -594,6 +561,10 @@ static int intel_idle_cpuidle_driver_init(void)
> mark_tsc_unstable("TSC halts in idle"
> " states deeper than C2");
>
> + if (cstate > 1 && !boot_cpu_has(X86_FEATURE_ARAT))
> + cpuidle_state_table[cstate].flags |=
> + CPUIDLE_FLAG_TIMER_STOP;
> +
> drv->states[drv->state_count] = /* structure copy */
> cpuidle_state_table[cstate];
>
> @@ -705,10 +676,6 @@ static void __exit intel_idle_exit(void)
> {
> intel_idle_cpuidle_devices_uninit();
> cpuidle_unregister_driver(&intel_idle_driver);
> -
> -
> - if (lapic_timer_reliable_states != LAPIC_TIMER_ALWAYS_RELIABLE)
> - on_each_cpu(__setup_broadcast_timer, (void *)false, 1);
> unregister_cpu_notifier(&cpu_hotplug_notifier);
>
> return;
>
--
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] cpuidle: add hotplug support to initialize the timer broadcast
2013-08-20 14:07 ` Rafael J. Wysocki
@ 2013-09-02 13:29 ` Daniel Lezcano
0 siblings, 0 replies; 9+ messages in thread
From: Daniel Lezcano @ 2013-09-02 13:29 UTC (permalink / raw)
To: Rafael J. Wysocki; +Cc: lenb, linux-pm, patches, linaro-kernel
On 08/20/2013 04:07 PM, Rafael J. Wysocki wrote:
> On Tuesday, July 30, 2013 03:54:27 PM Daniel Lezcano wrote:
>> Commit 89878baa73f0f1c679355006bd8632e5d78f96c2 introduced the flag
>> CPUIDLE_FLAG_TIMER_STOP where we specify a specific idle state stops the local
>> timer.
>>
>> Commit a06df062a189a8d5588babb8bf0bb78672497798 introduced the initialization
>> of the timer broadcast framework depending of the flag presence.
>>
>> If a system is booted with some cpus offline, by setting for example, maxcpus=1
>> in the kernel command line, and then they are set online, the timer broadcast
>> won't be setup automatically.
>>
>> Fix this by adding the cpu hotplug notifier and enable/disable the timer
>> broadcast automatically. So no need to handle that at the arch specific driver
>> level like eg. intel_idle does.
>>
>> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
>> ---
>> drivers/cpuidle/driver.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 48 insertions(+)
>>
>> diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c
>> index 3ac499d..e976994 100644
>> --- a/drivers/cpuidle/driver.c
>> +++ b/drivers/cpuidle/driver.c
>> @@ -10,6 +10,7 @@
>>
>> #include <linux/mutex.h>
>> #include <linux/module.h>
>> +#include <linux/cpu.h>
>> #include <linux/cpuidle.h>
>> #include <linux/cpumask.h>
>> #include <linux/clockchips.h>
>> @@ -147,6 +148,48 @@ static void cpuidle_setup_broadcast_timer(void *arg)
>> }
>>
>> /**
>> + * cpuidle_hotplug_notify: notifier callback when a cpu is onlined/offlined
>> + * @n: the notifier block
>> + * @action: an unsigned long giving the event related to the notification
>> + * @hcpu: a void pointer but used as the cpu number which the event is related
>> + *
>> + * The kernel can boot with some cpus offline, we have to init the timer
>> + * broadcast for these cpus when they are onlined. Also we have to disable
>> + * the timer broadcast when the cpu is down.
>> + *
>> + * Returns NOTIFY_OK
>> + */
>> +static int cpuidle_hotplug_notify(struct notifier_block *n,
>> + unsigned long action, void *hcpu)
>> +{
>> + int cpu = (unsigned long)hcpu;
>> + struct cpuidle_driver *drv;
>> +
>> + drv = __cpuidle_get_cpu_driver(cpu);
>> + if (!drv || !drv->bctimer)
>> + goto out;
>> +
>> + switch (action & 0xf) {
>
> What does the 0xf stand for?
>
> Please always use the defined symbols in such situations.
Ok, sure.
>> + case CPU_ONLINE:
>> + smp_call_function_single(cpu, cpuidle_setup_broadcast_timer,
>> + (void *)CLOCK_EVT_NOTIFY_BROADCAST_ON,
>> + 1);
>> + break;
>> + case CPU_DEAD:
>> + smp_call_function_single(cpu, cpuidle_setup_broadcast_timer,
>> + (void *)CLOCK_EVT_NOTIFY_BROADCAST_OFF,
>> + 1);
>> + break;
>
> This code is going to be run during every system suspend and resume.
> Is this intentional and if so, are you confident that it covers all of the
> cases that can happen then?
Actually there is a very similar code in the intel_idle driver but only
for CPU_ONLINE. This code is called with cpu hotplug also.
I tested by plug/unplug the cpus without problem on a intel i5.
>> + }
>> +out:
>> + return NOTIFY_OK;
>> +}
>> +
>> +static struct notifier_block cpuidle_hotplug_notifier = {
>> + .notifier_call = cpuidle_hotplug_notify,
>> +};
>> +
>> +/**
>> * __cpuidle_driver_init - initialize the driver's internal data
>> * @drv: a valid pointer to a struct cpuidle_driver
>> *
>> @@ -262,6 +305,9 @@ int cpuidle_register_driver(struct cpuidle_driver *drv)
>> ret = __cpuidle_register_driver(drv);
>> spin_unlock(&cpuidle_driver_lock);
>>
>> + if (!ret)
>> + ret = register_cpu_notifier(&cpuidle_hotplug_notifier);
>> +
>> return ret;
>> }
>> EXPORT_SYMBOL_GPL(cpuidle_register_driver);
>> @@ -276,6 +322,8 @@ EXPORT_SYMBOL_GPL(cpuidle_register_driver);
>> */
>> void cpuidle_unregister_driver(struct cpuidle_driver *drv)
>> {
>> + unregister_cpu_notifier(&cpuidle_hotplug_notifier);
>> +
>> spin_lock(&cpuidle_driver_lock);
>> __cpuidle_unregister_driver(drv);
>> spin_unlock(&cpuidle_driver_lock);
>>
>
> Thanks,
> Rafael
>
--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] x86: cpuidle: remove broadcast timer initialization
2013-08-20 14:11 ` Rafael J. Wysocki
@ 2013-09-02 14:02 ` Daniel Lezcano
0 siblings, 0 replies; 9+ messages in thread
From: Daniel Lezcano @ 2013-09-02 14:02 UTC (permalink / raw)
To: Rafael J. Wysocki; +Cc: lenb, linux-pm, patches, linaro-kernel, Len Brown
On 08/20/2013 04:11 PM, Rafael J. Wysocki wrote:
> On Tuesday, July 30, 2013 03:54:28 PM Daniel Lezcano wrote:
>> Commit 89878baa73f0f1c679355006bd8632e5d78f96c2 introduced the flag
>> CPUIDLE_FLAG_TIMER_STOP where we specify a specific idle state stops the local
>> timer.
>>
>> Commit a06df062a189a8d5588babb8bf0bb78672497798 introduced the initialization
>> of the timer broadcast framework depending of the flag presence.
>>
>> We have now a way to set a flag for a specific state to tell if the local timer
>> will be down in deep idle state or not and we have cpu hotplug support to setup
>> the broadcast timer.
>
> So this depends on [1/2], right?
Yes, that's correct.
>> Remove the timer broadcast initialization from init and at the cpu hotplug
>> time.
>>
>> Remove the timer broadcast activation in the idle loop.
>>
>> Remove the bitmap LAPIC_TIMER_ALWAYS_RELIABLE.
>>
>> Set the CPUIDLE_FLAG_TIMER_STOP on the states when they are greater than C1 and
>> the cpu has not X86_FEATURE_ARAT.
>>
>> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
>
> I generally like the changes made by this patch, but I wonder how much it
> has been tested?
Well it has been tested on my laptop which is an i5-3317.
With lapic_tsc_reliable_states 0xffffffff
> The subject is slightly misleading too, because it's about the intel_idle
> driver. Please put intel_idle in the subject.
Ok, sure.
>> ---
>> drivers/idle/intel_idle.c | 41 ++++-------------------------------------
>> 1 file changed, 4 insertions(+), 37 deletions(-)
>>
>> diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
>> index fa6964d..a975868 100644
>> --- a/drivers/idle/intel_idle.c
>> +++ b/drivers/idle/intel_idle.c
>> @@ -55,7 +55,6 @@
>>
>> #include <linux/kernel.h>
>> #include <linux/cpuidle.h>
>> -#include <linux/clockchips.h>
>> #include <trace/events/power.h>
>> #include <linux/sched.h>
>> #include <linux/notifier.h>
>> @@ -77,10 +76,6 @@ static int max_cstate = CPUIDLE_STATE_MAX - 1;
>>
>> static unsigned int mwait_substates;
>>
>> -#define LAPIC_TIMER_ALWAYS_RELIABLE 0xFFFFFFFF
>> -/* Reliable LAPIC Timer States, bit 1 for C1 etc. */
>> -static unsigned int lapic_timer_reliable_states = (1 << 1); /* Default to only C1 */
>> -
>> struct idle_cpu {
>> struct cpuidle_state *state_table;
>>
>> @@ -356,9 +351,6 @@ static int intel_idle(struct cpuidle_device *dev,
>> if (state->flags & CPUIDLE_FLAG_TLB_FLUSHED)
>> leave_mm(cpu);
>>
>> - if (!(lapic_timer_reliable_states & (1 << (cstate))))
>> - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
>> -
>> if (!need_resched()) {
>>
>> __monitor((void *)¤t_thread_info()->flags, 0, 0);
>> @@ -367,23 +359,9 @@ static int intel_idle(struct cpuidle_device *dev,
>> __mwait(eax, ecx);
>> }
>>
>> - if (!(lapic_timer_reliable_states & (1 << (cstate))))
>> - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
>> -
>> return index;
>> }
>>
>> -static void __setup_broadcast_timer(void *arg)
>> -{
>> - unsigned long reason = (unsigned long)arg;
>> - int cpu = smp_processor_id();
>> -
>> - reason = reason ?
>> - CLOCK_EVT_NOTIFY_BROADCAST_ON : CLOCK_EVT_NOTIFY_BROADCAST_OFF;
>> -
>> - clockevents_notify(reason, &cpu);
>> -}
>> -
>> static int cpu_hotplug_notify(struct notifier_block *n,
>> unsigned long action, void *hcpu)
>> {
>> @@ -393,10 +371,6 @@ static int cpu_hotplug_notify(struct notifier_block *n,
>> switch (action & 0xf) {
>> case CPU_ONLINE:
>>
>> - if (lapic_timer_reliable_states != LAPIC_TIMER_ALWAYS_RELIABLE)
>> - smp_call_function_single(hotcpu, __setup_broadcast_timer,
>> - (void *)true, 1);
>> -
>> /*
>> * Some systems can hotplug a cpu at runtime after
>> * the kernel has booted, we have to initialize the
>> @@ -524,16 +498,9 @@ static int intel_idle_probe(void)
>> icpu = (const struct idle_cpu *)id->driver_data;
>> cpuidle_state_table = icpu->state_table;
>>
>> - if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */
>> - lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE;
>> - else
>> - on_each_cpu(__setup_broadcast_timer, (void *)true, 1);
>> -
>> pr_debug(PREFIX "v" INTEL_IDLE_VERSION
>> " model 0x%X\n", boot_cpu_data.x86_model);
>>
>> - pr_debug(PREFIX "lapic_timer_reliable_states 0x%x\n",
>> - lapic_timer_reliable_states);
>> return 0;
>> }
>>
>> @@ -594,6 +561,10 @@ static int intel_idle_cpuidle_driver_init(void)
>> mark_tsc_unstable("TSC halts in idle"
>> " states deeper than C2");
>>
>> + if (cstate > 1 && !boot_cpu_has(X86_FEATURE_ARAT))
>> + cpuidle_state_table[cstate].flags |=
>> + CPUIDLE_FLAG_TIMER_STOP;
>> +
>> drv->states[drv->state_count] = /* structure copy */
>> cpuidle_state_table[cstate];
>>
>> @@ -705,10 +676,6 @@ static void __exit intel_idle_exit(void)
>> {
>> intel_idle_cpuidle_devices_uninit();
>> cpuidle_unregister_driver(&intel_idle_driver);
>> -
>> -
>> - if (lapic_timer_reliable_states != LAPIC_TIMER_ALWAYS_RELIABLE)
>> - on_each_cpu(__setup_broadcast_timer, (void *)false, 1);
>> unregister_cpu_notifier(&cpu_hotplug_notifier);
>>
>> return;
>>
--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2013-09-02 14:02 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-07-30 13:54 [PATCH 1/2] cpuidle: add hotplug support to initialize the timer broadcast Daniel Lezcano
2013-07-30 13:54 ` [PATCH 2/2] x86: cpuidle: remove broadcast timer initialization Daniel Lezcano
2013-08-20 14:11 ` Rafael J. Wysocki
2013-09-02 14:02 ` Daniel Lezcano
2013-08-06 8:36 ` [PATCH 1/2] cpuidle: add hotplug support to initialize the timer broadcast Daniel Lezcano
2013-08-06 14:10 ` Rafael J. Wysocki
2013-08-06 14:11 ` Daniel Lezcano
2013-08-20 14:07 ` Rafael J. Wysocki
2013-09-02 13:29 ` Daniel Lezcano
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).