2011-06-28 02:49:49

by Todd Poynor

[permalink] [raw]
Subject: [PATCH 0/3] Add generic idle notifiers

Add notifiers for idle entry and exit, called with IDLE_START when a
CPU goes idle and IDLE_END when it goes out of idle, based on the
existing idle notifiers for the x86_64 arch.

Convert x86_64 to use these notifiers, and call the notifiers on ARM.

Convert the ARM LEDs events for idle start/end to these notifiers.

arch/arm/kernel/leds.c | 27 ++++++++++++++++++++++++++-
arch/arm/kernel/process.c | 5 ++---
arch/x86/include/asm/idle.h | 7 -------
arch/x86/kernel/process_64.c | 18 ++----------------
include/linux/cpu.h | 7 +++++++
kernel/cpu.c | 20 ++++++++++++++++++++
6 files changed, 57 insertions(+), 27 deletions(-)

--
1.7.3.1


2011-06-28 02:49:52

by Todd Poynor

[permalink] [raw]
Subject: [PATCH 1/3] Move x86_64 idle notifiers to generic

Move the x86_64 idle notifiers originally by Andi Kleen and Venkatesh
Pallipadi to generic.

Change-Id: Idf29cda15be151f494ff245933c12462643388d5
Signed-off-by: Todd Poynor <[email protected]>
---
arch/x86/include/asm/idle.h | 7 -------
arch/x86/kernel/process_64.c | 18 ++----------------
include/linux/cpu.h | 7 +++++++
kernel/cpu.c | 20 ++++++++++++++++++++
4 files changed, 29 insertions(+), 23 deletions(-)

diff --git a/arch/x86/include/asm/idle.h b/arch/x86/include/asm/idle.h
index f49253d7..f1e4268 100644
--- a/arch/x86/include/asm/idle.h
+++ b/arch/x86/include/asm/idle.h
@@ -1,13 +1,6 @@
#ifndef _ASM_X86_IDLE_H
#define _ASM_X86_IDLE_H

-#define IDLE_START 1
-#define IDLE_END 2
-
-struct notifier_block;
-void idle_notifier_register(struct notifier_block *n);
-void idle_notifier_unregister(struct notifier_block *n);
-
#ifdef CONFIG_X86_64
void enter_idle(void);
void exit_idle(void);
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index ca6f7ab..63c8aed 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -56,31 +56,17 @@ asmlinkage extern void ret_from_fork(void);
DEFINE_PER_CPU(unsigned long, old_rsp);
static DEFINE_PER_CPU(unsigned char, is_idle);

-static ATOMIC_NOTIFIER_HEAD(idle_notifier);
-
-void idle_notifier_register(struct notifier_block *n)
-{
- atomic_notifier_chain_register(&idle_notifier, n);
-}
-EXPORT_SYMBOL_GPL(idle_notifier_register);
-
-void idle_notifier_unregister(struct notifier_block *n)
-{
- atomic_notifier_chain_unregister(&idle_notifier, n);
-}
-EXPORT_SYMBOL_GPL(idle_notifier_unregister);
-
void enter_idle(void)
{
percpu_write(is_idle, 1);
- atomic_notifier_call_chain(&idle_notifier, IDLE_START, NULL);
+ idle_notifier_call_chain(IDLE_START);
}

static void __exit_idle(void)
{
if (x86_test_and_clear_bit_percpu(0, is_idle) == 0)
return;
- atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL);
+ idle_notifier_call_chain(IDLE_END);
}

/* Called from interrupts to signify idle end */
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 5f09323..97f1ca7 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -174,4 +174,11 @@ static inline int disable_nonboot_cpus(void) { return 0; }
static inline void enable_nonboot_cpus(void) {}
#endif /* !CONFIG_PM_SLEEP_SMP */

+#define IDLE_START 1
+#define IDLE_END 2
+
+void idle_notifier_register(struct notifier_block *n);
+void idle_notifier_unregister(struct notifier_block *n);
+void idle_notifier_call_chain(unsigned long val);
+
#endif /* _LINUX_CPU_H_ */
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 12b7458..4047707 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -594,3 +594,23 @@ void init_cpu_online(const struct cpumask *src)
{
cpumask_copy(to_cpumask(cpu_online_bits), src);
}
+
+static ATOMIC_NOTIFIER_HEAD(idle_notifier);
+
+void idle_notifier_register(struct notifier_block *n)
+{
+ atomic_notifier_chain_register(&idle_notifier, n);
+}
+EXPORT_SYMBOL_GPL(idle_notifier_register);
+
+void idle_notifier_unregister(struct notifier_block *n)
+{
+ atomic_notifier_chain_unregister(&idle_notifier, n);
+}
+EXPORT_SYMBOL_GPL(idle_notifier_unregister);
+
+void idle_notifier_call_chain(unsigned long val)
+{
+ atomic_notifier_call_chain(&idle_notifier, val, NULL);
+}
+EXPORT_SYMBOL_GPL(idle_notifier_call_chain);
--
1.7.3.1

2011-06-28 02:49:59

by Todd Poynor

[permalink] [raw]
Subject: [PATCH 2/3] ARM: Call idle notifiers

Change-Id: Id833e61c13baa1783705ac9e9046d1f0cc90c95e
Signed-off-by: Todd Poynor <[email protected]>
---
arch/arm/kernel/process.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 5e1e541..1b9101e 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -184,6 +184,7 @@ void cpu_idle(void)
while (1) {
tick_nohz_stop_sched_tick(1);
leds_event(led_idle_start);
+ idle_notifier_call_chain(IDLE_START);
while (!need_resched()) {
#ifdef CONFIG_HOTPLUG_CPU
if (cpu_is_offline(smp_processor_id()))
@@ -208,6 +209,7 @@ void cpu_idle(void)
}
}
leds_event(led_idle_end);
+ idle_notifier_call_chain(IDLE_END);
tick_nohz_restart_sched_tick();
preempt_enable_no_resched();
schedule();
--
1.7.3.1

2011-06-28 02:49:55

by Todd Poynor

[permalink] [raw]
Subject: [PATCH 3/3] ARM: Move leds idle start/stop calls to idle notifiers

Change-Id: I5d8e4e85b17bbab7992ecb477f0bdb5e4138b166
Signed-off-by: Todd Poynor <[email protected]>
---
arch/arm/kernel/leds.c | 27 ++++++++++++++++++++++++++-
arch/arm/kernel/process.c | 3 ---
2 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/arch/arm/kernel/leds.c b/arch/arm/kernel/leds.c
index 0f107dc..136e837 100644
--- a/arch/arm/kernel/leds.c
+++ b/arch/arm/kernel/leds.c
@@ -9,6 +9,8 @@
*/
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/notifier.h>
+#include <linux/cpu.h>
#include <linux/sysdev.h>
#include <linux/syscore_ops.h>

@@ -101,6 +103,25 @@ static struct syscore_ops leds_syscore_ops = {
.resume = leds_resume,
};

+static int leds_idle_notifier(struct notifier_block *nb, unsigned long val,
+ void *data)
+{
+ switch (val) {
+ case IDLE_START:
+ leds_event(led_idle_start);
+ break;
+ case IDLE_END:
+ leds_event(led_idle_end);
+ break;
+ }
+
+ return 0;
+}
+
+static struct notifier_block leds_idle_nb = {
+ .notifier_call = leds_idle_notifier,
+};
+
static int __init leds_init(void)
{
int ret;
@@ -109,8 +130,12 @@ static int __init leds_init(void)
ret = sysdev_register(&leds_device);
if (ret == 0)
ret = sysdev_create_file(&leds_device, &attr_event);
- if (ret == 0)
+
+ if (ret == 0) {
register_syscore_ops(&leds_syscore_ops);
+ idle_notifier_register(&leds_idle_nb);
+ }
+
return ret;
}

diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 1b9101e..6adf53f 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -32,7 +32,6 @@
#include <linux/hw_breakpoint.h>

#include <asm/cacheflush.h>
-#include <asm/leds.h>
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/thread_notify.h>
@@ -183,7 +182,6 @@ void cpu_idle(void)
/* endless idle loop with no priority at all */
while (1) {
tick_nohz_stop_sched_tick(1);
- leds_event(led_idle_start);
idle_notifier_call_chain(IDLE_START);
while (!need_resched()) {
#ifdef CONFIG_HOTPLUG_CPU
@@ -208,7 +206,6 @@ void cpu_idle(void)
local_irq_enable();
}
}
- leds_event(led_idle_end);
idle_notifier_call_chain(IDLE_END);
tick_nohz_restart_sched_tick();
preempt_enable_no_resched();
--
1.7.3.1

2011-06-28 09:05:26

by Bryan Wu

[permalink] [raw]
Subject: Re: [PATCH 0/3] Add generic idle notifiers

On Tue, Jun 28, 2011 at 10:46 AM, Todd Poynor <[email protected]> wrote:
> Add notifiers for idle entry and exit, called with IDLE_START when a
> CPU goes idle and IDLE_END when it goes out of idle, based on the
> existing idle notifiers for the x86_64 arch.
>
> Convert x86_64 to use these notifiers, and call the notifiers on ARM.
>
> Convert the ARM LEDs events for idle start/end to these notifiers.
>

LinusW and I is working on consolidation LED events interface in ARM.
Please take a look at https://patchwork.kernel.org/patch/918792/

I do like to add notifiers into ledtrig-cpu driver, which can be also
shared by x86

Thanks,
-Bryan

> ?arch/arm/kernel/leds.c ? ? ? | ? 27 ++++++++++++++++++++++++++-
> ?arch/arm/kernel/process.c ? ?| ? ?5 ++---
> ?arch/x86/include/asm/idle.h ?| ? ?7 -------
> ?arch/x86/kernel/process_64.c | ? 18 ++----------------
> ?include/linux/cpu.h ? ? ? ? ?| ? ?7 +++++++
> ?kernel/cpu.c ? ? ? ? ? ? ? ? | ? 20 ++++++++++++++++++++
> ?6 files changed, 57 insertions(+), 27 deletions(-)
>
> --
> 1.7.3.1
>
> _______________________________________________
> linux-arm-kernel mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>



--
Bryan Wu <[email protected]>
Kernel Developer ? ?+86.138-1617-6545 Mobile
Ubuntu Kernel Team
Canonical Ltd. ? ? ?http://www.canonical.com
Ubuntu - Linux for human beings | http://www.ubuntu.com

2011-06-28 18:29:33

by Nicolas Pitre

[permalink] [raw]
Subject: Re: [PATCH 0/3] Add generic idle notifiers

On Mon, 27 Jun 2011, Todd Poynor wrote:

> Add notifiers for idle entry and exit, called with IDLE_START when a
> CPU goes idle and IDLE_END when it goes out of idle, based on the
> existing idle notifiers for the x86_64 arch.
>
> Convert x86_64 to use these notifiers, and call the notifiers on ARM.
>
> Convert the ARM LEDs events for idle start/end to these notifiers.

This is nice.

Acked-by: Nicolas Pitre <[email protected]>

for all 3 patches.


Nicolas

2011-06-28 18:30:27

by Nicolas Pitre

[permalink] [raw]
Subject: Re: [PATCH 0/3] Add generic idle notifiers

On Tue, 28 Jun 2011, Bryan Wu wrote:

> On Tue, Jun 28, 2011 at 10:46 AM, Todd Poynor <[email protected]> wrote:
> > Add notifiers for idle entry and exit, called with IDLE_START when a
> > CPU goes idle and IDLE_END when it goes out of idle, based on the
> > existing idle notifiers for the x86_64 arch.
> >
> > Convert x86_64 to use these notifiers, and call the notifiers on ARM.
> >
> > Convert the ARM LEDs events for idle start/end to these notifiers.
> >
>
> LinusW and I is working on consolidation LED events interface in ARM.
> Please take a look at https://patchwork.kernel.org/patch/918792/

There is no conflict between those two series as one deals with the way
the LED events are generated and the other with the way those events are
acted upon. The LED event mechanism in the middle is still untouched
(could be deprecated eventually when all its users have migrated to the
common LED API but not yet).


Nicolas