Skip to contentSkip to conversation

idle: Consolidate idle implementations

PATCH In review Thomas Gleixner 25 participants 135 messages Mar 21, 2013 – Nov 22, 2013 2 messages not in the archive

Subsystems (31)
lore
Share & tools
lore
#0 lore raw

cover idle: Consolidate idle implementations

Each architecture implements its own cpu_idle() code, which is more or less the same on all architectures (plus/minus a few bugs and a few missing extra functionalities, instrumentation ...). That also forces everyone who is interested in idle related features to add new functionality to every architecture. What a waste.

Aside of that pointless code duplicaiton the ongoing quest to consolidate the cpu hotplug code needs a common entry point for the non boot cpus.

The following series implements a generic idle function and converts most architectures over. I left out SPARC (it involves sparc asm) and UM (it made me barf). If we can move those architectures as well, we can get rid of the extra config switch and have everything consolidated.

I spent a lot of time to make sure that the conversion preserved the non obvious differences of the architecture implementations, but I really need help from the affected maintainers to prove the correctness.

Thanks,

tglx

---
 arch/openrisc/kernel/idle.c                         |   73 ------------
 linux-2.6/arch/Kconfig                              |    3 
 linux-2.6/arch/alpha/Kconfig                        |    1 
 linux-2.6/arch/alpha/include/asm/thread_info.h      |    2 
 linux-2.6/arch/alpha/kernel/process.c               |   19 ---
 linux-2.6/arch/alpha/kernel/smp.c                   |    3 
 linux-2.6/arch/arc/Kconfig                          |    1 
 linux-2.6/arch/arc/kernel/process.c                 |   27 ----
 linux-2.6/arch/arc/kernel/smp.c                     |    2 
 linux-2.6/arch/arm/Kconfig                          |    2 
 linux-2.6/arch/arm/include/asm/system_misc.h        |    3 
 linux-2.6/arch/arm/kernel/process.c                 |  100 ++++-------------
 linux-2.6/arch/arm/kernel/smp.c                     |    2 
 linux-2.6/arch/arm/mach-gemini/idle.c               |    4 
 linux-2.6/arch/arm/mach-gemini/irq.c                |    2 
 linux-2.6/arch/arm/mach-ixp4xx/common.c             |    2 
 linux-2.6/arch/arm/mach-omap1/pm.c                  |    5 
 linux-2.6/arch/arm/mach-omap2/omap_hwmod.c          |    6 -
 linux-2.6/arch/arm/mach-omap2/pm.c                  |    5 
 linux-2.6/arch/arm/mach-orion5x/board-dt.c          |    2 
 linux-2.6/arch/arm/mach-orion5x/common.c            |    2 
 linux-2.6/arch/arm/mach-shark/core.c                |    2 
 linux-2.6/arch/arm/mach-shmobile/suspend.c          |    4 
 linux-2.6/arch/arm/mach-w90x900/dev.c               |    2 
 linux-2.6/arch/arm64/Kconfig                        |    1 
 linux-2.6/arch/arm64/kernel/process.c               |   43 -------
 linux-2.6/arch/arm64/kernel/smp.c                   |    2 
 linux-2.6/arch/avr32/Kconfig                        |    1 
 linux-2.6/arch/avr32/kernel/process.c               |   13 --
 linux-2.6/arch/avr32/kernel/time.c                  |    8 +
 linux-2.6/arch/avr32/mach-at32ap/include/mach/pm.h  |   24 ----
 linux-2.6/arch/avr32/mach-at32ap/pm-at32ap700x.S    |    7 -
 linux-2.6/arch/blackfin/Kconfig                     |    1 
 linux-2.6/arch/blackfin/kernel/process.c            |   30 -----
 linux-2.6/arch/blackfin/mach-common/smp.c           |    2 
 linux-2.6/arch/c6x/Kconfig                          |    1 
 linux-2.6/arch/c6x/kernel/process.c                 |   28 ----
 linux-2.6/arch/cris/Kconfig                         |    1 
 linux-2.6/arch/cris/arch-v10/kernel/process.c       |    3 
 linux-2.6/arch/cris/arch-v32/kernel/process.c       |   12 --
 linux-2.6/arch/cris/arch-v32/kernel/smp.c           |    4 
 linux-2.6/arch/cris/include/asm/processor.h         |    7 -
 linux-2.6/arch/cris/kernel/process.c                |   49 --------
 linux-2.6/arch/frv/Kconfig                          |    1 
 linux-2.6/arch/frv/kernel/process.c                 |   27 ----
 linux-2.6/arch/h8300/Kconfig                        |    1 
 linux-2.6/arch/h8300/kernel/process.c               |   35 ------
 linux-2.6/arch/hexagon/Kconfig                      |    1 
 linux-2.6/arch/hexagon/kernel/process.c             |   23 ----
 linux-2.6/arch/hexagon/kernel/smp.c                 |    2 
 linux-2.6/arch/ia64/Kconfig                         |    1 
 linux-2.6/arch/ia64/include/asm/thread_info.h       |    2 
 linux-2.6/arch/ia64/kernel/perfmon.c                |   13 --
 linux-2.6/arch/ia64/kernel/process.c                |   83 ++------------
 linux-2.6/arch/ia64/kernel/smpboot.c                |    2 
 linux-2.6/arch/m32r/Kconfig                         |    1 
 linux-2.6/arch/m32r/kernel/process.c                |   18 ---
 linux-2.6/arch/m32r/kernel/smpboot.c                |    2 
 linux-2.6/arch/m68k/Kconfig                         |    1 
 linux-2.6/arch/m68k/kernel/process.c                |   32 -----
 linux-2.6/arch/metag/Kconfig                        |    1 
 linux-2.6/arch/metag/include/asm/thread_info.h      |    2 
 linux-2.6/arch/metag/kernel/process.c               |   32 -----
 linux-2.6/arch/metag/kernel/smp.c                   |    2 
 linux-2.6/arch/microblaze/Kconfig                   |    2 
 linux-2.6/arch/microblaze/include/asm/processor.h   |    5 
 linux-2.6/arch/microblaze/include/asm/thread_info.h |    1 
 linux-2.6/arch/microblaze/kernel/process.c          |   65 -----------
 linux-2.6/arch/mips/Kconfig                         |    1 
 linux-2.6/arch/mips/kernel/process.c                |   46 ++------
 linux-2.6/arch/mips/kernel/smp.c                    |    2 
 linux-2.6/arch/mn10300/Kconfig                      |    1 
 linux-2.6/arch/mn10300/include/asm/thread_info.h    |    2 
 linux-2.6/arch/mn10300/kernel/process.c             |   70 +-----------
 linux-2.6/arch/mn10300/kernel/smp.c                 |    7 -
 linux-2.6/arch/openrisc/Kconfig                     |    1 
 linux-2.6/arch/openrisc/include/asm/thread_info.h   |    2 
 linux-2.6/arch/parisc/Kconfig                       |    1 
 linux-2.6/arch/parisc/include/asm/thread_info.h     |    2 
 linux-2.6/arch/parisc/kernel/process.c              |   22 ---
 linux-2.6/arch/parisc/kernel/smp.c                  |    2 
 linux-2.6/arch/powerpc/Kconfig                      |    1 
 linux-2.6/arch/powerpc/include/asm/thread_info.h    |    4 
 linux-2.6/arch/powerpc/kernel/idle.c                |   78 +++----------
 linux-2.6/arch/powerpc/kernel/smp.c                 |    2 
 linux-2.6/arch/s390/kernel/process.c                |   25 +---
 linux-2.6/arch/s390/kernel/smp.c                    |    3 
 linux-2.6/arch/score/Kconfig                        |    1 
 linux-2.6/arch/score/kernel/process.c               |   18 ---
 linux-2.6/arch/sh/Kconfig                           |    2 
 linux-2.6/arch/sh/include/asm/thread_info.h         |    4 
 linux-2.6/arch/sh/kernel/idle.c                     |  102 +----------------
 linux-2.6/arch/sh/kernel/smp.c                      |    2 
 linux-2.6/arch/sparc/include/asm/thread_info_32.h   |    2 
 linux-2.6/arch/sparc/include/asm/thread_info_64.h   |    2 
 linux-2.6/arch/tile/include/asm/thread_info.h       |    2 
 linux-2.6/arch/tile/kernel/process.c                |   61 +---------
 linux-2.6/arch/tile/kernel/smpboot.c                |    4 
 linux-2.6/arch/unicore32/Kconfig                    |    1 
 linux-2.6/arch/unicore32/kernel/process.c           |   21 ---
 linux-2.6/arch/x86/Kconfig                          |    1 
 linux-2.6/arch/x86/include/asm/thread_info.h        |    2 
 linux-2.6/arch/x86/kernel/process.c                 |  106 +++++-------------
 linux-2.6/arch/x86/kernel/smpboot.c                 |    2 
 linux-2.6/arch/x86/xen/smp.c                        |    2 
 linux-2.6/arch/xtensa/Kconfig                       |    1 
 linux-2.6/arch/xtensa/kernel/process.c              |   14 --
 linux-2.6/include/linux/cpu.h                       |   16 ++
 linux-2.6/include/linux/sched.h                     |   41 +++++++
 linux-2.6/init/main.c                               |    2 
 linux-2.6/kernel/Makefile                           |    1 
 linux-2.6/kernel/cpu/Makefile                       |    1 
 linux-2.6/kernel/cpu/idle.c                         |  115 ++++++++++++++++++++
 linux-2.6/kernel/sched/core.c                       |    5 
 114 files changed, 432 insertions(+), 1237 deletions(-)
#1 lore raw

PATCH 1/34 arch: Cleanup enable/disable_hlt

enable/disable_hlt() does not need to be exported and can be killed on architectures which do not use it at all.

---
 arch/arm/kernel/process.c               |    4 ----
 arch/cris/arch-v32/kernel/process.c     |    8 +++-----
 arch/cris/include/asm/processor.h       |    7 -------
 arch/cris/kernel/process.c              |   25 -------------------------
 arch/microblaze/include/asm/processor.h |    2 --
 arch/microblaze/kernel/process.c        |   12 ------------
 arch/mn10300/kernel/smp.c               |    5 -----
 7 files changed, 3 insertions(+), 60 deletions(-)
arch/arm/kernel/process.c +0 -4
Index: linux-2.6/arch/arm/kernel/process.c
===================================================================
@@ -64,16 +64,12 @@ void disable_hlt(void)
 	hlt_counter++;
 }
 
-EXPORT_SYMBOL(disable_hlt);
-
 void enable_hlt(void)
 {
 	hlt_counter--;
 	BUG_ON(hlt_counter < 0);
 }
 
-EXPORT_SYMBOL(enable_hlt);
-
 static int __init nohlt_setup(char *__unused)
 {
 	hlt_counter = 1;
arch/cris/arch-v32/kernel/process.c +3 -5
Index: linux-2.6/arch/cris/arch-v32/kernel/process.c
===================================================================
@@ -20,16 +20,14 @@
 
 extern void stop_watchdog(void);
 
-extern int cris_hlt_counter;
-
 /* We use this if we don't have any better idle routine. */
 void default_idle(void)
 {
 	local_irq_disable();
-	if (!need_resched() && !cris_hlt_counter) {
-	        /* Halt until exception. */
+	if (!need_resched()) {
+		/* Halt until exception. */
 		__asm__ volatile("ei    \n\t"
-                                 "halt      ");
+				 "halt      ");
 	}
 	local_irq_enable();
 }
arch/cris/include/asm/processor.h +0 -7
Index: linux-2.6/arch/cris/include/asm/processor.h
===================================================================
@@ -65,13 +65,6 @@ static inline void release_thread(struct
 
 #define cpu_relax()     barrier()
 
-/*
- * disable hlt during certain critical i/o operations
- */
-#define HAVE_DISABLE_HLT
-void disable_hlt(void);
-void enable_hlt(void);
-
 void default_idle(void);
 
 #endif /* __ASM_CRIS_PROCESSOR_H */
arch/cris/kernel/process.c +0 -25
Index: linux-2.6/arch/cris/kernel/process.c
===================================================================
@@ -29,31 +29,6 @@
 
 //#define DEBUG
 
-/*
- * The hlt_counter, disable_hlt and enable_hlt is just here as a hook if
- * there would ever be a halt sequence (for power save when idle) with
- * some largish delay when halting or resuming *and* a driver that can't
- * afford that delay.  The hlt_counter would then be checked before
- * executing the halt sequence, and the driver marks the unhaltable
- * region by enable_hlt/disable_hlt.
- */
-
-int cris_hlt_counter=0;
-
-void disable_hlt(void)
-{
-	cris_hlt_counter++;
-}
-
-EXPORT_SYMBOL(disable_hlt);
-
-void enable_hlt(void)
-{
-	cris_hlt_counter--;
-}
-
-EXPORT_SYMBOL(enable_hlt);
- 
 extern void default_idle(void);
 
 void (*pm_power_off)(void);
arch/microblaze/include/asm/processor.h +0 -2
Index: linux-2.6/arch/microblaze/include/asm/processor.h
===================================================================
@@ -160,8 +160,6 @@ unsigned long get_wchan(struct task_stru
 #  define STACK_TOP	TASK_SIZE
 #  define STACK_TOP_MAX	STACK_TOP
 
-void disable_hlt(void);
-void enable_hlt(void);
 void default_idle(void);
 
 #ifdef CONFIG_DEBUG_FS
arch/microblaze/kernel/process.c +0 -12
Index: linux-2.6/arch/microblaze/kernel/process.c
===================================================================
@@ -46,18 +46,6 @@ EXPORT_SYMBOL(pm_power_off);
 
 static int hlt_counter = 1;
 
-void disable_hlt(void)
-{
-	hlt_counter++;
-}
-EXPORT_SYMBOL(disable_hlt);
-
-void enable_hlt(void)
-{
-	hlt_counter--;
-}
-EXPORT_SYMBOL(enable_hlt);
-
 static int __init nohlt_setup(char *__unused)
 {
 	hlt_counter = 1;
arch/mn10300/kernel/smp.c +0 -5
Index: linux-2.6/arch/mn10300/kernel/smp.c
===================================================================
@@ -935,8 +935,6 @@ int __cpu_up(unsigned int cpu, struct ta
 	int timeout;
 
 #ifdef CONFIG_HOTPLUG_CPU
-	if (num_online_cpus() == 1)
-		disable_hlt();
 	if (sleep_mode[cpu])
 		run_wakeup_cpu(cpu);
 #endif /* CONFIG_HOTPLUG_CPU */
@@ -1003,9 +1001,6 @@ int __cpu_disable(void)
 void __cpu_die(unsigned int cpu)
 {
 	run_sleep_cpu(cpu);
-
-	if (num_online_cpus() == 1)
-		enable_hlt();
 }
 
 #ifdef CONFIG_MN10300_CACHE_ENABLED
#2 lore raw

[tip:smp/hotplug] arch: Cleanup enable/disable_hlt

arch: Cleanup enable/disable_hlt
Commit-ID:  6546327ad187238ac63d2429701b32becb096fd8
Gitweb:     http://git.kernel.org/tip/6546327ad187238ac63d2429701b32becb096fd8
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:31 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:22 +0200

arch: Cleanup enable/disable_hlt

enable/disable_hlt() does not need to be exported and can be killed on architectures which do not use it at all.

---
 arch/arm/kernel/process.c               |  4 ----
 arch/cris/arch-v32/kernel/process.c     |  8 +++-----
 arch/cris/include/asm/processor.h       |  7 -------
 arch/cris/kernel/process.c              | 25 -------------------------
 arch/microblaze/include/asm/processor.h |  2 --
 arch/microblaze/kernel/process.c        | 12 ------------
 arch/mn10300/kernel/smp.c               |  5 -----
 7 files changed, 3 insertions(+), 60 deletions(-)
arch/arm/kernel/process.c +0 -4
index 047d3e4..92884c8 100644
@@ -64,16 +64,12 @@ void disable_hlt(void)
 	hlt_counter++;
 }
 
-EXPORT_SYMBOL(disable_hlt);
-
 void enable_hlt(void)
 {
 	hlt_counter--;
 	BUG_ON(hlt_counter < 0);
 }
 
-EXPORT_SYMBOL(enable_hlt);
-
 static int __init nohlt_setup(char *__unused)
 {
 	hlt_counter = 1;
arch/cris/arch-v32/kernel/process.c +3 -5
index 2b23ef0..4857933 100644
@@ -20,16 +20,14 @@
 
 extern void stop_watchdog(void);
 
-extern int cris_hlt_counter;
-
 /* We use this if we don't have any better idle routine. */
 void default_idle(void)
 {
 	local_irq_disable();
-	if (!need_resched() && !cris_hlt_counter) {
-	        /* Halt until exception. */
+	if (!need_resched()) {
+		/* Halt until exception. */
 		__asm__ volatile("ei    \n\t"
-                                 "halt      ");
+				 "halt      ");
 	}
 	local_irq_enable();
 }
arch/cris/include/asm/processor.h +0 -7
index 675823f..c0a29b9 100644
@@ -65,13 +65,6 @@ static inline void release_thread(struct task_struct *dead_task)
 
 #define cpu_relax()     barrier()
 
-/*
- * disable hlt during certain critical i/o operations
- */
-#define HAVE_DISABLE_HLT
-void disable_hlt(void);
-void enable_hlt(void);
-
 void default_idle(void);
 
 #endif /* __ASM_CRIS_PROCESSOR_H */
arch/cris/kernel/process.c +0 -25
index 104ff4d..508c9cd 100644
@@ -29,31 +29,6 @@
 
 //#define DEBUG
 
-/*
- * The hlt_counter, disable_hlt and enable_hlt is just here as a hook if
- * there would ever be a halt sequence (for power save when idle) with
- * some largish delay when halting or resuming *and* a driver that can't
- * afford that delay.  The hlt_counter would then be checked before
- * executing the halt sequence, and the driver marks the unhaltable
- * region by enable_hlt/disable_hlt.
- */
-
-int cris_hlt_counter=0;
-
-void disable_hlt(void)
-{
-	cris_hlt_counter++;
-}
-
-EXPORT_SYMBOL(disable_hlt);
-
-void enable_hlt(void)
-{
-	cris_hlt_counter--;
-}
-
-EXPORT_SYMBOL(enable_hlt);
- 
 extern void default_idle(void);
 
 void (*pm_power_off)(void);
arch/microblaze/include/asm/processor.h +0 -2
index 0759153..f576fe0 100644
@@ -160,8 +160,6 @@ unsigned long get_wchan(struct task_struct *p);
 #  define STACK_TOP	TASK_SIZE
 #  define STACK_TOP_MAX	STACK_TOP
 
-void disable_hlt(void);
-void enable_hlt(void);
 void default_idle(void);
 
 #ifdef CONFIG_DEBUG_FS
arch/microblaze/kernel/process.c +0 -12
index fa0ea60..7c36171 100644
@@ -46,18 +46,6 @@ EXPORT_SYMBOL(pm_power_off);
 
 static int hlt_counter = 1;
 
-void disable_hlt(void)
-{
-	hlt_counter++;
-}
-EXPORT_SYMBOL(disable_hlt);
-
-void enable_hlt(void)
-{
-	hlt_counter--;
-}
-EXPORT_SYMBOL(enable_hlt);
-
 static int __init nohlt_setup(char *__unused)
 {
 	hlt_counter = 1;
arch/mn10300/kernel/smp.c +0 -5
index 5d7e152..eaef5ad 100644
@@ -935,8 +935,6 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle)
 	int timeout;
 
 #ifdef CONFIG_HOTPLUG_CPU
-	if (num_online_cpus() == 1)
-		disable_hlt();
 	if (sleep_mode[cpu])
 		run_wakeup_cpu(cpu);
 #endif /* CONFIG_HOTPLUG_CPU */
@@ -1003,9 +1001,6 @@ int __cpu_disable(void)
 void __cpu_die(unsigned int cpu)
 {
 	run_sleep_cpu(cpu);
-
-	if (num_online_cpus() == 1)
-		enable_hlt();
 }
 
 #ifdef CONFIG_MN10300_CACHE_ENABLED
#3 lore raw

PATCH 2/34 arch: Consolidate tsk_is_polling()

In reply to Thomas Gleixner

Move it to a common place. Preparatory patch for implementing set/clear for the idle need_resched poll implementation.

---
 arch/alpha/include/asm/thread_info.h      |    2 --
 arch/ia64/include/asm/thread_info.h       |    2 --
 arch/metag/include/asm/thread_info.h      |    2 --
 arch/microblaze/include/asm/thread_info.h |    1 -
 arch/mn10300/include/asm/thread_info.h    |    2 --
 arch/openrisc/include/asm/thread_info.h   |    2 --
 arch/parisc/include/asm/thread_info.h     |    2 --
 arch/powerpc/include/asm/thread_info.h    |    4 ----
 arch/sh/include/asm/thread_info.h         |    4 ----
 arch/sparc/include/asm/thread_info_32.h   |    2 --
 arch/sparc/include/asm/thread_info_64.h   |    2 --
 arch/tile/include/asm/thread_info.h       |    2 --
 arch/x86/include/asm/thread_info.h        |    2 --
 include/linux/sched.h                     |   20 ++++++++++++++++++++
 kernel/sched/core.c                       |    5 -----
 15 files changed, 20 insertions(+), 34 deletions(-)
arch/alpha/include/asm/thread_info.h +0 -2
Index: linux-2.6/arch/alpha/include/asm/thread_info.h
===================================================================
@@ -95,8 +95,6 @@ register struct thread_info *__current_t
 #define TS_POLLING		0x0010	/* idle task polling need_resched,
 					   skip sending interrupt */
 
-#define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING)
-
 #ifndef __ASSEMBLY__
 #define HAVE_SET_RESTORE_SIGMASK	1
 static inline void set_restore_sigmask(void)
arch/ia64/include/asm/thread_info.h +0 -2
Index: linux-2.6/arch/ia64/include/asm/thread_info.h
===================================================================
@@ -131,8 +131,6 @@ struct thread_info {
 #define TS_POLLING		1 	/* true if in idle loop and not sleeping */
 #define TS_RESTORE_SIGMASK	2	/* restore signal mask in do_signal() */
 
-#define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING)
-
 #ifndef __ASSEMBLY__
 #define HAVE_SET_RESTORE_SIGMASK	1
 static inline void set_restore_sigmask(void)
arch/metag/include/asm/thread_info.h +0 -2
Index: linux-2.6/arch/metag/include/asm/thread_info.h
===================================================================
@@ -150,6 +150,4 @@ static inline int kstack_end(void *addr)
 #define _TIF_WORK_MASK		(_TIF_ALLWORK_MASK & ~(_TIF_SYSCALL_TRACE | \
 				 _TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP))
 
-#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
-
 #endif /* _ASM_THREAD_INFO_H */
arch/microblaze/include/asm/thread_info.h +0 -1
Index: linux-2.6/arch/microblaze/include/asm/thread_info.h
===================================================================
@@ -182,7 +182,6 @@ static inline bool test_and_clear_restor
 	ti->status &= ~TS_RESTORE_SIGMASK;
 	return true;
 }
-#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
 #endif
 
 #endif /* __KERNEL__ */
arch/mn10300/include/asm/thread_info.h +0 -2
Index: linux-2.6/arch/mn10300/include/asm/thread_info.h
===================================================================
@@ -165,8 +165,6 @@ void arch_release_thread_info(struct thr
 #define _TIF_WORK_MASK		0x0000FFFE	/* work to do on interrupt/exception return */
 #define _TIF_ALLWORK_MASK	0x0000FFFF	/* work to do on any return to u-space */
 
-#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
-
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_THREAD_INFO_H */
arch/openrisc/include/asm/thread_info.h +0 -2
Index: linux-2.6/arch/openrisc/include/asm/thread_info.h
===================================================================
@@ -128,8 +128,6 @@ register struct thread_info *current_thr
 /* For OpenRISC, this is anything in the LSW other than syscall trace */
 #define _TIF_WORK_MASK (0xff & ~(_TIF_SYSCALL_TRACE|_TIF_SINGLESTEP))
 
-#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
-
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_THREAD_INFO_H */
arch/parisc/include/asm/thread_info.h +0 -2
Index: linux-2.6/arch/parisc/include/asm/thread_info.h
===================================================================
@@ -77,8 +77,6 @@ struct thread_info {
 #define _TIF_SYSCALL_TRACE_MASK (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP |	\
 				 _TIF_BLOCKSTEP)
 
-#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
-
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_PARISC_THREAD_INFO_H */
arch/powerpc/include/asm/thread_info.h +0 -4
Index: linux-2.6/arch/powerpc/include/asm/thread_info.h
===================================================================
@@ -182,10 +182,6 @@ static inline bool test_thread_local_fla
 #define is_32bit_task()	(1)
 #endif
 
-#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
-
-#endif	/* !__ASSEMBLY__ */
-
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_POWERPC_THREAD_INFO_H */
arch/sh/include/asm/thread_info.h +0 -4
Index: linux-2.6/arch/sh/include/asm/thread_info.h
===================================================================
@@ -207,10 +207,6 @@ static inline bool test_and_clear_restor
 	return true;
 }
 
-#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
-
-#endif	/* !__ASSEMBLY__ */
-
 #endif /* __KERNEL__ */
 
 #endif /* __ASM_SH_THREAD_INFO_H */
arch/sparc/include/asm/thread_info_32.h +0 -2
Index: linux-2.6/arch/sparc/include/asm/thread_info_32.h
===================================================================
@@ -132,8 +132,6 @@ register struct thread_info *current_thr
 #define _TIF_DO_NOTIFY_RESUME_MASK	(_TIF_NOTIFY_RESUME | \
 					 _TIF_SIGPENDING)
 
-#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
-
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_THREAD_INFO_H */
arch/sparc/include/asm/thread_info_64.h +0 -2
Index: linux-2.6/arch/sparc/include/asm/thread_info_64.h
===================================================================
@@ -256,8 +256,6 @@ static inline bool test_and_clear_restor
 	return true;
 }
 
-#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
-
 #define thread32_stack_is_64bit(__SP) (((__SP) & 0x1) != 0)
 #define test_thread_64bit_stack(__SP) \
 	((test_thread_flag(TIF_32BIT) && !thread32_stack_is_64bit(__SP)) ? \
arch/tile/include/asm/thread_info.h +0 -2
Index: linux-2.6/arch/tile/include/asm/thread_info.h
===================================================================
@@ -153,8 +153,6 @@ extern void _cpu_idle(void);
 #define TS_POLLING		0x0004	/* in idle loop but not sleeping */
 #define TS_RESTORE_SIGMASK	0x0008	/* restore signal mask in do_signal */
 
-#define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING)
-
 #ifndef __ASSEMBLY__
 #define HAVE_SET_RESTORE_SIGMASK	1
 static inline void set_restore_sigmask(void)
arch/x86/include/asm/thread_info.h +0 -2
Index: linux-2.6/arch/x86/include/asm/thread_info.h
===================================================================
@@ -241,8 +241,6 @@ static inline struct thread_info *curren
 					   skip sending interrupt */
 #define TS_RESTORE_SIGMASK	0x0008	/* restore signal mask in do_signal() */
 
-#define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING)
-
 #ifndef __ASSEMBLY__
 #define HAVE_SET_RESTORE_SIGMASK	1
 static inline void set_restore_sigmask(void)
include/linux/sched.h +20 -0
Index: linux-2.6/include/linux/sched.h
===================================================================
@@ -2472,6 +2472,26 @@ static inline unsigned long *end_of_stac
 
 #endif
 
+/*
+ * Idle thread specific functions to determine the need_resched
+ * polling state. We have two versions, one based on TS_POLLING in
+ * thread_info.status and one based on TIF_POLLING_NRFLAG in
+ * thread_info.flags
+ */
+#ifdef TS_POLLING
+static inline int tsk_is_polling(struct task_struct *p)
+{
+	return task_thread_info(p)->status & TS_POLLING;
+}
+#elif defined(TIF_POLLING_NRFLAG)
+static inline int tsk_is_polling(struct task_struct *p)
+{
+	test_tsk_thread_flag(p, TIF_POLLING_NRFLAG);
+}
+#else
+static inline int tsk_is_polling(struct task_struct *p) { return 0; }
+#endif
+
 static inline int object_is_on_stack(void *obj)
 {
 	void *stack = task_stack_page(current);
kernel/sched/core.c +0 -5
Index: linux-2.6/kernel/sched/core.c
===================================================================
@@ -512,11 +512,6 @@ static inline void init_hrtick(void)
  * the target CPU.
  */
 #ifdef CONFIG_SMP
-
-#ifndef tsk_is_polling
-#define tsk_is_polling(t) 0
-#endif
-
 void resched_task(struct task_struct *p)
 {
 	int cpu;
#4 lore raw

Re: [patch 02/34] arch: Consolidate tsk_is_polling()

arch/powerpc/include/asm/thread_info.h static inline bool test_thread_local_fla · line 188

Quoted 12 lines · Thomas Gleixner

Index: linux-2.6/arch/powerpc/include/asm/thread_info.h
===================================================================

arch/powerpc/include/asm/thread_info.h +0 -4
@@ -182,10 +182,6 @@ static inline bool test_thread_local_fla
 #define is_32bit_task()	(1)
 #endif
 
-#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
-
-#endif	/* !__ASSEMBLY__ */
-

I think taking out this #endif is wrong. probably wrong in the other arches as well.

Yours Tony

#5 lore raw

Re: [patch 02/34] arch: Consolidate tsk_is_polling()

In reply to Thomas Gleixner
Quoted 6 lines · Thomas Gleixner
include/linux/sched.h +6 -0
+/*
+ * Idle thread specific functions to determine the need_resched
+ * polling state. We have two versions, one based on TS_POLLING in
+ * thread_info.status and one based on TIF_POLLING_NRFLAG in
+ * thread_info.flags
+ */

include/linux/sched.h static inline unsigned long *end_of_stac · line 2490

Quoted 10 lines
include/linux/sched.h +10 -0
+#ifdef TS_POLLING
+static inline int tsk_is_polling(struct task_struct *p)
+{
+	return task_thread_info(p)->status & TS_POLLING;
+}
+#elif defined(TIF_POLLING_NRFLAG)
+static inline int tsk_is_polling(struct task_struct *p)
+{
+	test_tsk_thread_flag(p, TIF_POLLING_NRFLAG);
+}

On powerpc (at least) this is used before it's declared. Also I think you're missing a 'return' in that function.

*cough* https://www.kernel.org/pub/tools/crosstool/ *cough*

Yours Tony

#6 lore raw

Re: [patch 02/34] arch: Consolidate tsk_is_polling()

Quoted 13 lines · Tony Breeds
Quoted 11 lines · Thomas Gleixner
include/linux/sched.h +11 -0
+/*
+ * Idle thread specific functions to determine the need_resched
+ * polling state. We have two versions, one based on TS_POLLING in
+ * thread_info.status and one based on TIF_POLLING_NRFLAG in
+ * thread_info.flags
+ */
+#ifdef TS_POLLING
+static inline int tsk_is_polling(struct task_struct *p)
+{
+	return task_thread_info(p)->status & TS_POLLING;
+}
Quoted 8 lines

include/linux/sched.h static inline unsigned long *end_of_stac · line 2490

Quoted 5 lines
include/linux/sched.h +5 -0
+#elif defined(TIF_POLLING_NRFLAG)
+static inline int tsk_is_polling(struct task_struct *p)
+{
+	test_tsk_thread_flag(p, TIF_POLLING_NRFLAG);
+}

On powerpc (at least) this is used before it's declared. Also I think you're missing a 'return' in that function.

Mooo

Quoted 1 line

*cough* https://www.kernel.org/pub/tools/crosstool/ *cough*

Yes, I know. /me feels bad

#7 lore raw

[tip:smp/hotplug] arch: Consolidate tsk_is_polling()

In reply to Thomas Gleixner
arch: Consolidate tsk_is_polling()
Commit-ID:  ee761f629d598579594d7e1eb8c552f3c5f71e4d
Gitweb:     http://git.kernel.org/tip/ee761f629d598579594d7e1eb8c552f3c5f71e4d
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:32 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:22 +0200

arch: Consolidate tsk_is_polling()

Move it to a common place. Preparatory patch for implementing set/clear for the idle need_resched poll implementation.

---
 arch/alpha/include/asm/thread_info.h      |  2 --
 arch/ia64/include/asm/thread_info.h       |  2 --
 arch/metag/include/asm/thread_info.h      |  2 --
 arch/microblaze/include/asm/thread_info.h |  1 -
 arch/mn10300/include/asm/thread_info.h    |  2 --
 arch/openrisc/include/asm/thread_info.h   |  2 --
 arch/parisc/include/asm/thread_info.h     |  2 --
 arch/powerpc/include/asm/thread_info.h    |  2 --
 arch/sh/include/asm/thread_info.h         |  2 --
 arch/sparc/include/asm/thread_info_32.h   |  2 --
 arch/sparc/include/asm/thread_info_64.h   |  2 --
 arch/tile/include/asm/thread_info.h       |  2 --
 arch/x86/include/asm/thread_info.h        |  2 --
 include/linux/sched.h                     | 20 ++++++++++++++++++++
 kernel/sched/core.c                       |  5 -----
 15 files changed, 20 insertions(+), 30 deletions(-)
arch/alpha/include/asm/thread_info.h +0 -2
index 1f8c729..52cd2a4 100644
@@ -95,8 +95,6 @@ register struct thread_info *__current_thread_info __asm__("$8");
 #define TS_POLLING		0x0010	/* idle task polling need_resched,
 					   skip sending interrupt */
 
-#define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING)
-
 #ifndef __ASSEMBLY__
 #define HAVE_SET_RESTORE_SIGMASK	1
 static inline void set_restore_sigmask(void)
arch/ia64/include/asm/thread_info.h +0 -2
index 020d655..cade13d 100644
@@ -131,8 +131,6 @@ struct thread_info {
 #define TS_POLLING		1 	/* true if in idle loop and not sleeping */
 #define TS_RESTORE_SIGMASK	2	/* restore signal mask in do_signal() */
 
-#define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING)
-
 #ifndef __ASSEMBLY__
 #define HAVE_SET_RESTORE_SIGMASK	1
 static inline void set_restore_sigmask(void)
arch/metag/include/asm/thread_info.h +0 -2
index 0ecd34d..7c4a330 100644
@@ -150,6 +150,4 @@ static inline int kstack_end(void *addr)
 #define _TIF_WORK_MASK		(_TIF_ALLWORK_MASK & ~(_TIF_SYSCALL_TRACE | \
 				 _TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP))
 
-#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
-
 #endif /* _ASM_THREAD_INFO_H */
arch/microblaze/include/asm/thread_info.h +0 -1
index 008f304..de26ea6 100644
@@ -182,7 +182,6 @@ static inline bool test_and_clear_restore_sigmask(void)
 	ti->status &= ~TS_RESTORE_SIGMASK;
 	return true;
 }
-#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
 #endif
 
 #endif /* __KERNEL__ */
arch/mn10300/include/asm/thread_info.h +0 -2
index f90062b..224b426 100644
@@ -165,8 +165,6 @@ void arch_release_thread_info(struct thread_info *ti);
 #define _TIF_WORK_MASK		0x0000FFFE	/* work to do on interrupt/exception return */
 #define _TIF_ALLWORK_MASK	0x0000FFFF	/* work to do on any return to u-space */
 
-#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
-
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_THREAD_INFO_H */
arch/openrisc/include/asm/thread_info.h +0 -2
index 07f3212..d797acc 100644
@@ -128,8 +128,6 @@ register struct thread_info *current_thread_info_reg asm("r10");
 /* For OpenRISC, this is anything in the LSW other than syscall trace */
 #define _TIF_WORK_MASK (0xff & ~(_TIF_SYSCALL_TRACE|_TIF_SINGLESTEP))
 
-#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
-
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_THREAD_INFO_H */
arch/parisc/include/asm/thread_info.h +0 -2
index d1fb79a..6182832 100644
@@ -77,8 +77,6 @@ struct thread_info {
 #define _TIF_SYSCALL_TRACE_MASK (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP |	\
 				 _TIF_BLOCKSTEP)
 
-#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
-
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_PARISC_THREAD_INFO_H */
arch/powerpc/include/asm/thread_info.h +0 -2
index 406b7b9..8ceea14 100644
@@ -182,8 +182,6 @@ static inline bool test_thread_local_flags(unsigned int flags)
 #define is_32bit_task()	(1)
 #endif
 
-#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
-
 #endif	/* !__ASSEMBLY__ */
 
 #endif /* __KERNEL__ */
arch/sh/include/asm/thread_info.h +0 -2
index 7d5ac4e..45a9366 100644
@@ -207,8 +207,6 @@ static inline bool test_and_clear_restore_sigmask(void)
 	return true;
 }
 
-#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
-
 #endif	/* !__ASSEMBLY__ */
 
 #endif /* __KERNEL__ */
arch/sparc/include/asm/thread_info_32.h +0 -2
index 25849ae..dd38075 100644
@@ -132,8 +132,6 @@ register struct thread_info *current_thread_info_reg asm("g6");
 #define _TIF_DO_NOTIFY_RESUME_MASK	(_TIF_NOTIFY_RESUME | \
 					 _TIF_SIGPENDING)
 
-#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
-
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_THREAD_INFO_H */
arch/sparc/include/asm/thread_info_64.h +0 -2
index 269bd92..d5e5042 100644
@@ -256,8 +256,6 @@ static inline bool test_and_clear_restore_sigmask(void)
 	return true;
 }
 
-#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
-
 #define thread32_stack_is_64bit(__SP) (((__SP) & 0x1) != 0)
 #define test_thread_64bit_stack(__SP) \
 	((test_thread_flag(TIF_32BIT) && !thread32_stack_is_64bit(__SP)) ? \
arch/tile/include/asm/thread_info.h +0 -2
index e9c670d..ccc8ef3 100644
@@ -153,8 +153,6 @@ extern void _cpu_idle(void);
 #define TS_POLLING		0x0004	/* in idle loop but not sleeping */
 #define TS_RESTORE_SIGMASK	0x0008	/* restore signal mask in do_signal */
 
-#define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING)
-
 #ifndef __ASSEMBLY__
 #define HAVE_SET_RESTORE_SIGMASK	1
 static inline void set_restore_sigmask(void)
arch/x86/include/asm/thread_info.h +0 -2
index 2cd056e..a1df6e8 100644
@@ -241,8 +241,6 @@ static inline struct thread_info *current_thread_info(void)
 					   skip sending interrupt */
 #define TS_RESTORE_SIGMASK	0x0008	/* restore signal mask in do_signal() */
 
-#define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING)
-
 #ifndef __ASSEMBLY__
 #define HAVE_SET_RESTORE_SIGMASK	1
 static inline void set_restore_sigmask(void)
include/linux/sched.h +20 -0
index d35d2b6..6709a58 100644
@@ -2622,6 +2622,26 @@ static inline int spin_needbreak(spinlock_t *lock)
 }
 
 /*
+ * Idle thread specific functions to determine the need_resched
+ * polling state. We have two versions, one based on TS_POLLING in
+ * thread_info.status and one based on TIF_POLLING_NRFLAG in
+ * thread_info.flags
+ */
+#ifdef TS_POLLING
+static inline int tsk_is_polling(struct task_struct *p)
+{
+	return task_thread_info(p)->status & TS_POLLING;
+}
+#elif defined(TIF_POLLING_NRFLAG)
+static inline int tsk_is_polling(struct task_struct *p)
+{
+	return test_tsk_thread_flag(p, TIF_POLLING_NRFLAG);
+}
+#else
+static inline int tsk_is_polling(struct task_struct *p) { return 0; }
+#endif
+
+/*
  * Thread group CPU time accounting.
  */
 void thread_group_cputime(struct task_struct *tsk, struct task_cputime *times);
kernel/sched/core.c +0 -5
index 7f12624..243a20c 100644
@@ -512,11 +512,6 @@ static inline void init_hrtick(void)
  * the target CPU.
  */
 #ifdef CONFIG_SMP
-
-#ifndef tsk_is_polling
-#define tsk_is_polling(t) 0
-#endif
-
 void resched_task(struct task_struct *p)
 {
 	int cpu;
#8 lore raw

PATCH 3/34 idle: Implement set/clr functions for need_resched poll

In reply to Thomas Gleixner

Implement set/clear functions for the idle need_resched poll implementation.

---
 include/linux/sched.h |   23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)
include/linux/sched.h +22 -1
Index: linux-2.6/include/linux/sched.h
===================================================================
@@ -2473,7 +2473,7 @@ static inline unsigned long *end_of_stac
 #endif
 
 /*
- * Idle thread specific functions to determine the need_resched
+ * Idle thread specific functions for the the need_resched
  * polling state. We have two versions, one based on TS_POLLING in
  * thread_info.status and one based on TIF_POLLING_NRFLAG in
  * thread_info.flags
@@ -2483,13 +2483,34 @@ static inline int tsk_is_polling(struct 
 {
 	return task_thread_info(p)->status & TS_POLLING;
 }
+static inline void current_set_polling(void)
+{
+	current_thread_info()->status |= TS_POLLING;
+}
+
+static inline void current_clr_polling(void)
+{
+	current_thread_info()->status &= ~TS_POLLING;
+	smp_mb__after_clear_bit();
+}
 #elif defined(TIF_POLLING_NRFLAG)
 static inline int tsk_is_polling(struct task_struct *p)
 {
 	test_tsk_thread_flag(p, TIF_POLLING_NRFLAG);
 }
+static inline void current_set_polling(void)
+{
+	set_thread_flag(TIF_POLLING_NRFLAG);
+}
+
+static inline void current_clr_polling(void)
+{
+	clear_thread_flag(TIF_POLLING_NRFLAG);
+}
 #else
 static inline int tsk_is_polling(struct task_struct *p) { return 0; }
+static inline void current_set_polling(void) { }
+static inline void current_clr_polling(void) { }
 #endif
 
 static inline int object_is_on_stack(void *obj)
#9 lore raw

Re: [patch 03/34] idle: Implement set/clr functions for need_resched poll

Quoted 13 lines · Thomas Gleixner

Implement set/clear functions for the idle need_resched poll implementation.

---
 include/linux/sched.h |   23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

Index: linux-2.6/include/linux/sched.h
===================================================================

include/linux/sched.h static inline unsigned long *end_of_stac · line 2477

Quoted 6 lines
include/linux/sched.h +1 -1
@@ -2473,7 +2473,7 @@ static inline unsigned long *end_of_stac
 #endif
 
 /*
- * Idle thread specific functions to determine the need_resched
+ * Idle thread specific functions for the the need_resched
  * polling state. We have two versions, one based on TS_POLLING in

s/the the/the/?

Cheers
James

#10 lore raw

[tip:smp/hotplug] idle: Implement set/ clr functions for need_resched poll

In reply to Thomas Gleixner
idle: Implement set/clr functions for need_resched poll
Commit-ID:  3a98f871ecaf44806e188184332c3fec27c8f08c
Gitweb:     http://git.kernel.org/tip/3a98f871ecaf44806e188184332c3fec27c8f08c
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:33 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:22 +0200

idle: Implement set/clr functions for need_resched poll

Implement set/clear functions for the idle need_resched poll implementation.

---
 include/linux/sched.h | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
include/linux/sched.h +21 -0
index 6709a58..21fe9a1 100644
@@ -2632,13 +2632,34 @@ static inline int tsk_is_polling(struct task_struct *p)
 {
 	return task_thread_info(p)->status & TS_POLLING;
 }
+static inline void current_set_polling(void)
+{
+	current_thread_info()->status |= TS_POLLING;
+}
+
+static inline void current_clr_polling(void)
+{
+	current_thread_info()->status &= ~TS_POLLING;
+	smp_mb__after_clear_bit();
+}
 #elif defined(TIF_POLLING_NRFLAG)
 static inline int tsk_is_polling(struct task_struct *p)
 {
 	return test_tsk_thread_flag(p, TIF_POLLING_NRFLAG);
 }
+static inline void current_set_polling(void)
+{
+	set_thread_flag(TIF_POLLING_NRFLAG);
+}
+
+static inline void current_clr_polling(void)
+{
+	clear_thread_flag(TIF_POLLING_NRFLAG);
+}
 #else
 static inline int tsk_is_polling(struct task_struct *p) { return 0; }
+static inline void current_set_polling(void) { }
+static inline void current_clr_polling(void) { }
 #endif
 
 /*
#11 lore raw

PATCH 4/34 idle: Provide a generic entry point for the idle code

In reply to Thomas Gleixner

For now this calls cpu_idle(), but in the long run we want to move the cpu bringup code to the core and therefor we add a state argument.

---
 include/linux/cpu.h |    8 ++++++++
 init/main.c         |    2 +-
 kernel/Makefile     |    1 +
 kernel/cpu/Makefile |    1 +
 kernel/cpu/idle.c   |   10 ++++++++++
 5 files changed, 21 insertions(+), 1 deletion(-)
include/linux/cpu.h +8 -0
Index: linux-2.6/include/linux/cpu.h
===================================================================
@@ -212,4 +212,12 @@ static inline int disable_nonboot_cpus(v
 static inline void enable_nonboot_cpus(void) {}
 #endif /* !CONFIG_PM_SLEEP_SMP */
 
+enum cpuhp_state {
+	CPUHP_OFFLINE,
+	CPUHP_ONLINE,
+};
+
+void cpu_startup_entry(enum cpuhp_state state);
+void cpu_idle(void);
+
 #endif /* _LINUX_CPU_H_ */
init/main.c +1 -1
Index: linux-2.6/init/main.c
===================================================================
@@ -384,7 +384,7 @@ static noinline void __init_refok rest_i
 	init_idle_bootup_task(current);
 	schedule_preempt_disabled();
 	/* Call into cpu_idle with preempt disabled */
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 /* Check for early params. */
kernel/Makefile +1 -0
Index: linux-2.6/kernel/Makefile
===================================================================
@@ -24,6 +24,7 @@ endif
 
 obj-y += sched/
 obj-y += power/
+obj-y += cpu/
 
 obj-$(CONFIG_CHECKPOINT_RESTORE) += kcmp.o
 obj-$(CONFIG_FREEZER) += freezer.o
kernel/cpu/Makefile new file +1 -0
Index: linux-2.6/kernel/cpu/Makefile
===================================================================
@@ -0,0 +1 @@
+obj-y	= idle.o
kernel/cpu/idle.c new file +10 -0
Index: linux-2.6/kernel/cpu/idle.c
===================================================================
@@ -0,0 +1,10 @@
+/*
+ * Generic entry point for the idle threads
+ */
+#include <linux/sched.h>
+#include <linux/cpu.h>
+
+void cpu_startup_entry(enum cpuhp_state state)
+{
+	cpu_idle();
+}
#12 lore raw

[tip:smp/hotplug] idle: Provide a generic entry point for the idle code

idle: Provide a generic entry point for the idle code
Commit-ID:  a1a04ec3c7c27a682473fd9beb2c996316a64649
Gitweb:     http://git.kernel.org/tip/a1a04ec3c7c27a682473fd9beb2c996316a64649
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:34 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:23 +0200

idle: Provide a generic entry point for the idle code

For now this calls cpu_idle(), but in the long run we want to move the cpu bringup code to the core and therefor we add a state argument.

---
 include/linux/cpu.h |  8 ++++++++
 init/main.c         |  2 +-
 kernel/Makefile     |  1 +
 kernel/cpu/Makefile |  1 +
 kernel/cpu/idle.c   | 10 ++++++++++
 5 files changed, 21 insertions(+), 1 deletion(-)
include/linux/cpu.h +8 -0
index ce7a074..7419e30 100644
@@ -212,4 +212,12 @@ static inline int disable_nonboot_cpus(void) { return 0; }
 static inline void enable_nonboot_cpus(void) {}
 #endif /* !CONFIG_PM_SLEEP_SMP */
 
+enum cpuhp_state {
+	CPUHP_OFFLINE,
+	CPUHP_ONLINE,
+};
+
+void cpu_startup_entry(enum cpuhp_state state);
+void cpu_idle(void);
+
 #endif /* _LINUX_CPU_H_ */
init/main.c +1 -1
index 63534a1..adb179d 100644
@@ -384,7 +384,7 @@ static noinline void __init_refok rest_init(void)
 	init_idle_bootup_task(current);
 	schedule_preempt_disabled();
 	/* Call into cpu_idle with preempt disabled */
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 /* Check for early params. */
kernel/Makefile +1 -0
index bbde5f1..d1574d4 100644
@@ -24,6 +24,7 @@ endif
 
 obj-y += sched/
 obj-y += power/
+obj-y += cpu/
 
 obj-$(CONFIG_CHECKPOINT_RESTORE) += kcmp.o
 obj-$(CONFIG_FREEZER) += freezer.o
kernel/cpu/Makefile new file +1 -0
new file mode 100644
index 0000000..59ab052
@@ -0,0 +1 @@
+obj-y	= idle.o
kernel/cpu/idle.c new file +10 -0
new file mode 100644
index 0000000..1908f00
@@ -0,0 +1,10 @@
+/*
+ * Generic entry point for the idle threads
+ */
+#include <linux/sched.h>
+#include <linux/cpu.h>
+
+void cpu_startup_entry(enum cpuhp_state state)
+{
+	cpu_idle();
+}
#13 lore raw

Re: [tip:smp/hotplug] idle: Provide a generic entry point for the idle code

Quoted 13 lines · tip-bot for Thomas Gleixner
Commit-ID:  a1a04ec3c7c27a682473fd9beb2c996316a64649
Gitweb:     http://git.kernel.org/tip/a1a04ec3c7c27a682473fd9beb2c996316a64649
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:34 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:23 +0200

idle: Provide a generic entry point for the idle code

For now this calls cpu_idle(), but in the long run we want to move the cpu bringup code to the core and therefor we add a state argument.

...

Quoted 1 line

What is that ?

looks your scripts has problem to convert Cc to Reviewed-by

Yinghai

#14 lore raw

PATCH 5/34 idle: Implement generic idle function

In reply to Thomas Gleixner

All idle functions in arch/* are more or less the same, plus minus a few bugs and extra instrumentation, tickless support and other optional items.

Implement a generic idle function which resembles the functionality found in arch/. Provide weak arch_cpu_idle_* functions which can be overridden by the architecture code if needed.

---
 arch/Kconfig        |    3 +
 include/linux/cpu.h |    8 +++
 kernel/cpu/idle.c   |  105 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 116 insertions(+)
arch/Kconfig +3 -0
Index: linux-2.6/arch/Kconfig
===================================================================
@@ -216,6 +216,9 @@ config USE_GENERIC_SMP_HELPERS
 config GENERIC_SMP_IDLE_THREAD
        bool
 
+config GENERIC_IDLE_LOOP
+       bool
+
 # Select if arch init_task initializer is different to init/init_task.c
 config ARCH_INIT_TASK
        bool
include/linux/cpu.h +8 -0
Index: linux-2.6/include/linux/cpu.h
===================================================================
@@ -220,4 +220,12 @@ enum cpuhp_state {
 void cpu_startup_entry(enum cpuhp_state state);
 void cpu_idle(void);
 
+void cpu_idle_poll_ctrl(bool enable);
+
+void arch_cpu_idle(void);
+void arch_cpu_idle_prepare(void);
+void arch_cpu_idle_enter(void);
+void arch_cpu_idle_exit(void);
+void arch_cpu_idle_dead(void);
+
 #endif /* _LINUX_CPU_H_ */
kernel/cpu/idle.c +105 -0

113 lines not on this page · raw message

#15 lore raw

Re: [patch 05/34] idle: Implement generic idle function

Quoted 9 lines · Thomas Gleixner

All idle functions in arch/* are more or less the same, plus minus a few bugs and extra instrumentation, tickless support and other optional items.

Implement a generic idle function which resembles the functionality found in arch/. Provide weak arch_cpu_idle_* functions which can be overridden by the architecture code if needed.

[...]

Quoted 14 lines
kernel/cpu/idle.c +14 -0
+static void cpu_idle_loop(void)
+{
+	while (1) {
+		tick_nohz_idle_enter();
+
+		while (!need_resched()) {
+			check_pgt_cache();
+			rmb();
+
+			if (cpu_is_offline(smp_processor_id()))
+				arch_cpu_idle_dead();
+
+			local_irq_disable();
+			arch_cpu_idle_enter();

kernel/cpu/idle.c line 94

Quoted 10 lines
kernel/cpu/idle.c +10 -0
+
+			if (cpu_idle_force_poll) {
+				cpu_idle_poll();
+			} else {
+				current_clr_polling();
+				if (!need_resched()) {
+					stop_critical_timings();
+					rcu_idle_enter();
+					arch_cpu_idle();
+					WARN_ON_ONCE(!irqs_disabled());

This should be WARN_ON_ONCE(irqs_disabled()), no?

kernel/cpu/idle.c line 104

Quoted 10 lines
kernel/cpu/idle.c +10 -0
+					rcu_idle_exit();
+					start_critical_timings();
+				} else {
+					local_irq_enable();
+				}
+				current_set_polling();
+			}
+			arch_cpu_idle_exit();
+		}
+		tick_nohz_idle_exit();

I was wondering why the scheduler doesn't complain when being called with irqs disabled. In fact tick_nohz_idle_exit() enables irqs unconditionally iff CONFIG_NO_HZ is set.

Quoted 11 lines
kernel/cpu/idle.c +11 -0
+		schedule_preempt_disabled();
+	}
+}
+
+void cpu_startup_entry(enum cpuhp_state state)
+{
+	current_set_polling();
+	arch_cpu_idle_prepare();
+	cpu_idle_loop();
+}
+#endif
#16 lore raw

Re: [patch 05/34] idle: Implement generic idle function

Quoted 31 lines · Heiko Carstens
Quoted 9 lines · Thomas Gleixner

All idle functions in arch/* are more or less the same, plus minus a few bugs and extra instrumentation, tickless support and other optional items.

Implement a generic idle function which resembles the functionality found in arch/. Provide weak arch_cpu_idle_* functions which can be overridden by the architecture code if needed.

[...]

Quoted 18 lines
kernel/cpu/idle.c +18 -0
+static void cpu_idle_loop(void)
+{
+	while (1) {
+		tick_nohz_idle_enter();
+
+		while (!need_resched()) {
+			check_pgt_cache();
+			rmb();
+
+			if (cpu_is_offline(smp_processor_id()))
+				arch_cpu_idle_dead();
+
+			local_irq_disable();
+			arch_cpu_idle_enter();
+
+			if (cpu_idle_force_poll) {
+				cpu_idle_poll();
+			} else {
Quoted 8 lines

kernel/cpu/idle.c line 94

Quoted 6 lines
kernel/cpu/idle.c +6 -0
+				current_clr_polling();
+				if (!need_resched()) {
+					stop_critical_timings();
+					rcu_idle_enter();
+					arch_cpu_idle();
+					WARN_ON_ONCE(!irqs_disabled());

This should be WARN_ON_ONCE(irqs_disabled()), no?

Gah, yes.

Quoted 6 lines
Quoted 6 lines
kernel/cpu/idle.c +6 -0
+					rcu_idle_exit();
+					start_critical_timings();
+				} else {
+					local_irq_enable();
+				}
+				current_set_polling();
Quoted 8 lines

kernel/cpu/idle.c line 104

Quoted 4 lines
kernel/cpu/idle.c +4 -0
+			}
+			arch_cpu_idle_exit();
+		}
+		tick_nohz_idle_exit();

I was wondering why the scheduler doesn't complain when being called with irqs disabled. In fact tick_nohz_idle_exit() enables irqs unconditionally iff CONFIG_NO_HZ is set.

It should complain. I'll have a look again.

Quoted 13 lines
Quoted 11 lines
kernel/cpu/idle.c +11 -0
+		schedule_preempt_disabled();
+	}
+}
+
+void cpu_startup_entry(enum cpuhp_state state)
+{
+	current_set_polling();
+	arch_cpu_idle_prepare();
+	cpu_idle_loop();
+}
+#endif
#17 lore raw

Re: [patch 05/34] idle: Implement generic idle function

In reply to Thomas Gleixner
Quoted 14 lines · Thomas Gleixner

All idle functions in arch/* are more or less the same, plus minus a few bugs and extra instrumentation, tickless support and other optional items.

Implement a generic idle function which resembles the functionality found in arch/. Provide weak arch_cpu_idle_* functions which can be overridden by the architecture code if needed.

---
 arch/Kconfig        |    3 +
 include/linux/cpu.h |    8 +++
 kernel/cpu/idle.c   |  105 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 116 insertions(+)

[...]

Quoted 18 lines
kernel/cpu/idle.c +18 -0
+
+/*
+ * Generic idle loop implementation
+ */
+static void cpu_idle_loop(void)
+{
+	while (1) {
+		tick_nohz_idle_enter();
+
+		while (!need_resched()) {
+			check_pgt_cache();
+			rmb();
+
+			if (cpu_is_offline(smp_processor_id()))
+				arch_cpu_idle_dead();
+
+			local_irq_disable();
+			arch_cpu_idle_enter();

kernel/cpu/idle.c line 94

Quoted 10 lines
kernel/cpu/idle.c +10 -0
+
+			if (cpu_idle_force_poll) {
+				cpu_idle_poll();
+			} else {
+				current_clr_polling();
+				if (!need_resched()) {
+					stop_critical_timings();
+					rcu_idle_enter();
+					arch_cpu_idle();
+					WARN_ON_ONCE(!irqs_disabled());

I understand that you have changed it to WARN_ON_ONCE(irqs_disabled()) in the v2 hosted in your git tree..

Sometime ago, Deepthi (in CC) had added such a check and Rafael had faced some weird problems with that, and hence it was removed. Below are some links to that discussion.

https://lkml.org/lkml/2012/6/22/48
https://lkml.org/lkml/2012/6/24/132
https://lkml.org/lkml/2012/6/25/402

Rafael, do you still see that problem after applying Thomas' patches?

Quoted 13 lines
kernel/cpu/idle.c +11 -0
+					rcu_idle_exit();
+					start_critical_timings();
+				} else {
+					local_irq_enable();
+				}
+				current_set_polling();
+			}
+			arch_cpu_idle_exit();
+		}
+		tick_nohz_idle_exit();
+		schedule_preempt_disabled();

kernel/cpu/idle.c line 115

Quoted 10 lines
kernel/cpu/idle.c +10 -0
+	}
+}
+
+void cpu_startup_entry(enum cpuhp_state state)
+{
+	current_set_polling();
+	arch_cpu_idle_prepare();
+	cpu_idle_loop();
+}
+#endif

Regards,
Srivatsa S. Bhat

#18 lore raw

[tip:smp/hotplug] idle: Implement generic idle function

In reply to Thomas Gleixner
idle: Implement generic idle function
Commit-ID:  d166991234347215dc23fc9dc15a63a83a1a54e1
Gitweb:     http://git.kernel.org/tip/d166991234347215dc23fc9dc15a63a83a1a54e1
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:35 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:23 +0200

idle: Implement generic idle function

All idle functions in arch/* are more or less the same, plus minus a few bugs and extra instrumentation, tickless support and other optional items.

Implement a generic idle function which resembles the functionality found in arch/. Provide weak arch_cpu_idle_* functions which can be overridden by the architecture code if needed.

---
 arch/Kconfig        |   3 ++
 include/linux/cpu.h |   8 ++++
 kernel/cpu/idle.c   | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 116 insertions(+)
arch/Kconfig +3 -0
index 1455579..a699f37 100644
@@ -216,6 +216,9 @@ config USE_GENERIC_SMP_HELPERS
 config GENERIC_SMP_IDLE_THREAD
        bool
 
+config GENERIC_IDLE_LOOP
+       bool
+
 # Select if arch init_task initializer is different to init/init_task.c
 config ARCH_INIT_TASK
        bool
include/linux/cpu.h +8 -0
index 7419e30..c6f6e08 100644
@@ -220,4 +220,12 @@ enum cpuhp_state {
 void cpu_startup_entry(enum cpuhp_state state);
 void cpu_idle(void);
 
+void cpu_idle_poll_ctrl(bool enable);
+
+void arch_cpu_idle(void);
+void arch_cpu_idle_prepare(void);
+void arch_cpu_idle_enter(void);
+void arch_cpu_idle_exit(void);
+void arch_cpu_idle_dead(void);
+
 #endif /* _LINUX_CPU_H_ */
kernel/cpu/idle.c +105 -0

113 lines not on this page · raw message

#19 lore raw

Re: [tip:smp/hotplug] idle: Implement generic idle function

Built next-20130415 and got this on ia64 early in boot:

WARNING: at kernel/cpu/idle.c:94 cpu_idle_loop+0x360/0x380()
Hardware name: server rx2620
Modules linked in:

Call Trace:
 [<a000000100014ac0>] show_stack+0x80/0xa0
                                sp=a000000101287c50 bsp=a000000101280e48
 [<a000000100dabd40>] dump_stack+0x30/0x50
                                sp=a000000101287e20 bsp=a000000101280e30
 [<a000000100073e40>] warn_slowpath_common+0xc0/0x100
                                sp=a000000101287e20 bsp=a000000101280de8
 [<a000000100073ec0>] warn_slowpath_null+0x40/0x60
                                sp=a000000101287e20 bsp=a000000101280dc0
 [<a0000001000fa7a0>] cpu_idle_loop+0x360/0x380
                                sp=a000000101287e20 bsp=a000000101280d80
 [<a0000001000fa800>] cpu_startup_entry+0x40/0x60
                                sp=a000000101287e20 bsp=a000000101280d68
 [<a000000100d9f460>] rest_init+0x100/0x120
                                sp=a000000101287e20 bsp=a000000101280d50
 [<a00000010114d3b0>] start_kernel+0x770/0x890
                                sp=a000000101287e20 bsp=a000000101280cd0
 [<a000000100d9f320>] start_ap+0x760/0x780
                                sp=a000000101287e30 bsp=a000000101280bc0
#20 lore raw

Re: [tip:smp/hotplug] idle: Implement generic idle function

Quoted 3 lines · Tony Luck

Built next-20130415 and got this on ia64 early in boot:

WARNING: at kernel/cpu/idle.c:94 cpu_idle_loop+0x360/0x380()

Hmm, is safe_halt() returning with interrupts disabled? If yes, it lacks a local_irq_enable().

Thanks,

tglx

#21 lore raw

Re: [tip:smp/hotplug] idle: Implement generic idle function

Quoted 2 lines · Thomas Gleixner

Hmm, is safe_halt() returning with interrupts disabled? If yes, it lacks a local_irq_enable().

Quite probably. Adding arch_local_irq_enable() to arch_safe_halt() makes all the problems go away. I'll send you the one-line patch from a system that won't mung it like gmail will.

-Tony

#22 lore raw

PATCH 1/1 ia64: Make sure interrupts enabled when we "safe_halt()"

In commit d166991234347215dc23fc9dc15a63a83a1a54e1
idle: Implement generic idle function
Thomas Gleixner cleaned up many things but perturbed some fragile code that was keeping ia64 alive. So we started seeing:

   WARNING: at kernel/cpu/idle.c:94 cpu_idle_loop+0x360/0x380()

and other unpleasantness like system hangs during boot.

We really shouldn't ever halt with interrupts disabled.

---

Please fold into the same branch as the generic idle changes.

arch/ia64/include/asm/irqflags.h +1 -0
index 2b68d85..1bf2cf2 100644
@@ -89,6 +89,7 @@ static inline bool arch_irqs_disabled(void)
 
 static inline void arch_safe_halt(void)
 {
+	arch_local_irq_enable();
 	ia64_pal_halt_light();	/* PAL_HALT_LIGHT */
 }
 
#23 lore raw

[tip:smp/hotplug] ia64: Make sure interrupts enabled when we " safe_halt()"

ia64: Make sure interrupts enabled when we "safe_halt()"
Commit-ID:  2412aa1293a4159c610616305c17efd237c8208d
Gitweb:     http://git.kernel.org/tip/2412aa1293a4159c610616305c17efd237c8208d
Author:     Luck, Tony <[email protected]>
AuthorDate: Tue, 16 Apr 2013 11:35:56 -0700
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Wed, 17 Apr 2013 10:39:37 +0200

ia64: Make sure interrupts enabled when we "safe_halt()"

In commit d166991234347215dc23fc9dc15a63a83a1a54e1
idle: Implement generic idle function
Thomas Gleixner cleaned up many things but perturbed some fragile code that was keeping ia64 alive. So we started seeing:

   WARNING: at kernel/cpu/idle.c:94 cpu_idle_loop+0x360/0x380()

and other unpleasantness like system hangs during boot.

We really shouldn't ever halt with interrupts disabled.

---
 arch/ia64/include/asm/irqflags.h | 1 +
 1 file changed, 1 insertion(+)
arch/ia64/include/asm/irqflags.h +1 -0
index 2b68d85..1bf2cf2 100644
@@ -89,6 +89,7 @@ static inline bool arch_irqs_disabled(void)
 
 static inline void arch_safe_halt(void)
 {
+	arch_local_irq_enable();
 	ia64_pal_halt_light();	/* PAL_HALT_LIGHT */
 }
 
#24 lore raw

Re: [patch 05/34] idle: Implement generic idle function

In reply to Thomas Gleixner

kernel/cpu/idle.c line 115

Quoted 10 lines · Thomas Gleixner
kernel/cpu/idle.c +7 -0
 
+void cpu_startup_entry(enum cpuhp_state state)
+{
+       current_set_polling();
+       arch_cpu_idle_prepare();
+       cpu_idle_loop();
+}
+#endif

Hi Thomas..

Manish (cc'd) recently asked me purpose of _state_ argument in this routine, As this is unused here..

Was this reserved for future use?

#25 lore raw

Re: [patch 05/34] idle: Implement generic idle function

Quoted 14 lines · Viresh Kumar

kernel/cpu/idle.c line 115

Quoted 10 lines · Thomas Gleixner
kernel/cpu/idle.c +7 -0
 
+void cpu_startup_entry(enum cpuhp_state state)
+{
+       current_set_polling();
+       arch_cpu_idle_prepare();
+       cpu_idle_loop();
+}
+#endif

Hi Thomas..

Quoted 4 lines

Manish (cc'd) recently asked me purpose of _state_ argument in this routine, As this is unused here..

Was this reserved for future use?

Yep, if you dig the mail archives you'll find my cpu hotplug series which tries to convert it to a full state machine. So the state argument is due to that, because the boot cpu will call into that with a certain state and we want to allow archs to skip some states even on secondary cpus. So yes, it's unused, but its there on purpose. It's going to be used when my work backlog drops down to the cpuhotplug mess again. About 2 lightyears from now ....

Thanks,

tglx

#26 lore raw

PATCH 6/34 arc: Use generic idle loop

In reply to Thomas Gleixner

The generic idle loop implements all functionality. Aside of that it allows arc to implement the tsk_is_polling() functionality correctly, despite the patently (now gone) comment in the original arc cpu_idle() function:
/* Since we SLEEP in idle loop, TIF_POLLING_NRFLAG can't be set */ See kernel/cpu/idle.c

---
 arch/arc/Kconfig          |    1 +
 arch/arc/kernel/process.c |   27 +--------------------------
 arch/arc/kernel/smp.c     |    2 +-
 3 files changed, 3 insertions(+), 27 deletions(-)
arch/arc/Kconfig +1 -0
Index: linux-2.6/arch/arc/Kconfig
===================================================================
@@ -20,6 +20,7 @@ config ARC
 	select GENERIC_KERNEL_THREAD
 	select GENERIC_PENDING_IRQ if SMP
 	select GENERIC_SMP_IDLE_THREAD
+	select GENERIC_IDLE_LOOP
 	select HAVE_ARCH_KGDB
 	select HAVE_ARCH_TRACEHOOK
 	select HAVE_GENERIC_HARDIRQS
arch/arc/kernel/process.c +1 -26
Index: linux-2.6/arch/arc/kernel/process.c
===================================================================
@@ -41,37 +41,12 @@ SYSCALL_DEFINE0(arc_gettls)
 	return task_thread_info(current)->thr_ptr;
 }
 
-static inline void arch_idle(void)
+void arch_cpu_idle(void)
 {
 	/* sleep, but enable all interrupts before committing */
 	__asm__("sleep 0x3");
 }
 
-void cpu_idle(void)
-{
-	/* Since we SLEEP in idle loop, TIF_POLLING_NRFLAG can't be set */
-
-	/* endless idle loop with no priority at all */
-	while (1) {
-		tick_nohz_idle_enter();
-		rcu_idle_enter();
-
-doze:
-		local_irq_disable();
-		if (!need_resched()) {
-			arch_idle();
-			goto doze;
-		} else {
-			local_irq_enable();
-		}
-
-		rcu_idle_exit();
-		tick_nohz_idle_exit();
-
-		schedule_preempt_disabled();
-	}
-}
-
 asmlinkage void ret_from_fork(void);
 
 /* Layout of Child kernel mode stack as setup at the end of this function is
arch/arc/kernel/smp.c +1 -1
Index: linux-2.6/arch/arc/kernel/smp.c
===================================================================
@@ -141,7 +141,7 @@ void __cpuinit start_kernel_secondary(vo
 
 	local_irq_enable();
 	preempt_disable();
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 /*
#27 lore raw

Re: [patch 06/34] arc: Use generic idle loop

Hi Thomas,

Quoted 1 line · Thomas Gleixner

While the ARC specific changes look simple enough, do you have the series put up somewhere which I can merge to give a quick build/run test.

Are you planning to add this to linux-next at some point as that will make it really trivial to test out.

Thx,
-Vineet

#28 lore raw

[tip:smp/hotplug] arc: Use generic idle loop

In reply to Thomas Gleixner
arc: Use generic idle loop
Commit-ID:  fa35e42a00ec0120db2b5128753206efb288e789
Gitweb:     http://git.kernel.org/tip/fa35e42a00ec0120db2b5128753206efb288e789
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:36 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:23 +0200

arc: Use generic idle loop

The generic idle loop implements all functionality. Aside of that it allows arc to implement the tsk_is_polling() functionality correctly, despite the patently (now gone) comment in the original arc cpu_idle() function:
/* Since we SLEEP in idle loop, TIF_POLLING_NRFLAG can't be set */ See kernel/cpu/idle.c

---
 arch/arc/Kconfig          |  1 +
 arch/arc/kernel/process.c | 27 +--------------------------
 arch/arc/kernel/smp.c     |  2 +-
 3 files changed, 3 insertions(+), 27 deletions(-)
arch/arc/Kconfig +1 -0
index e6f4eca..b006977 100644
@@ -14,6 +14,7 @@ config ARC
 	select GENERIC_ATOMIC64
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_FIND_FIRST_BIT
+	select GENERIC_IDLE_LOOP
 	# for now, we don't need GENERIC_IRQ_PROBE, CONFIG_GENERIC_IRQ_CHIP
 	select GENERIC_IRQ_SHOW
 	select GENERIC_KERNEL_EXECVE
arch/arc/kernel/process.c +1 -26
index 0a7531d..cad6685 100644
@@ -41,37 +41,12 @@ SYSCALL_DEFINE0(arc_gettls)
 	return task_thread_info(current)->thr_ptr;
 }
 
-static inline void arch_idle(void)
+void arch_cpu_idle(void)
 {
 	/* sleep, but enable all interrupts before committing */
 	__asm__("sleep 0x3");
 }
 
-void cpu_idle(void)
-{
-	/* Since we SLEEP in idle loop, TIF_POLLING_NRFLAG can't be set */
-
-	/* endless idle loop with no priority at all */
-	while (1) {
-		tick_nohz_idle_enter();
-		rcu_idle_enter();
-
-doze:
-		local_irq_disable();
-		if (!need_resched()) {
-			arch_idle();
-			goto doze;
-		} else {
-			local_irq_enable();
-		}
-
-		rcu_idle_exit();
-		tick_nohz_idle_exit();
-
-		schedule_preempt_disabled();
-	}
-}
-
 asmlinkage void ret_from_fork(void);
 
 /* Layout of Child kernel mode stack as setup at the end of this function is
arch/arc/kernel/smp.c +1 -1
index 3af3e06..5c7fd60 100644
@@ -141,7 +141,7 @@ void __cpuinit start_kernel_secondary(void)
 
 	local_irq_enable();
 	preempt_disable();
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 /*
#29 lore raw

PATCH 7/34 alpha: Use generic idle loop

In reply to Thomas Gleixner

The core provides a generic idle poll loop.

Cc Richard Henderson <[email protected]>
Cc Ivan Kokshaysky <[email protected]>
Cc Matt Turner <[email protected]>
---
 arch/alpha/Kconfig          |    1 +
 arch/alpha/kernel/process.c |   19 -------------------
 arch/alpha/kernel/smp.c     |    3 +--
 3 files changed, 2 insertions(+), 21 deletions(-)
arch/alpha/Kconfig +1 -0
Index: linux-2.6/arch/alpha/Kconfig
===================================================================
@@ -17,6 +17,7 @@ config ALPHA
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select GENERIC_SMP_IDLE_THREAD
+	select GENERIC_IDLE_LOOP
 	select GENERIC_CMOS_UPDATE
 	select GENERIC_STRNCPY_FROM_USER
 	select GENERIC_STRNLEN_USER
arch/alpha/kernel/process.c +0 -19
Index: linux-2.6/arch/alpha/kernel/process.c
===================================================================
@@ -46,25 +46,6 @@
 void (*pm_power_off)(void) = machine_power_off;
 EXPORT_SYMBOL(pm_power_off);
 
-void
-cpu_idle(void)
-{
-	current_thread_info()->status |= TS_POLLING;
-
-	while (1) {
-		/* FIXME -- EV6 and LCA45 know how to power down
-		   the CPU.  */
-
-		rcu_idle_enter();
-		while (!need_resched())
-			cpu_relax();
-
-		rcu_idle_exit();
-		schedule_preempt_disabled();
-	}
-}
-
-
 struct halt_info {
 	int mode;
 	char *restart_cmd;
arch/alpha/kernel/smp.c +1 -2
Index: linux-2.6/arch/alpha/kernel/smp.c
===================================================================
@@ -167,8 +167,7 @@ smp_callin(void)
 	      cpuid, current, current->active_mm));
 
 	preempt_disable();
-	/* Do nothing.  */
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 /* Wait until hwrpb->txrdy is clear for cpu.  Return -1 on timeout.  */
#30 lore raw

Re: [patch 07/34] alpha: Use generic idle loop

Quoted 41 lines · Thomas Gleixner

The core provides a generic idle poll loop.

Cc Richard Henderson <[email protected]>
Cc Ivan Kokshaysky <[email protected]>
Cc Matt Turner <[email protected]>
---
 arch/alpha/Kconfig          |    1 +
 arch/alpha/kernel/process.c |   19 -------------------
 arch/alpha/kernel/smp.c     |    3 +--
 3 files changed, 2 insertions(+), 21 deletions(-)

Index: linux-2.6/arch/alpha/Kconfig
===================================================================

arch/alpha/Kconfig +1 -0
@@ -17,6 +17,7 @@ config ALPHA
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select GENERIC_SMP_IDLE_THREAD
+	select GENERIC_IDLE_LOOP
 	select GENERIC_CMOS_UPDATE
 	select GENERIC_STRNCPY_FROM_USER
 	select GENERIC_STRNLEN_USER

Index: linux-2.6/arch/alpha/kernel/process.c
===================================================================

arch/alpha/kernel/process.c +0 -9
@@ -46,25 +46,6 @@
 void (*pm_power_off)(void) = machine_power_off;
 EXPORT_SYMBOL(pm_power_off);
 
-void
-cpu_idle(void)
-{
-	current_thread_info()->status |= TS_POLLING;
-
-	while (1) {
-		/* FIXME -- EV6 and LCA45 know how to power down
-		   the CPU.  */
-

arch/alpha/kernel/process.c line 67

Quoted 10 lines
arch/alpha/kernel/process.c +0 -10
-		rcu_idle_enter();
-		while (!need_resched())
-			cpu_relax();
-
-		rcu_idle_exit();
-		schedule_preempt_disabled();
-	}
-}
-
-

(In all my replies, I'm referring to the code in your v2 on your git tree, but replying to the corresponding patches in your v1).

So, in alpha, we poll in cpu idle. In the generic implementation in kernel/cpu/idle.c, arch_cpu_idle() is defined as:

void __weak arch_cpu_idle(void)

{
        cpu_idle_poll();
}

Should it not have been:

void __weak arch_cpu_idle(void)

{
	current_set_polling();
        cpu_idle_poll();
	current_clr_polling();
}

instead?

Regards,
Srivatsa S. Bhat

Quoted 19 lines
arch/alpha/kernel/process.c +0 -0
 struct halt_info {
 	int mode;
 	char *restart_cmd;

Index: linux-2.6/arch/alpha/kernel/smp.c
===================================================================

arch/alpha/kernel/smp.c +1 -2
@@ -167,8 +167,7 @@ smp_callin(void)
 	      cpuid, current, current->active_mm));
 
 	preempt_disable();
-	/* Do nothing.  */
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 /* Wait until hwrpb->txrdy is clear for cpu.  Return -1 on timeout.  */
#31 lore raw

Re: [patch 07/34] alpha: Use generic idle loop

Quoted 13 lines · Srivatsa S. Bhat

(In all my replies, I'm referring to the code in your v2 on your git tree, but replying to the corresponding patches in your v1).

So, in alpha, we poll in cpu idle. In the generic implementation in kernel/cpu/idle.c, arch_cpu_idle() is defined as:

void __weak arch_cpu_idle(void)

{
        cpu_idle_poll();
}

Should it not have been:

Quoted 8 lines

void __weak arch_cpu_idle(void)

{
	current_set_polling();
        cpu_idle_poll();
	current_clr_polling();
}

instead?

Hmm, we should not clear it at all, because we are always polling and never leave polling mode. So instead of calling cpu_idle_poll from the weak arch_cpu_idle() we should set cpu_idle_force_poll so we drop into

	if (cpu_idle_force_poll) {
		cpu_idle_poll();
	} else ...

which keeps the polling flag set.

Thanks,

tglx

#32 lore raw

[tip:smp/hotplug] alpha: Use generic idle loop

In reply to Thomas Gleixner
alpha: Use generic idle loop
Commit-ID:  a123322d8afcfb5f86e0cc0062024084658aeeb2
Gitweb:     http://git.kernel.org/tip/a123322d8afcfb5f86e0cc0062024084658aeeb2
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:37 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:23 +0200

alpha: Use generic idle loop

The core provides a generic idle poll loop.

---
 arch/alpha/Kconfig          |  1 +
 arch/alpha/kernel/process.c | 19 -------------------
 arch/alpha/kernel/smp.c     |  3 +--
 3 files changed, 2 insertions(+), 21 deletions(-)
arch/alpha/Kconfig +1 -0
index 8a33ba0..6046982 100644
@@ -17,6 +17,7 @@ config ALPHA
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select GENERIC_SMP_IDLE_THREAD
+	select GENERIC_IDLE_LOOP
 	select GENERIC_CMOS_UPDATE
 	select GENERIC_STRNCPY_FROM_USER
 	select GENERIC_STRNLEN_USER
arch/alpha/kernel/process.c +0 -19
index 63d27fb..a3fd8a2 100644
@@ -46,25 +46,6 @@
 void (*pm_power_off)(void) = machine_power_off;
 EXPORT_SYMBOL(pm_power_off);
 
-void
-cpu_idle(void)
-{
-	current_thread_info()->status |= TS_POLLING;
-
-	while (1) {
-		/* FIXME -- EV6 and LCA45 know how to power down
-		   the CPU.  */
-
-		rcu_idle_enter();
-		while (!need_resched())
-			cpu_relax();
-
-		rcu_idle_exit();
-		schedule_preempt_disabled();
-	}
-}
-
-
 struct halt_info {
 	int mode;
 	char *restart_cmd;
arch/alpha/kernel/smp.c +1 -2
index 9603bc2..7b60834 100644
@@ -167,8 +167,7 @@ smp_callin(void)
 	      cpuid, current, current->active_mm));
 
 	preempt_disable();
-	/* Do nothing.  */
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 /* Wait until hwrpb->txrdy is clear for cpu.  Return -1 on timeout.  */
#33 lore raw

PATCH 8/34 arm: Use generic idle loop

In reply to Thomas Gleixner

Use the generic idle loop and replace enable/disable_hlt with the respective core functions.

---
 arch/arm/Kconfig                   |    2 
 arch/arm/include/asm/system_misc.h |    3 -
 arch/arm/kernel/process.c          |   96 ++++++++++---------------------------
 arch/arm/kernel/smp.c              |    2 
 arch/arm/mach-gemini/idle.c        |    4 +
 arch/arm/mach-gemini/irq.c         |    2 
 arch/arm/mach-ixp4xx/common.c      |    2 
 arch/arm/mach-omap1/pm.c           |    5 -
 arch/arm/mach-omap2/omap_hwmod.c   |    6 +-
 arch/arm/mach-omap2/pm.c           |    5 -
 arch/arm/mach-orion5x/board-dt.c   |    2 
 arch/arm/mach-orion5x/common.c     |    2 
 arch/arm/mach-shark/core.c         |    2 
 arch/arm/mach-shmobile/suspend.c   |    4 -
 arch/arm/mach-w90x900/dev.c        |    2 
 15 files changed, 47 insertions(+), 92 deletions(-)
arch/arm/Kconfig +2 -0
Index: linux-2.6/arch/arm/Kconfig
===================================================================
@@ -15,6 +15,8 @@ config ARM
 	select GENERIC_IRQ_SHOW
 	select GENERIC_PCI_IOMAP
 	select GENERIC_SMP_IDLE_THREAD
+	select GENERIC_IDLE_LOOP
+	select GENERIC_IDLE_POLL_SETUP
 	select GENERIC_STRNCPY_FROM_USER
 	select GENERIC_STRNLEN_USER
 	select HARDIRQS_SW_RESEND
arch/arm/include/asm/system_misc.h +0 -3
Index: linux-2.6/arch/arm/include/asm/system_misc.h
===================================================================
@@ -21,9 +21,6 @@ extern void (*arm_pm_idle)(void);
 
 extern unsigned int user_debug;
 
-extern void disable_hlt(void);
-extern void enable_hlt(void);
-
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __ASM_ARM_SYSTEM_MISC_H */
arch/arm/kernel/process.c +26 -70

114 lines not on this page · raw message

arch/arm/kernel/smp.c +1 -1
Index: linux-2.6/arch/arm/kernel/smp.c
===================================================================
@@ -336,7 +336,7 @@ asmlinkage void __cpuinit secondary_star
 	/*
 	 * OK, it's off to the idle thread for us
 	 */
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 void __init smp_cpus_done(unsigned int max_cpus)
arch/arm/mach-gemini/idle.c +3 -1
Index: linux-2.6/arch/arm/mach-gemini/idle.c
===================================================================
@@ -13,9 +13,11 @@ static void gemini_idle(void)
 	 * will never wakeup... Acctualy it is not very good to enable
 	 * interrupts first since scheduler can miss a tick, but there is
 	 * no other way around this. Platforms that needs it for power saving
-	 * should call enable_hlt() in init code, since by default it is
+	 * should enable it in init code, since by default it is
 	 * disabled.
 	 */
+
+	/* FIXME: Enabling interrupts here is racy! */
 	local_irq_enable();
 	cpu_do_idle();
 }
arch/arm/mach-gemini/irq.c +1 -1
Index: linux-2.6/arch/arm/mach-gemini/irq.c
===================================================================
@@ -77,7 +77,7 @@ void __init gemini_init_irq(void)
 	 * Disable the idle handler by default since it is buggy
 	 * For more info see arch/arm/mach-gemini/idle.c
 	 */
-	disable_hlt();
+	cpu_idle_poll_ctrl(true);
 
 	request_resource(&iomem_resource, &irq_resource);
 
arch/arm/mach-ixp4xx/common.c +1 -1
Index: linux-2.6/arch/arm/mach-ixp4xx/common.c
===================================================================
@@ -239,7 +239,7 @@ void __init ixp4xx_init_irq(void)
 	 * ixp4xx does not implement the XScale PWRMODE register
 	 * so it must not call cpu_do_idle().
 	 */
-	disable_hlt();
+	cpu_idle_poll_ctrl(true);
 
 	/* Route all sources to IRQ instead of FIQ */
 	*IXP4XX_ICLR = 0x0;
arch/arm/mach-omap1/pm.c +2 -3
Index: linux-2.6/arch/arm/mach-omap1/pm.c
===================================================================
@@ -584,8 +584,7 @@ static void omap_pm_init_proc(void)
 static int omap_pm_prepare(void)
 {
 	/* We cannot sleep in idle until we have resumed */
-	disable_hlt();
-
+	cpu_idle_poll_ctrl(true);
 	return 0;
 }
 
@@ -621,7 +620,7 @@ static int omap_pm_enter(suspend_state_t
 
 static void omap_pm_finish(void)
 {
-	enable_hlt();
+	cpu_idle_poll_ctrl(false);
 }
 
 
arch/arm/mach-omap2/omap_hwmod.c +3 -3
Index: linux-2.6/arch/arm/mach-omap2/omap_hwmod.c
===================================================================
@@ -2154,7 +2154,7 @@ static int _enable(struct omap_hwmod *oh
 	if (soc_ops.enable_module)
 		soc_ops.enable_module(oh);
 	if (oh->flags & HWMOD_BLOCK_WFI)
-		disable_hlt();
+		cpu_idle_poll_ctrl(true);
 
 	if (soc_ops.update_context_lost)
 		soc_ops.update_context_lost(oh);
@@ -2218,7 +2218,7 @@ static int _idle(struct omap_hwmod *oh)
 	_del_initiator_dep(oh, mpu_oh);
 
 	if (oh->flags & HWMOD_BLOCK_WFI)
-		enable_hlt();
+		cpu_idle_poll_ctrl(false);
 	if (soc_ops.disable_module)
 		soc_ops.disable_module(oh);
 
@@ -2328,7 +2328,7 @@ static int _shutdown(struct omap_hwmod *
 		_del_initiator_dep(oh, mpu_oh);
 		/* XXX what about the other system initiators here? dma, dsp */
 		if (oh->flags & HWMOD_BLOCK_WFI)
-			enable_hlt();
+			cpu_idle_poll_ctrl(false);
 		if (soc_ops.disable_module)
 			soc_ops.disable_module(oh);
 		_disable_clocks(oh);
arch/arm/mach-omap2/pm.c +2 -3
Index: linux-2.6/arch/arm/mach-omap2/pm.c
===================================================================
@@ -218,7 +218,7 @@ static int omap_pm_enter(suspend_state_t
 
 static int omap_pm_begin(suspend_state_t state)
 {
-	disable_hlt();
+	cpu_idle_poll_ctrl(true);
 	if (cpu_is_omap34xx())
 		omap_prcm_irq_prepare();
 	return 0;
@@ -226,8 +226,7 @@ static int omap_pm_begin(suspend_state_t
 
 static void omap_pm_end(void)
 {
-	enable_hlt();
-	return;
+	cpu_idle_poll_ctrl(false);
 }
 
 static void omap_pm_finish(void)
arch/arm/mach-orion5x/board-dt.c +1 -1
Index: linux-2.6/arch/arm/mach-orion5x/board-dt.c
===================================================================
@@ -52,7 +52,7 @@ static void __init orion5x_dt_init(void)
 	 */
 	if (dev == MV88F5281_DEV_ID && rev == MV88F5281_REV_D0) {
 		printk(KERN_INFO "Orion: Applying 5281 D0 WFI workaround.\n");
-		disable_hlt();
+		cpu_idle_poll_ctrl(true);
 	}
 
 	if (of_machine_is_compatible("lacie,ethernet-disk-mini-v2"))
arch/arm/mach-orion5x/common.c +1 -1
Index: linux-2.6/arch/arm/mach-orion5x/common.c
===================================================================
@@ -293,7 +293,7 @@ void __init orion5x_init(void)
 	 */
 	if (dev == MV88F5281_DEV_ID && rev == MV88F5281_REV_D0) {
 		printk(KERN_INFO "Orion: Applying 5281 D0 WFI workaround.\n");
-		disable_hlt();
+		cpu_idle_poll_ctrl(true);
 	}
 
 	/*
arch/arm/mach-shark/core.c +1 -1
Index: linux-2.6/arch/arm/mach-shark/core.c
===================================================================
@@ -130,7 +130,7 @@ static void __init shark_timer_init(void
 
 static void shark_init_early(void)
 {
-	disable_hlt();
+	cpu_idle_poll_ctrl(true);
 }
 
 MACHINE_START(SHARK, "Shark")
arch/arm/mach-shmobile/suspend.c +2 -2
Index: linux-2.6/arch/arm/mach-shmobile/suspend.c
===================================================================
@@ -23,13 +23,13 @@ static int shmobile_suspend_default_ente
 
 static int shmobile_suspend_begin(suspend_state_t state)
 {
-	disable_hlt();
+	cpu_idle_poll_ctrl(true);
 	return 0;
 }
 
 static void shmobile_suspend_end(void)
 {
-	enable_hlt();
+	cpu_idle_poll_ctrl(false);
 }
 
 struct platform_suspend_ops shmobile_suspend_ops = {
arch/arm/mach-w90x900/dev.c +1 -1
Index: linux-2.6/arch/arm/mach-w90x900/dev.c
===================================================================
@@ -531,7 +531,7 @@ static struct platform_device *nuc900_pu
 
 void __init nuc900_board_init(struct platform_device **device, int size)
 {
-	disable_hlt();
+	cpu_idle_poll_ctrl(true);
 	platform_add_devices(device, size);
 	platform_add_devices(nuc900_public_dev, ARRAY_SIZE(nuc900_public_dev));
 	spi_register_board_info(nuc900_spi_board_info,
Tested-by on v1 8/34
#34 lore raw

Re: [patch 08/34] arm: Use generic idle loop

Hi Thomas,

Quoted 5 lines · Thomas Gleixner

Use the generic idle loop and replace enable/disable_hlt with the respective core functions.

I gave patches 1-5 + this a quick spin on ARM (specifially some OMAP3 and OMAP4 platforms, with and without CPUidle enabled.)

The OMAP stuff needed a couple minor compile fixes (below), but otherwise it passes the quick "seems to work" test.

So at least for ARM/OMAP:

Kevin

arch/arm/mach-omap1/pm.c +1 -0
index 23c653a..db37f49 100644
@@ -43,6 +43,7 @@
 #include <linux/module.h>
 #include <linux/io.h>
 #include <linux/atomic.h>
+#include <linux/cpu.h>
 
 #include <asm/fncpy.h>
 #include <asm/system_misc.h>
arch/arm/mach-omap2/omap_hwmod.c +1 -0
index 3a6c6b8..2f17f95 100644
@@ -138,6 +138,7 @@
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/bootmem.h>
+#include <linux/cpu.h>
 
 #include <asm/system_misc.h>
#35 lore raw

Re: [patch 08/34] arm: Use generic idle loop

Quoted 7 lines · Kevin Hilman

Hi Thomas,

Quoted 3 lines · Thomas Gleixner

Use the generic idle loop and replace enable/disable_hlt with the respective core functions.

Quoted 8 lines
Quoted 2 lines

I gave patches 1-5 + this a quick spin on ARM (specifially some OMAP3 and OMAP4 platforms, with and without CPUidle enabled.)

The OMAP stuff needed a couple minor compile fixes (below), but otherwise it passes the quick "seems to work" test.

Yeah, that's needed for the other arch/arm conversions as well.

Thanks,

tglx

Quoted 31 lines

So at least for ARM/OMAP:

Kevin

arch/arm/mach-omap1/pm.c +1 -0
index 23c653a..db37f49 100644
@@ -43,6 +43,7 @@
 #include <linux/module.h>
 #include <linux/io.h>
 #include <linux/atomic.h>
+#include <linux/cpu.h>
 
 #include <asm/fncpy.h>
 #include <asm/system_misc.h>
arch/arm/mach-omap2/omap_hwmod.c +1 -0
index 3a6c6b8..2f17f95 100644
@@ -138,6 +138,7 @@
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/bootmem.h>
+#include <linux/cpu.h>
 
 #include <asm/system_misc.h>
 
#36 lore raw

Re: [patch 08/34] arm: Use generic idle loop

Quoted 12 lines · Thomas Gleixner
Quoted 10 lines · Kevin Hilman

Hi Thomas,

Quoted 5 lines · Thomas Gleixner

Use the generic idle loop and replace enable/disable_hlt with the respective core functions.

Quoted 7 lines
Quoted 5 lines

I gave patches 1-5 + this a quick spin on ARM (specifially some OMAP3 and OMAP4 platforms, with and without CPUidle enabled.)

The OMAP stuff needed a couple minor compile fixes (below), but otherwise it passes the quick "seems to work" test.

Yeah, that's needed for the other arch/arm conversions as well.

So, the only patch I got was this one, which is useless to test on its own...

#37 lore raw

Re: [patch 08/34] arm: Use generic idle loop

Quoted 16 lines · Russell King - ARM Linux
Quoted 15 lines · Thomas Gleixner
Quoted 13 lines · Kevin Hilman

Hi Thomas,

Quoted 5 lines · Thomas Gleixner

Use the generic idle loop and replace enable/disable_hlt with the respective core functions.

I gave patches 1-5 + this a quick spin on ARM (specifially some OMAP3 and OMAP4 platforms, with and without CPUidle enabled.)

Quoted 7 lines
Quoted 4 lines
Quoted 2 lines

The OMAP stuff needed a couple minor compile fixes (below), but otherwise it passes the quick "seems to work" test.

Yeah, that's needed for the other arch/arm conversions as well.

So, the only patch I got was this one, which is useless to test on its own...

I'm testing V2 now and will post an git URL with a testing branch later tonight.

Thanks,

tglx

#38 lore raw

Re: [patch 08/34] arm: Use generic idle loop

Quoted 21 lines · Thomas Gleixner
Quoted 19 lines · Russell King - ARM Linux
Quoted 18 lines · Thomas Gleixner
Quoted 15 lines · Kevin Hilman

Hi Thomas,

Quoted 5 lines · Thomas Gleixner

Use the generic idle loop and replace enable/disable_hlt with the respective core functions.

I gave patches 1-5 + this a quick spin on ARM (specifially some OMAP3 and OMAP4 platforms, with and without CPUidle enabled.)

The OMAP stuff needed a couple minor compile fixes (below), but otherwise it passes the quick "seems to work" test.

Quoted 7 lines
Quoted 4 lines
Quoted 1 line

Yeah, that's needed for the other arch/arm conversions as well.

So, the only patch I got was this one, which is useless to test on its own...

I'm testing V2 now and will post an git URL with a testing branch later tonight.

So, how can I review these changes when all there is is a git URL, and I *do* not want to pull them into my tree without first looking at the patches, possibly reviewing them and *replying* with the patch inline?

I see you've now added this stuff to -tip. I guess ARM doesn't matter to you at all. I guess having ARM people review the core changes doesn't matter either.

Well, I guess if it's broken, we'll just have to fix it up after the merge window.

One rule for x86, a different one for ARM. Let x86 maintainers moan about ARM people, but don't let ARM people moan about x86 maintainers. Yes, sure, right, I get it.

So, explicitly, my concern is this replacement of enable_hlt()/disable_hlt() with this cpu_idle_poll_ctrl(), and whether this interface is still counted - so that it's possible to call disable_hlt() to _permanently_ disable any hlt-based idle loop.

If that's not possible with your revised interface, you have just broken some ARM platforms. I can only guess... because you never copied your entire patch set to me nor to the ARM lists.

author Reviewed-by Cc: Srivatsa S. Bhat
#39 lore raw

Re: [patch 08/34] arm: Use generic idle loop

Russell,

Quoted 4 lines · Russell King - ARM Linux

On Mon, Mar 25, 2013 at 03:02:39PM +0100, Thomas Gleixner wrote:
So, how can I review these changes when all there is is a git URL, and I *do* not want to pull them into my tree without first looking at the patches, possibly reviewing them and *replying* with the patch inline?

the patches were CC'ed to LKML and linux-arch and I expected that you are at least having the latter. Find the relevant patch inlined below.

Quoted 10 lines

I see you've now added this stuff to -tip. I guess ARM doesn't matter to you at all. I guess having ARM people review the core changes doesn't matter either.

Well, I guess if it's broken, we'll just have to fix it up after the merge window.

One rule for x86, a different one for ARM. Let x86 maintainers moan about ARM people, but don't let ARM people moan about x86 maintainers. Yes, sure, right, I get it.

Sigh no.

Quoted 4 lines

So, explicitly, my concern is this replacement of enable_hlt()/disable_hlt() with this cpu_idle_poll_ctrl(), and whether this interface is still counted - so that it's possible to call disable_hlt() to _permanently_ disable any hlt-based idle loop.

It is a counter. I looked carefully at all the various slightly differently fcked up implementations and picked the counter based one as it fits all requirements.

Thanks,

tglx
---
Subject: idle: Implement generic idle function
From: Thomas Gleixner <[email protected]>
Date: Thu, 21 Mar 2013 22:49:35 +0100

All idle functions in arch/* are more or less the same, plus minus a few bugs and extra instrumentation, tickless support and other optional items.

Implement a generic idle function which resembles the functionality found in arch/. Provide weak arch_cpu_idle_* functions which can be overridden by the architecture code if needed.

---
 arch/Kconfig        |    3 +
 include/linux/cpu.h |    8 +++
 kernel/cpu/idle.c   |  105 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 116 insertions(+)
arch/Kconfig +3 -0
Index: linux-2.6/arch/Kconfig
===================================================================
@@ -216,6 +216,9 @@ config USE_GENERIC_SMP_HELPERS
 config GENERIC_SMP_IDLE_THREAD
        bool
 
+config GENERIC_IDLE_LOOP
+       bool
+
 # Select if arch init_task initializer is different to init/init_task.c
 config ARCH_INIT_TASK
        bool
include/linux/cpu.h +8 -0
Index: linux-2.6/include/linux/cpu.h
===================================================================
@@ -220,4 +220,12 @@ enum cpuhp_state {
 void cpu_startup_entry(enum cpuhp_state state);
 void cpu_idle(void);
 
+void cpu_idle_poll_ctrl(bool enable);
+
+void arch_cpu_idle(void);
+void arch_cpu_idle_prepare(void);
+void arch_cpu_idle_enter(void);
+void arch_cpu_idle_exit(void);
+void arch_cpu_idle_dead(void);
+
 #endif /* _LINUX_CPU_H_ */
kernel/cpu/idle.c +105 -0

113 lines not on this page · raw message

#40 lore raw

Re: [patch 08/34] arm: Use generic idle loop

Quoted 8 lines · Thomas Gleixner
Quoted 4 lines · Russell King - ARM Linux

On Mon, Mar 25, 2013 at 03:02:39PM +0100, Thomas Gleixner wrote:
So, how can I review these changes when all there is is a git URL, and I *do* not want to pull them into my tree without first looking at the patches, possibly reviewing them and *replying* with the patch inline?

the patches were CC'ed to LKML and linux-arch and I expected that you are at least having the latter. Find the relevant patch inlined below.

I've not been on linux-arch for a few years now, after it evolved into yet another lkml-like list with high traffic rates, where mainly specific x86 issues seemed to be discussed, rather than it being a way to contact all arch maintainers.

Quoted 3 lines

It is a counter. I looked carefully at all the various slightly differently fcked up implementations and picked the counter based one as it fits all requirements.

Great, thanks. The attached patch looks fine to me.

#41 lore raw

Re: [patch 08/34] arm: Use generic idle loop

Quoted 13 lines · Russell King - ARM Linux
Quoted 7 lines · Thomas Gleixner
Quoted 4 lines · Russell King - ARM Linux

On Mon, Mar 25, 2013 at 03:02:39PM +0100, Thomas Gleixner wrote:
So, how can I review these changes when all there is is a git URL, and I *do* not want to pull them into my tree without first looking at the patches, possibly reviewing them and *replying* with the patch inline?

the patches were CC'ed to LKML and linux-arch and I expected that you are at least having the latter. Find the relevant patch inlined below.

I've not been on linux-arch for a few years now, after it evolved into yet another lkml-like list with high traffic rates, where mainly specific x86 issues seemed to be discussed, rather than it being a way to contact all arch maintainers.

Quoted 4 lines
Quoted 3 lines

It is a counter. I looked carefully at all the various slightly differently fcked up implementations and picked the counter based one as it fits all requirements.

Great, thanks. The attached patch looks fine to me.

I'm pretty sure that we need to apply this patch now that rcu_idle_enter()/exit() is called lower down in the idle loop. Kevin, did you test hotplug?

----8<-----

From: Stephen Boyd <[email protected]>
Subject: [PATCH] ARM: smp: Drop RCU_NONIDLE usage in cpu_die()

Before f7b861b (arm: Use generic idle loop, 2013-03-21) ARM would kill the CPU within the rcu idle section. Now that the rcu_idle_enter()/exit() pair have been pushed lower down in the idle loop this is no longer true and so using RCU_NONIDLE here is no longer necessary and also harmful because RCU is not actually idle at this point.

---
 arch/arm/kernel/smp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/kernel/smp.c +1 -1
index 4619177..78f1eb5 100644
@@ -233,7 +233,7 @@ void __ref cpu_die(void)
        mb();
 
        /* Tell __cpu_die() that this CPU is now safe to dispose of */
-       RCU_NONIDLE(complete(&cpu_died));
+       complete(&cpu_died);
 
        /*
         * actual CPU shutdown procedure is at least platform (if not
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
#42 lore raw

Re: [patch 08/34] arm: Use generic idle loop

Quoted 14 lines · Stephen Boyd
Quoted 13 lines · Russell King - ARM Linux
Quoted 7 lines · Thomas Gleixner
Quoted 4 lines · Russell King - ARM Linux

On Mon, Mar 25, 2013 at 03:02:39PM +0100, Thomas Gleixner wrote:
So, how can I review these changes when all there is is a git URL, and I *do* not want to pull them into my tree without first looking at the patches, possibly reviewing them and *replying* with the patch inline?

the patches were CC'ed to LKML and linux-arch and I expected that you are at least having the latter. Find the relevant patch inlined below.

I've not been on linux-arch for a few years now, after it evolved into yet another lkml-like list with high traffic rates, where mainly specific x86 issues seemed to be discussed, rather than it being a way to contact all arch maintainers.

Quoted 8 lines
Quoted 4 lines
Quoted 3 lines

It is a counter. I looked carefully at all the various slightly differently fcked up implementations and picked the counter based one as it fits all requirements.

Great, thanks. The attached patch looks fine to me.

I'm pretty sure that we need to apply this patch now that rcu_idle_enter()/exit() is called lower down in the idle loop. Kevin, did you test hotplug?

If the patch is agreed on, I guess I should take it via my idle consolidation branch, right ?

Quoted 36 lines

----8<-----

From: Stephen Boyd <[email protected]>
Subject: [PATCH] ARM: smp: Drop RCU_NONIDLE usage in cpu_die()

Before f7b861b (arm: Use generic idle loop, 2013-03-21) ARM would kill the CPU within the rcu idle section. Now that the rcu_idle_enter()/exit() pair have been pushed lower down in the idle loop this is no longer true and so using RCU_NONIDLE here is no longer necessary and also harmful because RCU is not actually idle at this point.

---
 arch/arm/kernel/smp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/kernel/smp.c +1 -1
index 4619177..78f1eb5 100644
@@ -233,7 +233,7 @@ void __ref cpu_die(void)
        mb();
 
        /* Tell __cpu_die() that this CPU is now safe to dispose of */
-       RCU_NONIDLE(complete(&cpu_died));
+       complete(&cpu_died);
 
        /*
         * actual CPU shutdown procedure is at least platform (if not
Signature · 3 lines
-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
#43 lore raw

Re: [patch 08/34] arm: Use generic idle loop

Quoted 18 lines · Thomas Gleixner
Quoted 17 lines · Stephen Boyd
Quoted 16 lines · Russell King - ARM Linux
Quoted 7 lines · Thomas Gleixner
Quoted 4 lines · Russell King - ARM Linux

On Mon, Mar 25, 2013 at 03:02:39PM +0100, Thomas Gleixner wrote:
So, how can I review these changes when all there is is a git URL, and I *do* not want to pull them into my tree without first looking at the patches, possibly reviewing them and *replying* with the patch inline?

the patches were CC'ed to LKML and linux-arch and I expected that you are at least having the latter. Find the relevant patch inlined below.

I've not been on linux-arch for a few years now, after it evolved into yet another lkml-like list with high traffic rates, where mainly specific x86 issues seemed to be discussed, rather than it being a way to contact all arch maintainers.

Quoted 3 lines

It is a counter. I looked carefully at all the various slightly differently fcked up implementations and picked the counter based one as it fits all requirements.

Quoted 6 lines
Quoted 4 lines
Quoted 1 line

Great, thanks. The attached patch looks fine to me.

I'm pretty sure that we need to apply this patch now that rcu_idle_enter()/exit() is called lower down in the idle loop. Kevin, did you test hotplug?

If the patch is agreed on, I guess I should take it via my idle consolidation branch, right ?

Yes I think so. Hopefully Russell King or Paul McKenney can ack this patch.

Quoted 37 lines
Quoted 37 lines

----8<-----

From: Stephen Boyd <[email protected]>
Subject: [PATCH] ARM: smp: Drop RCU_NONIDLE usage in cpu_die()

Before f7b861b (arm: Use generic idle loop, 2013-03-21) ARM would kill the CPU within the rcu idle section. Now that the rcu_idle_enter()/exit() pair have been pushed lower down in the idle loop this is no longer true and so using RCU_NONIDLE here is no longer necessary and also harmful because RCU is not actually idle at this point.

---
 arch/arm/kernel/smp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/kernel/smp.c +1 -1
index 4619177..78f1eb5 100644
@@ -233,7 +233,7 @@ void __ref cpu_die(void)
        mb();
 
        /* Tell __cpu_die() that this CPU is now safe to dispose of */
-       RCU_NONIDLE(complete(&cpu_died));
+       complete(&cpu_died);
 
        /*
         * actual CPU shutdown procedure is at least platform (if not
Signature · 3 lines
-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
#44 lore raw

Re: [patch 08/34] arm: Use generic idle loop

Quoted 19 lines · Stephen Boyd
Quoted 18 lines · Thomas Gleixner
Quoted 17 lines · Stephen Boyd
Quoted 16 lines · Russell King - ARM Linux
Quoted 7 lines · Thomas Gleixner
Quoted 4 lines · Russell King - ARM Linux

On Mon, Mar 25, 2013 at 03:02:39PM +0100, Thomas Gleixner wrote:
So, how can I review these changes when all there is is a git URL, and I *do* not want to pull them into my tree without first looking at the patches, possibly reviewing them and *replying* with the patch inline?

the patches were CC'ed to LKML and linux-arch and I expected that you are at least having the latter. Find the relevant patch inlined below.

I've not been on linux-arch for a few years now, after it evolved into yet another lkml-like list with high traffic rates, where mainly specific x86 issues seemed to be discussed, rather than it being a way to contact all arch maintainers.

Quoted 3 lines

It is a counter. I looked carefully at all the various slightly differently fcked up implementations and picked the counter based one as it fits all requirements.

Quoted 23 lines
Quoted 6 lines
Quoted 4 lines
Quoted 1 line

Great, thanks. The attached patch looks fine to me.

I'm pretty sure that we need to apply this patch now that rcu_idle_enter()/exit() is called lower down in the idle loop. Kevin, did you test hotplug?

If the patch is agreed on, I guess I should take it via my idle consolidation branch, right ?

Yes I think so. Hopefully Russell King or Paul McKenney can ack this patch.

Quoted 14 lines
Quoted 14 lines

----8<-----

From: Stephen Boyd <[email protected]>
Subject: [PATCH] ARM: smp: Drop RCU_NONIDLE usage in cpu_die()

Before f7b861b (arm: Use generic idle loop, 2013-03-21) ARM would kill the CPU within the rcu idle section. Now that the rcu_idle_enter()/exit() pair have been pushed lower down in the idle loop this is no longer true and so using RCU_NONIDLE here is no longer necessary and also harmful because RCU is not actually idle at this point.

From an RCU perspective:

Quoted 29 lines
Quoted 23 lines
Quoted 23 lines
---
 arch/arm/kernel/smp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/kernel/smp.c +1 -1
index 4619177..78f1eb5 100644
@@ -233,7 +233,7 @@ void __ref cpu_die(void)
        mb();
 
        /* Tell __cpu_die() that this CPU is now safe to dispose of */
-       RCU_NONIDLE(complete(&cpu_died));
+       complete(&cpu_died);
 
        /*
         * actual CPU shutdown procedure is at least platform (if not
Signature · 3 lines
-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
#45 lore raw

PATCH 1/1 ARM: smp: Drop RCU_NONIDLE usage in cpu_die()

Before f7b861b (arm: Use generic idle loop, 2013-03-21) ARM would kill the CPU within the rcu idle section. Now that the rcu_idle_enter()/exit() pair have been pushed lower down in the idle loop this is no longer true and so using RCU_NONIDLE here is no longer necessary and also harmful because RCU is not actually idle at this point.

---
 arch/arm/kernel/smp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/kernel/smp.c +1 -1
index 4619177..78f1eb5 100644
@@ -233,7 +233,7 @@ void __ref cpu_die(void)
 	mb();
 
 	/* Tell __cpu_die() that this CPU is now safe to dispose of */
-	RCU_NONIDLE(complete(&cpu_died));
+	complete(&cpu_died);
 
 	/*
 	 * actual CPU shutdown procedure is at least platform (if not
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
#46 lore raw

[tip:smp/hotplug] arm: Use generic idle loop

In reply to Thomas Gleixner
arm: Use generic idle loop
Commit-ID:  f7b861b7a6d9d1838cbbb5f4053e61578b86d134
Gitweb:     http://git.kernel.org/tip/f7b861b7a6d9d1838cbbb5f4053e61578b86d134
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:38 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:24 +0200

arm: Use generic idle loop

Use the generic idle loop and replace enable/disable_hlt with the respective core functions.

---
 arch/arm/Kconfig                   |  2 +
 arch/arm/include/asm/system_misc.h |  3 --
 arch/arm/kernel/process.c          | 96 +++++++++++---------------------------
 arch/arm/kernel/smp.c              |  2 +-
 arch/arm/mach-gemini/idle.c        |  4 +-
 arch/arm/mach-gemini/irq.c         |  4 +-
 arch/arm/mach-ixp4xx/common.c      |  3 +-
 arch/arm/mach-omap1/pm.c           |  6 +--
 arch/arm/mach-omap2/omap_hwmod.c   |  7 +--
 arch/arm/mach-omap2/pm.c           |  5 +-
 arch/arm/mach-orion5x/board-dt.c   |  3 +-
 arch/arm/mach-orion5x/common.c     |  2 +-
 arch/arm/mach-shark/core.c         |  3 +-
 arch/arm/mach-shmobile/suspend.c   |  6 ++-
 arch/arm/mach-w90x900/dev.c        |  3 +-
 15 files changed, 57 insertions(+), 92 deletions(-)
arch/arm/Kconfig +2 -0
index 1cacda4..128551f 100644
@@ -15,6 +15,8 @@ config ARM
 	select GENERIC_IRQ_SHOW
 	select GENERIC_PCI_IOMAP
 	select GENERIC_SMP_IDLE_THREAD
+	select GENERIC_IDLE_LOOP
+	select GENERIC_IDLE_POLL_SETUP
 	select GENERIC_STRNCPY_FROM_USER
 	select GENERIC_STRNLEN_USER
 	select HARDIRQS_SW_RESEND
arch/arm/include/asm/system_misc.h +0 -3
index 5a85f14..21a23e3 100644
@@ -21,9 +21,6 @@ extern void (*arm_pm_idle)(void);
 
 extern unsigned int user_debug;
 
-extern void disable_hlt(void);
-extern void enable_hlt(void);
-
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __ASM_ARM_SYSTEM_MISC_H */
arch/arm/kernel/process.c +26 -70

114 lines not on this page · raw message

arch/arm/kernel/smp.c +1 -1
index 1f2cccc..4619177 100644
@@ -336,7 +336,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
 	/*
 	 * OK, it's off to the idle thread for us
 	 */
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 void __init smp_cpus_done(unsigned int max_cpus)
arch/arm/mach-gemini/idle.c +3 -1
index 92bbd6b..87dff4f 100644
@@ -13,9 +13,11 @@ static void gemini_idle(void)
 	 * will never wakeup... Acctualy it is not very good to enable
 	 * interrupts first since scheduler can miss a tick, but there is
 	 * no other way around this. Platforms that needs it for power saving
-	 * should call enable_hlt() in init code, since by default it is
+	 * should enable it in init code, since by default it is
 	 * disabled.
 	 */
+
+	/* FIXME: Enabling interrupts here is racy! */
 	local_irq_enable();
 	cpu_do_idle();
 }
arch/arm/mach-gemini/irq.c +3 -1
index 020852d..6d8f6d1 100644
@@ -15,6 +15,8 @@
 #include <linux/stddef.h>
 #include <linux/list.h>
 #include <linux/sched.h>
+#include <linux/cpu.h>
+
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
 #include <asm/system_misc.h>
@@ -77,7 +79,7 @@ void __init gemini_init_irq(void)
 	 * Disable the idle handler by default since it is buggy
 	 * For more info see arch/arm/mach-gemini/idle.c
 	 */
-	disable_hlt();
+	cpu_idle_poll_ctrl(true);
 
 	request_resource(&iomem_resource, &irq_resource);
 
arch/arm/mach-ixp4xx/common.c +2 -1
index 1dbeb7c..6600cff 100644
@@ -29,6 +29,7 @@
 #include <linux/io.h>
 #include <linux/export.h>
 #include <linux/gpio.h>
+#include <linux/cpu.h>
 
 #include <mach/udc.h>
 #include <mach/hardware.h>
@@ -239,7 +240,7 @@ void __init ixp4xx_init_irq(void)
 	 * ixp4xx does not implement the XScale PWRMODE register
 	 * so it must not call cpu_do_idle().
 	 */
-	disable_hlt();
+	cpu_idle_poll_ctrl(true);
 
 	/* Route all sources to IRQ instead of FIQ */
 	*IXP4XX_ICLR = 0x0;
arch/arm/mach-omap1/pm.c +3 -3
index 7a7690a..db37f49 100644
@@ -43,6 +43,7 @@
 #include <linux/module.h>
 #include <linux/io.h>
 #include <linux/atomic.h>
+#include <linux/cpu.h>
 
 #include <asm/fncpy.h>
 #include <asm/system_misc.h>
@@ -584,8 +585,7 @@ static void omap_pm_init_proc(void)
 static int omap_pm_prepare(void)
 {
 	/* We cannot sleep in idle until we have resumed */
-	disable_hlt();
-
+	cpu_idle_poll_ctrl(true);
 	return 0;
 }
 
@@ -621,7 +621,7 @@ static int omap_pm_enter(suspend_state_t state)
 
 static void omap_pm_finish(void)
 {
-	enable_hlt();
+	cpu_idle_poll_ctrl(false);
 }
 
 
arch/arm/mach-omap2/omap_hwmod.c +4 -3
index a202a47..e512253 100644
@@ -138,6 +138,7 @@
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/bootmem.h>
+#include <linux/cpu.h>
 
 #include <asm/system_misc.h>
 
@@ -2157,7 +2158,7 @@ static int _enable(struct omap_hwmod *oh)
 	if (soc_ops.enable_module)
 		soc_ops.enable_module(oh);
 	if (oh->flags & HWMOD_BLOCK_WFI)
-		disable_hlt();
+		cpu_idle_poll_ctrl(true);
 
 	if (soc_ops.update_context_lost)
 		soc_ops.update_context_lost(oh);
@@ -2221,7 +2222,7 @@ static int _idle(struct omap_hwmod *oh)
 	_del_initiator_dep(oh, mpu_oh);
 
 	if (oh->flags & HWMOD_BLOCK_WFI)
-		enable_hlt();
+		cpu_idle_poll_ctrl(false);
 	if (soc_ops.disable_module)
 		soc_ops.disable_module(oh);
 
@@ -2331,7 +2332,7 @@ static int _shutdown(struct omap_hwmod *oh)
 		_del_initiator_dep(oh, mpu_oh);
 		/* XXX what about the other system initiators here? dma, dsp */
 		if (oh->flags & HWMOD_BLOCK_WFI)
-			enable_hlt();
+			cpu_idle_poll_ctrl(false);
 		if (soc_ops.disable_module)
 			soc_ops.disable_module(oh);
 		_disable_clocks(oh);
arch/arm/mach-omap2/pm.c +2 -3
index 673a4c1..dec5533 100644
@@ -218,7 +218,7 @@ static int omap_pm_enter(suspend_state_t suspend_state)
 
 static int omap_pm_begin(suspend_state_t state)
 {
-	disable_hlt();
+	cpu_idle_poll_ctrl(true);
 	if (cpu_is_omap34xx())
 		omap_prcm_irq_prepare();
 	return 0;
@@ -226,8 +226,7 @@ static int omap_pm_begin(suspend_state_t state)
 
 static void omap_pm_end(void)
 {
-	enable_hlt();
-	return;
+	cpu_idle_poll_ctrl(false);
 }
 
 static void omap_pm_finish(void)
arch/arm/mach-orion5x/board-dt.c +2 -1
index 35a8014..94fbb81 100644
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
+#include <linux/cpu.h>
 #include <asm/system_misc.h>
 #include <asm/mach/arch.h>
 #include <mach/orion5x.h>
@@ -52,7 +53,7 @@ static void __init orion5x_dt_init(void)
 	 */
 	if (dev == MV88F5281_DEV_ID && rev == MV88F5281_REV_D0) {
 		printk(KERN_INFO "Orion: Applying 5281 D0 WFI workaround.\n");
-		disable_hlt();
+		cpu_idle_poll_ctrl(true);
 	}
 
 	if (of_machine_is_compatible("lacie,ethernet-disk-mini-v2"))
arch/arm/mach-orion5x/common.c +1 -1
index d068f14..ad71c8a 100644
@@ -293,7 +293,7 @@ void __init orion5x_init(void)
 	 */
 	if (dev == MV88F5281_DEV_ID && rev == MV88F5281_REV_D0) {
 		printk(KERN_INFO "Orion: Applying 5281 D0 WFI workaround.\n");
-		disable_hlt();
+		cpu_idle_poll_ctrl(true);
 	}
 
 	/*
arch/arm/mach-shark/core.c +2 -1
index b63dec8..1535557 100644
@@ -10,6 +10,7 @@
 #include <linux/sched.h>
 #include <linux/serial_8250.h>
 #include <linux/io.h>
+#include <linux/cpu.h>
 
 #include <asm/setup.h>
 #include <asm/mach-types.h>
@@ -130,7 +131,7 @@ static void __init shark_timer_init(void)
 
 static void shark_init_early(void)
 {
-	disable_hlt();
+	cpu_idle_poll_ctrl(true);
 }
 
 MACHINE_START(SHARK, "Shark")
arch/arm/mach-shmobile/suspend.c +4 -2
index 47d83f7..5d92b5d 100644
@@ -12,6 +12,8 @@
 #include <linux/suspend.h>
 #include <linux/module.h>
 #include <linux/err.h>
+#include <linux/cpu.h>
+
 #include <asm/io.h>
 #include <asm/system_misc.h>
 
@@ -23,13 +25,13 @@ static int shmobile_suspend_default_enter(suspend_state_t suspend_state)
 
 static int shmobile_suspend_begin(suspend_state_t state)
 {
-	disable_hlt();
+	cpu_idle_poll_ctrl(true);
 	return 0;
 }
 
 static void shmobile_suspend_end(void)
 {
-	enable_hlt();
+	cpu_idle_poll_ctrl(false);
 }
 
 struct platform_suspend_ops shmobile_suspend_ops = {
arch/arm/mach-w90x900/dev.c +2 -1
index 7abdb96..e65a80a 100644
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
+#include <linux/cpu.h>
 
 #include <linux/mtd/physmap.h>
 #include <linux/mtd/mtd.h>
@@ -531,7 +532,7 @@ static struct platform_device *nuc900_public_dev[] __initdata = {
 
 void __init nuc900_board_init(struct platform_device **device, int size)
 {
-	disable_hlt();
+	cpu_idle_poll_ctrl(true);
 	platform_add_devices(device, size);
 	platform_add_devices(nuc900_public_dev, ARRAY_SIZE(nuc900_public_dev));
 	spi_register_board_info(nuc900_spi_board_info,
#47 lore raw

PATCH 9/34 arm64: Use generic idle loop

In reply to Thomas Gleixner
---
 arch/arm64/Kconfig          |    1 +
 arch/arm64/kernel/process.c |   43 +++++--------------------------------------
 arch/arm64/kernel/smp.c     |    2 +-
 3 files changed, 7 insertions(+), 39 deletions(-)
arch/arm64/Kconfig +1 -0
Index: linux-2.6/arch/arm64/Kconfig
===================================================================
@@ -14,6 +14,7 @@ config ARM64
 	select GENERIC_IRQ_PROBE
 	select GENERIC_IRQ_SHOW
 	select GENERIC_SMP_IDLE_THREAD
+	select GENERIC_IDLE_LOOP
 	select GENERIC_TIME_VSYSCALL
 	select HARDIRQS_SW_RESEND
 	select HAVE_ARCH_TRACEHOOK
arch/arm64/kernel/process.c +5 -38

59 lines not on this page · raw message

arch/arm64/kernel/smp.c +1 -1
Index: linux-2.6/arch/arm64/kernel/smp.c
===================================================================
@@ -216,7 +216,7 @@ asmlinkage void __cpuinit secondary_star
 	/*
 	 * OK, it's off to the idle thread for us
 	 */
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 void __init smp_cpus_done(unsigned int max_cpus)
maintainer Acked-by on v1 9/34
#48 lore raw

Re: [patch 09/34] arm64: Use generic idle loop

Quoted 8 lines · Thomas Gleixner

---
Index: linux-2.6/arch/arm64/Kconfig
===================================================================

arch/arm64/Kconfig config ARM64 · line 20

Quoted 7 lines
arch/arm64/Kconfig +1 -0
@@ -14,6 +14,7 @@ config ARM64
 	select GENERIC_IRQ_PROBE
 	select GENERIC_IRQ_SHOW
 	select GENERIC_SMP_IDLE_THREAD
+	select GENERIC_IDLE_LOOP
 	select GENERIC_TIME_VSYSCALL
 	select HARDIRQS_SW_RESEND
 	select HAVE_ARCH_TRACEHOOK

Minor thing, I try to keep these entries alphabetically sorted (it won't last long, I'm sure). Otherwise,

#49 lore raw

[tip:smp/hotplug] arm64: Use generic idle loop

In reply to Thomas Gleixner
arm64: Use generic idle loop
Commit-ID:  0087298f68a726493a637c4f68d148b31102b0d9
Gitweb:     http://git.kernel.org/tip/0087298f68a726493a637c4f68d148b31102b0d9
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:39 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:24 +0200

arm64: Use generic idle loop

---
 arch/arm64/Kconfig          |  1 +
 arch/arm64/kernel/process.c | 43 +++++--------------------------------------
 arch/arm64/kernel/smp.c     |  2 +-
 3 files changed, 7 insertions(+), 39 deletions(-)
arch/arm64/Kconfig +1 -0
index 9b6d19f..ca2c871 100644
@@ -9,6 +9,7 @@ config ARM64
 	select CLONE_BACKWARDS
 	select COMMON_CLK
 	select GENERIC_CLOCKEVENTS
+	select GENERIC_IDLE_LOOP
 	select GENERIC_IOMAP
 	select GENERIC_IRQ_PROBE
 	select GENERIC_IRQ_SHOW
arch/arm64/kernel/process.c +5 -38

59 lines not on this page · raw message

arch/arm64/kernel/smp.c +1 -1
index bdd3459..261445c 100644
@@ -216,7 +216,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
 	/*
 	 * OK, it's off to the idle thread for us
 	 */
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 void __init smp_cpus_done(unsigned int max_cpus)
#50 lore raw

PATCH 10/34 avr32: Use generic idle loop

In reply to Thomas Gleixner

Also replace the idle poll enforcement by the generic functionality.

Cc Hans-Christian Egtvedt <[email protected]>
---
 arch/avr32/Kconfig                       |    1 +
 arch/avr32/kernel/process.c              |   13 ++-----------
 arch/avr32/kernel/time.c                 |    8 ++++++--
 arch/avr32/mach-at32ap/include/mach/pm.h |   24 ------------------------
 arch/avr32/mach-at32ap/pm-at32ap700x.S   |    7 -------
 5 files changed, 9 insertions(+), 44 deletions(-)
arch/avr32/Kconfig +1 -0
Index: linux-2.6/arch/avr32/Kconfig
===================================================================
@@ -10,6 +10,7 @@ config AVR32
 	select VIRT_TO_BUS
 	select GENERIC_IRQ_PROBE
 	select GENERIC_ATOMIC64
+	seletc GENERIC_IDLE_LOOP
 	select HARDIRQS_SW_RESEND
 	select GENERIC_IRQ_SHOW
 	select ARCH_HAVE_CUSTOM_GPIO_H
arch/avr32/kernel/process.c +2 -11
Index: linux-2.6/arch/avr32/kernel/process.c
===================================================================
@@ -30,18 +30,9 @@ EXPORT_SYMBOL(pm_power_off);
  * This file handles the architecture-dependent parts of process handling..
  */
 
-void cpu_idle(void)
+void arch_cpu_idle(void)
 {
-	/* endless idle loop with no priority at all */
-	while (1) {
-		tick_nohz_idle_enter();
-		rcu_idle_enter();
-		while (!need_resched())
-			cpu_idle_sleep();
-		rcu_idle_exit();
-		tick_nohz_idle_exit();
-		schedule_preempt_disabled();
-	}
+	cpu_enter_idle();
 }
 
 void machine_halt(void)
arch/avr32/kernel/time.c +6 -2
Index: linux-2.6/arch/avr32/kernel/time.c
===================================================================
@@ -87,13 +87,17 @@ static void comparator_mode(enum clock_e
 		pr_debug("%s: start\n", evdev->name);
 		/* FALLTHROUGH */
 	case CLOCK_EVT_MODE_RESUME:
-		cpu_disable_idle_sleep();
+		/*
+		 * If we're using the COUNT and COMPARE registers we
+		 * need to force idle poll.
+		 */
+		cpu_idle_poll_ctrl(true);
 		break;
 	case CLOCK_EVT_MODE_UNUSED:
 	case CLOCK_EVT_MODE_SHUTDOWN:
 		sysreg_write(COMPARE, 0);
 		pr_debug("%s: stop\n", evdev->name);
-		cpu_enable_idle_sleep();
+		cpu_idle_poll_ctrl(false);
 		break;
 	default:
 		BUG();
arch/avr32/mach-at32ap/include/mach/pm.h +0 -24
Index: linux-2.6/arch/avr32/mach-at32ap/include/mach/pm.h
===================================================================
@@ -21,30 +21,6 @@
 extern void cpu_enter_idle(void);
 extern void cpu_enter_standby(unsigned long sdramc_base);
 
-extern bool disable_idle_sleep;
-
-static inline void cpu_disable_idle_sleep(void)
-{
-	disable_idle_sleep = true;
-}
-
-static inline void cpu_enable_idle_sleep(void)
-{
-	disable_idle_sleep = false;
-}
-
-static inline void cpu_idle_sleep(void)
-{
-	/*
-	 * If we're using the COUNT and COMPARE registers for
-	 * timekeeping, we can't use the IDLE state.
-	 */
-	if (disable_idle_sleep)
-		cpu_relax();
-	else
-		cpu_enter_idle();
-}
-
 void intc_set_suspend_handler(unsigned long offset);
 #endif
 
arch/avr32/mach-at32ap/pm-at32ap700x.S +0 -7
Index: linux-2.6/arch/avr32/mach-at32ap/pm-at32ap700x.S
===================================================================
@@ -18,13 +18,6 @@
 /* Same as 0xfff00000 but fits in a 21 bit signed immediate */
 #define PM_BASE	-0x100000
 
-	.section .bss, "wa", @nobits
-	.global	disable_idle_sleep
-	.type	disable_idle_sleep, @object
-disable_idle_sleep:
-	.int	4
-	.size	disable_idle_sleep, . - disable_idle_sleep
-
 	/* Keep this close to the irq handlers */
 	.section .irq.text, "ax", @progbits
 
#51 lore raw

[tip:smp/hotplug] avr32: Use generic idle loop

avr32: Use generic idle loop
Commit-ID:  01426478df3a8791ff5c8b6b82d409e699cfaf38
Gitweb:     http://git.kernel.org/tip/01426478df3a8791ff5c8b6b82d409e699cfaf38
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:40 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:24 +0200

avr32: Use generic idle loop

Also replace the idle poll enforcement by the generic functionality.

---
 arch/avr32/Kconfig                       |  1 +
 arch/avr32/kernel/process.c              | 13 ++-----------
 arch/avr32/kernel/time.c                 |  9 +++++++--
 arch/avr32/mach-at32ap/include/mach/pm.h | 24 ------------------------
 arch/avr32/mach-at32ap/pm-at32ap700x.S   |  7 -------
 5 files changed, 10 insertions(+), 44 deletions(-)
arch/avr32/Kconfig +1 -0
index c1a868d..bbecda4 100644
@@ -10,6 +10,7 @@ config AVR32
 	select VIRT_TO_BUS
 	select GENERIC_IRQ_PROBE
 	select GENERIC_ATOMIC64
+	select GENERIC_IDLE_LOOP
 	select HARDIRQS_SW_RESEND
 	select GENERIC_IRQ_SHOW
 	select ARCH_HAVE_CUSTOM_GPIO_H
arch/avr32/kernel/process.c +2 -11
index fd78f58..073c3c2 100644
@@ -30,18 +30,9 @@ EXPORT_SYMBOL(pm_power_off);
  * This file handles the architecture-dependent parts of process handling..
  */
 
-void cpu_idle(void)
+void arch_cpu_idle(void)
 {
-	/* endless idle loop with no priority at all */
-	while (1) {
-		tick_nohz_idle_enter();
-		rcu_idle_enter();
-		while (!need_resched())
-			cpu_idle_sleep();
-		rcu_idle_exit();
-		tick_nohz_idle_exit();
-		schedule_preempt_disabled();
-	}
+	cpu_enter_idle();
 }
 
 void machine_halt(void)
arch/avr32/kernel/time.c +7 -2
index 05ad291..869a1c6 100644
@@ -12,6 +12,7 @@
 #include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/time.h>
+#include <linux/cpu.h>
 
 #include <asm/sysreg.h>
 
@@ -87,13 +88,17 @@ static void comparator_mode(enum clock_event_mode mode,
 		pr_debug("%s: start\n", evdev->name);
 		/* FALLTHROUGH */
 	case CLOCK_EVT_MODE_RESUME:
-		cpu_disable_idle_sleep();
+		/*
+		 * If we're using the COUNT and COMPARE registers we
+		 * need to force idle poll.
+		 */
+		cpu_idle_poll_ctrl(true);
 		break;
 	case CLOCK_EVT_MODE_UNUSED:
 	case CLOCK_EVT_MODE_SHUTDOWN:
 		sysreg_write(COMPARE, 0);
 		pr_debug("%s: stop\n", evdev->name);
-		cpu_enable_idle_sleep();
+		cpu_idle_poll_ctrl(false);
 		break;
 	default:
 		BUG();
arch/avr32/mach-at32ap/include/mach/pm.h +0 -24
index 979b355..f29ff2c 100644
@@ -21,30 +21,6 @@
 extern void cpu_enter_idle(void);
 extern void cpu_enter_standby(unsigned long sdramc_base);
 
-extern bool disable_idle_sleep;
-
-static inline void cpu_disable_idle_sleep(void)
-{
-	disable_idle_sleep = true;
-}
-
-static inline void cpu_enable_idle_sleep(void)
-{
-	disable_idle_sleep = false;
-}
-
-static inline void cpu_idle_sleep(void)
-{
-	/*
-	 * If we're using the COUNT and COMPARE registers for
-	 * timekeeping, we can't use the IDLE state.
-	 */
-	if (disable_idle_sleep)
-		cpu_relax();
-	else
-		cpu_enter_idle();
-}
-
 void intc_set_suspend_handler(unsigned long offset);
 #endif
 
arch/avr32/mach-at32ap/pm-at32ap700x.S +0 -7
index f868f4c..1c8e4e6 100644
@@ -18,13 +18,6 @@
 /* Same as 0xfff00000 but fits in a 21 bit signed immediate */
 #define PM_BASE	-0x100000
 
-	.section .bss, "wa", @nobits
-	.global	disable_idle_sleep
-	.type	disable_idle_sleep, @object
-disable_idle_sleep:
-	.int	4
-	.size	disable_idle_sleep, . - disable_idle_sleep
-
 	/* Keep this close to the irq handlers */
 	.section .irq.text, "ax", @progbits
 
#52 lore raw

Re: [tip:smp/hotplug] avr32: Use generic idle loop

Quoted 11 lines · tip-bot for Thomas Gleixner
Commit-ID:  01426478df3a8791ff5c8b6b82d409e699cfaf38
Gitweb:     http://git.kernel.org/tip/01426478df3a8791ff5c8b6b82d409e699cfaf38
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:40 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:24 +0200

avr32: Use generic idle loop

Also replace the idle poll enforcement by the generic functionality.

Quoted 10 lines
Quoted 7 lines
---
 arch/avr32/Kconfig                       |  1 +
 arch/avr32/kernel/process.c              | 13 ++-----------
 arch/avr32/kernel/time.c                 |  9 +++++++--
 arch/avr32/mach-at32ap/include/mach/pm.h | 24 ------------------------
 arch/avr32/mach-at32ap/pm-at32ap700x.S   |  7 -------
 5 files changed, 10 insertions(+), 44 deletions(-)

<snipp diff>

Signature · 2 lines
mvh
Hans-Christian Egtvedt
#53 lore raw

PATCH 11/34 bfin: Use generic idle loop

In reply to Thomas Gleixner
---
 arch/blackfin/Kconfig           |    1 +
 arch/blackfin/kernel/process.c  |   30 ++----------------------------
 arch/blackfin/mach-common/smp.c |    2 +-
 3 files changed, 4 insertions(+), 29 deletions(-)
arch/blackfin/Kconfig +1 -0
Index: linux-2.6/arch/blackfin/Kconfig
===================================================================
@@ -41,6 +41,7 @@ config BLACKFIN
 	select USE_GENERIC_SMP_HELPERS if SMP
 	select HAVE_NMI_WATCHDOG if NMI_WATCHDOG
 	select GENERIC_SMP_IDLE_THREAD
+	select GENERIC_IDLE_LOOP
 	select ARCH_USES_GETTIMEOFFSET if !GENERIC_CLOCKEVENTS
 	select HAVE_MOD_ARCH_SPECIFIC
 	select MODULES_USE_ELF_RELA
arch/blackfin/kernel/process.c +2 -28
Index: linux-2.6/arch/blackfin/kernel/process.c
===================================================================
@@ -47,14 +47,14 @@ EXPORT_SYMBOL(pm_power_off);
  */
 #ifdef CONFIG_IDLE_L1
 static void default_idle(void)__attribute__((l1_text));
-void cpu_idle(void)__attribute__((l1_text));
+void arch_cpu_idle(void)__attribute__((l1_text));
 #endif
 
 /*
  * This is our default idle handler.  We need to disable
  * interrupts here to ensure we don't miss a wakeup call.
  */
-static void default_idle(void)
+void arch_cpu_idle(void)
 {
 #ifdef CONFIG_IPIPE
 	ipipe_suspend_domain();
@@ -67,32 +67,6 @@ static void default_idle(void)
 }
 
 /*
- * The idle thread.  We try to conserve power, while trying to keep
- * overall latency low.  The architecture specific idle is passed
- * a value to indicate the level of "idleness" of the system.
- */
-void cpu_idle(void)
-{
-	/* endless idle loop with no priority at all */
-	while (1) {
-
-#ifdef CONFIG_HOTPLUG_CPU
-		if (cpu_is_offline(smp_processor_id()))
-			cpu_die();
-#endif
-		tick_nohz_idle_enter();
-		rcu_idle_enter();
-		while (!need_resched())
-			default_idle();
-		rcu_idle_exit();
-		tick_nohz_idle_exit();
-		preempt_enable_no_resched();
-		schedule();
-		preempt_disable();
-	}
-}
-
-/*
  * Do necessary setup to start up a newly executed thread.
  *
  * pass the data segment into user programs if it exists,
arch/blackfin/mach-common/smp.c +1 -1
Index: linux-2.6/arch/blackfin/mach-common/smp.c
===================================================================
@@ -335,7 +335,7 @@ void __cpuinit secondary_start_kernel(vo
 	 */
 	calibrate_delay();
 
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 void __init smp_prepare_boot_cpu(void)
#54 lore raw

[tip:smp/hotplug] bfin: Use generic idle loop

bfin: Use generic idle loop
Commit-ID:  25d67f860f3a29d216f8206092a284cacbc6127e
Gitweb:     http://git.kernel.org/tip/25d67f860f3a29d216f8206092a284cacbc6127e
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:41 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:24 +0200

bfin: Use generic idle loop

---
 arch/blackfin/Kconfig           |  1 +
 arch/blackfin/kernel/process.c  | 32 ++++++--------------------------
 arch/blackfin/mach-common/smp.c |  2 +-
 3 files changed, 8 insertions(+), 27 deletions(-)
arch/blackfin/Kconfig +1 -0
index c3f2e0b..3d769a7 100644
@@ -41,6 +41,7 @@ config BLACKFIN
 	select USE_GENERIC_SMP_HELPERS if SMP
 	select HAVE_NMI_WATCHDOG if NMI_WATCHDOG
 	select GENERIC_SMP_IDLE_THREAD
+	select GENERIC_IDLE_LOOP
 	select ARCH_USES_GETTIMEOFFSET if !GENERIC_CLOCKEVENTS
 	select HAVE_MOD_ARCH_SPECIFIC
 	select MODULES_USE_ELF_RELA
arch/blackfin/kernel/process.c +6 -26
index 9782c03..f34323a 100644
@@ -46,15 +46,14 @@ EXPORT_SYMBOL(pm_power_off);
  * The idle loop on BFIN
  */
 #ifdef CONFIG_IDLE_L1
-static void default_idle(void)__attribute__((l1_text));
-void cpu_idle(void)__attribute__((l1_text));
+void arch_cpu_idle(void)__attribute__((l1_text));
 #endif
 
 /*
  * This is our default idle handler.  We need to disable
  * interrupts here to ensure we don't miss a wakeup call.
  */
-static void default_idle(void)
+void arch_cpu_idle(void)
 {
 #ifdef CONFIG_IPIPE
 	ipipe_suspend_domain();
@@ -66,31 +65,12 @@ static void default_idle(void)
 	hard_local_irq_enable();
 }
 
-/*
- * The idle thread.  We try to conserve power, while trying to keep
- * overall latency low.  The architecture specific idle is passed
- * a value to indicate the level of "idleness" of the system.
- */
-void cpu_idle(void)
+#ufdef CONFIG_HOTPLUG_CPU
+void arch_cpu_idle_dead(void)
 {
-	/* endless idle loop with no priority at all */
-	while (1) {
-
-#ifdef CONFIG_HOTPLUG_CPU
-		if (cpu_is_offline(smp_processor_id()))
-			cpu_die();
-#endif
-		tick_nohz_idle_enter();
-		rcu_idle_enter();
-		while (!need_resched())
-			default_idle();
-		rcu_idle_exit();
-		tick_nohz_idle_exit();
-		preempt_enable_no_resched();
-		schedule();
-		preempt_disable();
-	}
+	cpu_die();
 }
+#endif
 
 /*
  * Do necessary setup to start up a newly executed thread.
arch/blackfin/mach-common/smp.c +1 -1
index bb61ae4..1bc2ce6 100644
@@ -335,7 +335,7 @@ void __cpuinit secondary_start_kernel(void)
 	 */
 	calibrate_delay();
 
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 void __init smp_prepare_boot_cpu(void)
#55 lore raw

PATCH 12/34 c6x: Use generic idle loop

In reply to Thomas Gleixner
---
 arch/c6x/Kconfig          |    1 +
 arch/c6x/kernel/process.c |   28 +---------------------------
 2 files changed, 2 insertions(+), 27 deletions(-)
arch/c6x/Kconfig +1 -0
Index: linux-2.6/arch/c6x/Kconfig
===================================================================
@@ -18,6 +18,7 @@ config C6X
 	select OF_EARLY_FLATTREE
 	select GENERIC_CLOCKEVENTS
 	select MODULES_USE_ELF_RELA
+	select GENERIC_IDLE_LOOP
 
 config MMU
 	def_bool n
arch/c6x/kernel/process.c +1 -27
Index: linux-2.6/arch/c6x/kernel/process.c
===================================================================
@@ -33,7 +33,7 @@ extern asmlinkage void ret_from_kernel_t
 void (*pm_power_off)(void);
 EXPORT_SYMBOL(pm_power_off);
 
-static void c6x_idle(void)
+void arch_cpu_idle(void)
 {
 	unsigned long tmp;
 
@@ -49,32 +49,6 @@ static void c6x_idle(void)
 		      : "=b"(tmp));
 }
 
-/*
- * The idle loop for C64x
- */
-void cpu_idle(void)
-{
-	/* endless idle loop with no priority at all */
-	while (1) {
-		tick_nohz_idle_enter();
-		rcu_idle_enter();
-		while (1) {
-			local_irq_disable();
-			if (need_resched()) {
-				local_irq_enable();
-				break;
-			}
-			c6x_idle(); /* enables local irqs */
-		}
-		rcu_idle_exit();
-		tick_nohz_idle_exit();
-
-		preempt_enable_no_resched();
-		schedule();
-		preempt_disable();
-	}
-}
-
 static void halt_loop(void)
 {
 	printk(KERN_EMERG "System Halted, OK to turn off power\n");
#56 lore raw

[tip:smp/hotplug] c6x: Use generic idle loop

c6x: Use generic idle loop
Commit-ID:  e46746cd5542b74f1e34bb1b8a997c5c0a6e69ea
Gitweb:     http://git.kernel.org/tip/e46746cd5542b74f1e34bb1b8a997c5c0a6e69ea
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:42 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:24 +0200

c6x: Use generic idle loop

---
 arch/c6x/Kconfig          |  1 +
 arch/c6x/kernel/process.c | 28 +---------------------------
 2 files changed, 2 insertions(+), 27 deletions(-)
arch/c6x/Kconfig +1 -0
index f6a3648..af2aa4b 100644
@@ -18,6 +18,7 @@ config C6X
 	select OF_EARLY_FLATTREE
 	select GENERIC_CLOCKEVENTS
 	select MODULES_USE_ELF_RELA
+	select GENERIC_IDLE_LOOP
 
 config MMU
 	def_bool n
arch/c6x/kernel/process.c +1 -27
index 6434df4..57d2ea8 100644
@@ -33,7 +33,7 @@ extern asmlinkage void ret_from_kernel_thread(void);
 void (*pm_power_off)(void);
 EXPORT_SYMBOL(pm_power_off);
 
-static void c6x_idle(void)
+void arch_cpu_idle(void)
 {
 	unsigned long tmp;
 
@@ -49,32 +49,6 @@ static void c6x_idle(void)
 		      : "=b"(tmp));
 }
 
-/*
- * The idle loop for C64x
- */
-void cpu_idle(void)
-{
-	/* endless idle loop with no priority at all */
-	while (1) {
-		tick_nohz_idle_enter();
-		rcu_idle_enter();
-		while (1) {
-			local_irq_disable();
-			if (need_resched()) {
-				local_irq_enable();
-				break;
-			}
-			c6x_idle(); /* enables local irqs */
-		}
-		rcu_idle_exit();
-		tick_nohz_idle_exit();
-
-		preempt_enable_no_resched();
-		schedule();
-		preempt_disable();
-	}
-}
-
 static void halt_loop(void)
 {
 	printk(KERN_EMERG "System Halted, OK to turn off power\n");
#57 lore raw

PATCH 13/34 cris: Use generic idle loop

In reply to Thomas Gleixner
---
 arch/cris/Kconfig                   |    1 +
 arch/cris/arch-v10/kernel/process.c |    3 ++-
 arch/cris/arch-v32/kernel/process.c |   10 ++++------
 arch/cris/arch-v32/kernel/smp.c     |    4 +---
 arch/cris/kernel/process.c          |   24 ++----------------------
 5 files changed, 10 insertions(+), 32 deletions(-)
arch/cris/Kconfig +1 -0
Index: linux-2.6/arch/cris/Kconfig
===================================================================
@@ -48,6 +48,7 @@ config CRIS
 	select GENERIC_IRQ_SHOW
 	select GENERIC_IOMAP
 	select GENERIC_SMP_IDLE_THREAD if ETRAX_ARCH_V32
+	select GENERIC_IDLE_LOOP
 	select GENERIC_CMOS_UPDATE
 	select MODULES_USE_ELF_RELA
 	select CLONE_BACKWARDS2
arch/cris/arch-v10/kernel/process.c +2 -1
Index: linux-2.6/arch/cris/arch-v10/kernel/process.c
===================================================================
@@ -30,8 +30,9 @@ void etrax_gpio_wake_up_check(void); /* 
 void default_idle(void)
 {
 #ifdef CONFIG_ETRAX_GPIO
-  etrax_gpio_wake_up_check();
+	etrax_gpio_wake_up_check();
 #endif
+	local_irq_enable();
 }
 
 /*
arch/cris/arch-v32/kernel/process.c +4 -6
Index: linux-2.6/arch/cris/arch-v32/kernel/process.c
===================================================================
@@ -23,12 +23,10 @@ extern void stop_watchdog(void);
 /* We use this if we don't have any better idle routine. */
 void default_idle(void)
 {
-	local_irq_disable();
-	if (!need_resched()) {
-		/* Halt until exception. */
-		__asm__ volatile("ei    \n\t"
-				 "halt      ");
-	}
+	/* Halt until exception. */
+	__asm__ volatile("ei    \n\t"
+			 "halt      ");
+	/* CHECKME: Is this really needed ?? */
 	local_irq_enable();
 }
 
arch/cris/arch-v32/kernel/smp.c +1 -3
Index: linux-2.6/arch/cris/arch-v32/kernel/smp.c
===================================================================
@@ -145,8 +145,6 @@ smp_boot_one_cpu(int cpuid, struct task_
  * specific stuff such as the local timer and the MMU. */
 void __init smp_callin(void)
 {
-	extern void cpu_idle(void);
-
 	int cpu = cpu_now_booting;
 	reg_intr_vect_rw_mask vect_mask = {0};
 
@@ -170,7 +168,7 @@ void __init smp_callin(void)
 	local_irq_enable();
 
 	set_cpu_online(cpu, true);
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 /* Stop execution on this CPU.*/
arch/cris/kernel/process.c +2 -22
Index: linux-2.6/arch/cris/kernel/process.c
===================================================================
@@ -34,29 +34,9 @@ extern void default_idle(void);
 void (*pm_power_off)(void);
 EXPORT_SYMBOL(pm_power_off);
 
-/*
- * The idle thread. There's no useful work to be
- * done, so just try to conserve power and have a
- * low exit latency (ie sit in a loop waiting for
- * somebody to say that they'd like to reschedule)
- */
-
-void cpu_idle (void)
+void arch_cpu_idle(void)
 {
-	/* endless idle loop with no priority at all */
-	while (1) {
-		rcu_idle_enter();
-		while (!need_resched()) {
-			/*
-			 * Mark this as an RCU critical section so that
-			 * synchronize_kernel() in the unload path waits
-			 * for our completion.
-			 */
-			default_idle();
-		}
-		rcu_idle_exit();
-		schedule_preempt_disabled();
-	}
+	default_idle();
 }
 
 void hard_reset_now (void);
Acked-by on v1 13/34
#58 lore raw

Re: [patch 13/34] cris: Use generic idle loop

On Thu, Mar 21, 2013 at 09:53:06PM -0000, Thomas Gleixner wrote:
[snip]

Quoted 9 lines

Index: linux-2.6/arch/cris/arch-v32/kernel/process.c
===================================================================

arch/cris/arch-v32/kernel/process.c +0 -1
@@ -23,12 +23,10 @@ extern void stop_watchdog(void);
 /* We use this if we don't have any better idle routine. */
 void default_idle(void)
 {
-	local_irq_disable();

arch/cris/arch-v32/kernel/process.c extern void stop_watchdog(void); · line 30

Quoted 10 lines
arch/cris/arch-v32/kernel/process.c +4 -5
-	if (!need_resched()) {
-		/* Halt until exception. */
-		__asm__ volatile("ei    \n\t"
-				 "halt      ");
-	}
+	/* Halt until exception. */
+	__asm__ volatile("ei    \n\t"
+			 "halt      ");
+	/* CHECKME: Is this really needed ?? */
 	local_irq_enable();

No, that local_irq_enable() is redundant since we already enabled interrupts in the assembler directive above.

arch/cris/arch-v32/kernel/process.c extern void stop_watchdog(void); · line 31

Quoted 1 line
arch/cris/arch-v32/kernel/process.c +0 -0
 }

Looks good,

/^JN - Jesper Nilsson

Signature · 1 line
               Jesper Nilsson -- [email protected]
#59 lore raw

Re: [patch 13/34] cris: Use generic idle loop

Quoted 17 lines · Jesper Nilsson

On Thu, Mar 21, 2013 at 09:53:06PM -0000, Thomas Gleixner wrote:
[snip]

Quoted 14 lines

Index: linux-2.6/arch/cris/arch-v32/kernel/process.c
===================================================================

arch/cris/arch-v32/kernel/process.c +0 -6
@@ -23,12 +23,10 @@ extern void stop_watchdog(void);
 /* We use this if we don't have any better idle routine. */
 void default_idle(void)
 {
-	local_irq_disable();
-	if (!need_resched()) {
-		/* Halt until exception. */
-		__asm__ volatile("ei    \n\t"
-				 "halt      ");
-	}
Quoted 8 lines

arch/cris/arch-v32/kernel/process.c extern void stop_watchdog(void); · line 30

Quoted 5 lines
arch/cris/arch-v32/kernel/process.c +4 -0
+	/* Halt until exception. */
+	__asm__ volatile("ei    \n\t"
+			 "halt      ");
+	/* CHECKME: Is this really needed ?? */
 	local_irq_enable();

No, that local_irq_enable() is redundant since we already enabled interrupts in the assembler directive above.

That's what I thought:) Will remove it.

Thanks,

tglx

#60 lore raw

[tip:smp/hotplug] cris: Use generic idle loop

In reply to Thomas Gleixner
cris: Use generic idle loop
Commit-ID:  8dc7c5ecd8d0f739728d844ee794c4fae169f9c2
Gitweb:     http://git.kernel.org/tip/8dc7c5ecd8d0f739728d844ee794c4fae169f9c2
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:43 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:25 +0200

cris: Use generic idle loop

---
 arch/cris/Kconfig                   |  1 +
 arch/cris/arch-v10/kernel/process.c |  3 ++-
 arch/cris/arch-v32/kernel/process.c | 10 +++-------
 arch/cris/arch-v32/kernel/smp.c     |  4 +---
 arch/cris/kernel/process.c          | 24 ++----------------------
 5 files changed, 9 insertions(+), 33 deletions(-)
arch/cris/Kconfig +1 -0
index 06dd026..1dd3635 100644
@@ -48,6 +48,7 @@ config CRIS
 	select GENERIC_IRQ_SHOW
 	select GENERIC_IOMAP
 	select GENERIC_SMP_IDLE_THREAD if ETRAX_ARCH_V32
+	select GENERIC_IDLE_LOOP
 	select GENERIC_CMOS_UPDATE
 	select MODULES_USE_ELF_RELA
 	select CLONE_BACKWARDS2
arch/cris/arch-v10/kernel/process.c +2 -1
index b101875..2ba23c1 100644
@@ -30,8 +30,9 @@ void etrax_gpio_wake_up_check(void); /* drivers/gpio.c */
 void default_idle(void)
 {
 #ifdef CONFIG_ETRAX_GPIO
-  etrax_gpio_wake_up_check();
+	etrax_gpio_wake_up_check();
 #endif
+	local_irq_enable();
 }
 
 /*
arch/cris/arch-v32/kernel/process.c +3 -7
index 4857933..57451fa 100644
@@ -23,13 +23,9 @@ extern void stop_watchdog(void);
 /* We use this if we don't have any better idle routine. */
 void default_idle(void)
 {
-	local_irq_disable();
-	if (!need_resched()) {
-		/* Halt until exception. */
-		__asm__ volatile("ei    \n\t"
-				 "halt      ");
-	}
-	local_irq_enable();
+	/* Halt until exception. */
+	__asm__ volatile("ei    \n\t"
+			 "halt      ");
 }
 
 /*
arch/cris/arch-v32/kernel/smp.c +1 -3
index 04a16ed..cdd1202 100644
@@ -145,8 +145,6 @@ smp_boot_one_cpu(int cpuid, struct task_struct idle)
  * specific stuff such as the local timer and the MMU. */
 void __init smp_callin(void)
 {
-	extern void cpu_idle(void);
-
 	int cpu = cpu_now_booting;
 	reg_intr_vect_rw_mask vect_mask = {0};
 
@@ -170,7 +168,7 @@ void __init smp_callin(void)
 	local_irq_enable();
 
 	set_cpu_online(cpu, true);
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 /* Stop execution on this CPU.*/
arch/cris/kernel/process.c +2 -22
index 508c9cd..b78498e 100644
@@ -34,29 +34,9 @@ extern void default_idle(void);
 void (*pm_power_off)(void);
 EXPORT_SYMBOL(pm_power_off);
 
-/*
- * The idle thread. There's no useful work to be
- * done, so just try to conserve power and have a
- * low exit latency (ie sit in a loop waiting for
- * somebody to say that they'd like to reschedule)
- */
-
-void cpu_idle (void)
+void arch_cpu_idle(void)
 {
-	/* endless idle loop with no priority at all */
-	while (1) {
-		rcu_idle_enter();
-		while (!need_resched()) {
-			/*
-			 * Mark this as an RCU critical section so that
-			 * synchronize_kernel() in the unload path waits
-			 * for our completion.
-			 */
-			default_idle();
-		}
-		rcu_idle_exit();
-		schedule_preempt_disabled();
-	}
+	default_idle();
 }
 
 void hard_reset_now (void);
#61 lore raw

PATCH 14/34 frv: Use generic idle loop

In reply to Thomas Gleixner
---
 arch/frv/Kconfig          |    1 +
 arch/frv/kernel/process.c |   27 +++++----------------------
 2 files changed, 6 insertions(+), 22 deletions(-)
arch/frv/Kconfig +1 -0
Index: linux-2.6/arch/frv/Kconfig
===================================================================
@@ -8,6 +8,7 @@ config FRV
 	select HAVE_GENERIC_HARDIRQS
 	select VIRT_TO_BUS
 	select GENERIC_IRQ_SHOW
+	select GENERIC_IDLE_LOOP
 	select HAVE_DEBUG_BUGVERBOSE
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select GENERIC_CPU_DEVICES
arch/frv/kernel/process.c +5 -22
Index: linux-2.6/arch/frv/kernel/process.c
===================================================================
@@ -59,29 +59,12 @@ static void core_sleep_idle(void)
 	mb();
 }
 
-void (*idle)(void) = core_sleep_idle;
-
-/*
- * The idle thread. There's no useful work to be
- * done, so just try to conserve power and have a
- * low exit latency (ie sit in a loop waiting for
- * somebody to say that they'd like to reschedule)
- */
-void cpu_idle(void)
+void arch_cpu_idle(void)
 {
-	/* endless idle loop with no priority at all */
-	while (1) {
-		rcu_idle_enter();
-		while (!need_resched()) {
-			check_pgt_cache();
-
-			if (!frv_dma_inprogress && idle)
-				idle();
-		}
-		rcu_idle_exit();
-
-		schedule_preempt_disabled();
-	}
+	if (!frv_dma_inprogress)
+		core_sleep_idle();
+	else
+		local_irq_enable();
 }
 
 void machine_restart(char * __unused)
#62 lore raw

[tip:smp/hotplug] frv: Use generic idle loop

frv: Use generic idle loop
Commit-ID:  ccf8e78fe2a7e92b6d43de8023786b9dd199aab1
Gitweb:     http://git.kernel.org/tip/ccf8e78fe2a7e92b6d43de8023786b9dd199aab1
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:44 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:25 +0200

frv: Use generic idle loop

---
 arch/frv/Kconfig          |  1 +
 arch/frv/kernel/process.c | 27 +++++----------------------
 2 files changed, 6 insertions(+), 22 deletions(-)
arch/frv/Kconfig +1 -0
index 2ce731f..0d998db 100644
@@ -8,6 +8,7 @@ config FRV
 	select HAVE_GENERIC_HARDIRQS
 	select VIRT_TO_BUS
 	select GENERIC_IRQ_SHOW
+	select GENERIC_IDLE_LOOP
 	select HAVE_DEBUG_BUGVERBOSE
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select GENERIC_CPU_DEVICES
arch/frv/kernel/process.c +5 -22
index 23916b2..5d40aeb77 100644
@@ -59,29 +59,12 @@ static void core_sleep_idle(void)
 	mb();
 }
 
-void (*idle)(void) = core_sleep_idle;
-
-/*
- * The idle thread. There's no useful work to be
- * done, so just try to conserve power and have a
- * low exit latency (ie sit in a loop waiting for
- * somebody to say that they'd like to reschedule)
- */
-void cpu_idle(void)
+void arch_cpu_idle(void)
 {
-	/* endless idle loop with no priority at all */
-	while (1) {
-		rcu_idle_enter();
-		while (!need_resched()) {
-			check_pgt_cache();
-
-			if (!frv_dma_inprogress && idle)
-				idle();
-		}
-		rcu_idle_exit();
-
-		schedule_preempt_disabled();
-	}
+	if (!frv_dma_inprogress)
+		core_sleep_idle();
+	else
+		local_irq_enable();
 }
 
 void machine_restart(char * __unused)
#63 lore raw

PATCH 15/34 h8300: Use generic idle loop

In reply to Thomas Gleixner

Use the core idle poll function instead of the private one

---
 arch/h8300/Kconfig          |    1 +
 arch/h8300/kernel/process.c |   35 ++++-------------------------------
 2 files changed, 5 insertions(+), 31 deletions(-)
arch/h8300/Kconfig +1 -0
Index: linux-2.6/arch/h8300/Kconfig
===================================================================
@@ -8,6 +8,7 @@ config H8300
 	select VIRT_TO_BUS
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select GENERIC_IRQ_SHOW
+	select GENERIC_IDLE_LOOP
 	select GENERIC_CPU_DEVICES
 	select MODULES_USE_ELF_RELA
 	select OLD_SIGSUSPEND3
arch/h8300/kernel/process.c +4 -31
Index: linux-2.6/arch/h8300/kernel/process.c
===================================================================
@@ -53,40 +53,13 @@ asmlinkage void ret_from_kernel_thread(v
  * The idle loop on an H8/300..
  */
 #if !defined(CONFIG_H8300H_SIM) && !defined(CONFIG_H8S_SIM)
-static void default_idle(void)
+void arch_cpu_idle(void)
 {
-	local_irq_disable();
-	if (!need_resched()) {
-		local_irq_enable();
-		/* XXX: race here! What if need_resched() gets set now? */
-		__asm__("sleep");
-	} else
-		local_irq_enable();
-}
-#else
-static void default_idle(void)
-{
-	cpu_relax();
+	local_irq_enable();
+	/* XXX: race here! What if need_resched() gets set now? */
+	__asm__("sleep");
 }
 #endif
-void (*idle)(void) = default_idle;
-
-/*
- * The idle thread. There's no useful work to be
- * done, so just try to conserve power and have a
- * low exit latency (ie sit in a loop waiting for
- * somebody to say that they'd like to reschedule)
- */
-void cpu_idle(void)
-{
-	while (1) {
-		rcu_idle_enter();
-		while (!need_resched())
-			idle();
-		rcu_idle_exit();
-		schedule_preempt_disabled();
-	}
-}
 
 void machine_restart(char * __unused)
 {
#64 lore raw

[tip:smp/hotplug] h8300: Use generic idle loop

h8300: Use generic idle loop
Commit-ID:  0d24260c9e27fc1de20c72669bcc387767a1c170
Gitweb:     http://git.kernel.org/tip/0d24260c9e27fc1de20c72669bcc387767a1c170
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:45 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:25 +0200

h8300: Use generic idle loop

Use the core idle poll function instead of the private one

---
 arch/h8300/Kconfig          |  1 +
 arch/h8300/kernel/process.c | 35 ++++-------------------------------
 2 files changed, 5 insertions(+), 31 deletions(-)
arch/h8300/Kconfig +1 -0
index 79250de..5374975 100644
@@ -8,6 +8,7 @@ config H8300
 	select VIRT_TO_BUS
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select GENERIC_IRQ_SHOW
+	select GENERIC_IDLE_LOOP
 	select GENERIC_CPU_DEVICES
 	select MODULES_USE_ELF_RELA
 	select OLD_SIGSUSPEND3
arch/h8300/kernel/process.c +4 -31
index b609f63..a17d2cd 100644
@@ -53,40 +53,13 @@ asmlinkage void ret_from_kernel_thread(void);
  * The idle loop on an H8/300..
  */
 #if !defined(CONFIG_H8300H_SIM) && !defined(CONFIG_H8S_SIM)
-static void default_idle(void)
+void arch_cpu_idle(void)
 {
-	local_irq_disable();
-	if (!need_resched()) {
-		local_irq_enable();
-		/* XXX: race here! What if need_resched() gets set now? */
-		__asm__("sleep");
-	} else
-		local_irq_enable();
-}
-#else
-static void default_idle(void)
-{
-	cpu_relax();
+	local_irq_enable();
+	/* XXX: race here! What if need_resched() gets set now? */
+	__asm__("sleep");
 }
 #endif
-void (*idle)(void) = default_idle;
-
-/*
- * The idle thread. There's no useful work to be
- * done, so just try to conserve power and have a
- * low exit latency (ie sit in a loop waiting for
- * somebody to say that they'd like to reschedule)
- */
-void cpu_idle(void)
-{
-	while (1) {
-		rcu_idle_enter();
-		while (!need_resched())
-			idle();
-		rcu_idle_exit();
-		schedule_preempt_disabled();
-	}
-}
 
 void machine_restart(char * __unused)
 {
#65 lore raw

PATCH 16/34 hexagon: Use generic idle loop

In reply to Thomas Gleixner
---
 arch/hexagon/Kconfig          |    1 +
 arch/hexagon/kernel/process.c |   23 +++--------------------
 arch/hexagon/kernel/smp.c     |    2 +-
 3 files changed, 5 insertions(+), 21 deletions(-)
arch/hexagon/Kconfig +1 -0
Index: linux-2.6/arch/hexagon/Kconfig
===================================================================
@@ -24,6 +24,7 @@ config HEXAGON
 	select NO_IOPORT
 	select GENERIC_IOMAP
 	select GENERIC_SMP_IDLE_THREAD
+	select GENERIC_IDLE_LOOP
 	select STACKTRACE_SUPPORT
 	select KTIME_SCALAR
 	select GENERIC_CLOCKEVENTS
arch/hexagon/kernel/process.c +3 -20
Index: linux-2.6/arch/hexagon/kernel/process.c
===================================================================
@@ -51,28 +51,11 @@ void start_thread(struct pt_regs *regs, 
  *  If hardware or VM offer wait termination even though interrupts
  *  are disabled.
  */
-static void default_idle(void)
+void arch_cpu_idle(void)
 {
 	__vmwait();
-}
-
-void (*idle_sleep)(void) = default_idle;
-
-void cpu_idle(void)
-{
-	while (1) {
-		tick_nohz_idle_enter();
-		local_irq_disable();
-		while (!need_resched()) {
-			idle_sleep();
-			/*  interrupts wake us up, but aren't serviced  */
-			local_irq_enable();	/* service interrupt   */
-			local_irq_disable();
-		}
-		local_irq_enable();
-		tick_nohz_idle_exit();
-		schedule();
-	}
+	/*  interrupts wake us up, but irqs are still disabled */
+	local_irq_enable();
 }
 
 /*
arch/hexagon/kernel/smp.c +1 -1
Index: linux-2.6/arch/hexagon/kernel/smp.c
===================================================================
@@ -184,7 +184,7 @@ void __cpuinit start_secondary(void)
 
 	local_irq_enable();
 
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 
#66 lore raw

[tip:smp/hotplug] hexagon: Use generic idle loop

hexagon: Use generic idle loop
Commit-ID:  4e0fcc567239ef4b3f80bba778c30b0a4b624eff
Gitweb:     http://git.kernel.org/tip/4e0fcc567239ef4b3f80bba778c30b0a4b624eff
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:46 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:25 +0200

hexagon: Use generic idle loop

---
 arch/hexagon/Kconfig          |  1 +
 arch/hexagon/kernel/process.c | 23 +++--------------------
 arch/hexagon/kernel/smp.c     |  2 +-
 3 files changed, 5 insertions(+), 21 deletions(-)
arch/hexagon/Kconfig +1 -0
index e4decc6..6e3710e 100644
@@ -24,6 +24,7 @@ config HEXAGON
 	select NO_IOPORT
 	select GENERIC_IOMAP
 	select GENERIC_SMP_IDLE_THREAD
+	select GENERIC_IDLE_LOOP
 	select STACKTRACE_SUPPORT
 	select KTIME_SCALAR
 	select GENERIC_CLOCKEVENTS
arch/hexagon/kernel/process.c +3 -20
index 06ae9ff..9b948c6 100644
@@ -51,28 +51,11 @@ void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long sp)
  *  If hardware or VM offer wait termination even though interrupts
  *  are disabled.
  */
-static void default_idle(void)
+void arch_cpu_idle(void)
 {
 	__vmwait();
-}
-
-void (*idle_sleep)(void) = default_idle;
-
-void cpu_idle(void)
-{
-	while (1) {
-		tick_nohz_idle_enter();
-		local_irq_disable();
-		while (!need_resched()) {
-			idle_sleep();
-			/*  interrupts wake us up, but aren't serviced  */
-			local_irq_enable();	/* service interrupt   */
-			local_irq_disable();
-		}
-		local_irq_enable();
-		tick_nohz_idle_exit();
-		schedule();
-	}
+	/*  interrupts wake us up, but irqs are still disabled */
+	local_irq_enable();
 }
 
 /*
arch/hexagon/kernel/smp.c +1 -1
index 8e095df..0e364ca 100644
@@ -184,7 +184,7 @@ void __cpuinit start_secondary(void)
 
 	local_irq_enable();
 
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 
#67 lore raw

PATCH 17/34 ia64: Use generic idle loop

In reply to Thomas Gleixner
---
 arch/ia64/Kconfig          |    1 
 arch/ia64/kernel/perfmon.c |   13 ++-----
 arch/ia64/kernel/process.c |   83 +++++++++------------------------------------
 arch/ia64/kernel/smpboot.c |    2 -
 4 files changed, 23 insertions(+), 76 deletions(-)
arch/ia64/Kconfig +1 -0
Index: linux-2.6/arch/ia64/Kconfig
===================================================================
@@ -35,6 +35,7 @@ config IA64
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select GENERIC_IOMAP
 	select GENERIC_SMP_IDLE_THREAD
+	select GENERIC_IDLE_LOOP
 	select ARCH_INIT_TASK
 	select ARCH_TASK_STRUCT_ALLOCATOR
 	select ARCH_THREAD_INFO_ALLOCATOR
arch/ia64/kernel/perfmon.c +4 -9
Index: linux-2.6/arch/ia64/kernel/perfmon.c
===================================================================
@@ -1322,8 +1322,6 @@ out:
 }
 EXPORT_SYMBOL(pfm_unregister_buffer_fmt);
 
-extern void update_pal_halt_status(int);
-
 static int
 pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu)
 {
@@ -1371,9 +1369,9 @@ pfm_reserve_session(struct task_struct *
 		cpu));
 
 	/*
-	 * disable default_idle() to go to PAL_HALT
+	 * Force idle() into poll mode
 	 */
-	update_pal_halt_status(0);
+	cpu_idle_poll_ctrl(true);
 
 	UNLOCK_PFS(flags);
 
@@ -1430,11 +1428,8 @@ pfm_unreserve_session(pfm_context_t *ctx
 		is_syswide,
 		cpu));
 
-	/*
-	 * if possible, enable default_idle() to go into PAL_HALT
-	 */
-	if (pfm_sessions.pfs_task_sessions == 0 && pfm_sessions.pfs_sys_sessions == 0)
-		update_pal_halt_status(1);
+	/* Undo forced polling. Last session reenables pal_halt */
+	cpu_idle_poll_ctrl(false);
 
 	UNLOCK_PFS(flags);
 
arch/ia64/kernel/process.c +17 -66

108 lines not on this page · raw message

arch/ia64/kernel/smpboot.c +1 -1
Index: linux-2.6/arch/ia64/kernel/smpboot.c
===================================================================
@@ -455,7 +455,7 @@ start_secondary (void *unused)
 	preempt_disable();
 	smp_callin();
 
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 	return 0;
 }
 
#68 lore raw

Re: [patch 17/34] ia64: Use generic idle loop

Quoted 9 lines · Thomas Gleixner
---
 arch/ia64/Kconfig          |    1 
 arch/ia64/kernel/perfmon.c |   13 ++-----
 arch/ia64/kernel/process.c |   83 +++++++++------------------------------------
 arch/ia64/kernel/smpboot.c |    2 -
 4 files changed, 23 insertions(+), 76 deletions(-)

[...]

Quoted 15 lines
arch/ia64/kernel/process.c +0 -15
-void
-update_pal_halt_status(int status)
-{
-	can_do_pal_halt = pal_halt && status;
-}
-
-/*
- * We use this if we don't have any better idle routine..
- */
-void
-default_idle (void)
-{
-	local_irq_enable();
-	while (!need_resched()) {
-		if (can_do_pal_halt) {

arch/ia64/kernel/process.c do_notify_resume_user(sigset_t *unused, · line 246

Quoted 10 lines
arch/ia64/kernel/process.c +0 -10
-			local_irq_disable();
-			if (!need_resched()) {
-				safe_halt();
-			}
-			local_irq_enable();
-		} else
-			cpu_relax();
-	}
-}
-

We can also get rid of the function prototype declaration of default_idle() inside arch/ia64/include/asm/processor.h

Regards,
Srivatsa S. Bhat

#69 lore raw

[tip:smp/hotplug] ia64: Use generic idle loop

In reply to Thomas Gleixner
ia64: Use generic idle loop
Commit-ID:  91d591c387af34db00c39da2d1d25e69a91cf591
Gitweb:     http://git.kernel.org/tip/91d591c387af34db00c39da2d1d25e69a91cf591
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:47 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:25 +0200

ia64: Use generic idle loop

---
 arch/ia64/Kconfig          |  1 +
 arch/ia64/kernel/perfmon.c | 14 +++------
 arch/ia64/kernel/process.c | 78 ++++++++++------------------------------------
 arch/ia64/kernel/smpboot.c |  2 +-
 4 files changed, 23 insertions(+), 72 deletions(-)
arch/ia64/Kconfig +1 -0
index 9a02f71..e0b39c3 100644
@@ -35,6 +35,7 @@ config IA64
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select GENERIC_IOMAP
 	select GENERIC_SMP_IDLE_THREAD
+	select GENERIC_IDLE_LOOP
 	select ARCH_INIT_TASK
 	select ARCH_TASK_STRUCT_ALLOCATOR
 	select ARCH_THREAD_INFO_ALLOCATOR
arch/ia64/kernel/perfmon.c +5 -9
index 2eda284..9ea25fc 100644
@@ -42,6 +42,7 @@
 #include <linux/completion.h>
 #include <linux/tracehook.h>
 #include <linux/slab.h>
+#include <linux/cpu.h>
 
 #include <asm/errno.h>
 #include <asm/intrinsics.h>
@@ -1322,8 +1323,6 @@ out:
 }
 EXPORT_SYMBOL(pfm_unregister_buffer_fmt);
 
-extern void update_pal_halt_status(int);
-
 static int
 pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu)
 {
@@ -1371,9 +1370,9 @@ pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu)
 		cpu));
 
 	/*
-	 * disable default_idle() to go to PAL_HALT
+	 * Force idle() into poll mode
 	 */
-	update_pal_halt_status(0);
+	cpu_idle_poll_ctrl(true);
 
 	UNLOCK_PFS(flags);
 
@@ -1430,11 +1429,8 @@ pfm_unreserve_session(pfm_context_t *ctx, int is_syswide, unsigned int cpu)
 		is_syswide,
 		cpu));
 
-	/*
-	 * if possible, enable default_idle() to go into PAL_HALT
-	 */
-	if (pfm_sessions.pfs_task_sessions == 0 && pfm_sessions.pfs_sys_sessions == 0)
-		update_pal_halt_status(1);
+	/* Undo forced polling. Last session reenables pal_halt */
+	cpu_idle_poll_ctrl(false);
 
 	UNLOCK_PFS(flags);
 
arch/ia64/kernel/process.c +16 -62

104 lines not on this page · raw message

arch/ia64/kernel/smpboot.c +1 -1
index 500f1e4..8d87168 100644
@@ -455,7 +455,7 @@ start_secondary (void *unused)
 	preempt_disable();
 	smp_callin();
 
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 	return 0;
 }
 
#70 lore raw

PATCH 18/34 m32r: Use generic idle loop

In reply to Thomas Gleixner

Replace the private poller.

---
 arch/m32r/Kconfig          |    1 +
 arch/m32r/kernel/process.c |   18 ------------------
 arch/m32r/kernel/smpboot.c |    2 +-
 3 files changed, 2 insertions(+), 19 deletions(-)
arch/m32r/Kconfig +1 -0
Index: linux-2.6/arch/m32r/Kconfig
===================================================================
@@ -13,6 +13,7 @@ config M32R
 	select VIRT_TO_BUS
 	select GENERIC_IRQ_PROBE
 	select GENERIC_IRQ_SHOW
+	select GENERIC_IDLE_LOOP
 	select GENERIC_ATOMIC64
 	select ARCH_USES_GETTIMEOFFSET
 	select MODULES_USE_ELF_RELA
arch/m32r/kernel/process.c +0 -18
Index: linux-2.6/arch/m32r/kernel/process.c
===================================================================
@@ -47,24 +47,6 @@ unsigned long thread_saved_pc(struct tas
 void (*pm_power_off)(void) = NULL;
 EXPORT_SYMBOL(pm_power_off);
 
-/*
- * The idle thread. There's no useful work to be
- * done, so just try to conserve power and have a
- * low exit latency (ie sit in a loop waiting for
- * somebody to say that they'd like to reschedule)
- */
-void cpu_idle (void)
-{
-	/* endless idle loop with no priority at all */
-	while (1) {
-		rcu_idle_enter();
-		while (!need_resched())
-			cpu_relax();
-		rcu_idle_exit();
-		schedule_preempt_disabled();
-	}
-}
-
 void machine_restart(char *__unused)
 {
 #if defined(CONFIG_PLAT_MAPPI3)
arch/m32r/kernel/smpboot.c +1 -1
Index: linux-2.6/arch/m32r/kernel/smpboot.c
===================================================================
@@ -432,7 +432,7 @@ int __init start_secondary(void *unused)
 	 */
 	local_flush_tlb_all();
 
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 	return 0;
 }
 
#71 lore raw

[tip:smp/hotplug] m32r: Use generic idle loop

m32r: Use generic idle loop
Commit-ID:  01436228bfefca77493efa00aa49a8b67167d4c5
Gitweb:     http://git.kernel.org/tip/01436228bfefca77493efa00aa49a8b67167d4c5
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:48 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:26 +0200

m32r: Use generic idle loop

Replace the private poller.

---
 arch/m32r/Kconfig          |  1 +
 arch/m32r/kernel/process.c | 18 ------------------
 arch/m32r/kernel/smpboot.c |  2 +-
 3 files changed, 2 insertions(+), 19 deletions(-)
arch/m32r/Kconfig +1 -0
index bcd17b2..af814fe 100644
@@ -13,6 +13,7 @@ config M32R
 	select VIRT_TO_BUS
 	select GENERIC_IRQ_PROBE
 	select GENERIC_IRQ_SHOW
+	select GENERIC_IDLE_LOOP
 	select GENERIC_ATOMIC64
 	select ARCH_USES_GETTIMEOFFSET
 	select MODULES_USE_ELF_RELA
arch/m32r/kernel/process.c +0 -18
index bde899e..e2d0490 100644
@@ -47,24 +47,6 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
 void (*pm_power_off)(void) = NULL;
 EXPORT_SYMBOL(pm_power_off);
 
-/*
- * The idle thread. There's no useful work to be
- * done, so just try to conserve power and have a
- * low exit latency (ie sit in a loop waiting for
- * somebody to say that they'd like to reschedule)
- */
-void cpu_idle (void)
-{
-	/* endless idle loop with no priority at all */
-	while (1) {
-		rcu_idle_enter();
-		while (!need_resched())
-			cpu_relax();
-		rcu_idle_exit();
-		schedule_preempt_disabled();
-	}
-}
-
 void machine_restart(char *__unused)
 {
 #if defined(CONFIG_PLAT_MAPPI3)
arch/m32r/kernel/smpboot.c +1 -1
index 13168a7..0ac558a 100644
@@ -432,7 +432,7 @@ int __init start_secondary(void *unused)
 	 */
 	local_flush_tlb_all();
 
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 	return 0;
 }
 
#72 lore raw

PATCH 19/34 m68k: Use generic idle loop

In reply to Thomas Gleixner
Cc Geert Uytterhoeven <[email protected]>
---
 arch/m68k/Kconfig          |    1 +
 arch/m68k/kernel/process.c |   32 ++++----------------------------
 2 files changed, 5 insertions(+), 28 deletions(-)
arch/m68k/Kconfig +1 -0
Index: linux-2.6/arch/m68k/Kconfig
===================================================================
@@ -6,6 +6,7 @@ config M68K
 	select HAVE_DEBUG_BUGVERBOSE
 	select HAVE_GENERIC_HARDIRQS
 	select GENERIC_IRQ_SHOW
+	select GENERIC_IDLE_LOOP
 	select GENERIC_ATOMIC64
 	select HAVE_UID16
 	select VIRT_TO_BUS
arch/m68k/kernel/process.c +4 -28
Index: linux-2.6/arch/m68k/kernel/process.c
===================================================================
@@ -51,40 +51,16 @@ unsigned long thread_saved_pc(struct tas
 		return sw->retpc;
 }
 
-/*
- * The idle loop on an m68k..
- */
-static void default_idle(void)
+void arch_cpu_idle(void)
 {
-	if (!need_resched())
 #if defined(MACH_ATARI_ONLY)
-		/* block out HSYNC on the atari (falcon) */
-		__asm__("stop #0x2200" : : : "cc");
+	/* block out HSYNC on the atari (falcon) */
+	__asm__("stop #0x2200" : : : "cc");
 #else
-		__asm__("stop #0x2000" : : : "cc");
+	__asm__("stop #0x2000" : : : "cc");
 #endif
 }
 
-void (*idle)(void) = default_idle;
-
-/*
- * The idle thread. There's no useful work to be
- * done, so just try to conserve power and have a
- * low exit latency (ie sit in a loop waiting for
- * somebody to say that they'd like to reschedule)
- */
-void cpu_idle(void)
-{
-	/* endless idle loop with no priority at all */
-	while (1) {
-		rcu_idle_enter();
-		while (!need_resched())
-			idle();
-		rcu_idle_exit();
-		schedule_preempt_disabled();
-	}
-}
-
 void machine_restart(char * __unused)
 {
 	if (mach_reset)
#73 lore raw

[tip:smp/hotplug] m68k: Use generic idle loop

m68k: Use generic idle loop
Commit-ID:  dfa174dcf841d0665065dedec2bc133227da56ef
Gitweb:     http://git.kernel.org/tip/dfa174dcf841d0665065dedec2bc133227da56ef
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:49 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:26 +0200

m68k: Use generic idle loop

---
 arch/m68k/Kconfig          |  1 +
 arch/m68k/kernel/process.c | 32 ++++----------------------------
 2 files changed, 5 insertions(+), 28 deletions(-)
arch/m68k/Kconfig +1 -0
index 6de8133..41859405 100644
@@ -6,6 +6,7 @@ config M68K
 	select HAVE_DEBUG_BUGVERBOSE
 	select HAVE_GENERIC_HARDIRQS
 	select GENERIC_IRQ_SHOW
+	select GENERIC_IDLE_LOOP
 	select GENERIC_ATOMIC64
 	select HAVE_UID16
 	select VIRT_TO_BUS
arch/m68k/kernel/process.c +4 -28
index d538694..c55ff71 100644
@@ -51,40 +51,16 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
 		return sw->retpc;
 }
 
-/*
- * The idle loop on an m68k..
- */
-static void default_idle(void)
+void arch_cpu_idle(void)
 {
-	if (!need_resched())
 #if defined(MACH_ATARI_ONLY)
-		/* block out HSYNC on the atari (falcon) */
-		__asm__("stop #0x2200" : : : "cc");
+	/* block out HSYNC on the atari (falcon) */
+	__asm__("stop #0x2200" : : : "cc");
 #else
-		__asm__("stop #0x2000" : : : "cc");
+	__asm__("stop #0x2000" : : : "cc");
 #endif
 }
 
-void (*idle)(void) = default_idle;
-
-/*
- * The idle thread. There's no useful work to be
- * done, so just try to conserve power and have a
- * low exit latency (ie sit in a loop waiting for
- * somebody to say that they'd like to reschedule)
- */
-void cpu_idle(void)
-{
-	/* endless idle loop with no priority at all */
-	while (1) {
-		rcu_idle_enter();
-		while (!need_resched())
-			idle();
-		rcu_idle_exit();
-		schedule_preempt_disabled();
-	}
-}
-
 void machine_restart(char * __unused)
 {
 	if (mach_reset)
#74 lore raw

PATCH 20/34 metag: Use generic idle loop

In reply to Thomas Gleixner
---
 arch/metag/Kconfig          |    1 +
 arch/metag/kernel/process.c |   32 +++-----------------------------
 arch/metag/kernel/smp.c     |    2 +-
 3 files changed, 5 insertions(+), 30 deletions(-)
arch/metag/Kconfig +1 -0
Index: linux-2.6/arch/metag/Kconfig
===================================================================
@@ -9,6 +9,7 @@ config METAG
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_IRQ_SHOW
 	select GENERIC_SMP_IDLE_THREAD
+	select GENERIC_IDLE_LOOP
 	select HAVE_64BIT_ALIGNED_ACCESS
 	select HAVE_ARCH_TRACEHOOK
 	select HAVE_C_RECORDMCOUNT
arch/metag/kernel/process.c +3 -29
Index: linux-2.6/arch/metag/kernel/process.c
===================================================================
@@ -31,7 +31,7 @@
 /*
  * Wait for the next interrupt and enable local interrupts
  */
-static inline void arch_idle(void)
+void arch_cpu_idle(void)
 {
 	int tmp;
 
@@ -59,35 +59,9 @@ static inline void arch_idle(void)
 		      : "r" (get_trigger_mask()));
 }
 
-void cpu_idle(void)
+void arch_cpu_idle_dead(void)
 {
-	set_thread_flag(TIF_POLLING_NRFLAG);
-
-	while (1) {
-		tick_nohz_idle_enter();
-		rcu_idle_enter();
-
-		while (!need_resched()) {
-			/*
-			 * We need to disable interrupts here to ensure we don't
-			 * miss a wakeup call.
-			 */
-			local_irq_disable();
-			if (!need_resched()) {
-#ifdef CONFIG_HOTPLUG_CPU
-				if (cpu_is_offline(smp_processor_id()))
-					cpu_die();
-#endif
-				arch_idle();
-			} else {
-				local_irq_enable();
-			}
-		}
-
-		rcu_idle_exit();
-		tick_nohz_idle_exit();
-		schedule_preempt_disabled();
-	 }
+	cpu_die();
 }
 
 void (*pm_power_off)(void);
arch/metag/kernel/smp.c +1 -1
Index: linux-2.6/arch/metag/kernel/smp.c
===================================================================
@@ -297,7 +297,7 @@ asmlinkage void secondary_start_kernel(v
 	/*
 	 * OK, it's off to the idle thread for us
 	 */
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 void __init smp_cpus_done(unsigned int max_cpus)
#75 lore raw

Re: [patch 20/34] metag: Use generic idle loop

Quoted 13 lines · Thomas Gleixner
---
 arch/metag/Kconfig          |    1 +
 arch/metag/kernel/process.c |   32 +++-----------------------------
 arch/metag/kernel/smp.c     |    2 +-
 3 files changed, 5 insertions(+), 30 deletions(-)

Index: linux-2.6/arch/metag/Kconfig
===================================================================

arch/metag/Kconfig config METAG · line 12

Quoted 4 lines
arch/metag/Kconfig +1 -0
@@ -9,6 +9,7 @@ config METAG
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_IRQ_SHOW
 	select GENERIC_SMP_IDLE_THREAD
+	select GENERIC_IDLE_LOOP

Please preserve alphabetical ordering

Quoted 41 lines
arch/metag/Kconfig +0 -0
 	select HAVE_64BIT_ALIGNED_ACCESS
 	select HAVE_ARCH_TRACEHOOK
 	select HAVE_C_RECORDMCOUNT

Index: linux-2.6/arch/metag/kernel/process.c
===================================================================

arch/metag/kernel/process.c +2 -20
@@ -31,7 +31,7 @@
 /*
  * Wait for the next interrupt and enable local interrupts
  */
-static inline void arch_idle(void)
+void arch_cpu_idle(void)
 {
 	int tmp;
 
@@ -59,35 +59,9 @@ static inline void arch_idle(void)
 		      : "r" (get_trigger_mask()));
 }
 
-void cpu_idle(void)
+void arch_cpu_idle_dead(void)
 {
-	set_thread_flag(TIF_POLLING_NRFLAG);
-
-	while (1) {
-		tick_nohz_idle_enter();
-		rcu_idle_enter();
-
-		while (!need_resched()) {
-			/*
-			 * We need to disable interrupts here to ensure we don't
-			 * miss a wakeup call.
-			 */
-			local_irq_disable();
-			if (!need_resched()) {
-#ifdef CONFIG_HOTPLUG_CPU
-				if (cpu_is_offline(smp_processor_id()))
-					cpu_die();
-#endif
-				arch_idle();

arch/metag/kernel/process.c static inline void arch_idle(void) · line 64

Quoted 10 lines
arch/metag/kernel/process.c +1 -9
-			} else {
-				local_irq_enable();
-			}
-		}
-
-		rcu_idle_exit();
-		tick_nohz_idle_exit();
-		schedule_preempt_disabled();
-	 }
+	cpu_die();

This requires #include <linux/smp.h> and even then the definition of cpu_die() is guarded by #ifdef CONFIG_HOTPLUG_CPU, like blackfin & s390.

Quoted 10 lines
arch/metag/kernel/process.c +0 -0
 }
 
 void (*pm_power_off)(void);

Index: linux-2.6/arch/metag/kernel/smp.c
===================================================================

arch/metag/kernel/smp.c asmlinkage void secondary_start_kernel(v · line 303

Quoted 8 lines
arch/metag/kernel/smp.c +1 -1
@@ -297,7 +297,7 @@ asmlinkage void secondary_start_kernel(v
 	/*
 	 * OK, it's off to the idle thread for us
 	 */
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 void __init smp_cpus_done(unsigned int max_cpus)

I also hit the same problems Tony Breeds hit.

After hacking around them, and enabling SMP and HOTPLUG_CPU, I hit the WARN_ON_ONCE(!irqs_disabled()) after arch_cpu_idle() in cpu_idle_loop():

Quoted 1 line

META213-Thread1 DSP [LogF] WARNING: at kernel/cpu/idle.c:94 _cpu_startup_entry+0x1cc/0x1e0()

arch_cpu_idle() enables interrupts. See Arnd's comment in
https://patchwork.kernel.org/patch/2002571/:

Quoted 4 lines

To avoid that, you need to disable interrupts around the inner loop. The sleep instruction should return with interrupts implicitly enabled if ARC behaves like most other architectures doing this.

Cheers
James

#76 lore raw

Re: [patch 20/34] metag: Use generic idle loop

Quoted 9 lines · James Hogan
Quoted 8 lines · Thomas Gleixner
---
 arch/metag/Kconfig          |    1 +
 arch/metag/kernel/process.c |   32 +++-----------------------------
 arch/metag/kernel/smp.c     |    2 +-
 3 files changed, 5 insertions(+), 30 deletions(-)
Quoted 11 lines

arch/metag/Kconfig config METAG · line 12

Quoted 9 lines

Index: linux-2.6/arch/metag/Kconfig
===================================================================

arch/metag/Kconfig +1 -0
@@ -9,6 +9,7 @@ config METAG
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_IRQ_SHOW
 	select GENERIC_SMP_IDLE_THREAD
+	select GENERIC_IDLE_LOOP

Please preserve alphabetical ordering

Ok.

Quoted 46 lines
Quoted 46 lines
arch/metag/Kconfig +0 -0
 	select HAVE_64BIT_ALIGNED_ACCESS
 	select HAVE_ARCH_TRACEHOOK
 	select HAVE_C_RECORDMCOUNT

Index: linux-2.6/arch/metag/kernel/process.c
===================================================================

arch/metag/kernel/process.c +2 -25
@@ -31,7 +31,7 @@
 /*
  * Wait for the next interrupt and enable local interrupts
  */
-static inline void arch_idle(void)
+void arch_cpu_idle(void)
 {
 	int tmp;
 
@@ -59,35 +59,9 @@ static inline void arch_idle(void)
 		      : "r" (get_trigger_mask()));
 }
 
-void cpu_idle(void)
+void arch_cpu_idle_dead(void)
 {
-	set_thread_flag(TIF_POLLING_NRFLAG);
-
-	while (1) {
-		tick_nohz_idle_enter();
-		rcu_idle_enter();
-
-		while (!need_resched()) {
-			/*
-			 * We need to disable interrupts here to ensure we don't
-			 * miss a wakeup call.
-			 */
-			local_irq_disable();
-			if (!need_resched()) {
-#ifdef CONFIG_HOTPLUG_CPU
-				if (cpu_is_offline(smp_processor_id()))
-					cpu_die();
-#endif
-				arch_idle();
-			} else {
-				local_irq_enable();
-			}
-		}
-
Quoted 8 lines

arch/metag/kernel/process.c static inline void arch_idle(void) · line 64

Quoted 5 lines
arch/metag/kernel/process.c +1 -4
-		rcu_idle_exit();
-		tick_nohz_idle_exit();
-		schedule_preempt_disabled();
-	 }
+	cpu_die();

This requires #include <linux/smp.h> and even then the definition of cpu_die() is guarded by #ifdef CONFIG_HOTPLUG_CPU, like blackfin & s390.

Will fix.

Quoted 15 lines
Quoted 15 lines
arch/metag/kernel/process.c +0 -0
 }
 
 void (*pm_power_off)(void);

Index: linux-2.6/arch/metag/kernel/smp.c
===================================================================

arch/metag/kernel/smp.c +1 -1
@@ -297,7 +297,7 @@ asmlinkage void secondary_start_kernel(v
 	/*
 	 * OK, it's off to the idle thread for us
 	 */
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
Quoted 8 lines

arch/metag/kernel/smp.c asmlinkage void secondary_start_kernel(v · line 303

Quoted 3 lines
arch/metag/kernel/smp.c +0 -0
 void __init smp_cpus_done(unsigned int max_cpus)

I also hit the same problems Tony Breeds hit.

After hacking around them, and enabling SMP and HOTPLUG_CPU, I hit the WARN_ON_ONCE(!irqs_disabled()) after arch_cpu_idle() in cpu_idle_loop():

My stupidity. I fatfingered it when last minute changing it to WARN_ON_ONCE

Quoted 9 lines
Quoted 1 line

META213-Thread1 DSP [LogF] WARNING: at kernel/cpu/idle.c:94 _cpu_startup_entry+0x1cc/0x1e0()

arch_cpu_idle() enables interrupts. See Arnd's comment in
https://patchwork.kernel.org/patch/2002571/:

Quoted 4 lines

To avoid that, you need to disable interrupts around the inner loop. The sleep instruction should return with interrupts implicitly enabled if ARC behaves like most other architectures doing this.

Right. My fault. See above.

Thanks,

tglx

#77 lore raw

[tip:smp/hotplug] metag: Use generic idle loop

In reply to Thomas Gleixner
metag: Use generic idle loop
Commit-ID:  d1dba0fcd3e62f32d5925bcb91eba8757951464c
Gitweb:     http://git.kernel.org/tip/d1dba0fcd3e62f32d5925bcb91eba8757951464c
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:50 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:26 +0200

metag: Use generic idle loop

---
 arch/metag/Kconfig          |  1 +
 arch/metag/kernel/process.c | 35 ++++++-----------------------------
 arch/metag/kernel/smp.c     |  2 +-
 3 files changed, 8 insertions(+), 30 deletions(-)
arch/metag/Kconfig +1 -0
index afc8973..3164f6c 100644
@@ -7,6 +7,7 @@ config METAG
 	select EMBEDDED
 	select GENERIC_ATOMIC64
 	select GENERIC_CLOCKEVENTS
+	select GENERIC_IDLE_LOOP
 	select GENERIC_IRQ_SHOW
 	select GENERIC_SMP_IDLE_THREAD
 	select HAVE_64BIT_ALIGNED_ACCESS
arch/metag/kernel/process.c +6 -29
index c6efe62..dc59235 100644
@@ -22,6 +22,7 @@
 #include <linux/pm.h>
 #include <linux/syscalls.h>
 #include <linux/uaccess.h>
+#include <linux/smp.h>
 #include <asm/core_reg.h>
 #include <asm/user_gateway.h>
 #include <asm/tcm.h>
@@ -31,7 +32,7 @@
 /*
  * Wait for the next interrupt and enable local interrupts
  */
-static inline void arch_idle(void)
+void arch_cpu_idle(void)
 {
 	int tmp;
 
@@ -59,36 +60,12 @@ static inline void arch_idle(void)
 		      : "r" (get_trigger_mask()));
 }
 
-void cpu_idle(void)
-{
-	set_thread_flag(TIF_POLLING_NRFLAG);
-
-	while (1) {
-		tick_nohz_idle_enter();
-		rcu_idle_enter();
-
-		while (!need_resched()) {
-			/*
-			 * We need to disable interrupts here to ensure we don't
-			 * miss a wakeup call.
-			 */
-			local_irq_disable();
-			if (!need_resched()) {
 #ifdef CONFIG_HOTPLUG_CPU
-				if (cpu_is_offline(smp_processor_id()))
-					cpu_die();
-#endif
-				arch_idle();
-			} else {
-				local_irq_enable();
-			}
-		}
-
-		rcu_idle_exit();
-		tick_nohz_idle_exit();
-		schedule_preempt_disabled();
-	 }
+void arch_cpu_idle_dead(void)
+{
+	cpu_die();
 }
+#endif
 
 void (*pm_power_off)(void);
 EXPORT_SYMBOL(pm_power_off);
arch/metag/kernel/smp.c +1 -1
index 4b6d1f14..4de8fc8 100644
@@ -297,7 +297,7 @@ asmlinkage void secondary_start_kernel(void)
 	/*
 	 * OK, it's off to the idle thread for us
 	 */
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 void __init smp_cpus_done(unsigned int max_cpus)
#78 lore raw

PATCH 21/34 microblaze: Use generic idle loop

In reply to Thomas Gleixner

The microblaze idle loop provides a polling and a non polling version, which are suprisingly both polling, just with slightly different instrumentation. Remove them and use the generic poller.

---
 arch/microblaze/Kconfig                 |    2 +
 arch/microblaze/include/asm/processor.h |    3 -
 arch/microblaze/kernel/process.c        |   53 --------------------------------
 3 files changed, 2 insertions(+), 56 deletions(-)
arch/microblaze/Kconfig +2 -0
Index: linux-2.6/arch/microblaze/Kconfig
===================================================================
@@ -26,6 +26,8 @@ config MICROBLAZE
 	select GENERIC_CPU_DEVICES
 	select GENERIC_ATOMIC64
 	select GENERIC_CLOCKEVENTS
+	select GENERIC_IDLE_LOOP
+	select GENERIC_IDLE_POLL_SETUP
 	select MODULES_USE_ELF_RELA
 	select CLONE_BACKWARDS
 
arch/microblaze/include/asm/processor.h +0 -3
Index: linux-2.6/arch/microblaze/include/asm/processor.h
===================================================================
@@ -22,7 +22,6 @@
 extern const struct seq_operations cpuinfo_op;
 
 # define cpu_relax()		barrier()
-# define cpu_sleep()		do {} while (0)
 
 #define task_pt_regs(tsk) \
 		(((struct pt_regs *)(THREAD_SIZE + task_stack_page(tsk))) - 1)
@@ -160,8 +159,6 @@ unsigned long get_wchan(struct task_stru
 #  define STACK_TOP	TASK_SIZE
 #  define STACK_TOP_MAX	STACK_TOP
 
-void default_idle(void);
-
 #ifdef CONFIG_DEBUG_FS
 extern struct dentry *of_debugfs_root;
 #endif
arch/microblaze/kernel/process.c +0 -53

59 lines not on this page · raw message

#79 lore raw

[tip:smp/hotplug] microblaze: Use generic idle loop

microblaze: Use generic idle loop
Commit-ID:  e962bb9e9cf73b8c8893c95903e791dd5ec19fb4
Gitweb:     http://git.kernel.org/tip/e962bb9e9cf73b8c8893c95903e791dd5ec19fb4
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:51 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:26 +0200

microblaze: Use generic idle loop

The microblaze idle loop provides a polling and a non polling version, which are suprisingly both polling, just with slightly different instrumentation. Remove them and use the generic poller.

---
 arch/microblaze/Kconfig                 |  2 ++
 arch/microblaze/include/asm/processor.h |  3 --
 arch/microblaze/kernel/process.c        | 53 ---------------------------------
 3 files changed, 2 insertions(+), 56 deletions(-)
arch/microblaze/Kconfig +2 -0
index 1323fa2..0bb0d51 100644
@@ -26,6 +26,8 @@ config MICROBLAZE
 	select GENERIC_CPU_DEVICES
 	select GENERIC_ATOMIC64
 	select GENERIC_CLOCKEVENTS
+	select GENERIC_IDLE_LOOP
+	select GENERIC_IDLE_POLL_SETUP
 	select MODULES_USE_ELF_RELA
 	select CLONE_BACKWARDS
 
arch/microblaze/include/asm/processor.h +0 -3
index f576fe0..d6e0ffe 100644
@@ -22,7 +22,6 @@
 extern const struct seq_operations cpuinfo_op;
 
 # define cpu_relax()		barrier()
-# define cpu_sleep()		do {} while (0)
 
 #define task_pt_regs(tsk) \
 		(((struct pt_regs *)(THREAD_SIZE + task_stack_page(tsk))) - 1)
@@ -160,8 +159,6 @@ unsigned long get_wchan(struct task_struct *p);
 #  define STACK_TOP	TASK_SIZE
 #  define STACK_TOP_MAX	STACK_TOP
 
-void default_idle(void);
-
 #ifdef CONFIG_DEBUG_FS
 extern struct dentry *of_debugfs_root;
 #endif
arch/microblaze/kernel/process.c +0 -53

59 lines not on this page · raw message

#80 lore raw

PATCH 22/34 mips: Use generic idle loop

In reply to Thomas Gleixner
---
 arch/mips/Kconfig          |    1 
 arch/mips/kernel/process.c |   46 ++++++++++++---------------------------------
 arch/mips/kernel/smp.c     |    2 -
 3 files changed, 15 insertions(+), 34 deletions(-)
arch/mips/Kconfig +1 -0
Index: linux-2.6/arch/mips/Kconfig
===================================================================
@@ -34,6 +34,7 @@ config MIPS
 	select HAVE_MEMBLOCK_NODE_MAP
 	select ARCH_DISCARD_MEMBLOCK
 	select GENERIC_SMP_IDLE_THREAD
+	select GENERIC_IDLE_LOOP
 	select BUILDTIME_EXTABLE_SORT
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_CMOS_UPDATE
arch/mips/kernel/process.c +13 -33

57 lines not on this page · raw message

arch/mips/kernel/smp.c +1 -1
Index: linux-2.6/arch/mips/kernel/smp.c
===================================================================
@@ -139,7 +139,7 @@ asmlinkage __cpuinit void start_secondar
 	WARN_ON_ONCE(!irqs_disabled());
 	mp_ops->smp_finish();
 
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 /*
#81 lore raw

Re: [patch 22/34] mips: Use generic idle loop

Quoted 8 lines · Thomas Gleixner
---
 arch/mips/Kconfig          |    1 
 arch/mips/kernel/process.c |   46 ++++++++++++---------------------------------
 arch/mips/kernel/smp.c     |    2 -
 3 files changed, 15 insertions(+), 34 deletions(-)

[...]

Quoted 13 lines

Index: linux-2.6/arch/mips/kernel/process.c
===================================================================

arch/mips/kernel/process.c +0 -5
@@ -41,44 +41,24 @@
 #include <asm/inst.h>
 #include <asm/stacktrace.h>
 
-/*
- * The idle thread. There's no useful work to be done, so just try to conserve
- * power and have a low exit latency (ie sit in a loop waiting for somebody to
- * say that they'd like to reschedule)
- */

arch/mips/kernel/process.c line 48

Quoted 10 lines
arch/mips/kernel/process.c +4 -5
-void __noreturn cpu_idle(void)
+void arch_cpu_idle_dead(void)
 {
-	int cpu;
-
-	/* CPU is going idle. */
-	cpu = smp_processor_id();
+	/* What the heck is this check doing ? */
+	if (!cpu_isset(cpu, cpu_callin_map))
+		play_dead();}

Extra closing brace?

arch/mips/kernel/process.c line 51

Quoted 8 lines
arch/mips/kernel/process.c +2 -5
+}
 
-	/* endless idle loop with no priority at all */
-	while (1) {
-		tick_nohz_idle_enter();
-		rcu_idle_enter();
-		while (!need_resched() && cpu_online(cpu)) {
+void arch__cpu_idle(void)

s/arch__cpu_idle/arch_cpu_idle (single underscore)

Regards,
Srivatsa S. Bhat

Quoted 30 lines
arch/mips/kernel/process.c +7 -18
+{
 #ifdef CONFIG_MIPS_MT_SMTC
-			extern void smtc_idle_loop_hook(void);
+	extern void smtc_idle_loop_hook(void);
 
-			smtc_idle_loop_hook();
+	smtc_idle_loop_hook();
 #endif
-
-			if (cpu_wait) {
-				/* Don't trace irqs off for idle */
-				stop_critical_timings();
-				(*cpu_wait)();
-				start_critical_timings();
-			}
-		}
-#ifdef CONFIG_HOTPLUG_CPU
-		if (!cpu_online(cpu) && !cpu_isset(cpu, cpu_callin_map))
-			play_dead();
-#endif
-		rcu_idle_exit();
-		tick_nohz_idle_exit();
-		schedule_preempt_disabled();
-	}
+	if (cpu_wait)
+		(*cpu_wait)();
+	else
+		local_irq_enable();
 }
 
#82 lore raw

[tip:smp/hotplug] mips: Use generic idle loop

In reply to Thomas Gleixner
mips: Use generic idle loop
Commit-ID:  cdbedc61c8d0122ad682815936f0d11df1fe5f57
Gitweb:     http://git.kernel.org/tip/cdbedc61c8d0122ad682815936f0d11df1fe5f57
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:52 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:26 +0200

mips: Use generic idle loop

---
 arch/mips/Kconfig          |  1 +
 arch/mips/kernel/process.c | 48 +++++++++++++++-------------------------------
 arch/mips/kernel/smp.c     |  2 +-
 3 files changed, 17 insertions(+), 34 deletions(-)
arch/mips/Kconfig +1 -0
index 51244bf..e1a3d02 100644
@@ -34,6 +34,7 @@ config MIPS
 	select HAVE_MEMBLOCK_NODE_MAP
 	select ARCH_DISCARD_MEMBLOCK
 	select GENERIC_SMP_IDLE_THREAD
+	select GENERIC_IDLE_LOOP
 	select BUILDTIME_EXTABLE_SORT
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_CMOS_UPDATE
arch/mips/kernel/process.c +15 -33

59 lines not on this page · raw message

arch/mips/kernel/smp.c +1 -1
index 66bf4e2..aee04af 100644
@@ -139,7 +139,7 @@ asmlinkage __cpuinit void start_secondary(void)
 	WARN_ON_ONCE(!irqs_disabled());
 	mp_ops->smp_finish();
 
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 /*
#83 lore raw

PATCH 23/34 mn10300: Use generic idle loop

In reply to Thomas Gleixner

default_idle() boils down to safe_halt() and the other option is idle polling. Use the core functionality.

---
 arch/mn10300/Kconfig          |    1 
 arch/mn10300/kernel/process.c |   70 +++---------------------------------------
 arch/mn10300/kernel/smp.c     |    2 -
 3 files changed, 8 insertions(+), 65 deletions(-)
arch/mn10300/Kconfig +1 -0
Index: linux-2.6/arch/mn10300/Kconfig
===================================================================
@@ -13,6 +13,7 @@ config MN10300
 	select MODULES_USE_ELF_RELA
 	select OLD_SIGSUSPEND3
 	select OLD_SIGACTION
+	select GENERIC_IDLE_LOOP
 
 config AM33_2
 	def_bool n
arch/mn10300/kernel/process.c +6 -64

83 lines not on this page · raw message

arch/mn10300/kernel/smp.c +1 -1
Index: linux-2.6/arch/mn10300/kernel/smp.c
===================================================================
@@ -675,7 +675,7 @@ int __init start_secondary(void *unused)
 #ifdef CONFIG_GENERIC_CLOCKEVENTS
 	init_clockevents();
 #endif
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 	return 0;
 }
 
#84 lore raw

[tip:smp/hotplug] mn10300: Use generic idle loop

mn10300: Use generic idle loop
Commit-ID:  af695cd931edab7f202fb616d69d4b746c5d6912
Gitweb:     http://git.kernel.org/tip/af695cd931edab7f202fb616d69d4b746c5d6912
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:53 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:27 +0200

mn10300: Use generic idle loop

default_idle() boils down to safe_halt() and the other option is idle polling. Use the core functionality.

---
 arch/mn10300/Kconfig          |  1 +
 arch/mn10300/kernel/process.c | 70 ++++---------------------------------------
 arch/mn10300/kernel/smp.c     |  2 +-
 3 files changed, 8 insertions(+), 65 deletions(-)
arch/mn10300/Kconfig +1 -0
index 428da17..ae7158b6 100644
@@ -13,6 +13,7 @@ config MN10300
 	select MODULES_USE_ELF_RELA
 	select OLD_SIGSUSPEND3
 	select OLD_SIGACTION
+	select GENERIC_IDLE_LOOP
 
 config AM33_2
 	def_bool n
arch/mn10300/kernel/process.c +6 -64

83 lines not on this page · raw message

arch/mn10300/kernel/smp.c +1 -1
index eaef5ad..a17f9c9 100644
@@ -675,7 +675,7 @@ int __init start_secondary(void *unused)
 #ifdef CONFIG_GENERIC_CLOCKEVENTS
 	init_clockevents();
 #endif
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 	return 0;
 }
 
#85 lore raw

PATCH 24/34 openrisc: Use generic idle loop

In reply to Thomas Gleixner

Idle poller with an extra check_pgt_cache() invocation. Use the core code.

---
 arch/openrisc/Kconfig       |    1 
 arch/openrisc/kernel/idle.c |   73 --------------------------------------------
 2 files changed, 1 insertion(+), 73 deletions(-)
arch/openrisc/Kconfig +1 -0
Index: linux-2.6/arch/openrisc/Kconfig
===================================================================
@@ -21,6 +21,7 @@ config OPENRISC
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_STRNCPY_FROM_USER
 	select GENERIC_STRNLEN_USER
+	select GENERIC_IDLE_LOOP
 	select MODULES_USE_ELF_RELA
 
 config MMU
arch/openrisc/kernel/idle.c deleted +0 -73

73 lines not on this page · raw message

#86 lore raw

[tip:smp/hotplug] openrisc: Use generic idle loop

openrisc: Use generic idle loop
Commit-ID:  6862c05ce4bc59ac52165df66f2a55ad692ef941
Gitweb:     http://git.kernel.org/tip/6862c05ce4bc59ac52165df66f2a55ad692ef941
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:54 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:27 +0200

openrisc: Use generic idle loop

Idle poller with an extra check_pgt_cache() invocation. Use the core code.

---
 arch/openrisc/Kconfig         |  1 +
 arch/openrisc/kernel/Makefile |  2 +-
 arch/openrisc/kernel/idle.c   | 73 -------------------------------------------
 3 files changed, 2 insertions(+), 74 deletions(-)
arch/openrisc/Kconfig +1 -0
index 9ab3bf2..e111b52 100644
@@ -21,6 +21,7 @@ config OPENRISC
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_STRNCPY_FROM_USER
 	select GENERIC_STRNLEN_USER
+	select GENERIC_IDLE_LOOP
 	select MODULES_USE_ELF_RELA
 
 config MMU
arch/openrisc/kernel/Makefile +1 -1
index 35f92ce..ec6d9d3 100644
@@ -4,7 +4,7 @@
 
 extra-y	:= head.o vmlinux.lds
 
-obj-y	:= setup.o idle.o or32_ksyms.o process.o dma.o \
+obj-y	:= setup.o or32_ksyms.o process.o dma.o \
 	   traps.o time.o irq.o entry.o ptrace.o signal.o \
 	   sys_call_table.o
 
arch/openrisc/kernel/idle.c deleted +0 -73

73 lines not on this page · raw message

#87 lore raw

PATCH 25/34 parisc: Use generic idle loop

In reply to Thomas Gleixner
Cc "James E.J. Bottomley" <[email protected]>
Cc Helge Deller <[email protected]>
---
 arch/parisc/Kconfig          |    1 +
 arch/parisc/kernel/process.c |   22 ----------------------
 arch/parisc/kernel/smp.c     |    2 +-
 3 files changed, 2 insertions(+), 23 deletions(-)
arch/parisc/Kconfig +1 -0
Index: linux-2.6/arch/parisc/Kconfig
===================================================================
@@ -18,6 +18,7 @@ config PARISC
 	select GENERIC_PCI_IOMAP
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select GENERIC_SMP_IDLE_THREAD
+	select GENERIC_IDLE_LOOP
 	select GENERIC_STRNCPY_FROM_USER
 	select SYSCTL_ARCH_UNALIGN_ALLOW
 	select HAVE_MOD_ARCH_SPECIFIC
arch/parisc/kernel/process.c +0 -22
Index: linux-2.6/arch/parisc/kernel/process.c
===================================================================
@@ -59,28 +59,6 @@
 #include <asm/unwind.h>
 #include <asm/sections.h>
 
-/*
- * The idle thread. There's no useful work to be
- * done, so just try to conserve power and have a
- * low exit latency (ie sit in a loop waiting for
- * somebody to say that they'd like to reschedule)
- */
-void cpu_idle(void)
-{
-	set_thread_flag(TIF_POLLING_NRFLAG);
-
-	/* endless idle loop with no priority at all */
-	while (1) {
-		rcu_idle_enter();
-		while (!need_resched())
-			barrier();
-		rcu_idle_exit();
-		schedule_preempt_disabled();
-		check_pgt_cache();
-	}
-}
-
-
 #define COMMAND_GLOBAL  F_EXTEND(0xfffe0030)
 #define CMD_RESET       5       /* reset any module */
 
arch/parisc/kernel/smp.c +1 -1
Index: linux-2.6/arch/parisc/kernel/smp.c
===================================================================
@@ -329,7 +329,7 @@ void __init smp_callin(void)
 
 	local_irq_enable();  /* Interrupts have been off until now */
 
-	cpu_idle();      /* Wait for timer to schedule some work */
+	cpu_startup_entry(CPUHP_ONLINE);
 
 	/* NOTREACHED */
 	panic("smp_callin() AAAAaaaaahhhh....\n");
#88 lore raw

[tip:smp/hotplug] parisc: Use generic idle loop

parisc: Use generic idle loop
Commit-ID:  fad48ad63dd14656e3b571d42f700a1f2cadd036
Gitweb:     http://git.kernel.org/tip/fad48ad63dd14656e3b571d42f700a1f2cadd036
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:55 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:27 +0200

parisc: Use generic idle loop

---
 arch/parisc/Kconfig          |  1 +
 arch/parisc/kernel/process.c | 22 ----------------------
 arch/parisc/kernel/smp.c     |  2 +-
 3 files changed, 2 insertions(+), 23 deletions(-)
arch/parisc/Kconfig +1 -0
index 0339181..0821e70 100644
@@ -18,6 +18,7 @@ config PARISC
 	select GENERIC_PCI_IOMAP
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select GENERIC_SMP_IDLE_THREAD
+	select GENERIC_IDLE_LOOP
 	select GENERIC_STRNCPY_FROM_USER
 	select SYSCTL_ARCH_UNALIGN_ALLOW
 	select HAVE_MOD_ARCH_SPECIFIC
arch/parisc/kernel/process.c +0 -22
index d135072..55f92b6 100644
@@ -59,28 +59,6 @@
 #include <asm/unwind.h>
 #include <asm/sections.h>
 
-/*
- * The idle thread. There's no useful work to be
- * done, so just try to conserve power and have a
- * low exit latency (ie sit in a loop waiting for
- * somebody to say that they'd like to reschedule)
- */
-void cpu_idle(void)
-{
-	set_thread_flag(TIF_POLLING_NRFLAG);
-
-	/* endless idle loop with no priority at all */
-	while (1) {
-		rcu_idle_enter();
-		while (!need_resched())
-			barrier();
-		rcu_idle_exit();
-		schedule_preempt_disabled();
-		check_pgt_cache();
-	}
-}
-
-
 #define COMMAND_GLOBAL  F_EXTEND(0xfffe0030)
 #define CMD_RESET       5       /* reset any module */
 
arch/parisc/kernel/smp.c +1 -1
index 6266730..fd1bb15 100644
@@ -329,7 +329,7 @@ void __init smp_callin(void)
 
 	local_irq_enable();  /* Interrupts have been off until now */
 
-	cpu_idle();      /* Wait for timer to schedule some work */
+	cpu_startup_entry(CPUHP_ONLINE);
 
 	/* NOTREACHED */
 	panic("smp_callin() AAAAaaaaahhhh....\n");
#89 lore raw

PATCH 26/34 powerpc: Use generic idle loop

In reply to Thomas Gleixner
Cc Benjamin Herrenschmidt <[email protected]>
---
 arch/powerpc/Kconfig       |    1 
 arch/powerpc/kernel/idle.c |   78 ++++++++++++---------------------------------
 arch/powerpc/kernel/smp.c  |    2 -
 3 files changed, 24 insertions(+), 57 deletions(-)
arch/powerpc/Kconfig +1 -0
Index: linux-2.6/arch/powerpc/Kconfig
===================================================================
@@ -133,6 +133,7 @@ config PPC
 	select HAVE_ARCH_JUMP_LABEL
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select GENERIC_SMP_IDLE_THREAD
+	select GENERIC_IDLE_LOOP
 	select GENERIC_CMOS_UPDATE
 	select GENERIC_TIME_VSYSCALL_OLD
 	select GENERIC_CLOCKEVENTS
arch/powerpc/kernel/idle.c +22 -56

86 lines not on this page · raw message

arch/powerpc/kernel/smp.c +1 -1
Index: linux-2.6/arch/powerpc/kernel/smp.c
===================================================================
@@ -669,7 +669,7 @@ __cpuinit void start_secondary(void *unu
 
 	local_irq_enable();
 
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 
 	BUG();
 }
#90 lore raw

Re: [patch 26/34] powerpc: Use generic idle loop

Quoted 3 lines · Thomas Gleixner
Cc Benjamin Herrenschmidt <[email protected]>

---

[...]

Quoted 80 lines

Index: linux-2.6/arch/powerpc/kernel/idle.c
===================================================================

arch/powerpc/kernel/idle.c +15 -56
@@ -50,64 +50,30 @@ static int __init powersave_off(char *ar
 }
 __setup("powersave=off", powersave_off);
 
-/*
- * The body of the idle task.
- */
-void cpu_idle(void)
+void arch_cpu_idle(void)
 {
-	set_thread_flag(TIF_POLLING_NRFLAG);
-	while (1) {
-		tick_nohz_idle_enter();
-		rcu_idle_enter();
-
-		while (!need_resched() && !cpu_should_die()) {
-			ppc64_runlatch_off();
-
-			if (ppc_md.power_save) {
-				clear_thread_flag(TIF_POLLING_NRFLAG);
-				/*
-				 * smp_mb is so clearing of TIF_POLLING_NRFLAG
-				 * is ordered w.r.t. need_resched() test.
-				 */
-				smp_mb();
-				local_irq_disable();
-
-				/* Don't trace irqs off for idle */
-				stop_critical_timings();
-
-				/* check again after disabling irqs */
-				if (!need_resched() && !cpu_should_die())
-					ppc_md.power_save();
-
-				start_critical_timings();
-
-				/* Some power_save functions return with
-				 * interrupts enabled, some don't.
-				 */
-				if (irqs_disabled())
-					local_irq_enable();
-				set_thread_flag(TIF_POLLING_NRFLAG);
-
-			} else {
-				/*
-				 * Go into low thread priority and possibly
-				 * low power mode.
-				 */
-				HMT_low();
-				HMT_very_low();
-			}
-		}
-
-		HMT_medium();
-		ppc64_runlatch_on();
-		rcu_idle_exit();
-		tick_nohz_idle_exit();
-		if (cpu_should_die()) {
-			sched_preempt_enable_no_resched();
-			cpu_die();
-		}
-		schedule_preempt_disabled();
+	ppc64_runlatch_off();
+
+	if (ppc_md.power_save) {
+		ppc_md.power_save();
+		/*
+		 * Some power_save functions return with
+		 * interrupts enabled, some don't.
+		 */
+		if (irqs_disabled())
+			local_irq_enable();
+	} else {
+		local_irq_enable();
+		/*
+		 * Go into low thread priority and possibly

arch/powerpc/kernel/idle.c static int __init powersave_off(char *ar · line 78

Quoted 10 lines
arch/powerpc/kernel/idle.c +7 -0
+		 * low power mode.
+		 */
+		HMT_low();
+		HMT_very_low();
 	}
+
+	HMT_medium();
+	ppc64_runlatch_on();
 }
 

The call to cpu_die() seems to be missing. And considering this commit,

commit a7c2bb8279d20d853e43c34584eaf2b039de8026

Author: Signed-off-by: Darren Hart <[email protected]>
Date:   Wed Aug 4 18:28:33 2010 +0000

powerpc: Re-enable preemption before cpu_die()

we need to call it with preempt enabled. So how about folding the following diff with this patch?

arch/powerpc/kernel/idle.c +6 -5
index b751baa..e434fb9 100644
@@ -33,11 +33,6 @@
 #include <asm/runlatch.h>
 #include <asm/smp.h>
 
-#ifdef CONFIG_HOTPLUG_CPU
-#define cpu_should_die()	cpu_is_offline(smp_processor_id())
-#else
-#define cpu_should_die()	0
-#endif
 
 unsigned long cpuidle_disable = IDLE_NO_OVERRIDE;
 EXPORT_SYMBOL(cpuidle_disable);
@@ -50,6 +45,12 @@ static int __init powersave_off(char *arg)
 }
 __setup("powersave=off", powersave_off);
 
+void arch_cpu_idle_dead(void)
+{
+	sched_preempt_enable_no_resched();
+	cpu_die();
+}
+
 void arch_cpu_idle(void)
 {
 	ppc64_runlatch_off();

Regards,
Srivatsa S. Bhat

Tested-by
#91 lore raw

Re: [patch 26/34] powerpc: Use generic idle loop

Quoted 87 lines · Srivatsa S. Bhat
Quoted 3 lines · Thomas Gleixner
Cc Benjamin Herrenschmidt <[email protected]>

---

[...]

Quoted 82 lines

Index: linux-2.6/arch/powerpc/kernel/idle.c
===================================================================

arch/powerpc/kernel/idle.c +17 -56
@@ -50,64 +50,30 @@ static int __init powersave_off(char *ar
 }
 __setup("powersave=off", powersave_off);
 
-/*
- * The body of the idle task.
- */
-void cpu_idle(void)
+void arch_cpu_idle(void)
 {
-	set_thread_flag(TIF_POLLING_NRFLAG);
-	while (1) {
-		tick_nohz_idle_enter();
-		rcu_idle_enter();
-
-		while (!need_resched() && !cpu_should_die()) {
-			ppc64_runlatch_off();
-
-			if (ppc_md.power_save) {
-				clear_thread_flag(TIF_POLLING_NRFLAG);
-				/*
-				 * smp_mb is so clearing of TIF_POLLING_NRFLAG
-				 * is ordered w.r.t. need_resched() test.
-				 */
-				smp_mb();
-				local_irq_disable();
-
-				/* Don't trace irqs off for idle */
-				stop_critical_timings();
-
-				/* check again after disabling irqs */
-				if (!need_resched() && !cpu_should_die())
-					ppc_md.power_save();
-
-				start_critical_timings();
-
-				/* Some power_save functions return with
-				 * interrupts enabled, some don't.
-				 */
-				if (irqs_disabled())
-					local_irq_enable();
-				set_thread_flag(TIF_POLLING_NRFLAG);
-
-			} else {
-				/*
-				 * Go into low thread priority and possibly
-				 * low power mode.
-				 */
-				HMT_low();
-				HMT_very_low();
-			}
-		}
-
-		HMT_medium();
-		ppc64_runlatch_on();
-		rcu_idle_exit();
-		tick_nohz_idle_exit();
-		if (cpu_should_die()) {
-			sched_preempt_enable_no_resched();
-			cpu_die();
-		}
-		schedule_preempt_disabled();
+	ppc64_runlatch_off();
+
+	if (ppc_md.power_save) {
+		ppc_md.power_save();
+		/*
+		 * Some power_save functions return with
+		 * interrupts enabled, some don't.
+		 */
+		if (irqs_disabled())
+			local_irq_enable();
+	} else {
+		local_irq_enable();
+		/*
+		 * Go into low thread priority and possibly
+		 * low power mode.
+		 */
Quoted 8 lines

arch/powerpc/kernel/idle.c static int __init powersave_off(char *ar · line 78

Quoted 8 lines
arch/powerpc/kernel/idle.c +5 -0
+		HMT_low();
+		HMT_very_low();
 	}
+
+	HMT_medium();
+	ppc64_runlatch_on();
 }
 

The below patch is essential to get hotplug working on POWER. With that, generic idle loop works fine for PSERIES.

Quoted 47 lines

The call to cpu_die() seems to be missing. And considering this commit,

commit a7c2bb8279d20d853e43c34584eaf2b039de8026

Author: Signed-off-by: Darren Hart <[email protected]>
Date:   Wed Aug 4 18:28:33 2010 +0000

powerpc: Re-enable preemption before cpu_die()

we need to call it with preempt enabled. So how about folding the following diff with this patch?

arch/powerpc/kernel/idle.c +6 -5
index b751baa..e434fb9 100644
@@ -33,11 +33,6 @@
 #include <asm/runlatch.h>
 #include <asm/smp.h>
 
-#ifdef CONFIG_HOTPLUG_CPU
-#define cpu_should_die()	cpu_is_offline(smp_processor_id())
-#else
-#define cpu_should_die()	0
-#endif
 
 unsigned long cpuidle_disable = IDLE_NO_OVERRIDE;
 EXPORT_SYMBOL(cpuidle_disable);
@@ -50,6 +45,12 @@ static int __init powersave_off(char *arg)
 }
 __setup("powersave=off", powersave_off);
 
+void arch_cpu_idle_dead(void)
+{
+	sched_preempt_enable_no_resched();
+	cpu_die();
+}
+
 void arch_cpu_idle(void)
 {
 	ppc64_runlatch_off();

Regards,
Srivatsa S. Bhat

#92 lore raw

[tip:smp/hotplug] powerpc: Use generic idle loop

In reply to Thomas Gleixner
powerpc: Use generic idle loop
Commit-ID:  799fef06123f86ff69cf754f996219e6ad1678f8
Gitweb:     http://git.kernel.org/tip/799fef06123f86ff69cf754f996219e6ad1678f8
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:56 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:27 +0200

powerpc: Use generic idle loop

---
 arch/powerpc/Kconfig       |  1 +
 arch/powerpc/kernel/idle.c | 89 +++++++++++++++-------------------------------
 arch/powerpc/kernel/smp.c  |  2 +-
 3 files changed, 31 insertions(+), 61 deletions(-)
arch/powerpc/Kconfig +1 -0
index ea5bb04..19de32c 100644
@@ -133,6 +133,7 @@ config PPC
 	select HAVE_ARCH_JUMP_LABEL
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select GENERIC_SMP_IDLE_THREAD
+	select GENERIC_IDLE_LOOP
 	select GENERIC_CMOS_UPDATE
 	select GENERIC_TIME_VSYSCALL_OLD
 	select GENERIC_CLOCKEVENTS
arch/powerpc/kernel/idle.c +29 -60

104 lines not on this page · raw message

arch/powerpc/kernel/smp.c +1 -1
index 76bd9da..ee7ac5e 100644
@@ -669,7 +669,7 @@ __cpuinit void start_secondary(void *unused)
 
 	local_irq_enable();
 
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 
 	BUG();
 }
#93 lore raw

PATCH 27/34 s390: Use generic idle loop

In reply to Thomas Gleixner
---
 arch/s390/kernel/process.c |   25 +++++++------------------
 arch/s390/kernel/smp.c     |    3 +--
 2 files changed, 8 insertions(+), 20 deletions(-)
arch/s390/kernel/process.c +7 -18
Index: linux-2.6/arch/s390/kernel/process.c
===================================================================
@@ -62,17 +62,15 @@ unsigned long thread_saved_pc(struct tas
 }
 
 /*
- * The idle loop on a S390...
+ * The idle function on a S390...
  */
-static void default_idle(void)
+void arch_cpu_idle(void)
 {
-	if (cpu_is_offline(smp_processor_id()))
-		cpu_die();
-	local_irq_disable();
-	if (need_resched()) {
+	if (test_thread_flag(TIF_MCCK_PENDING)) {
 		local_irq_enable();
 		return;
 	}
+
 	local_mcck_disable();
 	if (test_thread_flag(TIF_MCCK_PENDING)) {
 		local_mcck_enable();
@@ -83,19 +81,10 @@ static void default_idle(void)
 	vtime_stop_cpu();
 }
 
-void cpu_idle(void)
+void arch_cpu_idle_exit(void)
 {
-	for (;;) {
-		tick_nohz_idle_enter();
-		rcu_idle_enter();
-		while (!need_resched() && !test_thread_flag(TIF_MCCK_PENDING))
-			default_idle();
-		rcu_idle_exit();
-		tick_nohz_idle_exit();
-		if (test_thread_flag(TIF_MCCK_PENDING))
-			s390_handle_mcck();
-		schedule_preempt_disabled();
-	}
+	if (test_thread_flag(TIF_MCCK_PENDING))
+		s390_handle_mcck();
 }
 
 extern void __kprobes kernel_thread_starter(void);
arch/s390/kernel/smp.c +1 -2
Index: linux-2.6/arch/s390/kernel/smp.c
===================================================================
@@ -711,8 +711,7 @@ static void __cpuinit smp_start_secondar
 	set_cpu_online(smp_processor_id(), true);
 	inc_irq_stat(CPU_RST);
 	local_irq_enable();
-	/* cpu_idle will call schedule for us */
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 /* Upping and downing of CPUs */
#94 lore raw

Re: [patch 27/34] s390: Use generic idle loop

Quoted 6 lines · Thomas Gleixner
---
 arch/s390/kernel/process.c |   25 +++++++------------------
 arch/s390/kernel/smp.c     |    3 +--
 2 files changed, 8 insertions(+), 20 deletions(-)

Please merge the patch below into your patch to fix some issues.

---
 arch/s390/Kconfig          |  1 +
 arch/s390/kernel/process.c | 13 +++++--------
 arch/s390/kernel/vtime.c   |  5 -----
 3 files changed, 6 insertions(+), 13 deletions(-)
arch/s390/Kconfig +1 -0
index eb8fb62..749513d 100644
@@ -97,6 +97,7 @@ config S390
 	select CLONE_BACKWARDS2
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_CPU_DEVICES if !SMP
+	select GENERIC_IDLE_LOOP
 	select GENERIC_KERNEL_THREAD
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_TIME_VSYSCALL_OLD
arch/s390/kernel/process.c +5 -8
index 546afed..2bc3edd 100644
@@ -61,16 +61,8 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
 	return sf->gprs[8];
 }
 
-/*
- * The idle function on a S390...
- */
 void arch_cpu_idle(void)
 {
-	if (test_thread_flag(TIF_MCCK_PENDING)) {
-		local_irq_enable();
-		return;
-	}
-
 	local_mcck_disable();
 	if (test_thread_flag(TIF_MCCK_PENDING)) {
 		local_mcck_enable();
@@ -87,6 +79,11 @@ void arch_cpu_idle_exit(void)
 		s390_handle_mcck();
 }
 
+void arch_cpu_idle_dead(void)
+{
+	cpu_die();
+}
+
 extern void __kprobes kernel_thread_starter(void);
 
 /*
arch/s390/kernel/vtime.c +0 -5
index a0042ac..3fb0935 100644
@@ -158,8 +158,6 @@ void __kprobes vtime_stop_cpu(void)
 	unsigned long psw_mask;
 
 	trace_hardirqs_on();
-	/* Don't trace preempt off for idle. */
-	stop_critical_timings();
 
 	/* Wait for external, I/O or machine check interrupt. */
 	psw_mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_DAT |
@@ -169,9 +167,6 @@ void __kprobes vtime_stop_cpu(void)
 	/* Call the assembler magic in entry.S */
 	psw_idle(idle, psw_mask);
 
-	/* Reenable preemption tracer. */
-	start_critical_timings();
-
 	/* Account time spent with enabled wait psw loaded as idle time. */
 	idle->sequence++;
 	smp_wmb();
Signature · 1 line
1.7.12.4
#95 lore raw

Re: [patch 27/34] s390: Use generic idle loop

In reply to Thomas Gleixner
Quoted 6 lines · Thomas Gleixner
---
 arch/s390/kernel/process.c |   25 +++++++------------------
 arch/s390/kernel/smp.c     |    3 +--
 2 files changed, 8 insertions(+), 20 deletions(-)

FWIW, the patch below is also needed to fix a compile error. I'll take care it gets upstream independently of your work.

From 10c8cd5139f9a18cd6e955793ae7ad0877b5dd86 Mon Sep 17 00:00:00 2001
From: Heiko Carstens <[email protected]>
Date: Sat, 23 Mar 2013 10:29:01 +0100
Subject: [PATCH 2/2] s390/mm: provide emtpy check_pgt_cache() function

All architectures need to provide a check_pgt_cache() function. The s390 one got lost somewhere.
So reintroduce it to prevent future compile errors e.g. if Thomas Gleixner's idle loop rework patches get merged.

---
 arch/s390/include/asm/pgtable.h | 2 ++
 1 file changed, 2 insertions(+)
arch/s390/include/asm/pgtable.h +2 -0
index 4a29308..a11c773 100644
@@ -1533,6 +1533,8 @@ extern int s390_enable_sie(void);
  */
 #define pgtable_cache_init()	do { } while (0)
 
+static inline void check_pgt_cache(void) { }
+
 #include <asm-generic/pgtable.h>
 
 #endif /* _S390_PAGE_H */
Signature · 1 line
1.7.12.4
#96 lore raw

[tip:smp/hotplug] s390: Use generic idle loop

In reply to Thomas Gleixner
s390: Use generic idle loop
Commit-ID:  52c0065947b7f78a3d9808b421006a3d870d1f92
Gitweb:     http://git.kernel.org/tip/52c0065947b7f78a3d9808b421006a3d870d1f92
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:57 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:27 +0200

s390: Use generic idle loop

---
 arch/s390/Kconfig          |  1 +
 arch/s390/kernel/process.c | 32 +++++++++-----------------------
 arch/s390/kernel/smp.c     |  3 +--
 arch/s390/kernel/vtime.c   |  5 -----
 4 files changed, 11 insertions(+), 30 deletions(-)
arch/s390/Kconfig +1 -0
index eb8fb62..749513d 100644
@@ -97,6 +97,7 @@ config S390
 	select CLONE_BACKWARDS2
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_CPU_DEVICES if !SMP
+	select GENERIC_IDLE_LOOP
 	select GENERIC_KERNEL_THREAD
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_TIME_VSYSCALL_OLD
arch/s390/kernel/process.c +9 -23
index 536d645..2bc3edd 100644
@@ -61,18 +61,8 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
 	return sf->gprs[8];
 }
 
-/*
- * The idle loop on a S390...
- */
-static void default_idle(void)
+void arch_cpu_idle(void)
 {
-	if (cpu_is_offline(smp_processor_id()))
-		cpu_die();
-	local_irq_disable();
-	if (need_resched()) {
-		local_irq_enable();
-		return;
-	}
 	local_mcck_disable();
 	if (test_thread_flag(TIF_MCCK_PENDING)) {
 		local_mcck_enable();
@@ -83,19 +73,15 @@ static void default_idle(void)
 	vtime_stop_cpu();
 }
 
-void cpu_idle(void)
+void arch_cpu_idle_exit(void)
 {
-	for (;;) {
-		tick_nohz_idle_enter();
-		rcu_idle_enter();
-		while (!need_resched() && !test_thread_flag(TIF_MCCK_PENDING))
-			default_idle();
-		rcu_idle_exit();
-		tick_nohz_idle_exit();
-		if (test_thread_flag(TIF_MCCK_PENDING))
-			s390_handle_mcck();
-		schedule_preempt_disabled();
-	}
+	if (test_thread_flag(TIF_MCCK_PENDING))
+		s390_handle_mcck();
+}
+
+void arch_cpu_idle_dead(void)
+{
+	cpu_die();
 }
 
 extern void __kprobes kernel_thread_starter(void);
arch/s390/kernel/smp.c +1 -2
index 549c9d1..6ff5845 100644
@@ -711,8 +711,7 @@ static void __cpuinit smp_start_secondary(void *cpuvoid)
 	set_cpu_online(smp_processor_id(), true);
 	inc_irq_stat(CPU_RST);
 	local_irq_enable();
-	/* cpu_idle will call schedule for us */
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 /* Upping and downing of CPUs */
arch/s390/kernel/vtime.c +0 -5
index a0042ac..3fb0935 100644
@@ -158,8 +158,6 @@ void __kprobes vtime_stop_cpu(void)
 	unsigned long psw_mask;
 
 	trace_hardirqs_on();
-	/* Don't trace preempt off for idle. */
-	stop_critical_timings();
 
 	/* Wait for external, I/O or machine check interrupt. */
 	psw_mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_DAT |
@@ -169,9 +167,6 @@ void __kprobes vtime_stop_cpu(void)
 	/* Call the assembler magic in entry.S */
 	psw_idle(idle, psw_mask);
 
-	/* Reenable preemption tracer. */
-	start_critical_timings();
-
 	/* Account time spent with enabled wait psw loaded as idle time. */
 	idle->sequence++;
 	smp_wmb();
#97 lore raw

PATCH 28/34 score: Use generic idle loop

In reply to Thomas Gleixner
---
 arch/score/Kconfig          |    1 +
 arch/score/kernel/process.c |   18 ------------------
 2 files changed, 1 insertion(+), 18 deletions(-)
arch/score/Kconfig +1 -0
Index: linux-2.6/arch/score/Kconfig
===================================================================
@@ -11,6 +11,7 @@ config SCORE
        select ARCH_DISCARD_MEMBLOCK
        select GENERIC_CPU_DEVICES
        select GENERIC_CLOCKEVENTS
+       select GENERIC_IDLE_LOOP
        select HAVE_MOD_ARCH_SPECIFIC
 	select VIRT_TO_BUS
 	select MODULES_USE_ELF_REL
arch/score/kernel/process.c +0 -18
Index: linux-2.6/arch/score/kernel/process.c
===================================================================
@@ -41,24 +41,6 @@ void machine_halt(void) {}
 /* If or when software machine-power-off is implemented, add code here. */
 void machine_power_off(void) {}
 
-/*
- * The idle thread. There's no useful work to be
- * done, so just try to conserve power and have a
- * low exit latency (ie sit in a loop waiting for
- * somebody to say that they'd like to reschedule)
- */
-void __noreturn cpu_idle(void)
-{
-	/* endless idle loop with no priority at all */
-	while (1) {
-		rcu_idle_enter();
-		while (!need_resched())
-			barrier();
-		rcu_idle_exit();
-		schedule_preempt_disabled();
-	}
-}
-
 void ret_from_fork(void);
 void ret_from_kernel_thread(void);
 
#98 lore raw

[tip:smp/hotplug] score: Use generic idle loop

score: Use generic idle loop
Commit-ID:  99444202b924e916aad95073d23f9995ae8eb558
Gitweb:     http://git.kernel.org/tip/99444202b924e916aad95073d23f9995ae8eb558
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:58 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:28 +0200

score: Use generic idle loop

---
 arch/score/Kconfig          |  1 +
 arch/score/kernel/process.c | 18 ------------------
 2 files changed, 1 insertion(+), 18 deletions(-)
arch/score/Kconfig +1 -0
index c8def8b..eaac45d 100644
@@ -11,6 +11,7 @@ config SCORE
        select ARCH_DISCARD_MEMBLOCK
        select GENERIC_CPU_DEVICES
        select GENERIC_CLOCKEVENTS
+       select GENERIC_IDLE_LOOP
        select HAVE_MOD_ARCH_SPECIFIC
 	select VIRT_TO_BUS
 	select MODULES_USE_ELF_REL
arch/score/kernel/process.c +0 -18
index 7956846..f4c6d02 100644
@@ -41,24 +41,6 @@ void machine_halt(void) {}
 /* If or when software machine-power-off is implemented, add code here. */
 void machine_power_off(void) {}
 
-/*
- * The idle thread. There's no useful work to be
- * done, so just try to conserve power and have a
- * low exit latency (ie sit in a loop waiting for
- * somebody to say that they'd like to reschedule)
- */
-void __noreturn cpu_idle(void)
-{
-	/* endless idle loop with no priority at all */
-	while (1) {
-		rcu_idle_enter();
-		while (!need_resched())
-			barrier();
-		rcu_idle_exit();
-		schedule_preempt_disabled();
-	}
-}
-
 void ret_from_fork(void);
 void ret_from_kernel_thread(void);
 
#99 lore raw

PATCH 29/34 sh: Use generic idle loop

In reply to Thomas Gleixner
---
 arch/sh/Kconfig       |    2 
 arch/sh/kernel/idle.c |  102 ++++----------------------------------------------
 arch/sh/kernel/smp.c  |    2 
 3 files changed, 12 insertions(+), 94 deletions(-)
arch/sh/Kconfig +2 -0
Index: linux-2.6/arch/sh/Kconfig
===================================================================
@@ -33,6 +33,8 @@ config SUPERH
 	select GENERIC_ATOMIC64
 	select GENERIC_IRQ_SHOW
 	select GENERIC_SMP_IDLE_THREAD
+	select GENERIC_IDLE_LOOP
+	select GENERIC_IDLE_POLL_SETUP
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_CMOS_UPDATE if SH_SH03 || SH_DREAMCAST
 	select GENERIC_STRNCPY_FROM_USER
arch/sh/kernel/idle.c +9 -93

120 lines not on this page · raw message

arch/sh/kernel/smp.c +1 -1
Index: linux-2.6/arch/sh/kernel/smp.c
===================================================================
@@ -203,7 +203,7 @@ asmlinkage void __cpuinit start_secondar
 	set_cpu_online(cpu, true);
 	per_cpu(cpu_state, cpu) = CPU_ONLINE;
 
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 extern struct {
#100 lore raw

Re: [patch 29/34] sh: Use generic idle loop

Quoted 3 lines · Thomas Gleixner

---

[...]

Quoted 35 lines
(quoted diff) +1 -32
-/*
- * The idle thread. There's no useful work to be done, so just try to conserve
- * power and have a low exit latency (ie sit in a loop waiting for somebody to
- * say that they'd like to reschedule)
- */
-void cpu_idle(void)
+void arch_cpu_idle(void)
 {
-	unsigned int cpu = smp_processor_id();
-
-	set_thread_flag(TIF_POLLING_NRFLAG);
-
-	/* endless idle loop with no priority at all */
-	while (1) {
-		tick_nohz_idle_enter();
-		rcu_idle_enter();
-
-		while (!need_resched()) {
-			check_pgt_cache();
-			rmb();
-
-			if (cpu_is_offline(cpu))
-				play_dead();
-
-			local_irq_disable();
-			/* Don't trace irqs off for idle */
-			stop_critical_timings();
-			if (cpuidle_idle_call())
-				sh_idle();
-			/*
-			 * Sanity check to ensure that sh_idle() returns
-			 * with IRQs enabled
-			 */
-			WARN_ON(irqs_disabled());

Review

Quoted 10 lines
(quoted diff) +2 -7
-			start_critical_timings();
-		}
-
-		rcu_idle_exit();
-		tick_nohz_idle_exit();
-		schedule_preempt_disabled();
-	}
+	if (cpuidle_idle_call())
+		sh_idle();
 }

Missing call to play_dead(). Perhaps you can fold the following diff:

arch/sh/kernel/idle.c +5 -0
index 8b9d5d7..2ea4483 100644
@@ -33,6 +33,11 @@ void default_idle(void)
 	clear_bl_bit();
 }
 
+void arch_cpu_idle_dead(void)
+{
+	play_dead();
+}
+
 void arch_cpu_idle(void)
 {
 	if (cpuidle_idle_call())

Regards,
Srivatsa S. Bhat

#101 lore raw

[tip:smp/hotplug] sh: Use generic idle loop

In reply to Thomas Gleixner
sh: Use generic idle loop
Commit-ID:  dc775dd886618a1ea6f092bfb3ddc78660aa1a19
Gitweb:     http://git.kernel.org/tip/dc775dd886618a1ea6f092bfb3ddc78660aa1a19
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:49:59 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:28 +0200

sh: Use generic idle loop

---
 arch/sh/Kconfig       |   2 +
 arch/sh/kernel/idle.c | 101 ++++++--------------------------------------------
 arch/sh/kernel/smp.c  |   2 +-
 3 files changed, 14 insertions(+), 91 deletions(-)
arch/sh/Kconfig +2 -0
index 5e85963..853cbc9 100644
@@ -33,6 +33,8 @@ config SUPERH
 	select GENERIC_ATOMIC64
 	select GENERIC_IRQ_SHOW
 	select GENERIC_SMP_IDLE_THREAD
+	select GENERIC_IDLE_LOOP
+	select GENERIC_IDLE_POLL_SETUP
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_CMOS_UPDATE if SH_SH03 || SH_DREAMCAST
 	select GENERIC_STRNCPY_FROM_USER
arch/sh/kernel/idle.c +11 -90

122 lines not on this page · raw message

arch/sh/kernel/smp.c +1 -1
index 2062aa8..4569645 100644
@@ -203,7 +203,7 @@ asmlinkage void __cpuinit start_secondary(void)
 	set_cpu_online(cpu, true);
 	per_cpu(cpu_state, cpu) = CPU_ONLINE;
 
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 extern struct {
#102 lore raw

PATCH 30/34 tile: Enter idle with preemption disabled

In reply to Thomas Gleixner

cpu_idle() needs to be called with preemption disabled.

---
 arch/tile/kernel/smpboot.c |    2 --
 1 file changed, 2 deletions(-)
arch/tile/kernel/smpboot.c +0 -2
Index: linux-2.6/arch/tile/kernel/smpboot.c
===================================================================
@@ -207,8 +207,6 @@ void __cpuinit online_secondary(void)
 	/* Set up tile-timer clock-event device on this cpu */
 	setup_tile_timer();
 
-	preempt_enable();
-
 	cpu_idle();
 }
 
#103 lore raw

Re: [patch 30/34] tile: Enter idle with preemption disabled

Quoted 7 lines · Thomas Gleixner

cpu_idle() needs to be called with preemption disabled.

---
 arch/tile/kernel/smpboot.c |    2 --
 1 file changed, 2 deletions(-)

Thanks. I had fixed this in our internal tree, but hadn't pushed it up yet. I'll take your version into the public tile tree.

Signature · 2 lines
Chris Metcalf, Tilera Corp.
http://www.tilera.com
Acked-by on v1 30/34
#104 lore raw

Re: [patch 30/34] tile: Enter idle with preemption disabled

In reply to Thomas Gleixner
Quoted 7 lines · Thomas Gleixner

cpu_idle() needs to be called with preemption disabled.

---
 arch/tile/kernel/smpboot.c |    2 --
 1 file changed, 2 deletions(-)

Or, given this is part of a series you're presumably intending to push yourself, it probably makes more sense just to add my

to both this patch and patch 31/34.

Signature · 2 lines
Chris Metcalf, Tilera Corp.
http://www.tilera.com
#105 lore raw

Re: [patch 30/34] tile: Enter idle with preemption disabled

In reply to Thomas Gleixner
Quoted 13 lines · Thomas Gleixner

cpu_idle() needs to be called with preemption disabled.

---
 arch/tile/kernel/smpboot.c |    2 --
 1 file changed, 2 deletions(-)

Index: linux-2.6/arch/tile/kernel/smpboot.c
===================================================================

arch/tile/kernel/smpboot.c void __cpuinit online_secondary(void) · line 211

Quoted 5 lines
arch/tile/kernel/smpboot.c +0 -2
@@ -207,8 +207,6 @@ void __cpuinit online_secondary(void)
 	/* Set up tile-timer clock-event device on this cpu */
 	setup_tile_timer();
 
-	preempt_enable();
-

Hmm, so shouldn't we call preempt_disabled() here?

I see that start_secondary() calls preempt_disabled(), but I didn't quite understand as to which of the *_secondary() functions have to call it... especially since its the online_secondary() function which calls cpu_idle().

arch/tile/kernel/smpboot.c void __cpuinit online_secondary(void) · line 212

Quoted 5 lines
arch/tile/kernel/smpboot.c +0 -0
 	cpu_idle();
 }
 

Regards,
Srivatsa S. Bhat

#106 lore raw

[tip:smp/hotplug] tile: Enter idle with preemption disabled

In reply to Thomas Gleixner
tile: Enter idle with preemption disabled
Commit-ID:  e26ef8fe722d5c1c0c1a0212542da8fc2b21a89f
Gitweb:     http://git.kernel.org/tip/e26ef8fe722d5c1c0c1a0212542da8fc2b21a89f
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:50:00 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:28 +0200

tile: Enter idle with preemption disabled

cpu_idle() needs to be called with preemption disabled.

---
 arch/tile/kernel/smpboot.c | 2 --
 1 file changed, 2 deletions(-)
arch/tile/kernel/smpboot.c +0 -2
index e686c5a..11c0190 100644
@@ -207,8 +207,6 @@ void __cpuinit online_secondary(void)
 	/* Set up tile-timer clock-event device on this cpu */
 	setup_tile_timer();
 
-	preempt_enable();
-
 	cpu_idle();
 }
 
#107 lore raw

PATCH 31/34 tile: Use generic idle loop

In reply to Thomas Gleixner
---
 arch/tile/kernel/process.c |   61 ++++-----------------------------------------
 arch/tile/kernel/smpboot.c |    2 -
 2 files changed, 7 insertions(+), 56 deletions(-)
arch/tile/kernel/process.c +6 -55
Index: linux-2.6/arch/tile/kernel/process.c
===================================================================
@@ -40,13 +40,11 @@
 #include <arch/abi.h>
 #include <arch/sim_def.h>
 
-
 /*
  * Use the (x86) "idle=poll" option to prefer low latency when leaving the
  * idle loop over low power while in the idle loop, e.g. if we have
  * one thread per core and we want to get threads out of futex waits fast.
  */
-static int no_idle_nap;
 static int __init idle_setup(char *str)
 {
 	if (!str)
@@ -54,64 +52,17 @@ static int __init idle_setup(char *str)
 
 	if (!strcmp(str, "poll")) {
 		pr_info("using polling idle threads.\n");
-		no_idle_nap = 1;
+		cpu_idle_poll_ctrl(true);
 	} else if (!strcmp(str, "halt"))
-		no_idle_nap = 0;
-	else
-		return -1;
-
-	return 0;
+		return 0;
+	return -1;
 }
 early_param("idle", idle_setup);
 
-/*
- * The idle thread. There's no useful work to be
- * done, so just try to conserve power and have a
- * low exit latency (ie sit in a loop waiting for
- * somebody to say that they'd like to reschedule)
- */
-void cpu_idle(void)
+void arch_cpu_idle(void)
 {
-	int cpu = smp_processor_id();
-
-
-	current_thread_info()->status |= TS_POLLING;
-
-	if (no_idle_nap) {
-		while (1) {
-			while (!need_resched())
-				cpu_relax();
-			schedule();
-		}
-	}
-
-	/* endless idle loop with no priority at all */
-	while (1) {
-		tick_nohz_idle_enter();
-		rcu_idle_enter();
-		while (!need_resched()) {
-			if (cpu_is_offline(cpu))
-				BUG();  /* no HOTPLUG_CPU */
-
-			local_irq_disable();
-			__get_cpu_var(irq_stat).idle_timestamp = jiffies;
-			current_thread_info()->status &= ~TS_POLLING;
-			/*
-			 * TS_POLLING-cleared state must be visible before we
-			 * test NEED_RESCHED:
-			 */
-			smp_mb();
-
-			if (!need_resched())
-				_cpu_idle();
-			else
-				local_irq_enable();
-			current_thread_info()->status |= TS_POLLING;
-		}
-		rcu_idle_exit();
-		tick_nohz_idle_exit();
-		schedule_preempt_disabled();
-	}
+	__get_cpu_var(irq_stat).idle_timestamp = jiffies;
+	_cpu_idle();
 }
 
 /*
arch/tile/kernel/smpboot.c +1 -1
Index: linux-2.6/arch/tile/kernel/smpboot.c
===================================================================
@@ -207,7 +207,7 @@ void __cpuinit online_secondary(void)
 	/* Set up tile-timer clock-event device on this cpu */
 	setup_tile_timer();
 
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
#108 lore raw

Re: [patch 31/34] tile: Use generic idle loop

Quoted 32 lines · Thomas Gleixner
---
 arch/tile/kernel/process.c |   61 ++++-----------------------------------------
 arch/tile/kernel/smpboot.c |    2 -
 2 files changed, 7 insertions(+), 56 deletions(-)

Index: linux-2.6/arch/tile/kernel/process.c
===================================================================

arch/tile/kernel/process.c +1 -3
@@ -40,13 +40,11 @@
 #include <arch/abi.h>
 #include <arch/sim_def.h>
 
-
 /*
  * Use the (x86) "idle=poll" option to prefer low latency when leaving the
  * idle loop over low power while in the idle loop, e.g. if we have
  * one thread per core and we want to get threads out of futex waits fast.
  */
-static int no_idle_nap;
 static int __init idle_setup(char *str)
 {
 	if (!str)
@@ -54,64 +52,17 @@ static int __init idle_setup(char *str)
 
 	if (!strcmp(str, "poll")) {
 		pr_info("using polling idle threads.\n");
-		no_idle_nap = 1;
+		cpu_idle_poll_ctrl(true);
 	} else if (!strcmp(str, "halt"))

arch/tile/kernel/process.c static int __init idle_setup(char *str) · line 61

Quoted 10 lines
arch/tile/kernel/process.c +2 -5
-		no_idle_nap = 0;
-	else
-		return -1;
-
-	return 0;
+		return 0;
+	return -1;
 }
 early_param("idle", idle_setup);
 

That doesn't look quite right, since it returns -1 (instead of 0) when str == poll.

Regards,
Srivatsa S. Bhat

#109 lore raw

Re: [patch 31/34] tile: Use generic idle loop

Quoted 3 lines · Srivatsa S. Bhat

That doesn't look quite right, since it returns -1 (instead of 0) when str == poll.

Stupid me.

#110 lore raw

[tip:smp/hotplug] tile: Use generic idle loop

In reply to Thomas Gleixner
tile: Use generic idle loop
Commit-ID:  0dc8153cfebac68c9523b8852b14f10b31209f08
Gitweb:     http://git.kernel.org/tip/0dc8153cfebac68c9523b8852b14f10b31209f08
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:50:01 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:28 +0200

tile: Use generic idle loop

---
 arch/tile/Kconfig          |  1 +
 arch/tile/kernel/process.c | 65 +++++++---------------------------------------
 arch/tile/kernel/smpboot.c |  2 +-
 3 files changed, 11 insertions(+), 57 deletions(-)
arch/tile/Kconfig +1 -0
index 25877ae..85b2ede 100644
@@ -22,6 +22,7 @@ config TILE
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select GENERIC_CLOCKEVENTS
 	select MODULES_USE_ELF_RELA
+	select GENERIC_IDLE_LOOP
 
 # FIXME: investigate whether we need/want these options.
 #	select HAVE_IOREMAP_PROT
arch/tile/kernel/process.c +9 -56

86 lines not on this page · raw message

arch/tile/kernel/smpboot.c +1 -1
index 11c0190..44bab29 100644
@@ -207,7 +207,7 @@ void __cpuinit online_secondary(void)
 	/* Set up tile-timer clock-event device on this cpu */
 	setup_tile_timer();
 
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
#111 lore raw

PATCH 32/34 unicore: Use generic idle loop

In reply to Thomas Gleixner
---
 arch/unicore32/Kconfig          |    1 +
 arch/unicore32/kernel/process.c |   21 +++------------------
 2 files changed, 4 insertions(+), 18 deletions(-)
arch/unicore32/Kconfig +1 -0
Index: linux-2.6/arch/unicore32/Kconfig
===================================================================
@@ -17,6 +17,7 @@ config UNICORE32
 	select ARCH_WANT_FRAME_POINTERS
 	select GENERIC_IOMAP
 	select MODULES_USE_ELF_REL
+	select GENERIC_IDLE_LOOP
 	help
 	  UniCore-32 is 32-bit Instruction Set Architecture,
 	  including a series of low-power-consumption RISC chip
arch/unicore32/kernel/process.c +3 -18
Index: linux-2.6/arch/unicore32/kernel/process.c
===================================================================
@@ -45,25 +45,10 @@ static const char * const processor_mode
 	"UK18", "UK19", "UK1A", "EXTN", "UK1C", "UK1D", "UK1E", "SUSR"
 };
 
-void cpu_idle(void)
+void arch_cpu_idle(void)
 {
-	/* endless idle loop with no priority at all */
-	while (1) {
-		tick_nohz_idle_enter();
-		rcu_idle_enter();
-		while (!need_resched()) {
-			local_irq_disable();
-			stop_critical_timings();
-			cpu_do_idle();
-			local_irq_enable();
-			start_critical_timings();
-		}
-		rcu_idle_exit();
-		tick_nohz_idle_exit();
-		preempt_enable_no_resched();
-		schedule();
-		preempt_disable();
-	}
+	cpu_do_idle();
+	local_irq_enable();
 }
 
 static char reboot_mode = 'h';
#112 lore raw

[tip:smp/hotplug] unicore: Use generic idle loop

unicore: Use generic idle loop
Commit-ID:  aba92c9e2cf3042bf6efc68fa2e4235ba01bf499
Gitweb:     http://git.kernel.org/tip/aba92c9e2cf3042bf6efc68fa2e4235ba01bf499
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:50:02 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:29 +0200

unicore: Use generic idle loop

---
 arch/unicore32/Kconfig          |  1 +
 arch/unicore32/kernel/process.c | 21 +++------------------
 2 files changed, 4 insertions(+), 18 deletions(-)
arch/unicore32/Kconfig +1 -0
index 2943e3a..e12678d 100644
@@ -17,6 +17,7 @@ config UNICORE32
 	select ARCH_WANT_FRAME_POINTERS
 	select GENERIC_IOMAP
 	select MODULES_USE_ELF_REL
+	select GENERIC_IDLE_LOOP
 	help
 	  UniCore-32 is 32-bit Instruction Set Architecture,
 	  including a series of low-power-consumption RISC chip
arch/unicore32/kernel/process.c +3 -18
index 872d7e2..7fab86d 100644
@@ -45,25 +45,10 @@ static const char * const processor_modes[] = {
 	"UK18", "UK19", "UK1A", "EXTN", "UK1C", "UK1D", "UK1E", "SUSR"
 };
 
-void cpu_idle(void)
+void arch_cpu_idle(void)
 {
-	/* endless idle loop with no priority at all */
-	while (1) {
-		tick_nohz_idle_enter();
-		rcu_idle_enter();
-		while (!need_resched()) {
-			local_irq_disable();
-			stop_critical_timings();
-			cpu_do_idle();
-			local_irq_enable();
-			start_critical_timings();
-		}
-		rcu_idle_exit();
-		tick_nohz_idle_exit();
-		preempt_enable_no_resched();
-		schedule();
-		preempt_disable();
-	}
+	cpu_do_idle();
+	local_irq_enable();
 }
 
 static char reboot_mode = 'h';
#113 lore raw

PATCH 33/34 x86: Use generic idle loop

In reply to Thomas Gleixner
---
 arch/x86/Kconfig          |    1 
 arch/x86/kernel/process.c |  106 ++++++++++++----------------------------------
 arch/x86/kernel/smpboot.c |    2 
 arch/x86/xen/smp.c        |    2 
 4 files changed, 32 insertions(+), 79 deletions(-)
arch/x86/Kconfig +1 -0
Index: linux-2.6/arch/x86/Kconfig
===================================================================
@@ -97,6 +97,7 @@ config X86
 	select GENERIC_IOMAP
 	select DCACHE_WORD_ACCESS
 	select GENERIC_SMP_IDLE_THREAD
+	select GENERIC_IDLE_LOOP
 	select ARCH_WANT_IPC_PARSE_VERSION if X86_32
 	select HAVE_ARCH_SECCOMP_FILTER
 	select BUILDTIME_EXTABLE_SORT
arch/x86/kernel/process.c +29 -77

154 lines not on this page · raw message

arch/x86/kernel/smpboot.c +1 -1
Index: linux-2.6/arch/x86/kernel/smpboot.c
===================================================================
@@ -284,7 +284,7 @@ notrace static void __cpuinit start_seco
 	x86_cpuinit.setup_percpu_clockev();
 
 	wmb();
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 void __init smp_store_boot_cpu_info(void)
arch/x86/xen/smp.c +1 -1
Index: linux-2.6/arch/x86/xen/smp.c
===================================================================
@@ -95,7 +95,7 @@ static void __cpuinit cpu_bringup(void)
 static void __cpuinit cpu_bringup_and_idle(void)
 {
 	cpu_bringup();
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 static int xen_smp_intr_init(unsigned int cpu)
#114 lore raw

Re: [patch 33/34] x86: Use generic idle loop

Quoted 3 lines · Thomas Gleixner

---

[...]

Quoted 2 lines
arch/x86/kernel/process.c +2 -0
+#define POLL_IDLE	(void*) 0x01
+

[...]

Quoted 32 lines

#ifdef CONFIG_APM_MODULE

arch/x86/kernel/process.c +1 -15
@@ -411,20 +376,6 @@ void stop_this_cpu(void *dummy)
 		halt();
 }
 
-/*
- * On SMP it's slightly faster (but much more power-consuming!)
- * to poll the ->work.need_resched flag instead of waiting for the
- * cross-CPU IPI to arrive. Use this option with caution.
- */
-static void poll_idle(void)
-{
-	trace_cpu_idle_rcuidle(0, smp_processor_id());
-	local_irq_enable();
-	while (!need_resched())
-		cpu_relax();
-	trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id());
-}
-
 bool amd_e400_c1e_detected;
 EXPORT_SYMBOL(amd_e400_c1e_detected);
 
@@ -489,7 +440,7 @@ static void amd_e400_idle(void)
 void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
 {
 #ifdef CONFIG_SMP
-	if (x86_idle == poll_idle && smp_num_siblings > 1)
+	if (x86_idle == POLL_IDLE && smp_num_siblings > 1)
 		pr_warn_once("WARNING: polling idle and HT enabled, performance may degrade\n");
 #endif
 	if (x86_idle)

arch/x86/kernel/process.c static int __init idle_setup(char *str) · line 473

Quoted 7 lines
arch/x86/kernel/process.c +2 -1
@@ -517,8 +468,9 @@ static int __init idle_setup(char *str)
 
 	if (!strcmp(str, "poll")) {
 		pr_info("using polling idle threads\n");
-		x86_idle = poll_idle;
+		x86_idle = POLL_IDLE;
 		boot_option_idle_override = IDLE_POLL;
+		cpu_idle_poll_ctrl(true);

Why is that POLL_IDLE needed? Won't cpu_idle_poll_ctrl() suffice?

By the way, booting with idle=poll locks up the kernel during boot with this patch applied (I verified it). So I think we should just skip the whole POLL_IDLE thing and leave the job to cpu_idle_poll_ctrl().

Regards,
Srivatsa S. Bhat

#115 lore raw

[tip:smp/hotplug] x86: Use generic idle loop

In reply to Thomas Gleixner
x86: Use generic idle loop
Commit-ID:  7d1a941731fabf27e5fb6edbebb79fe856edb4e5
Gitweb:     http://git.kernel.org/tip/7d1a941731fabf27e5fb6edbebb79fe856edb4e5
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:50:03 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:29 +0200

x86: Use generic idle loop

---
 arch/x86/Kconfig          |   1 +
 arch/x86/kernel/process.c | 105 ++++++++++++----------------------------------
 arch/x86/kernel/smpboot.c |   2 +-
 arch/x86/xen/smp.c        |   2 +-
 4 files changed, 30 insertions(+), 80 deletions(-)
arch/x86/Kconfig +1 -0
index 70c0f3d..422a72b 100644
@@ -97,6 +97,7 @@ config X86
 	select GENERIC_IOMAP
 	select DCACHE_WORD_ACCESS
 	select GENERIC_SMP_IDLE_THREAD
+	select GENERIC_IDLE_LOOP
 	select ARCH_WANT_IPC_PARSE_VERSION if X86_32
 	select HAVE_ARCH_SECCOMP_FILTER
 	select BUILDTIME_EXTABLE_SORT
arch/x86/kernel/process.c +27 -78

149 lines not on this page · raw message

arch/x86/kernel/smpboot.c +1 -1
index 9f190a2..9c73b51 100644
@@ -284,7 +284,7 @@ notrace static void __cpuinit start_secondary(void *unused)
 	x86_cpuinit.setup_percpu_clockev();
 
 	wmb();
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 void __init smp_store_boot_cpu_info(void)
arch/x86/xen/smp.c +1 -1
index 09ea61d..73642e9 100644
@@ -95,7 +95,7 @@ static void __cpuinit cpu_bringup(void)
 static void __cpuinit cpu_bringup_and_idle(void)
 {
 	cpu_bringup();
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 static int xen_smp_intr_init(unsigned int cpu)
#116 lore raw

PATCH 34/34 xtensa: Use generic idle loop

In reply to Thomas Gleixner

Unfortunately this arch does not compile at all :(

---
 arch/xtensa/Kconfig          |    1 +
 arch/xtensa/kernel/process.c |   14 ++------------
 2 files changed, 3 insertions(+), 12 deletions(-)
arch/xtensa/Kconfig +1 -0
Index: linux-2.6/arch/xtensa/Kconfig
===================================================================
@@ -19,6 +19,7 @@ config XTENSA
 	select CLONE_BACKWARDS
 	select IRQ_DOMAIN
 	select HAVE_OPROFILE
+	select GENERIC_IDLE_LOOP
 	help
 	  Xtensa processors are 32-bit RISC machines designed by Tensilica
 	  primarily for embedded systems.  These processors are both
arch/xtensa/kernel/process.c +2 -12
Index: linux-2.6/arch/xtensa/kernel/process.c
===================================================================
@@ -105,19 +105,9 @@ void coprocessor_flush_all(struct thread
 /*
  * Powermanagement idle function, if any is provided by the platform.
  */
-
-void cpu_idle(void)
+void arch_cpu_idle(void)
 {
-	local_irq_enable();
-
-	/* endless idle loop with no priority at all */
-	while (1) {
-		rcu_idle_enter();
-		while (!need_resched())
-			platform_idle();
-		rcu_idle_exit();
-		schedule_preempt_disabled();
-	}
+	platform_idle();
 }
 
 /*
maintainer
#117 lore raw

Re: [patch 34/34] xtensa: Use generic idle loop

Quoted 1 line · Thomas Gleixner

Unfortunately this arch does not compile at all :(

Hi Thomas,

according to KISSKB http://kisskb.ellerman.id.au/kisskb/compiler/19/
it does, you probably don't need to build allmodconfig.

With this patch I see WARN coming from the kernel/cpu/idle.c:94, xtensa __platform_idle returns with interrupts enabled. Interestingly, even the default arch_cpu_idle does so.

Signature · 2 lines
Thanks.
-- Max
#118 lore raw

[tip:smp/hotplug] xtensa: Use generic idle loop

In reply to Thomas Gleixner
xtensa: Use generic idle loop
Commit-ID:  f4e2e9a4b26789d963000f974f2dc80230bb4674
Gitweb:     http://git.kernel.org/tip/f4e2e9a4b26789d963000f974f2dc80230bb4674
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Thu, 21 Mar 2013 22:50:04 +0100
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 8 Apr 2013 17:39:29 +0200

xtensa: Use generic idle loop

---
 arch/xtensa/Kconfig          |  1 +
 arch/xtensa/kernel/process.c | 14 ++------------
 2 files changed, 3 insertions(+), 12 deletions(-)
arch/xtensa/Kconfig +1 -0
index b09de49..e0144ff 100644
@@ -19,6 +19,7 @@ config XTENSA
 	select CLONE_BACKWARDS
 	select IRQ_DOMAIN
 	select HAVE_OPROFILE
+	select GENERIC_IDLE_LOOP
 	help
 	  Xtensa processors are 32-bit RISC machines designed by Tensilica
 	  primarily for embedded systems.  These processors are both
arch/xtensa/kernel/process.c +2 -12
index 5cd82e9..1c85323 100644
@@ -105,19 +105,9 @@ void coprocessor_flush_all(struct thread_info *ti)
 /*
  * Powermanagement idle function, if any is provided by the platform.
  */
-
-void cpu_idle(void)
+void arch_cpu_idle(void)
 {
-	local_irq_enable();
-
-	/* endless idle loop with no priority at all */
-	while (1) {
-		rcu_idle_enter();
-		while (!need_resched())
-			platform_idle();
-		rcu_idle_exit();
-		schedule_preempt_disabled();
-	}
+	platform_idle();
 }
 
 /*
#119 lore raw
In reply to Thomas Gleixner

Hi Thomas.

Quoted 10 lines · Thomas Gleixner

Each architecture implements its own cpu_idle() code, which is more or less the same on all architectures (plus/minus a few bugs and a few missing extra functionalities, instrumentation ...). That also forces everyone who is interested in idle related features to add new functionality to every architecture. What a waste.

Aside of that pointless code duplicaiton the ongoing quest to consolidate the cpu hotplug code needs a common entry point for the non boot cpus.

Quoted 5 lines

The following series implements a generic idle function and converts most architectures over. I left out SPARC (it involves sparc asm) and UM (it made me barf). If we can move those architectures as well, we can get rid of the extra config switch and have everything consolidated.

I wanted to take a quick look at sparc - but build failed after applying patch 1-5. Looks like the same issue Tony already reaported.

At very first glnce it looks straightforward to convert
both sparc32 and sparc64.
The assembler stuff used by sparc64 fits into one of the arch functions as far as I could see.

When I get back from vacation I may take a look.

Sam

A message that is not in the archive (sent off-list or not yet received): alpine.LFD.2.02.1303271940150.22263@ionos

A message that is not in the archive (sent off-list or not yet received): [email protected]

#122 lore raw
Quoted 4 lines · Chris Zankel

For Xtensa:

Thanks for going the extra mile and test-compiling it.

Though, the build fails later with:

arch/xtensa/kernel/built-in.o:(.init.literal+0x90): undefined reference to platform_pcibios_init' arch/xtensa/kernel/built-in.o: In function setup_arch':
(.init.text+0x1de): undefined reference to `platform_pcibios_init'
drivers/built-in.o: In function `pci_assign_unassigned_resources':
(.init.text+0x52b): dangerous relocation: call8: call target out of range: (.ref.text+0x3ac) drivers/built-in.o: In function `pci_assign_unassigned_resources':
(.init.text+0x5b5): dangerous relocation: call8: call target out of range: (.ref.text+0x2c8) drivers/built-in.o: In function `sysrq_init':
sysrq.c:(.init.text+0xb61): dangerous relocation: call8: call target out of range: panic drivers/built-in.o: In function `console_map_init':
(.init.text+0xc97): dangerous relocation: call8: call target out of range: printk drivers/built-in.o: In function `vtconsole_class_init':
vt.c:(.init.text+0xcdd): dangerous relocation: call8: call target out of range: printk drivers/built-in.o: In function `con_init':
vt.c:(.init.text+0xe75): dangerous relocation: call8: call target out of range: printk vt.c:(.init.text+0xece): dangerous relocation: call8: call target out of range: panic drivers/built-in.o: In function `vty_init':
(.init.text+0xf32): dangerous relocation: call8: call target out of range: panic drivers/built-in.o: In function `vty_init':
(.init.text+0xf8e): dangerous relocation: call8: call target out of range: panic drivers/built-in.o: In function `serial8250_isa_init_ports':
8250.c:(.init.text+0x10ea): dangerous relocation: call8: call target out of range: printk drivers/built-in.o: In function `setup_early_serial8250_console':
(.init.text+0x1450): dangerous relocation: call8: call target out of range: printk drivers/built-in.o: In function `setup_early_serial8250_console':
(.init.text+0x1456): dangerous relocation: call8: call target out of range: panic drivers/built-in.o: In function `setup_early_serial8250_console':
(.init.text+0x1461): dangerous relocation: call8: call target out of range: printk drivers/built-in.o: In function `setup_early_serial8250_console':
(.init.text+0x155d): dangerous relocation: call8: call target out of range: printk drivers/built-in.o: In function `setup_early_serial8250_console':
(.init.text+0x156e): dangerous relocation: call8: call target out of range: printk drivers/built-in.o: In function `setup_early_serial8250_console':
(.init.text+0x1625): dangerous relocation: call8: call target out of range: printk drivers/built-in.o: In function `chr_dev_init':
mem.c:(.init.text+0x16e6): dangerous relocation: call8: call target out of range: printk drivers/built-in.o: In function `random_int_secret_init':
random.c:(.init.text+0x171a): dangerous relocation: call8: call target out of range: printk drivers/built-in.o: In function `misc_init':
misc.c:(.init.text+0x1765): dangerous relocation: call8: call target out of range: printk misc.c:(.init.text+0x1789): dangerous relocation: call8: call target out of range: printk net/built-in.o: In function `synchronize_net':
(.text+0xc650): dangerous relocation: call8: misaligned call target: (.text.unlikely+0x43) net/built-in.o: In function `alloc_netdev_mqs':
(.text+0xc7ed): dangerous relocation: call8: misaligned call target: (.text.unlikely+0x43) net/built-in.o: In function `netlink_proto_init':
af_netlink.c:(.init.text+0x7a9): dangerous relocation: call8: call target out of range: (.text.unlikely+0xa4) make[1]: *** [vmlinux] Error 1

maintainer
#123 lore raw

Hi Thomas,

Quoted 5 lines · Thomas Gleixner
Quoted 3 lines · Chris Zankel

For Xtensa:

Quoted 7 lines
Quoted 1 line

Thanks for going the extra mile and test-compiling it.

Though, the build fails later with:

arch/xtensa/kernel/built-in.o:(.init.literal+0x90): undefined reference to platform_pcibios_init' arch/xtensa/kernel/built-in.o: In function setup_arch':
(.init.text+0x1de): undefined reference to platform_pcibios_init' drivers/built-in.o: In function pci_assign_unassigned_resources':

[...]

Thanks for the info. With KALLSYMS enabled, the .rodata section between the .text and the .init.text section is extended to a point where it exceeds the call range between those sections. I'm working on a fix (basically, move the .init.text section close to the .init section).

Thanks,
-Chris

#124 lore raw
In reply to Thomas Gleixner
Quoted 16 lines · Thomas Gleixner

Each architecture implements its own cpu_idle() code, which is more or less the same on all architectures (plus/minus a few bugs and a few missing extra functionalities, instrumentation ...). That also forces everyone who is interested in idle related features to add new functionality to every architecture. What a waste.

Aside of that pointless code duplicaiton the ongoing quest to consolidate the cpu hotplug code needs a common entry point for the non boot cpus.

The following series implements a generic idle function and converts most architectures over. I left out SPARC (it involves sparc asm) and UM (it made me barf). If we can move those architectures as well, we can get rid of the extra config switch and have everything consolidated.

Quoted 4 lines

I spent a lot of time to make sure that the conversion preserved the non obvious differences of the architecture implementations, but I really need help from the affected maintainers to prove the correctness.

Hi Thomas.

Where can I find the git tree with the latest patches? Or do you plan to submit a v2 soon?

Sam

#125 lore raw

PATCH 1/1 sparc: Use generic idle loop

Add generic cpu_idle support

sparc32:
- replace call to cpu_idle() with cpu_startup_entry()
- add arch_cpu_idle()

sparc64:
- smp_callin() includes cpu_startup_entry() call so we can skip calling cpu_idle from assembler
- add arch_cpu_idle_enter() and arch_cpu_idle_dead()

Cc David S. Miller <[email protected]>

---
This patch is on top of smp/testing in the tip tree. It is build tested on sparc32 + sparc64

Sam

arch/sparc/Kconfig +1 -0
index 3d361f2..5f22169 100644
@@ -39,6 +39,7 @@ config SPARC
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_STRNCPY_FROM_USER
 	select GENERIC_STRNLEN_USER
+	select GENERIC_IDLE_LOOP
 	select MODULES_USE_ELF_RELA
 	select ODD_RT_SIGACTION
 	select OLD_SIGSUSPEND
arch/sparc/kernel/hvtramp.S +1 -2
index 9365432..605c960 100644
@@ -128,8 +128,7 @@ hv_cpu_startup:
 
 	call		smp_callin
 	 nop
-	call		cpu_idle
-	 mov		0, %o0
+
 	call		cpu_panic
 	 nop
 
arch/sparc/kernel/process_32.c +6 -16
index 62eede1..ec92959 100644
@@ -64,23 +64,13 @@ extern void fpsave(unsigned long *, unsigned long *, void *, unsigned long *);
 struct task_struct *last_task_used_math = NULL;
 struct thread_info *current_set[NR_CPUS];
 
-/*
- * the idle loop on a Sparc... ;)
- */
-void cpu_idle(void)
+/* the idle loop on a Sparc... ;) */
+void arch_cpu_idle(void)
 {
-	set_thread_flag(TIF_POLLING_NRFLAG);
-
-	/* endless idle loop with no priority at all */
-	for (;;) {
-		while (!need_resched()) {
-			if (sparc_idle)
-				(*sparc_idle)();
-			else
-				cpu_relax();
-		}
-		schedule_preempt_disabled();
-	}
+	if (sparc_idle)
+		(*sparc_idle)();
+	else
+		cpu_relax();
 }
 
 /* XXX cli/sti -> local_irq_xxx here, check this works once SMP is fixed. */
arch/sparc/kernel/process_64.c +9 -25
index cdb80b2..5ed6b02 100644
@@ -52,8 +52,13 @@
 
 #include "kstack.h"
 
-static void sparc64_yield(int cpu)
+/* The idle loop on sparc64. */
+void arch_cpu_idle_enter()
 {
+	int cpu;
+
+	cpu = smp_processor_id();
+
 	if (tlb_type != hypervisor) {
 		touch_nmi_watchdog();
 		return;
@@ -88,31 +93,10 @@ static void sparc64_yield(int cpu)
 	set_thread_flag(TIF_POLLING_NRFLAG);
 }
 
-/* The idle loop on sparc64. */
-void cpu_idle(void)
+void arch_cpu_idle_dead()
 {
-	int cpu = smp_processor_id();
-
-	set_thread_flag(TIF_POLLING_NRFLAG);
-
-	while(1) {
-		tick_nohz_idle_enter();
-		rcu_idle_enter();
-
-		while (!need_resched() && !cpu_is_offline(cpu))
-			sparc64_yield(cpu);
-
-		rcu_idle_exit();
-		tick_nohz_idle_exit();
-
-#ifdef CONFIG_HOTPLUG_CPU
-		if (cpu_is_offline(cpu)) {
-			sched_preempt_enable_no_resched();
-			cpu_play_dead();
-		}
-#endif
-		schedule_preempt_disabled();
-	}
+	sched_preempt_enable_no_resched();
+	cpu_play_dead();
 }
 
 #ifdef CONFIG_COMPAT
arch/sparc/kernel/smp_32.c +1 -1
index 9e7e6d7..e3f2b81 100644
@@ -369,7 +369,7 @@ void __cpuinit sparc_start_secondary(void *arg)
 	local_irq_enable();
 
 	wmb();
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 
 	/* We should never reach here! */
 	BUG();
arch/sparc/kernel/smp_64.c +2 -0
index 537eb66..c025ffc 100644
@@ -127,6 +127,8 @@ void __cpuinit smp_callin(void)
 
 	/* idle thread is expected to have preempt disabled */
 	preempt_disable();
+
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 void cpu_panic(void)
arch/sparc/kernel/trampoline_64.S +1 -2
index da1b781..2e973a2 100644
@@ -407,8 +407,7 @@ after_lock_tlb:
 
 	call		smp_callin
 	 nop
-	call		cpu_idle
-	 mov		0, %o0
+
 	call		cpu_panic
 	 nop
 1:	b,a,pt		%xcc, 1b
maintainer Acked-by on v1 1/1
#126 lore raw

Re: [PATCH] sparc: Use generic idle loop

From: Sam Ravnborg <[email protected]>
Date: Fri, 29 Mar 2013 21:29:26 +0100

Quoted 6 lines

Add generic cpu_idle support

sparc32:
- replace call to cpu_idle() with cpu_startup_entry()
- add arch_cpu_idle()

Quoted 6 lines

sparc64:
- smp_callin() includes cpu_startup_entry() call so we can skip calling cpu_idle from assembler
- add arch_cpu_idle_enter() and arch_cpu_idle_dead()

#127 lore raw

Re: [PATCH] sparc: Use generic idle loop

In reply to Sam Ravnborg
Quoted 20 lines · Sam Ravnborg

Add generic cpu_idle support

sparc32:
- replace call to cpu_idle() with cpu_startup_entry()
- add arch_cpu_idle()

sparc64:
- smp_callin() includes cpu_startup_entry() call so we can skip calling cpu_idle from assembler
- add arch_cpu_idle_enter() and arch_cpu_idle_dead()

Cc David S. Miller <[email protected]>

---
This patch is on top of smp/testing in the tip tree. It is build tested on sparc32 + sparc64

Sam

[...]

Quoted 23 lines
arch/sparc/kernel/process_32.c +2 -11
index 62eede1..ec92959 100644
@@ -64,23 +64,13 @@ extern void fpsave(unsigned long *, unsigned long *, void *, unsigned long *);
 struct task_struct *last_task_used_math = NULL;
 struct thread_info *current_set[NR_CPUS];
 
-/*
- * the idle loop on a Sparc... ;)
- */
-void cpu_idle(void)
+/* the idle loop on a Sparc... ;) */
+void arch_cpu_idle(void)
 {
-	set_thread_flag(TIF_POLLING_NRFLAG);
-
-	/* endless idle loop with no priority at all */
-	for (;;) {
-		while (!need_resched()) {
-			if (sparc_idle)
-				(*sparc_idle)();

arch/sparc/kernel/process_32.c extern void fpsave(unsigned long *, unsigned long *, void *, unsigned long *); · line 74

Quoted 10 lines
arch/sparc/kernel/process_32.c +4 -5
-			else
-				cpu_relax();
-		}
-		schedule_preempt_disabled();
-	}
+	if (sparc_idle)
+		(*sparc_idle)();
+	else
+		cpu_relax();
 }

You need to enable interrupts when coming out in the 'else' case, because we enter with interrupts disabled and expect to come out of arch_cpu_idle() with interrupts enabled. (Otherwise you'll hit that WARN_ON() in the generic code). Thomas has handled a similar case in the mips patch.

Quoted 22 lines
arch/sparc/kernel/process_32.c +0 -0
 /* XXX cli/sti -> local_irq_xxx here, check this works once SMP is fixed. */
arch/sparc/kernel/process_64.c +6 -1
index cdb80b2..5ed6b02 100644
@@ -52,8 +52,13 @@
 
 #include "kstack.h"
 
-static void sparc64_yield(int cpu)
+/* The idle loop on sparc64. */
+void arch_cpu_idle_enter()
 {
+	int cpu;
+
+	cpu = smp_processor_id();
+
 	if (tlb_type != hypervisor) {
 		touch_nmi_watchdog();
 		return;

arch/sparc/kernel/process_64.c static void sparc64_yield(int cpu) · line 95

Quoted 3 lines
arch/sparc/kernel/process_64.c +0 -0
@@ -88,31 +93,10 @@ static void sparc64_yield(int cpu)
 	set_thread_flag(TIF_POLLING_NRFLAG);
 }
 

Hmm, this looks weird. The contents of this function should have been inside arch_cpu_idle() (not arch_cpu_idle_enter). And it is unnecessary to set/clear POLLING flags here, since they are handled in the generic code. (Same is the case with the need_resched and the cpu_is_offline check).

I agree that the naming is a little subtle, but in the current scheme of things in this patchset, arch_cpu_idle_enter() is what you call to do initialization _before_ you perform cpu idle, whereas arch_cpu_idle() is the function that is supposed to do the actual arch-specific idling.

Regards,
Srivatsa S. Bhat

Quoted 29 lines
arch/sparc/kernel/process_64.c +3 -24
-/* The idle loop on sparc64. */
-void cpu_idle(void)
+void arch_cpu_idle_dead()
 {
-	int cpu = smp_processor_id();
-
-	set_thread_flag(TIF_POLLING_NRFLAG);
-
-	while(1) {
-		tick_nohz_idle_enter();
-		rcu_idle_enter();
-
-		while (!need_resched() && !cpu_is_offline(cpu))
-			sparc64_yield(cpu);
-
-		rcu_idle_exit();
-		tick_nohz_idle_exit();
-
-#ifdef CONFIG_HOTPLUG_CPU
-		if (cpu_is_offline(cpu)) {
-			sched_preempt_enable_no_resched();
-			cpu_play_dead();
-		}
-#endif
-		schedule_preempt_disabled();
-	}
+	sched_preempt_enable_no_resched();
+	cpu_play_dead();
 }
#128 lore raw

Re: [PATCH] sparc: Use generic idle loop

Hi Srivatsa,

thanks for the feedback!

@davem - I need you to look at this again. I am not sure about the changes I do in sparc64_yield().

Quoted 6 lines
Quoted 6 lines
(quoted diff) +5 -0
+/* the idle loop on a Sparc... ;) */
+void arch_cpu_idle(void)
 {
+	if (sparc_idle)
+		(*sparc_idle)();
+	else
Quoted 8 lines

Review

Quoted 2 lines
(quoted diff) +1 -0
+		cpu_relax();
 }

You need to enable interrupts when coming out in the 'else' case, because we enter with interrupts disabled and expect to come out of arch_cpu_idle() with interrupts enabled. (Otherwise you'll hit that WARN_ON() in the generic code). Thomas has handled a similar case in the mips patch.

Something like this should do it then:

/* Idle loop support */
void arch_cpu_idle(void)

{
        if (sparc_idle)
                (*sparc_idle)();
        else
                local_irq_enable();
}

I dropped cpu_relax() as this is a simple barrier() which is part of the generic code (using rmb()).

Quoted 10 lines
Quoted 10 lines
(quoted diff) +6 -1
-static void sparc64_yield(int cpu)
+/* The idle loop on sparc64. */
+void arch_cpu_idle_enter()
 {
+	int cpu;
+
+	cpu = smp_processor_id();
+
 	if (tlb_type != hypervisor) {
 		touch_nmi_watchdog();
Quoted 8 lines

Review static void sparc64_yield(int cpu) · line 95

Quoted 5 lines
(quoted diff) +0 -0
 		return;
@@ -88,31 +93,10 @@ static void sparc64_yield(int cpu)
 	set_thread_flag(TIF_POLLING_NRFLAG);
 }
 

Hmm, this looks weird. The contents of this function should have been inside arch_cpu_idle() (not arch_cpu_idle_enter).

Yep - I see now.

Quoted 3 lines

And it is
unnecessary to set/clear POLLING flags here, since they are handled in the generic code.

OK

Quoted 2 lines

(Same is the case with the need_resched and
the cpu_is_offline check).

There are some comments about race-conditions in the commit where they were added. I think the out-most pair can be dropped as this is done in generic code but that the inner ones needs to stay.

I simplified arch_cpu_idle() - former sparc64_yield() based on your comments.
- dropped TIF_POLLING_NRFLAG handling
- dropped smp_mb__after_clear_bit() - this is done in generic code using rmb()
- dropped the out-most while (!need_resched() && !cpu_is_offline(cpu))
- always enable irq on exit (but I am not sure if this is correct)

But I need davem to have a look at this - as I am fooling around in code that I do not know much about..
So this is *NOT* to be applied.

Sam

arch/sparc/Kconfig +1 -0
index 3d361f2..ee5eacc 100644
@@ -37,6 +37,7 @@ config SPARC
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_CMOS_UPDATE
 	select GENERIC_CLOCKEVENTS
+	select GENERIC_IDLE_LOOP
 	select GENERIC_STRNCPY_FROM_USER
 	select GENERIC_STRNLEN_USER
 	select MODULES_USE_ELF_RELA
arch/sparc/kernel/hvtramp.S +1 -2
index 9365432..605c960 100644
@@ -128,8 +128,7 @@ hv_cpu_startup:
 
 	call		smp_callin
 	 nop
-	call		cpu_idle
-	 mov		0, %o0
+
 	call		cpu_panic
 	 nop
 
arch/sparc/kernel/process_32.c +6 -16
index 62eede1..890d7c4 100644
@@ -64,23 +64,13 @@ extern void fpsave(unsigned long *, unsigned long *, void *, unsigned long *);
 struct task_struct *last_task_used_math = NULL;
 struct thread_info *current_set[NR_CPUS];
 
-/*
- * the idle loop on a Sparc... ;)
- */
-void cpu_idle(void)
+/* Idle loop support. */
+void arch_cpu_idle(void)
 {
-	set_thread_flag(TIF_POLLING_NRFLAG);
-
-	/* endless idle loop with no priority at all */
-	for (;;) {
-		while (!need_resched()) {
-			if (sparc_idle)
-				(*sparc_idle)();
-			else
-				cpu_relax();
-		}
-		schedule_preempt_disabled();
-	}
+	if (sparc_idle)
+		(*sparc_idle)();
+	else
+		local_irq_enable();
 }
 
 /* XXX cli/sti -> local_irq_xxx here, check this works once SMP is fixed. */
arch/sparc/kernel/process_64.c +10 -35

70 lines not on this page · raw message

arch/sparc/kernel/smp_32.c +1 -1
index 9e7e6d7..e3f2b81 100644
@@ -369,7 +369,7 @@ void __cpuinit sparc_start_secondary(void *arg)
 	local_irq_enable();
 
 	wmb();
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 
 	/* We should never reach here! */
 	BUG();
arch/sparc/kernel/smp_64.c +2 -0
index 537eb66..c025ffc 100644
@@ -127,6 +127,8 @@ void __cpuinit smp_callin(void)
 
 	/* idle thread is expected to have preempt disabled */
 	preempt_disable();
+
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 void cpu_panic(void)
arch/sparc/kernel/trampoline_64.S +1 -2
index da1b781..2e973a2 100644
@@ -407,8 +407,7 @@ after_lock_tlb:
 
 	call		smp_callin
 	 nop
-	call		cpu_idle
-	 mov		0, %o0
+
 	call		cpu_panic
 	 nop
 1:	b,a,pt		%xcc, 1b
Reviewed-by
#129 lore raw

Re: [PATCH] sparc: Use generic idle loop

Hi Sam,

Quoted 33 lines · Sam Ravnborg

Hi Srivatsa,

thanks for the feedback!

@davem - I need you to look at this again. I am not sure about the changes I do in sparc64_yield().

Quoted 6 lines
Quoted 6 lines
arch/sparc/kernel/process_32.c +5 -0
+/* the idle loop on a Sparc... ;) */
+void arch_cpu_idle(void)
 {
+	if (sparc_idle)
+		(*sparc_idle)();
+	else
Quoted 8 lines

Review

Quoted 2 lines
(quoted diff) +1 -0
+		cpu_relax();
 }

You need to enable interrupts when coming out in the 'else' case, because we enter with interrupts disabled and expect to come out of arch_cpu_idle() with interrupts enabled. (Otherwise you'll hit that WARN_ON() in the generic code). Thomas has handled a similar case in the mips patch.

Something like this should do it then:

/* Idle loop support */
void arch_cpu_idle(void)

{
        if (sparc_idle)
                (*sparc_idle)();
        else
                local_irq_enable();
}
Quoted 3 lines

I dropped cpu_relax() as this is a simple barrier() which is part of the generic code (using rmb()).

Yep, that sounds good.

[...]

Quoted 18 lines
Quoted 2 lines

(Same is the case with the need_resched and
the cpu_is_offline check).

There are some comments about race-conditions in the commit where they were added. I think the out-most pair can be dropped as this is done in generic code but that the inner ones needs to stay.

I simplified arch_cpu_idle() - former sparc64_yield() based on your comments.
- dropped TIF_POLLING_NRFLAG handling
- dropped smp_mb__after_clear_bit() - this is done in generic code using rmb()
- dropped the out-most while (!need_resched() && !cpu_is_offline(cpu))
- always enable irq on exit (but I am not sure if this is correct)

But I need davem to have a look at this - as I am fooling around in code that I do not know much about..
So this is *NOT* to be applied.

Sam

[...]

Quoted 36 lines

/* XXX cli/sti -> local_irq_xxx here, check this works once SMP is fixed. */

arch/sparc/kernel/process_64.c +4 -9
index cdb80b2..cecb0d6 100644
@@ -52,17 +52,12 @@
 
 #include "kstack.h"
 
-static void sparc64_yield(int cpu)
+/* Idle loop support on sparc64. */
+void arch_cpu_idle(void)
 {
 	if (tlb_type != hypervisor) {
 		touch_nmi_watchdog();
-		return;
-	}
-
-	clear_thread_flag(TIF_POLLING_NRFLAG);
-	smp_mb__after_clear_bit();
-
-	while (!need_resched() && !cpu_is_offline(cpu)) {
+	} else {
 		unsigned long pstate;
 
 		/* Disable interrupts. */
@@ -73,7 +68,7 @@ static void sparc64_yield(int cpu)
 			: "=&r" (pstate)
 			: "i" (PSTATE_IE));
 
-		if (!need_resched() && !cpu_is_offline(cpu))
+		if (!need_resched() && !cpu_is_offline(smp_processor_id()))
 			sun4v_cpu_yield();
 
 		/* Re-enable interrupts. */

arch/sparc/kernel/process_64.c static void sparc64_yield(int cpu) · line 83

Quoted 7 lines
arch/sparc/kernel/process_64.c +1 -2
@@ -84,36 +79,16 @@ static void sparc64_yield(int cpu)
 			: "=&r" (pstate)
 			: "i" (PSTATE_IE));
 	}
-
-	set_thread_flag(TIF_POLLING_NRFLAG);
+	local_irq_enable();
 }

Nitpick: you can probably move the local_irq_enable() to the 'if' block, since the else block already has assembly code to enable the interrupts. But anyway its up to you.

This version of your code looks fine to me.

Regards,
Srivatsa S. Bhat

#130 lore raw

Re: [PATCH] sparc: Use generic idle loop

Quoted 29 lines
Quoted 29 lines
arch/sparc/kernel/process_64.c +4 -9
@@ -52,17 +52,12 @@
 
 #include "kstack.h"
 
-static void sparc64_yield(int cpu)
+/* Idle loop support on sparc64. */
+void arch_cpu_idle(void)
 {
 	if (tlb_type != hypervisor) {
 		touch_nmi_watchdog();
-		return;
-	}
-
-	clear_thread_flag(TIF_POLLING_NRFLAG);
-	smp_mb__after_clear_bit();
-
-	while (!need_resched() && !cpu_is_offline(cpu)) {
+	} else {
 		unsigned long pstate;
 
 		/* Disable interrupts. */
@@ -73,7 +68,7 @@ static void sparc64_yield(int cpu)
 			: "=&r" (pstate)
 			: "i" (PSTATE_IE));
 
-		if (!need_resched() && !cpu_is_offline(cpu))
+		if (!need_resched() && !cpu_is_offline(smp_processor_id()))
 			sun4v_cpu_yield();
 
Quoted 13 lines

arch/sparc/kernel/process_64.c static void sparc64_yield(int cpu) · line 83

Quoted 9 lines
arch/sparc/kernel/process_64.c +1 -2
 		/* Re-enable interrupts. */
@@ -84,36 +79,16 @@ static void sparc64_yield(int cpu)
 			: "=&r" (pstate)
 			: "i" (PSTATE_IE));
 	}
-
-	set_thread_flag(TIF_POLLING_NRFLAG);
+	local_irq_enable();
 }

Nitpick: you can probably move the local_irq_enable() to the 'if' block, since the else block already has assembly code to enable the interrupts. But anyway its up to you.

I think not.
local_irq_disable writes 0 to the PIL register, whereas the above code set the IE (Interrupt enable) bit to 0.

So the implementations differs - and I think there is a good reason for being so.

But this is the part where I refer to that I am fooling around in code that I do not understand.
I re-checked the SPARC V9 manual - but I did not within a few minutes reading understand what is the difference between the twoo.

Sam

maintainer
#131 lore raw

Re: [PATCH] sparc: Use generic idle loop

From: Sam Ravnborg <[email protected]>
Date: Mon, 8 Apr 2013 19:10:35 +0200

Quoted 11 lines

I think not.
local_irq_disable writes 0 to the PIL register, whereas the above code set the IE (Interrupt enable) bit to 0.

So the implementations differs - and I think there is a good reason for being so.

But this is the part where I refer to that I am fooling around in code that I do not understand.
I re-checked the SPARC V9 manual - but I did not within a few minutes reading understand what is the difference between the twoo.

Device interrupts arrive first as high-priority interrupt packets that are serviced by traps which are enabled only if PSTATE.IE is set.

These trap handlers reschedule the interrupt quickly into a PIL levelled interrupt, whose delivery is covered by (%pil & PSTATE.IE)

The sun4v sleeping code requires that we have PSTATE.IE clear over the cpu sleep hypervisor call.

#132 lore raw

PATCH v2 1/1 sparc: Use generic idle loop

Add generic cpu_idle support

sparc32:
- replace call to cpu_idle() with cpu_startup_entry()
- add arch_cpu_idle()

sparc64:
- smp_callin() now include cpu_startup_entry() call so we can skip calling cpu_idle from assembler
- add arch_cpu_idle() and arch_cpu_idle_dead()

---
v1->v2:
- simplified arch_cpu_idle() - former sparc64_yield() based on comments from Srivatsa
- dropped TIF_POLLING_NRFLAG handling
- dropped smp_mb__after_clear_bit() - this is done in generic code using rmb()
- dropped the out-most while (!need_resched() && !cpu_is_offline(cpu))
- always enable irq on exit in arch_cpu_idle (both sparc32 and sparc64)
- added comment from davem why we need to clear IE bit in sparc64 arch_cpu_idle()

Sam

arch/sparc/Kconfig +1 -0
index 3d361f2..ee5eacc 100644
@@ -37,6 +37,7 @@ config SPARC
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_CMOS_UPDATE
 	select GENERIC_CLOCKEVENTS
+	select GENERIC_IDLE_LOOP
 	select GENERIC_STRNCPY_FROM_USER
 	select GENERIC_STRNLEN_USER
 	select MODULES_USE_ELF_RELA
arch/sparc/kernel/hvtramp.S +1 -2
index 9365432..605c960 100644
@@ -128,8 +128,7 @@ hv_cpu_startup:
 
 	call		smp_callin
 	 nop
-	call		cpu_idle
-	 mov		0, %o0
+
 	call		cpu_panic
 	 nop
 
arch/sparc/kernel/process_32.c +5 -16
index 62eede1..c852410 100644
@@ -64,23 +64,12 @@ extern void fpsave(unsigned long *, unsigned long *, void *, unsigned long *);
 struct task_struct *last_task_used_math = NULL;
 struct thread_info *current_set[NR_CPUS];
 
-/*
- * the idle loop on a Sparc... ;)
- */
-void cpu_idle(void)
+/* Idle loop support. */
+void arch_cpu_idle(void)
 {
-	set_thread_flag(TIF_POLLING_NRFLAG);
-
-	/* endless idle loop with no priority at all */
-	for (;;) {
-		while (!need_resched()) {
-			if (sparc_idle)
-				(*sparc_idle)();
-			else
-				cpu_relax();
-		}
-		schedule_preempt_disabled();
-	}
+	if (sparc_idle)
+		(*sparc_idle)();
+	local_irq_enable();
 }
 
 /* XXX cli/sti -> local_irq_xxx here, check this works once SMP is fixed. */
arch/sparc/kernel/process_64.c +13 -36

76 lines not on this page · raw message

arch/sparc/kernel/smp_32.c +1 -1
index 9e7e6d7..e3f2b81 100644
@@ -369,7 +369,7 @@ void __cpuinit sparc_start_secondary(void *arg)
 	local_irq_enable();
 
 	wmb();
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 
 	/* We should never reach here! */
 	BUG();
arch/sparc/kernel/smp_64.c +2 -0
index 537eb66..c025ffc 100644
@@ -127,6 +127,8 @@ void __cpuinit smp_callin(void)
 
 	/* idle thread is expected to have preempt disabled */
 	preempt_disable();
+
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 void cpu_panic(void)
arch/sparc/kernel/trampoline_64.S +1 -2
index da1b781..2e973a2 100644
@@ -407,8 +407,7 @@ after_lock_tlb:
 
 	call		smp_callin
 	 nop
-	call		cpu_idle
-	 mov		0, %o0
+
 	call		cpu_panic
 	 nop
 1:	b,a,pt		%xcc, 1b
#133 lore raw

Re: [PATCH v2] sparc: Use generic idle loop

Quoted 10 lines · Sam Ravnborg

Add generic cpu_idle support

sparc32:
- replace call to cpu_idle() with cpu_startup_entry()
- add arch_cpu_idle()

sparc64:
- smp_callin() now include cpu_startup_entry() call so we can skip calling cpu_idle from assembler
- add arch_cpu_idle() and arch_cpu_idle_dead()

Nice !

If Dave acks it, I'll pick it up

Thanks,

tglx

Quoted 198 lines

---
v1->v2:
- simplified arch_cpu_idle() - former sparc64_yield() based on comments from Srivatsa
- dropped TIF_POLLING_NRFLAG handling
- dropped smp_mb__after_clear_bit() - this is done in generic code using rmb()
- dropped the out-most while (!need_resched() && !cpu_is_offline(cpu))
- always enable irq on exit in arch_cpu_idle (both sparc32 and sparc64)
- added comment from davem why we need to clear IE bit in sparc64 arch_cpu_idle()

Sam

arch/sparc/Kconfig +1 -0
index 3d361f2..ee5eacc 100644
@@ -37,6 +37,7 @@ config SPARC
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_CMOS_UPDATE
 	select GENERIC_CLOCKEVENTS
+	select GENERIC_IDLE_LOOP
 	select GENERIC_STRNCPY_FROM_USER
 	select GENERIC_STRNLEN_USER
 	select MODULES_USE_ELF_RELA
arch/sparc/kernel/hvtramp.S +1 -2
index 9365432..605c960 100644
@@ -128,8 +128,7 @@ hv_cpu_startup:
 
 	call		smp_callin
 	 nop
-	call		cpu_idle
-	 mov		0, %o0
+
 	call		cpu_panic
 	 nop
 
arch/sparc/kernel/process_32.c +5 -16
index 62eede1..c852410 100644
@@ -64,23 +64,12 @@ extern void fpsave(unsigned long *, unsigned long *, void *, unsigned long *);
 struct task_struct *last_task_used_math = NULL;
 struct thread_info *current_set[NR_CPUS];
 
-/*
- * the idle loop on a Sparc... ;)
- */
-void cpu_idle(void)
+/* Idle loop support. */
+void arch_cpu_idle(void)
 {
-	set_thread_flag(TIF_POLLING_NRFLAG);
-
-	/* endless idle loop with no priority at all */
-	for (;;) {
-		while (!need_resched()) {
-			if (sparc_idle)
-				(*sparc_idle)();
-			else
-				cpu_relax();
-		}
-		schedule_preempt_disabled();
-	}
+	if (sparc_idle)
+		(*sparc_idle)();
+	local_irq_enable();
 }
 
 /* XXX cli/sti -> local_irq_xxx here, check this works once SMP is fixed. */
arch/sparc/kernel/process_64.c +13 -36
index cdb80b2..9fbf0d1 100644
@@ -52,20 +52,17 @@
 
 #include "kstack.h"
 
-static void sparc64_yield(int cpu)
+/* Idle loop support on sparc64. */
+void arch_cpu_idle(void)
 {
 	if (tlb_type != hypervisor) {
 		touch_nmi_watchdog();
-		return;
-	}
-
-	clear_thread_flag(TIF_POLLING_NRFLAG);
-	smp_mb__after_clear_bit();
-
-	while (!need_resched() && !cpu_is_offline(cpu)) {
+	} else {
 		unsigned long pstate;
 
-		/* Disable interrupts. */
+                /* The sun4v sleeping code requires that we have PSTATE.IE cleared over
+                 * the cpu sleep hypervisor call.
+                 */
 		__asm__ __volatile__(
 			"rdpr %%pstate, %0\n\t"
 			"andn %0, %1, %0\n\t"
@@ -73,7 +70,7 @@ static void sparc64_yield(int cpu)
 			: "=&r" (pstate)
 			: "i" (PSTATE_IE));
 
-		if (!need_resched() && !cpu_is_offline(cpu))
+		if (!need_resched() && !cpu_is_offline(smp_processor_id()))
 			sun4v_cpu_yield();
 
 		/* Re-enable interrupts. */
@@ -84,36 +81,16 @@ static void sparc64_yield(int cpu)
 			: "=&r" (pstate)
 			: "i" (PSTATE_IE));
 	}
-
-	set_thread_flag(TIF_POLLING_NRFLAG);
+	local_irq_enable();
 }
 
-/* The idle loop on sparc64. */
-void cpu_idle(void)
-{
-	int cpu = smp_processor_id();
-
-	set_thread_flag(TIF_POLLING_NRFLAG);
-
-	while(1) {
-		tick_nohz_idle_enter();
-		rcu_idle_enter();
-
-		while (!need_resched() && !cpu_is_offline(cpu))
-			sparc64_yield(cpu);
-
-		rcu_idle_exit();
-		tick_nohz_idle_exit();
-
 #ifdef CONFIG_HOTPLUG_CPU
-		if (cpu_is_offline(cpu)) {
-			sched_preempt_enable_no_resched();
-			cpu_play_dead();
-		}
-#endif
-		schedule_preempt_disabled();
-	}
+void arch_cpu_idle_dead()
+{
+	sched_preempt_enable_no_resched();
+	cpu_play_dead();
 }
+#endif
 
 #ifdef CONFIG_COMPAT
 static void show_regwindow32(struct pt_regs *regs)
arch/sparc/kernel/smp_32.c +1 -1
index 9e7e6d7..e3f2b81 100644
@@ -369,7 +369,7 @@ void __cpuinit sparc_start_secondary(void *arg)
 	local_irq_enable();
 
 	wmb();
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 
 	/* We should never reach here! */
 	BUG();
arch/sparc/kernel/smp_64.c +2 -0
index 537eb66..c025ffc 100644
@@ -127,6 +127,8 @@ void __cpuinit smp_callin(void)
 
 	/* idle thread is expected to have preempt disabled */
 	preempt_disable();
+
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 void cpu_panic(void)
arch/sparc/kernel/trampoline_64.S +1 -2
index da1b781..2e973a2 100644
@@ -407,8 +407,7 @@ after_lock_tlb:
 
 	call		smp_callin
 	 nop
-	call		cpu_idle
-	 mov		0, %o0
+
 	call		cpu_panic
 	 nop
 1:	b,a,pt		%xcc, 1b
maintainer Acked-by
#134 lore raw

Re: [PATCH v2] sparc: Use generic idle loop

From: Thomas Gleixner <[email protected]>
Date: Fri, 12 Apr 2013 20:56:10 +0200 (CEST)

Quoted 8 lines · Sam Ravnborg
Quoted 7 lines

Add generic cpu_idle support

sparc32:
- replace call to cpu_idle() with cpu_startup_entry()
- add arch_cpu_idle()

Quoted 8 lines
Quoted 4 lines

sparc64:
- smp_callin() now include cpu_startup_entry() call so we can skip calling cpu_idle from assembler
- add arch_cpu_idle() and arch_cpu_idle_dead()

Nice !

If Dave acks it, I'll pick it up

#135 lore raw

[tip:smp/hotplug] sparc: Use generic idle loop

In reply to Sam Ravnborg
sparc: Use generic idle loop
Commit-ID:  87fa05aeb3a5e8e21b1a5510eef6983650eff092
Gitweb:     http://git.kernel.org/tip/87fa05aeb3a5e8e21b1a5510eef6983650eff092
Author:     Sam Ravnborg <[email protected]>
AuthorDate: Thu, 11 Apr 2013 21:38:50 +0200
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Sat, 13 Apr 2013 21:36:27 +0200

sparc: Use generic idle loop

Add generic cpu_idle support

sparc32:
- replace call to cpu_idle() with cpu_startup_entry()
- add arch_cpu_idle()

sparc64:
- smp_callin() now include cpu_startup_entry() call so we can skip calling cpu_idle from assembler
- add arch_cpu_idle() and arch_cpu_idle_dead()

---
 arch/sparc/Kconfig                |  1 +
 arch/sparc/kernel/hvtramp.S       |  3 +--
 arch/sparc/kernel/process_32.c    | 21 ++++-------------
 arch/sparc/kernel/process_64.c    | 49 +++++++++++----------------------------
 arch/sparc/kernel/smp_32.c        |  2 +-
 arch/sparc/kernel/smp_64.c        |  2 ++
 arch/sparc/kernel/trampoline_64.S |  3 +--
 7 files changed, 24 insertions(+), 57 deletions(-)
arch/sparc/Kconfig +1 -0
index 3d361f2..ee5eacc 100644
@@ -37,6 +37,7 @@ config SPARC
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_CMOS_UPDATE
 	select GENERIC_CLOCKEVENTS
+	select GENERIC_IDLE_LOOP
 	select GENERIC_STRNCPY_FROM_USER
 	select GENERIC_STRNLEN_USER
 	select MODULES_USE_ELF_RELA
arch/sparc/kernel/hvtramp.S +1 -2
index 9365432..605c960 100644
@@ -128,8 +128,7 @@ hv_cpu_startup:
 
 	call		smp_callin
 	 nop
-	call		cpu_idle
-	 mov		0, %o0
+
 	call		cpu_panic
 	 nop
 
arch/sparc/kernel/process_32.c +5 -16
index 62eede1..c852410 100644
@@ -64,23 +64,12 @@ extern void fpsave(unsigned long *, unsigned long *, void *, unsigned long *);
 struct task_struct *last_task_used_math = NULL;
 struct thread_info *current_set[NR_CPUS];
 
-/*
- * the idle loop on a Sparc... ;)
- */
-void cpu_idle(void)
+/* Idle loop support. */
+void arch_cpu_idle(void)
 {
-	set_thread_flag(TIF_POLLING_NRFLAG);
-
-	/* endless idle loop with no priority at all */
-	for (;;) {
-		while (!need_resched()) {
-			if (sparc_idle)
-				(*sparc_idle)();
-			else
-				cpu_relax();
-		}
-		schedule_preempt_disabled();
-	}
+	if (sparc_idle)
+		(*sparc_idle)();
+	local_irq_enable();
 }
 
 /* XXX cli/sti -> local_irq_xxx here, check this works once SMP is fixed. */
arch/sparc/kernel/process_64.c +13 -36

76 lines not on this page · raw message

arch/sparc/kernel/smp_32.c +1 -1
index 9e7e6d7..e3f2b81 100644
@@ -369,7 +369,7 @@ void __cpuinit sparc_start_secondary(void *arg)
 	local_irq_enable();
 
 	wmb();
-	cpu_idle();
+	cpu_startup_entry(CPUHP_ONLINE);
 
 	/* We should never reach here! */
 	BUG();
arch/sparc/kernel/smp_64.c +2 -0
index 537eb66..c025ffc 100644
@@ -127,6 +127,8 @@ void __cpuinit smp_callin(void)
 
 	/* idle thread is expected to have preempt disabled */
 	preempt_disable();
+
+	cpu_startup_entry(CPUHP_ONLINE);
 }
 
 void cpu_panic(void)
arch/sparc/kernel/trampoline_64.S +1 -2
index da1b781..2e973a2 100644
@@ -407,8 +407,7 @@ after_lock_tlb:
 
 	call		smp_callin
 	 nop
-	call		cpu_idle
-	 mov		0, %o0
+
 	call		cpu_panic
 	 nop
 1:	b,a,pt		%xcc, 1b
#136 lore raw
In reply to Thomas Gleixner

Hi Thomas,

Quoted 5 lines · Thomas Gleixner

Each architecture implements its own cpu_idle() code, which is more or less the same on all architectures (plus/minus a few bugs and a few missing extra functionalities, instrumentation ...). That also forces everyone who is interested in idle related features to add new functionality to every architecture. What a waste.

I noticed there are still prototypes for cpu_idle() in include/linux/cpu.h and include/linux/smp.h, so I ran a full "git grep -w cpu_idle", which suggested a few more places that needs updates:

Documentation/s390/Debugging390.txt:0001b304 T cpu_idle Documentation/s390/Debugging390.txt:is cpu_idle+0x66 ( quiet the cpu is asleep, don't wake it ) Documentation/scheduler/sched-arch.txt:Your cpu_idle routines need to obey the following rules:
Documentation/scheduler/sched-arch.txt:3. When cpu_idle finds (need_resched() = 'true'), it should call
Documentation/trace/events-power.txt:cpu_idle "state=%lu cpu_id=%lu"
Documentation/trace/ftrace.txt: <idle>-0 [002] .N.1
21169.031484: rcu_idle_exit <-cpu_idle Documentation/trace/ftrace.txt: => cpu_idle
Documentation/trace/ftrace.txt: <idle>-0 3.N.1 11us :
rcu_idle_exit <-cpu_idle
Documentation/trace/ftrace.txt: <idle>-0 3.N.1 11us :
tick_nohz_idle_exit <-cpu_idle
Documentation/trace/ftrace.txt: <idle>-0 3.N.1 25us :
sub_preempt_count <-cpu_idle
Documentation/trace/ftrace.txt: <idle>-0 3.N.. 25us :
schedule <-cpu_idle
Documentation/trace/ftrace.txt: <idle>-0 2.N.2 3us :
cpu_idle: stateB94967295 cpu_id=2
Documentation/virtual/uml/UserModeLinux-HOWTO.txt: #3
0x100a5508 in cpu_idle () at process_kern.c:471
arch/arm/Kconfig: This option adds a write barrier to the
cpu_idle loop so that,
arch/cris/arch-v10/drivers/gpio.c: * from cpu_idle() in kernel/process.c
arch/cris/arch-v10/drivers/gpio.c: * The check in cpu_idle()
reduces latency from ~15 ms to ~6 ms
arch/cris/arch-v32/drivers/mach-fs/gpio.c: * from cpu_idle() in
kernel/process.c
arch/cris/arch-v32/drivers/mach-fs/gpio.c: * The check in
cpu_idle() reduces latency from ~15 ms to ~6 ms
arch/mips/kernel/smtc.c: printk("Dangling IXMT in cpu_idle()\n");
arch/powerpc/kernel/irq.c: * in cpu_idle() will properly re-enable everything. arch/sparc/kernel/leon_pmc.c:/* leon_pmc.c: LEON Power-down cpu_idle() handler
arch/sparc/kernel/smp_32.c: printk("CPU[%d]: Returns from
cpu_idle!\n", smp_processor_id());
arch/sparc/kernel/smp_64.c: printk("CPU[%d]: Returns from
cpu_idle!\n", smp_processor_id()); arch/tile/include/asm/thread_info.h:/* Enable interrupts racelessly and nap forever: helper for cpu_idle(). */
drivers/acpi/processor_driver.c: * Set flag to delay
cpu_idle/throttling initialization
include/linux/cpu.h:void cpu_idle(void); include/linux/smp.h:extern void cpu_idle(void); include/trace/events/power.h:DEFINE_EVENT(cpu, cpu_idle,

init/main.c: * cpu_idle.
init/main.c:    /* Call into cpu_idle with preempt disabled */
init/main.c:     * fragile until we cpu_idle() for the first time.

kernel/trace/power-traces.c:EXPORT_TRACEPOINT_SYMBOL_GPL(cpu_idle);
tools/perf/builtin-timechart.c: * Mapping all these
"power:cpu_idle" strings to the tracepoint
tools/perf/builtin-timechart.c: if (strcmp(event_str,
"power:cpu_idle") = 0) {

tools/perf/builtin-timechart.c:         "-e", "power:cpu_idle",
tools/perf/builtin-timechart.c: if (!is_valid_tracepoint("power:cpu_idle") &&
tools/perf/builtin-top.c:       "cpu_idle",

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds