linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1
@ 2012-04-20 13:05 Thomas Gleixner
  2012-04-20 13:05 ` [patch 01/18] m32r: Remove pointless function prototypes Thomas Gleixner
                   ` (27 more replies)
  0 siblings, 28 replies; 75+ messages in thread
From: Thomas Gleixner @ 2012-04-20 13:05 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Peter Zijlstra, Rusty Russell, Paul E. McKenney,
	Ingo Molnar, Srivatsa S. Bhat

Dear all,

I'm working on refactoring the SMP boot and CPU hotplug implementation.

The current code has evolved over time into a conglomerate of
warts. My main goals are to:

 - reduce the architecture code by moving repeating constructs to the
   core

 - redesigning the handling of per cpu threads. There is no point to
   tear down the threads just to create them again.

 - restructuring the notifier facility into a proper tree with
   dependencies to avoid the gazillion of callbacks and moving
   setup/teardown code into the context of the upcoming/dying cpu

The motivation behind this work is the cpu hotplug nightmare which we
are facing in the RT kernel and the requests from several groups
(e.g. ARM) to make hotplug more lightweight and faster.

This first part moves the idle thread management for non-boot cpus
into the core. fork_idle() is called in a workqueue as it is
implemented in a few architectures already. This is necessary when not
all cpus are brought up by the early boot code as otherwise we would
take a ref on the user task VM of the thread which brings the cpu up
via the sysfs interface.

This converts all architectures except m32r, mn10300, tile and UM to
the new core facility. These architecture are calling fork_idle() in
the very early boot code in smp_prepare_cpus() for unknown reasons.
I haven't analyzed yet, whether this is on purpose or can be moved
over to the generic facility. It'd be nice if the responsible maintainers
could look into that as well.

Thanks,

	tglx




^ permalink raw reply	[flat|nested] 75+ messages in thread

* [patch 01/18] m32r: Remove pointless function prototypes
  2012-04-20 13:05 [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
@ 2012-04-20 13:05 ` Thomas Gleixner
  2012-04-28  9:01   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
  2012-04-20 13:05 ` [patch 02/18] smp: Add task_struct argument to __cpu_up() Thomas Gleixner
                   ` (26 subsequent siblings)
  27 siblings, 1 reply; 75+ messages in thread
From: Thomas Gleixner @ 2012-04-20 13:05 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Peter Zijlstra, Rusty Russell, Paul E. McKenney,
	Ingo Molnar, Srivatsa S. Bhat, Hirokazu Takata

[-- Attachment #1: m32r-remove-pointless-declaration.patch --]
[-- Type: text/plain, Size: 904 bytes --]

Already declared in include/linux/smp.h

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Hirokazu Takata <takata@linux-m32r.org>
---
 arch/m32r/kernel/smpboot.c |    4 ----
 1 file changed, 4 deletions(-)

Index: linux-2.6/arch/m32r/kernel/smpboot.c
===================================================================
--- linux-2.6.orig/arch/m32r/kernel/smpboot.c
+++ linux-2.6/arch/m32r/kernel/smpboot.c
@@ -109,12 +109,8 @@ static unsigned int calibration_result;
 /* Function Prototypes                                                       */
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
 
-void smp_prepare_boot_cpu(void);
-void smp_prepare_cpus(unsigned int);
 static void init_ipi_lock(void);
 static void do_boot_cpu(int);
-int __cpu_up(unsigned int);
-void smp_cpus_done(unsigned int);
 
 int start_secondary(void *);
 static void smp_callin(void);



^ permalink raw reply	[flat|nested] 75+ messages in thread

* [patch 02/18] smp: Add task_struct argument to __cpu_up()
  2012-04-20 13:05 [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
  2012-04-20 13:05 ` [patch 01/18] m32r: Remove pointless function prototypes Thomas Gleixner
@ 2012-04-20 13:05 ` Thomas Gleixner
  2012-04-23  7:58   ` Jesper Nilsson
  2012-04-28  9:02   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
  2012-04-20 13:05 ` [patch 03/18] smp: Add generic smpboot facility Thomas Gleixner
                   ` (25 subsequent siblings)
  27 siblings, 2 replies; 75+ messages in thread
From: Thomas Gleixner @ 2012-04-20 13:05 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Peter Zijlstra, Rusty Russell, Paul E. McKenney,
	Ingo Molnar, Srivatsa S. Bhat, Matt Turner, Russell King,
	Mike Frysinger, Jesper Nilsson, Richard Kuo, Tony Luck,
	Hirokazu Takata, Ralf Baechle, David Howells,
	James E.J. Bottomley, Benjamin Herrenschmidt, Martin Schwidefsky,
	Paul Mundt, David S. Miller, Chris Metcalf, Richard Weinberger,
	x86

[-- Attachment #1: smp-add-task-struct-argument-to-cpu-up.patch --]
[-- Type: text/plain, Size: 11432 bytes --]

Preparatory patch to make the idle thread allocation for secondary
cpus generic.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Matt Turner <mattst88@gmail.com>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Mike Frysinger <vapier@gentoo.org>
Cc: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: Richard Kuo <rkuo@codeaurora.org>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Hirokazu Takata <takata@linux-m32r.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: David Howells <dhowells@redhat.com>
Cc: "James E.J. Bottomley" <jejb@parisc-linux.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Chris Metcalf <cmetcalf@tilera.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: x86@kernel.org

---
 arch/alpha/kernel/smp.c         |    2 +-
 arch/arm/kernel/smp.c           |    2 +-
 arch/blackfin/mach-common/smp.c |    2 +-
 arch/cris/arch-v32/kernel/smp.c |    2 +-
 arch/hexagon/kernel/smp.c       |    2 +-
 arch/ia64/kernel/smpboot.c      |    2 +-
 arch/m32r/kernel/smpboot.c      |    2 +-
 arch/mips/kernel/smp.c          |    2 +-
 arch/mn10300/kernel/smp.c       |    2 +-
 arch/parisc/kernel/smp.c        |    2 +-
 arch/powerpc/kernel/smp.c       |    2 +-
 arch/s390/include/asm/smp.h     |    2 +-
 arch/s390/kernel/smp.c          |    2 +-
 arch/sh/kernel/smp.c            |    2 +-
 arch/sparc/kernel/smp_32.c      |    2 +-
 arch/sparc/kernel/smp_64.c      |    2 +-
 arch/tile/kernel/smpboot.c      |    2 +-
 arch/um/kernel/smp.c            |    2 +-
 arch/x86/include/asm/smp.h      |    4 +++-
 include/linux/smp.h             |    2 +-
 kernel/cpu.c                    |    2 +-
 21 files changed, 23 insertions(+), 21 deletions(-)

Index: linux-2.6/arch/alpha/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/alpha/kernel/smp.c
+++ linux-2.6/arch/alpha/kernel/smp.c
@@ -487,7 +487,7 @@ smp_prepare_boot_cpu(void)
 }
 
 int __cpuinit
-__cpu_up(unsigned int cpu)
+__cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	smp_boot_one_cpu(cpu);
 
Index: linux-2.6/arch/arm/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/arm/kernel/smp.c
+++ linux-2.6/arch/arm/kernel/smp.c
@@ -60,7 +60,7 @@ enum ipi_msg_type {
 
 static DECLARE_COMPLETION(cpu_running);
 
-int __cpuinit __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	struct cpuinfo_arm *ci = &per_cpu(cpu_data, cpu);
 	struct task_struct *idle = ci->idle;
Index: linux-2.6/arch/blackfin/mach-common/smp.c
===================================================================
--- linux-2.6.orig/arch/blackfin/mach-common/smp.c
+++ linux-2.6/arch/blackfin/mach-common/smp.c
@@ -340,7 +340,7 @@ void smp_send_stop(void)
 	return;
 }
 
-int __cpuinit __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	int ret;
 	struct blackfin_cpudata *ci = &per_cpu(cpu_data, cpu);
Index: linux-2.6/arch/cris/arch-v32/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/cris/arch-v32/kernel/smp.c
+++ linux-2.6/arch/cris/arch-v32/kernel/smp.c
@@ -207,7 +207,7 @@ int setup_profiling_timer(unsigned int m
  */
 unsigned long cache_decay_ticks = 1;
 
-int __cpuinit __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	smp_boot_one_cpu(cpu);
 	return cpu_online(cpu) ? 0 : -ENOSYS;
Index: linux-2.6/arch/hexagon/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/hexagon/kernel/smp.c
+++ linux-2.6/arch/hexagon/kernel/smp.c
@@ -190,7 +190,7 @@ void __cpuinit start_secondary(void)
  * maintains control until "cpu_online(cpu)" is set.
  */
 
-int __cpuinit __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	struct task_struct *idle;
 	struct thread_info *thread;
Index: linux-2.6/arch/ia64/kernel/smpboot.c
===================================================================
--- linux-2.6.orig/arch/ia64/kernel/smpboot.c
+++ linux-2.6/arch/ia64/kernel/smpboot.c
@@ -793,7 +793,7 @@ set_cpu_sibling_map(int cpu)
 }
 
 int __cpuinit
-__cpu_up (unsigned int cpu)
+__cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	int ret;
 	int sapicid;
Index: linux-2.6/arch/m32r/kernel/smpboot.c
===================================================================
--- linux-2.6.orig/arch/m32r/kernel/smpboot.c
+++ linux-2.6/arch/m32r/kernel/smpboot.c
@@ -343,7 +343,7 @@ static void __init do_boot_cpu(int phys_
 	}
 }
 
-int __cpuinit __cpu_up(unsigned int cpu_id)
+int __cpuinit __cpu_up(unsigned int cpu_id, struct task_struct *tidle)
 {
 	int timeout;
 
Index: linux-2.6/arch/mips/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/mips/kernel/smp.c
+++ linux-2.6/arch/mips/kernel/smp.c
@@ -209,7 +209,7 @@ static void __cpuinit do_fork_idle(struc
 	complete(&c_idle->done);
 }
 
-int __cpuinit __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	struct task_struct *idle;
 
Index: linux-2.6/arch/mn10300/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/mn10300/kernel/smp.c
+++ linux-2.6/arch/mn10300/kernel/smp.c
@@ -921,7 +921,7 @@ void initialize_secondary(void)
  * __cpu_up - Set smp_commenced_mask for the nominated CPU
  * @cpu: The target CPU.
  */
-int __devinit __cpu_up(unsigned int cpu)
+int __devinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	int timeout;
 
Index: linux-2.6/arch/parisc/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/parisc/kernel/smp.c
+++ linux-2.6/arch/parisc/kernel/smp.c
@@ -449,7 +449,7 @@ void smp_cpus_done(unsigned int cpu_max)
 }
 
 
-int __cpuinit __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	if (cpu != 0 && cpu < parisc_max_cpus)
 		smp_boot_one_cpu(cpu);
Index: linux-2.6/arch/powerpc/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/powerpc/kernel/smp.c
+++ linux-2.6/arch/powerpc/kernel/smp.c
@@ -482,7 +482,7 @@ static int __cpuinit create_idle(unsigne
 	return 0;
 }
 
-int __cpuinit __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	int rc, c;
 
Index: linux-2.6/arch/s390/include/asm/smp.h
===================================================================
--- linux-2.6.orig/arch/s390/include/asm/smp.h
+++ linux-2.6/arch/s390/include/asm/smp.h
@@ -16,7 +16,7 @@
 extern struct mutex smp_cpu_state_mutex;
 extern struct save_area *zfcpdump_save_areas[NR_CPUS + 1];
 
-extern int __cpu_up(unsigned int cpu);
+extern int __cpu_up(unsigned int cpu, struct task_struct *tidle);
 
 extern void arch_send_call_function_single_ipi(int cpu);
 extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
Index: linux-2.6/arch/s390/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/s390/kernel/smp.c
+++ linux-2.6/arch/s390/kernel/smp.c
@@ -738,7 +738,7 @@ static void __cpuinit smp_fork_idle(stru
 }
 
 /* Upping and downing of CPUs */
-int __cpuinit __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	struct create_idle c_idle;
 	struct pcpu *pcpu;
Index: linux-2.6/arch/sh/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/sh/kernel/smp.c
+++ linux-2.6/arch/sh/kernel/smp.c
@@ -220,7 +220,7 @@ extern struct {
 	void *thread_info;
 } stack_start;
 
-int __cpuinit __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	struct task_struct *tsk;
 	unsigned long timeout;
Index: linux-2.6/arch/sparc/kernel/smp_32.c
===================================================================
--- linux-2.6.orig/arch/sparc/kernel/smp_32.c
+++ linux-2.6/arch/sparc/kernel/smp_32.c
@@ -411,7 +411,7 @@ void __init smp_prepare_boot_cpu(void)
 	set_cpu_possible(cpuid, true);
 }
 
-int __cpuinit __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	extern int __cpuinit smp4m_boot_one_cpu(int);
 	extern int __cpuinit smp4d_boot_one_cpu(int);
Index: linux-2.6/arch/sparc/kernel/smp_64.c
===================================================================
--- linux-2.6.orig/arch/sparc/kernel/smp_64.c
+++ linux-2.6/arch/sparc/kernel/smp_64.c
@@ -1227,7 +1227,7 @@ void __devinit smp_fill_in_sib_core_maps
 	}
 }
 
-int __cpuinit __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	int ret = smp_boot_one_cpu(cpu);
 
Index: linux-2.6/arch/tile/kernel/smpboot.c
===================================================================
--- linux-2.6.orig/arch/tile/kernel/smpboot.c
+++ linux-2.6/arch/tile/kernel/smpboot.c
@@ -222,7 +222,7 @@ void __cpuinit online_secondary(void)
 	cpu_idle();
 }
 
-int __cpuinit __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	/* Wait 5s total for all CPUs for them to come online */
 	static int timeout;
Index: linux-2.6/arch/um/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/um/kernel/smp.c
+++ linux-2.6/arch/um/kernel/smp.c
@@ -140,7 +140,7 @@ void smp_prepare_boot_cpu(void)
 	set_cpu_online(smp_processor_id(), true);
 }
 
-int __cpu_up(unsigned int cpu)
+int __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	cpu_set(cpu, smp_commenced_mask);
 	while (!cpu_online(cpu))
Index: linux-2.6/arch/x86/include/asm/smp.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/smp.h
+++ linux-2.6/arch/x86/include/asm/smp.h
@@ -62,6 +62,8 @@ DECLARE_EARLY_PER_CPU(int, x86_cpu_to_lo
 /* Static state in head.S used to set up a CPU */
 extern unsigned long stack_start; /* Initial stack pointer address */
 
+struct task_struct;
+
 struct smp_ops {
 	void (*smp_prepare_boot_cpu)(void);
 	void (*smp_prepare_cpus)(unsigned max_cpus);
@@ -113,7 +115,7 @@ static inline void smp_cpus_done(unsigne
 	smp_ops.smp_cpus_done(max_cpus);
 }
 
-static inline int __cpu_up(unsigned int cpu)
+static inline int __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	return smp_ops.cpu_up(cpu);
 }
Index: linux-2.6/include/linux/smp.h
===================================================================
--- linux-2.6.orig/include/linux/smp.h
+++ linux-2.6/include/linux/smp.h
@@ -61,7 +61,7 @@ extern void smp_prepare_cpus(unsigned in
 /*
  * Bring a CPU up
  */
-extern int __cpu_up(unsigned int cpunum);
+extern int __cpu_up(unsigned int cpunum, struct task_struct *tidle);
 
 /*
  * Final polishing of CPUs
Index: linux-2.6/kernel/cpu.c
===================================================================
--- linux-2.6.orig/kernel/cpu.c
+++ linux-2.6/kernel/cpu.c
@@ -309,7 +309,7 @@ static int __cpuinit _cpu_up(unsigned in
 	}
 
 	/* Arch-specific enabling code. */
-	ret = __cpu_up(cpu);
+	ret = __cpu_up(cpu, NULL);
 	if (ret != 0)
 		goto out_notify;
 	BUG_ON(!cpu_online(cpu));



^ permalink raw reply	[flat|nested] 75+ messages in thread

* [patch 03/18] smp: Add generic smpboot facility
  2012-04-20 13:05 [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
  2012-04-20 13:05 ` [patch 01/18] m32r: Remove pointless function prototypes Thomas Gleixner
  2012-04-20 13:05 ` [patch 02/18] smp: Add task_struct argument to __cpu_up() Thomas Gleixner
@ 2012-04-20 13:05 ` Thomas Gleixner
  2012-04-20 20:07   ` Yinghai Lu
                     ` (2 more replies)
  2012-04-20 13:05 ` [patch 04/18] smp: Provide generic idle thread allocation Thomas Gleixner
                   ` (24 subsequent siblings)
  27 siblings, 3 replies; 75+ messages in thread
From: Thomas Gleixner @ 2012-04-20 13:05 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Peter Zijlstra, Rusty Russell, Paul E. McKenney,
	Ingo Molnar, Srivatsa S. Bhat, Matt Turner, Russell King,
	Mike Frysinger, Jesper Nilsson, Richard Kuo, Tony Luck,
	Hirokazu Takata, Ralf Baechle, David Howells,
	James E.J. Bottomley, Benjamin Herrenschmidt, Martin Schwidefsky,
	Paul Mundt, David S. Miller, Chris Metcalf, Richard Weinberger,
	x86

[-- Attachment #1: smp-add-generic-smpboot-facility.patch --]
[-- Type: text/plain, Size: 2876 bytes --]

Start a new file, which will hold SMP and CPU hotplug related generic
infrastructure.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Matt Turner <mattst88@gmail.com>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Mike Frysinger <vapier@gentoo.org>
Cc: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: Richard Kuo <rkuo@codeaurora.org>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Hirokazu Takata <takata@linux-m32r.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: David Howells <dhowells@redhat.com>
Cc: "James E.J. Bottomley" <jejb@parisc-linux.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Chris Metcalf <cmetcalf@tilera.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: x86@kernel.org
---
 kernel/Makefile  |    1 +
 kernel/cpu.c     |    8 ++++++++
 kernel/smpboot.c |   12 ++++++++++++
 kernel/smpboot.h |    6 ++++++
 4 files changed, 27 insertions(+)

Index: linux-2.6/kernel/Makefile
===================================================================
--- linux-2.6.orig/kernel/Makefile
+++ linux-2.6/kernel/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_DEBUG_RT_MUTEXES) += rtmute
 obj-$(CONFIG_RT_MUTEX_TESTER) += rtmutex-tester.o
 obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
 obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_SMP) += smpboot.o
 ifneq ($(CONFIG_SMP),y)
 obj-y += up.o
 endif
Index: linux-2.6/kernel/cpu.c
===================================================================
--- linux-2.6.orig/kernel/cpu.c
+++ linux-2.6/kernel/cpu.c
@@ -17,6 +17,8 @@
 #include <linux/gfp.h>
 #include <linux/suspend.h>
 
+#include "smpboot.h"
+
 #ifdef CONFIG_SMP
 /* Serializes the updates to cpu_online_mask, cpu_present_mask */
 static DEFINE_MUTEX(cpu_add_remove_lock);
@@ -300,6 +302,11 @@ static int __cpuinit _cpu_up(unsigned in
 		return -EINVAL;
 
 	cpu_hotplug_begin();
+
+	ret = smpboot_prepare(cpu);
+	if (ret)
+		goto out;
+
 	ret = __cpu_notify(CPU_UP_PREPARE | mod, hcpu, -1, &nr_calls);
 	if (ret) {
 		nr_calls--;
@@ -320,6 +327,7 @@ static int __cpuinit _cpu_up(unsigned in
 out_notify:
 	if (ret != 0)
 		__cpu_notify(CPU_UP_CANCELED | mod, hcpu, nr_calls, NULL);
+out:
 	cpu_hotplug_done();
 
 	return ret;
Index: linux-2.6/kernel/smpboot.c
===================================================================
--- /dev/null
+++ linux-2.6/kernel/smpboot.c
@@ -0,0 +1,12 @@
+/*
+ * Common SMP CPU bringup/teardown functions
+ */
+
+#include "smpboot.h"
+
+/**
+ * smpboot_prepare - generic smpboot preparation
+ */
+int __cpuinit smpboot_prepare(unsigned int cpu)
+{
+}
Index: linux-2.6/kernel/smpboot.h
===================================================================
--- /dev/null
+++ linux-2.6/kernel/smpboot.h
@@ -0,0 +1,6 @@
+#ifndef SMPBOOT_H
+#define SMPBOOT_H
+
+int smpboot_prepare(unsigned int cpu);
+
+#endif



^ permalink raw reply	[flat|nested] 75+ messages in thread

* [patch 04/18] smp: Provide generic idle thread allocation
  2012-04-20 13:05 [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
                   ` (2 preceding siblings ...)
  2012-04-20 13:05 ` [patch 03/18] smp: Add generic smpboot facility Thomas Gleixner
@ 2012-04-20 13:05 ` Thomas Gleixner
  2012-04-20 16:21   ` Sam Ravnborg
                     ` (3 more replies)
  2012-04-20 13:05 ` [patch 05/18] x86: Add task_struct argument to smp_ops.cpu_up Thomas Gleixner
                   ` (23 subsequent siblings)
  27 siblings, 4 replies; 75+ messages in thread
From: Thomas Gleixner @ 2012-04-20 13:05 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Peter Zijlstra, Rusty Russell, Paul E. McKenney,
	Ingo Molnar, Srivatsa S. Bhat, Matt Turner, Russell King,
	Mike Frysinger, Jesper Nilsson, Richard Kuo, Tony Luck,
	Hirokazu Takata, Ralf Baechle, David Howells,
	James E.J. Bottomley, Benjamin Herrenschmidt, Martin Schwidefsky,
	Paul Mundt, David S. Miller, Chris Metcalf, Richard Weinberger,
	x86

[-- Attachment #1: smp-provide-generic-idle-thread-allocation.patch --]
[-- Type: text/plain, Size: 6047 bytes --]

All SMP architectures have magic to fork the idle task and to store it
for reusage when cpu hotplug is enabled. Provide a generic
infrastructure for it.

Create/reinit the idle thread for the cpu which is brought up in the
generic code and hand the thread pointer to the architecture code via
__cpu_up().

Note, that fork_idle() is called via a workqueue, because this
guarantees that the idle thread does not get a reference to a user
space VM. This can happen when the boot process did not bring up all
possible cpus and a later cpu_up() is initiated via the sysfs
interface. In that case fork_idle() would be called in the context of
the user space task and take a reference on the user space VM.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Matt Turner <mattst88@gmail.com>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Mike Frysinger <vapier@gentoo.org>
Cc: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: Richard Kuo <rkuo@codeaurora.org>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Hirokazu Takata <takata@linux-m32r.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: David Howells <dhowells@redhat.com>
Cc: "James E.J. Bottomley" <jejb@parisc-linux.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Chris Metcalf <cmetcalf@tilera.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: x86@kernel.org
---
 arch/Kconfig        |    3 +
 kernel/cpu.c        |    2 -
 kernel/sched/core.c |    2 +
 kernel/smpboot.c    |   83 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 kernel/smpboot.h    |   10 ++++++
 5 files changed, 99 insertions(+), 1 deletion(-)

Index: linux-2.6/arch/Kconfig
===================================================================
--- linux-2.6.orig/arch/Kconfig
+++ linux-2.6/arch/Kconfig
@@ -145,6 +145,9 @@ config HAVE_DMA_ATTRS
 config USE_GENERIC_SMP_HELPERS
 	bool
 
+config GENERIC_SMP_IDLE_THREAD
+       bool
+
 config HAVE_REGS_AND_STACK_ACCESS_API
 	bool
 	help
Index: linux-2.6/kernel/cpu.c
===================================================================
--- linux-2.6.orig/kernel/cpu.c
+++ linux-2.6/kernel/cpu.c
@@ -316,7 +316,7 @@ static int __cpuinit _cpu_up(unsigned in
 	}
 
 	/* Arch-specific enabling code. */
-	ret = __cpu_up(cpu, NULL);
+	ret = __cpu_up(cpu, idle_thread_get(cpu));
 	if (ret != 0)
 		goto out_notify;
 	BUG_ON(!cpu_online(cpu));
Index: linux-2.6/kernel/sched/core.c
===================================================================
--- linux-2.6.orig/kernel/sched/core.c
+++ linux-2.6/kernel/sched/core.c
@@ -83,6 +83,7 @@
 
 #include "sched.h"
 #include "../workqueue_sched.h"
+#include "../smpboot.h"
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/sched.h>
@@ -7049,6 +7050,7 @@ void __init sched_init(void)
 	/* May be allocated at isolcpus cmdline parse time */
 	if (cpu_isolated_map == NULL)
 		zalloc_cpumask_var(&cpu_isolated_map, GFP_NOWAIT);
+	idle_thread_set_boot_cpu();
 #endif
 	init_sched_fair_class();
 
Index: linux-2.6/kernel/smpboot.c
===================================================================
--- linux-2.6.orig/kernel/smpboot.c
+++ linux-2.6/kernel/smpboot.c
@@ -1,12 +1,95 @@
 /*
  * Common SMP CPU bringup/teardown functions
  */
+#include <linux/err.h>
+#include <linux/smp.h>
+#include <linux/sched.h>
+#include <linux/percpu.h>
+#include <linux/workqueue.h>
 
 #include "smpboot.h"
 
+#ifdef CONFIG_GENERIC_SMP_IDLE_THREAD
+struct create_idle {
+	struct work_struct	work;
+	struct task_struct	*idle;
+	struct completion	done;
+	unsigned int cpu;
+};
+
+static void __cpuinit do_fork_idle(struct work_struct *work)
+{
+	struct create_idle *c = container_of(work, struct create_idle, work);
+
+	c->idle = fork_idle(c->cpu);
+	complete(&c->done);
+}
+
+static struct task_struct * __cpuinit idle_thread_create(unsigned int cpu)
+{
+	struct create_idle c_idle = {
+		.cpu	= cpu,
+		.done	= COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
+	};
+
+	INIT_WORK_ONSTACK(&c_idle.work, do_fork_idle);
+	schedule_work(&c_idle.work);
+	wait_for_completion(&c_idle.done);
+	destroy_work_on_stack(&c_idle.work);
+	return c_idle.idle;
+}
+
+/*
+ * For the hotplug case we keep the task structs around and reuse
+ * them.
+ */
+static DEFINE_PER_CPU(struct task_struct *, idle_threads);
+
+static inline struct task_struct *get_idle_for_cpu(unsigned int cpu)
+{
+	struct task_struct *tsk = per_cpu(idle_threads, cpu);
+
+	if (!tsk)
+		return idle_thread_create(cpu);
+	init_idle(tsk, cpu);
+	return tsk;
+}
+
+struct task_struct * __cpuinit idle_thread_get(unsigned int cpu)
+{
+	return per_cpu(idle_threads, cpu);
+}
+
+void __init idle_thread_set_boot_cpu(void)
+{
+	per_cpu(idle_threads, smp_processor_id()) = current;
+}
+
+/**
+ * idle_thread_init - Initialize the idle thread for a cpu
+ * @cpu:	The cpu for which the idle thread should be initialized
+ *
+ * Creates the thread if it does not exist.
+ */
+static int __cpuinit idle_thread_init(unsigned int cpu)
+{
+	struct task_struct *idle = get_idle_for_cpu(cpu);
+
+	if (IS_ERR(idle)) {
+		printk(KERN_ERR "failed fork for CPU %u\n", cpu);
+		return PTR_ERR(idle);
+	}
+	per_cpu(idle_threads, cpu) = idle;
+	return 0;
+}
+#else
+static inline int idle_thread_init(unsigned int cpu) { return 0; }
+#endif
+
 /**
  * smpboot_prepare - generic smpboot preparation
  */
 int __cpuinit smpboot_prepare(unsigned int cpu)
 {
+	return idle_thread_init(cpu);
 }
Index: linux-2.6/kernel/smpboot.h
===================================================================
--- linux-2.6.orig/kernel/smpboot.h
+++ linux-2.6/kernel/smpboot.h
@@ -1,6 +1,16 @@
 #ifndef SMPBOOT_H
 #define SMPBOOT_H
 
+struct task_struct;
+
 int smpboot_prepare(unsigned int cpu);
 
+#ifdef CONFIG_GENERIC_SMP_IDLE_THREAD
+struct task_struct *idle_thread_get(unsigned int cpu);
+void idle_thread_set_boot_cpu(void);
+#else
+static inline struct task_struct *idle_thread_get(unsigned int cpu) { return NULL; }
+static inline void idle_thread_set_boot_cpu(void) { }
+#endif
+
 #endif



^ permalink raw reply	[flat|nested] 75+ messages in thread

* [patch 05/18] x86: Add task_struct argument to smp_ops.cpu_up
  2012-04-20 13:05 [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
                   ` (3 preceding siblings ...)
  2012-04-20 13:05 ` [patch 04/18] smp: Provide generic idle thread allocation Thomas Gleixner
@ 2012-04-20 13:05 ` Thomas Gleixner
  2012-04-28  9:05   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
  2012-04-20 13:05 ` [patch 06/18] x86: Use generic idle thread allocation Thomas Gleixner
                   ` (22 subsequent siblings)
  27 siblings, 1 reply; 75+ messages in thread
From: Thomas Gleixner @ 2012-04-20 13:05 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Peter Zijlstra, Rusty Russell, Paul E. McKenney,
	Ingo Molnar, Srivatsa S. Bhat, x86, Jeremy Fitzhardinge

[-- Attachment #1: x86-expand-smp-ops-cpu-up.patch --]
[-- Type: text/plain, Size: 2747 bytes --]

Preparatory patch to use the generic idle thread allocation.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: x86@kernel.org
Cc: Jeremy Fitzhardinge <jeremy@goop.org>
---
 arch/x86/include/asm/smp.h |    6 +++---
 arch/x86/kernel/smpboot.c  |    2 +-
 arch/x86/xen/smp.c         |    6 +++---
 3 files changed, 7 insertions(+), 7 deletions(-)

Index: linux-2.6/arch/x86/include/asm/smp.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/smp.h
+++ linux-2.6/arch/x86/include/asm/smp.h
@@ -72,7 +72,7 @@ struct smp_ops {
 	void (*stop_other_cpus)(int wait);
 	void (*smp_send_reschedule)(int cpu);
 
-	int (*cpu_up)(unsigned cpu);
+	int (*cpu_up)(unsigned cpu, struct task_struct *tidle);
 	int (*cpu_disable)(void);
 	void (*cpu_die)(unsigned int cpu);
 	void (*play_dead)(void);
@@ -117,7 +117,7 @@ static inline void smp_cpus_done(unsigne
 
 static inline int __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
-	return smp_ops.cpu_up(cpu);
+	return smp_ops.cpu_up(cpu, tidle);
 }
 
 static inline int __cpu_disable(void)
@@ -154,7 +154,7 @@ void cpu_disable_common(void);
 void native_smp_prepare_boot_cpu(void);
 void native_smp_prepare_cpus(unsigned int max_cpus);
 void native_smp_cpus_done(unsigned int max_cpus);
-int native_cpu_up(unsigned int cpunum);
+int native_cpu_up(unsigned int cpunum, struct task_struct *tidle);
 int native_cpu_disable(void);
 void native_cpu_die(unsigned int cpu);
 void native_play_dead(void);
Index: linux-2.6/arch/x86/kernel/smpboot.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/smpboot.c
+++ linux-2.6/arch/x86/kernel/smpboot.c
@@ -818,7 +818,7 @@ do_rest:
 	return boot_error;
 }
 
-int __cpuinit native_cpu_up(unsigned int cpu)
+int __cpuinit native_cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	int apicid = apic->cpu_present_to_apicid(cpu);
 	unsigned long flags;
Index: linux-2.6/arch/x86/xen/smp.c
===================================================================
--- linux-2.6.orig/arch/x86/xen/smp.c
+++ linux-2.6/arch/x86/xen/smp.c
@@ -331,7 +331,7 @@ cpu_initialize_context(unsigned int cpu,
 	return 0;
 }
 
-static int __cpuinit xen_cpu_up(unsigned int cpu)
+static int __cpuinit xen_cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	struct task_struct *idle = idle_task(cpu);
 	int rc;
@@ -547,10 +547,10 @@ static void __init xen_hvm_smp_prepare_c
 	xen_init_lock_cpu(0);
 }
 
-static int __cpuinit xen_hvm_cpu_up(unsigned int cpu)
+static int __cpuinit xen_hvm_cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	int rc;
-	rc = native_cpu_up(cpu);
+	rc = native_cpu_up(cpu, tidle);
 	WARN_ON (xen_smp_intr_init(cpu));
 	return rc;
 }



^ permalink raw reply	[flat|nested] 75+ messages in thread

* [patch 07/18] powerpc: Use generic idle thread allocation
  2012-04-20 13:05 [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
                   ` (5 preceding siblings ...)
  2012-04-20 13:05 ` [patch 06/18] x86: Use generic idle thread allocation Thomas Gleixner
@ 2012-04-20 13:05 ` Thomas Gleixner
  2012-04-28  9:07   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
  2012-04-20 13:05 ` [patch 08/18] ia64: " Thomas Gleixner
                   ` (20 subsequent siblings)
  27 siblings, 1 reply; 75+ messages in thread
From: Thomas Gleixner @ 2012-04-20 13:05 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Peter Zijlstra, Rusty Russell, Paul E. McKenney,
	Ingo Molnar, Srivatsa S. Bhat, Benjamin Herrenschmidt

[-- Attachment #1: powerpc-use-generic-idle-thread-allocation.patch --]
[-- Type: text/plain, Size: 3858 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 arch/powerpc/Kconfig      |    1 
 arch/powerpc/kernel/smp.c |   74 +++-------------------------------------------
 2 files changed, 6 insertions(+), 69 deletions(-)

Index: linux-2.6/arch/powerpc/Kconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/Kconfig
+++ linux-2.6/arch/powerpc/Kconfig
@@ -144,6 +144,7 @@ config PPC
 	select HAVE_BPF_JIT if (PPC64 && NET)
 	select HAVE_ARCH_JUMP_LABEL
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
+	select GENERIC_SMP_IDLE_THREAD
 
 config EARLY_PRINTK
 	bool
Index: linux-2.6/arch/powerpc/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/powerpc/kernel/smp.c
+++ linux-2.6/arch/powerpc/kernel/smp.c
@@ -57,27 +57,9 @@
 #define DBG(fmt...)
 #endif
 
-
-/* Store all idle threads, this can be reused instead of creating
-* a new thread. Also avoids complicated thread destroy functionality
-* for idle threads.
-*/
 #ifdef CONFIG_HOTPLUG_CPU
-/*
- * Needed only for CONFIG_HOTPLUG_CPU because __cpuinitdata is
- * removed after init for !CONFIG_HOTPLUG_CPU.
- */
-static DEFINE_PER_CPU(struct task_struct *, idle_thread_array);
-#define get_idle_for_cpu(x)      (per_cpu(idle_thread_array, x))
-#define set_idle_for_cpu(x, p)   (per_cpu(idle_thread_array, x) = (p))
-
 /* State of each CPU during hotplug phases */
 static DEFINE_PER_CPU(int, cpu_state) = { 0 };
-
-#else
-static struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ;
-#define get_idle_for_cpu(x)      (idle_thread_array[(x)])
-#define set_idle_for_cpu(x, p)   (idle_thread_array[(x)] = (p))
 #endif
 
 struct thread_info *secondary_ti;
@@ -429,57 +411,16 @@ int generic_check_cpu_restart(unsigned i
 }
 #endif
 
-struct create_idle {
-	struct work_struct work;
-	struct task_struct *idle;
-	struct completion done;
-	int cpu;
-};
-
-static void __cpuinit do_fork_idle(struct work_struct *work)
-{
-	struct create_idle *c_idle =
-		container_of(work, struct create_idle, work);
-
-	c_idle->idle = fork_idle(c_idle->cpu);
-	complete(&c_idle->done);
-}
-
-static int __cpuinit create_idle(unsigned int cpu)
+static void cpu_idle_thread_init(unsigned int cpu, struct task_struct *idle)
 {
-	struct thread_info *ti;
-	struct create_idle c_idle = {
-		.cpu	= cpu,
-		.done	= COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
-	};
-	INIT_WORK_ONSTACK(&c_idle.work, do_fork_idle);
-
-	c_idle.idle = get_idle_for_cpu(cpu);
-
-	/* We can't use kernel_thread since we must avoid to
-	 * reschedule the child. We use a workqueue because
-	 * we want to fork from a kernel thread, not whatever
-	 * userspace process happens to be trying to online us.
-	 */
-	if (!c_idle.idle) {
-		schedule_work(&c_idle.work);
-		wait_for_completion(&c_idle.done);
-	} else
-		init_idle(c_idle.idle, cpu);
-	if (IS_ERR(c_idle.idle)) {		
-		pr_err("Failed fork for CPU %u: %li", cpu, PTR_ERR(c_idle.idle));
-		return PTR_ERR(c_idle.idle);
-	}
-	ti = task_thread_info(c_idle.idle);
+	struct thread_info *ti = task_thread_info(idle);
 
 #ifdef CONFIG_PPC64
-	paca[cpu].__current = c_idle.idle;
+	paca[cpu].__current = idle;
 	paca[cpu].kstack = (unsigned long)ti + THREAD_SIZE - STACK_FRAME_OVERHEAD;
 #endif
 	ti->cpu = cpu;
-	current_set[cpu] = ti;
-
-	return 0;
+	secondary_ti = current_set[cpu] = ti;
 }
 
 int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
@@ -490,12 +431,7 @@ int __cpuinit __cpu_up(unsigned int cpu,
 	    (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)))
 		return -EINVAL;
 
-	/* Make sure we have an idle thread */
-	rc = create_idle(cpu);
-	if (rc)
-		return rc;
-
-	secondary_ti = current_set[cpu];
+	cpu_idle_thread_init(cpu, tidle);
 
 	/* Make sure callin-map entry is 0 (can be leftover a CPU
 	 * hotplug



^ permalink raw reply	[flat|nested] 75+ messages in thread

* [patch 06/18] x86: Use generic idle thread allocation
  2012-04-20 13:05 [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
                   ` (4 preceding siblings ...)
  2012-04-20 13:05 ` [patch 05/18] x86: Add task_struct argument to smp_ops.cpu_up Thomas Gleixner
@ 2012-04-20 13:05 ` Thomas Gleixner
  2012-04-28  9:06   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
  2012-04-20 13:05 ` [patch 07/18] powerpc: " Thomas Gleixner
                   ` (21 subsequent siblings)
  27 siblings, 1 reply; 75+ messages in thread
From: Thomas Gleixner @ 2012-04-20 13:05 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Peter Zijlstra, Rusty Russell, Paul E. McKenney,
	Ingo Molnar, Srivatsa S. Bhat, x86, Jeremy Fitzhardinge

[-- Attachment #1: x86-use-generic-idle-thread-allocation.patch --]
[-- Type: text/plain, Size: 6884 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: x86@kernel.org
Cc: Jeremy Fitzhardinge <jeremy@goop.org>
---
 arch/x86/Kconfig           |    1 
 arch/x86/include/asm/smp.h |    1 
 arch/x86/kernel/smpboot.c  |   81 +++++----------------------------------------
 arch/x86/xen/smp.c         |   15 +-------
 4 files changed, 14 insertions(+), 84 deletions(-)

Index: linux-2.6/arch/x86/Kconfig
===================================================================
--- linux-2.6.orig/arch/x86/Kconfig
+++ linux-2.6/arch/x86/Kconfig
@@ -82,6 +82,7 @@ config X86
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select GENERIC_IOMAP
 	select DCACHE_WORD_ACCESS if !DEBUG_PAGEALLOC
+	select GENERIC_SMP_IDLE_THREAD
 
 config INSTRUCTION_DECODER
 	def_bool (KPROBES || PERF_EVENTS)
Index: linux-2.6/arch/x86/include/asm/smp.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/smp.h
+++ linux-2.6/arch/x86/include/asm/smp.h
@@ -164,6 +164,7 @@ int wbinvd_on_all_cpus(void);
 
 void native_send_call_func_ipi(const struct cpumask *mask);
 void native_send_call_func_single_ipi(int cpu);
+void x86_idle_thread_init(unsigned int cpu, struct task_struct *idle);
 
 void smp_store_cpu_info(int id);
 #define cpu_physical_id(cpu)	per_cpu(x86_cpu_to_apicid, cpu)
Index: linux-2.6/arch/x86/kernel/smpboot.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/smpboot.c
+++ linux-2.6/arch/x86/kernel/smpboot.c
@@ -76,20 +76,8 @@
 /* State of each CPU */
 DEFINE_PER_CPU(int, cpu_state) = { 0 };
 
-/* Store all idle threads, this can be reused instead of creating
-* a new thread. Also avoids complicated thread destroy functionality
-* for idle threads.
-*/
 #ifdef CONFIG_HOTPLUG_CPU
 /*
- * Needed only for CONFIG_HOTPLUG_CPU because __cpuinitdata is
- * removed after init for !CONFIG_HOTPLUG_CPU.
- */
-static DEFINE_PER_CPU(struct task_struct *, idle_thread_array);
-#define get_idle_for_cpu(x)      (per_cpu(idle_thread_array, x))
-#define set_idle_for_cpu(x, p)   (per_cpu(idle_thread_array, x) = (p))
-
-/*
  * We need this for trampoline_base protection from concurrent accesses when
  * off- and onlining cores wildly.
  */
@@ -97,20 +85,16 @@ static DEFINE_MUTEX(x86_cpu_hotplug_driv
 
 void cpu_hotplug_driver_lock(void)
 {
-        mutex_lock(&x86_cpu_hotplug_driver_mutex);
+	mutex_lock(&x86_cpu_hotplug_driver_mutex);
 }
 
 void cpu_hotplug_driver_unlock(void)
 {
-        mutex_unlock(&x86_cpu_hotplug_driver_mutex);
+	mutex_unlock(&x86_cpu_hotplug_driver_mutex);
 }
 
 ssize_t arch_cpu_probe(const char *buf, size_t count) { return -1; }
 ssize_t arch_cpu_release(const char *buf, size_t count) { return -1; }
-#else
-static struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ;
-#define get_idle_for_cpu(x)      (idle_thread_array[(x)])
-#define set_idle_for_cpu(x, p)   (idle_thread_array[(x)] = (p))
 #endif
 
 /* Number of siblings per CPU package */
@@ -618,22 +602,6 @@ wakeup_secondary_cpu_via_init(int phys_a
 	return (send_status | accept_status);
 }
 
-struct create_idle {
-	struct work_struct work;
-	struct task_struct *idle;
-	struct completion done;
-	int cpu;
-};
-
-static void __cpuinit do_fork_idle(struct work_struct *work)
-{
-	struct create_idle *c_idle =
-		container_of(work, struct create_idle, work);
-
-	c_idle->idle = fork_idle(c_idle->cpu);
-	complete(&c_idle->done);
-}
-
 /* reduce the number of lines printed when booting a large cpu count system */
 static void __cpuinit announce_cpu(int cpu, int apicid)
 {
@@ -660,58 +628,31 @@ static void __cpuinit announce_cpu(int c
  * Returns zero if CPU booted OK, else error code from
  * ->wakeup_secondary_cpu.
  */
-static int __cpuinit do_boot_cpu(int apicid, int cpu)
+static int __cpuinit do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
 {
 	unsigned long boot_error = 0;
 	unsigned long start_ip;
 	int timeout;
-	struct create_idle c_idle = {
-		.cpu	= cpu,
-		.done	= COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
-	};
-
-	INIT_WORK_ONSTACK(&c_idle.work, do_fork_idle);
 
 	alternatives_smp_switch(1);
 
-	c_idle.idle = get_idle_for_cpu(cpu);
-
-	/*
-	 * We can't use kernel_thread since we must avoid to
-	 * reschedule the child.
-	 */
-	if (c_idle.idle) {
-		c_idle.idle->thread.sp = (unsigned long) (((struct pt_regs *)
-			(THREAD_SIZE +  task_stack_page(c_idle.idle))) - 1);
-		init_idle(c_idle.idle, cpu);
-		goto do_rest;
-	}
+	idle->thread.sp = (unsigned long) (((struct pt_regs *)
+			  (THREAD_SIZE +  task_stack_page(idle))) - 1);
+	per_cpu(current_task, cpu) = idle;
 
-	schedule_work(&c_idle.work);
-	wait_for_completion(&c_idle.done);
-
-	if (IS_ERR(c_idle.idle)) {
-		printk("failed fork for CPU %d\n", cpu);
-		destroy_work_on_stack(&c_idle.work);
-		return PTR_ERR(c_idle.idle);
-	}
-
-	set_idle_for_cpu(cpu, c_idle.idle);
-do_rest:
-	per_cpu(current_task, cpu) = c_idle.idle;
 #ifdef CONFIG_X86_32
 	/* Stack for startup_32 can be just as for start_secondary onwards */
 	irq_ctx_init(cpu);
 #else
-	clear_tsk_thread_flag(c_idle.idle, TIF_FORK);
+	clear_tsk_thread_flag(idle, TIF_FORK);
 	initial_gs = per_cpu_offset(cpu);
 	per_cpu(kernel_stack, cpu) =
-		(unsigned long)task_stack_page(c_idle.idle) -
+		(unsigned long)task_stack_page(idle) -
 		KERNEL_STACK_OFFSET + THREAD_SIZE;
 #endif
 	early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
 	initial_code = (unsigned long)start_secondary;
-	stack_start  = c_idle.idle->thread.sp;
+	stack_start  = idle->thread.sp;
 
 	/* start_ip had better be page-aligned! */
 	start_ip = trampoline_address();
@@ -813,8 +754,6 @@ do_rest:
 		 */
 		smpboot_restore_warm_reset_vector();
 	}
-
-	destroy_work_on_stack(&c_idle.work);
 	return boot_error;
 }
 
@@ -851,7 +790,7 @@ int __cpuinit native_cpu_up(unsigned int
 
 	per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
 
-	err = do_boot_cpu(apicid, cpu);
+	err = do_boot_cpu(apicid, cpu, tidle);
 	if (err) {
 		pr_debug("do_boot_cpu failed %d\n", err);
 		return -EIO;
Index: linux-2.6/arch/x86/xen/smp.c
===================================================================
--- linux-2.6.orig/arch/x86/xen/smp.c
+++ linux-2.6/arch/x86/xen/smp.c
@@ -250,18 +250,8 @@ static void __init xen_smp_prepare_cpus(
 		set_cpu_possible(cpu, false);
 	}
 
-	for_each_possible_cpu (cpu) {
-		struct task_struct *idle;
-
-		if (cpu == 0)
-			continue;
-
-		idle = fork_idle(cpu);
-		if (IS_ERR(idle))
-			panic("failed fork for CPU %d", cpu);
-
+	for_each_possible_cpu(cpu)
 		set_cpu_present(cpu, true);
-	}
 }
 
 static int __cpuinit
@@ -331,9 +321,8 @@ cpu_initialize_context(unsigned int cpu,
 	return 0;
 }
 
-static int __cpuinit xen_cpu_up(unsigned int cpu, struct task_struct *tidle)
+static int __cpuinit xen_cpu_up(unsigned int cpu, struct task_struct *idle)
 {
-	struct task_struct *idle = idle_task(cpu);
 	int rc;
 
 	per_cpu(current_task, cpu) = idle;



^ permalink raw reply	[flat|nested] 75+ messages in thread

* [patch 08/18] ia64: Use generic idle thread allocation
  2012-04-20 13:05 [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
                   ` (6 preceding siblings ...)
  2012-04-20 13:05 ` [patch 07/18] powerpc: " Thomas Gleixner
@ 2012-04-20 13:05 ` Thomas Gleixner
  2012-04-28  9:08   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
  2012-04-20 13:05 ` [patch 09/18] arm: " Thomas Gleixner
                   ` (19 subsequent siblings)
  27 siblings, 1 reply; 75+ messages in thread
From: Thomas Gleixner @ 2012-04-20 13:05 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Peter Zijlstra, Rusty Russell, Paul E. McKenney,
	Ingo Molnar, Srivatsa S. Bhat, Tony Luck

[-- Attachment #1: ia64-use-generic-idle-thread-allocation.patch --]
[-- Type: text/plain, Size: 3210 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Tony Luck <tony.luck@intel.com>
---
 arch/ia64/Kconfig          |    1 
 arch/ia64/kernel/smpboot.c |   61 ++-------------------------------------------
 2 files changed, 4 insertions(+), 58 deletions(-)

Index: linux-2.6/arch/ia64/Kconfig
===================================================================
--- linux-2.6.orig/arch/ia64/Kconfig
+++ linux-2.6/arch/ia64/Kconfig
@@ -33,6 +33,7 @@ config IA64
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select GENERIC_IOMAP
+	select GENERIC_SMP_IDLE_THREAD
 	default y
 	help
 	  The Itanium Processor Family is Intel's 64-bit successor to
Index: linux-2.6/arch/ia64/kernel/smpboot.c
===================================================================
--- linux-2.6.orig/arch/ia64/kernel/smpboot.c
+++ linux-2.6/arch/ia64/kernel/smpboot.c
@@ -75,13 +75,6 @@
 #endif
 
 /*
- * Store all idle threads, this can be reused instead of creating
- * a new thread. Also avoids complicated thread destroy functionality
- * for idle threads.
- */
-struct task_struct *idle_thread_array[NR_CPUS];
-
-/*
  * Global array allocated for NR_CPUS at boot time
  */
 struct sal_to_os_boot sal_boot_rendez_state[NR_CPUS];
@@ -94,13 +87,7 @@ struct sal_to_os_boot *sal_state_for_boo
 
 #define set_brendez_area(x) (sal_state_for_booting_cpu = &sal_boot_rendez_state[(x)]);
 
-#define get_idle_for_cpu(x)		(idle_thread_array[(x)])
-#define set_idle_for_cpu(x,p)	(idle_thread_array[(x)] = (p))
-
 #else
-
-#define get_idle_for_cpu(x)		(NULL)
-#define set_idle_for_cpu(x,p)
 #define set_brendez_area(x)
 #endif
 
@@ -480,54 +467,12 @@ struct pt_regs * __cpuinit idle_regs(str
 	return NULL;
 }
 
-struct create_idle {
-	struct work_struct work;
-	struct task_struct *idle;
-	struct completion done;
-	int cpu;
-};
-
-void __cpuinit
-do_fork_idle(struct work_struct *work)
-{
-	struct create_idle *c_idle =
-		container_of(work, struct create_idle, work);
-
-	c_idle->idle = fork_idle(c_idle->cpu);
-	complete(&c_idle->done);
-}
-
 static int __cpuinit
-do_boot_cpu (int sapicid, int cpu)
+do_boot_cpu (int sapicid, int cpu, struct task_struct *idle)
 {
 	int timeout;
-	struct create_idle c_idle = {
-		.work = __WORK_INITIALIZER(c_idle.work, do_fork_idle),
-		.cpu	= cpu,
-		.done	= COMPLETION_INITIALIZER(c_idle.done),
-	};
-
-	/*
-	 * We can't use kernel_thread since we must avoid to
-	 * reschedule the child.
-	 */
- 	c_idle.idle = get_idle_for_cpu(cpu);
- 	if (c_idle.idle) {
-		init_idle(c_idle.idle, cpu);
- 		goto do_rest;
-	}
-
-	schedule_work(&c_idle.work);
-	wait_for_completion(&c_idle.done);
-
-	if (IS_ERR(c_idle.idle))
-		panic("failed fork for CPU %d", cpu);
-
-	set_idle_for_cpu(cpu, c_idle.idle);
-
-do_rest:
-	task_for_booting_cpu = c_idle.idle;
 
+	task_for_booting_cpu = idle;
 	Dprintk("Sending wakeup vector %lu to AP 0x%x/0x%x.\n", ap_wakeup_vector, cpu, sapicid);
 
 	set_brendez_area(cpu);
@@ -811,7 +756,7 @@ __cpu_up(unsigned int cpu, struct task_s
 
 	per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
 	/* Processor goes to start_secondary(), sets online flag */
-	ret = do_boot_cpu(sapicid, cpu);
+	ret = do_boot_cpu(sapicid, cpu, tidle);
 	if (ret < 0)
 		return ret;
 



^ permalink raw reply	[flat|nested] 75+ messages in thread

* [patch 09/18] arm: Use generic idle thread allocation
  2012-04-20 13:05 [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
                   ` (7 preceding siblings ...)
  2012-04-20 13:05 ` [patch 08/18] ia64: " Thomas Gleixner
@ 2012-04-20 13:05 ` Thomas Gleixner
  2012-04-28  9:09   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
  2012-04-20 13:05 ` [patch 11/18] hexagon: " Thomas Gleixner
                   ` (18 subsequent siblings)
  27 siblings, 1 reply; 75+ messages in thread
From: Thomas Gleixner @ 2012-04-20 13:05 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Peter Zijlstra, Rusty Russell, Paul E. McKenney,
	Ingo Molnar, Srivatsa S. Bhat, Russell King

[-- Attachment #1: arm-use-generic-idle-thread-allocation.patch --]
[-- Type: text/plain, Size: 2430 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Russell King <linux@arm.linux.org.uk>
---
 arch/arm/Kconfig           |    1 +
 arch/arm/include/asm/cpu.h |    1 -
 arch/arm/kernel/smp.c      |   26 +-------------------------
 3 files changed, 2 insertions(+), 26 deletions(-)

Index: linux-2.6/arch/arm/Kconfig
===================================================================
--- linux-2.6.orig/arch/arm/Kconfig
+++ linux-2.6/arch/arm/Kconfig
@@ -34,6 +34,7 @@ config ARM
 	select CPU_PM if (SUSPEND || CPU_IDLE)
 	select GENERIC_PCI_IOMAP
 	select HAVE_BPF_JIT if NET
+	select GENERIC_SMP_IDLE_THREAD
 	help
 	  The ARM series is a line of low-power-consumption RISC chip designs
 	  licensed by ARM Ltd and targeted at embedded applications and
Index: linux-2.6/arch/arm/include/asm/cpu.h
===================================================================
--- linux-2.6.orig/arch/arm/include/asm/cpu.h
+++ linux-2.6/arch/arm/include/asm/cpu.h
@@ -16,7 +16,6 @@
 struct cpuinfo_arm {
 	struct cpu	cpu;
 #ifdef CONFIG_SMP
-	struct task_struct *idle;
 	unsigned int	loops_per_jiffy;
 #endif
 };
Index: linux-2.6/arch/arm/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/arm/kernel/smp.c
+++ linux-2.6/arch/arm/kernel/smp.c
@@ -60,32 +60,11 @@ enum ipi_msg_type {
 
 static DECLARE_COMPLETION(cpu_running);
 
-int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
 {
-	struct cpuinfo_arm *ci = &per_cpu(cpu_data, cpu);
-	struct task_struct *idle = ci->idle;
 	int ret;
 
 	/*
-	 * Spawn a new process manually, if not already done.
-	 * Grab a pointer to its task struct so we can mess with it
-	 */
-	if (!idle) {
-		idle = fork_idle(cpu);
-		if (IS_ERR(idle)) {
-			printk(KERN_ERR "CPU%u: fork() failed\n", cpu);
-			return PTR_ERR(idle);
-		}
-		ci->idle = idle;
-	} else {
-		/*
-		 * Since this idle thread is being re-used, call
-		 * init_idle() to reinitialize the thread structure.
-		 */
-		init_idle(idle, cpu);
-	}
-
-	/*
 	 * We need to tell the secondary core where to find
 	 * its stack and the page tables.
 	 */
@@ -318,9 +297,6 @@ void __init smp_cpus_done(unsigned int m
 
 void __init smp_prepare_boot_cpu(void)
 {
-	unsigned int cpu = smp_processor_id();
-
-	per_cpu(cpu_data, cpu).idle = current;
 }
 
 void __init smp_prepare_cpus(unsigned int max_cpus)



^ permalink raw reply	[flat|nested] 75+ messages in thread

* [patch 10/18] mips: Use generic idle thread allocation
  2012-04-20 13:05 [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
                   ` (9 preceding siblings ...)
  2012-04-20 13:05 ` [patch 11/18] hexagon: " Thomas Gleixner
@ 2012-04-20 13:05 ` Thomas Gleixner
  2012-04-28  9:10   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
  2012-04-20 13:05 ` [patch 12/18] s390: " Thomas Gleixner
                   ` (16 subsequent siblings)
  27 siblings, 1 reply; 75+ messages in thread
From: Thomas Gleixner @ 2012-04-20 13:05 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Peter Zijlstra, Rusty Russell, Paul E. McKenney,
	Ingo Molnar, Srivatsa S. Bhat, Ralf Baechle

[-- Attachment #1: mips-use-generic-idle-thread-allocation.patch --]
[-- Type: text/plain, Size: 2449 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Ralf Baechle <ralf@linux-mips.org>
---
 arch/mips/Kconfig      |    1 
 arch/mips/kernel/smp.c |   54 -------------------------------------------------
 2 files changed, 2 insertions(+), 53 deletions(-)

Index: linux-2.6/arch/mips/Kconfig
===================================================================
--- linux-2.6.orig/arch/mips/Kconfig
+++ linux-2.6/arch/mips/Kconfig
@@ -29,6 +29,7 @@ config MIPS
 	select HAVE_MEMBLOCK
 	select HAVE_MEMBLOCK_NODE_MAP
 	select ARCH_DISCARD_MEMBLOCK
+	select GENERIC_SMP_IDLE_THREAD
 
 menu "Machine selection"
 
Index: linux-2.6/arch/mips/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/mips/kernel/smp.c
+++ linux-2.6/arch/mips/kernel/smp.c
@@ -186,61 +186,9 @@ void __devinit smp_prepare_boot_cpu(void
 	cpu_set(0, cpu_callin_map);
 }
 
-/*
- * Called once for each "cpu_possible(cpu)".  Needs to spin up the cpu
- * and keep control until "cpu_online(cpu)" is set.  Note: cpu is
- * physical, not logical.
- */
-static struct task_struct *cpu_idle_thread[NR_CPUS];
-
-struct create_idle {
-	struct work_struct work;
-	struct task_struct *idle;
-	struct completion done;
-	int cpu;
-};
-
-static void __cpuinit do_fork_idle(struct work_struct *work)
-{
-	struct create_idle *c_idle =
-		container_of(work, struct create_idle, work);
-
-	c_idle->idle = fork_idle(c_idle->cpu);
-	complete(&c_idle->done);
-}
-
 int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
-	struct task_struct *idle;
-
-	/*
-	 * Processor goes to start_secondary(), sets online flag
-	 * The following code is purely to make sure
-	 * Linux can schedule processes on this slave.
-	 */
-	if (!cpu_idle_thread[cpu]) {
-		/*
-		 * Schedule work item to avoid forking user task
-		 * Ported from arch/x86/kernel/smpboot.c
-		 */
-		struct create_idle c_idle = {
-			.cpu    = cpu,
-			.done   = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
-		};
-
-		INIT_WORK_ONSTACK(&c_idle.work, do_fork_idle);
-		schedule_work(&c_idle.work);
-		wait_for_completion(&c_idle.done);
-		idle = cpu_idle_thread[cpu] = c_idle.idle;
-
-		if (IS_ERR(idle))
-			panic(KERN_ERR "Fork failed for CPU %d", cpu);
-	} else {
-		idle = cpu_idle_thread[cpu];
-		init_idle(idle, cpu);
-	}
-
-	mp_ops->boot_secondary(cpu, idle);
+	mp_ops->boot_secondary(cpu, tidle);
 
 	/*
 	 * Trust is futile.  We should really have timeouts ...



^ permalink raw reply	[flat|nested] 75+ messages in thread

* [patch 11/18] hexagon: Use generic idle thread allocation
  2012-04-20 13:05 [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
                   ` (8 preceding siblings ...)
  2012-04-20 13:05 ` [patch 09/18] arm: " Thomas Gleixner
@ 2012-04-20 13:05 ` Thomas Gleixner
  2012-04-24 16:47   ` Richard Kuo
  2012-04-28  9:10   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
  2012-04-20 13:05 ` [patch 10/18] mips: " Thomas Gleixner
                   ` (17 subsequent siblings)
  27 siblings, 2 replies; 75+ messages in thread
From: Thomas Gleixner @ 2012-04-20 13:05 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Peter Zijlstra, Rusty Russell, Paul E. McKenney,
	Ingo Molnar, Srivatsa S. Bhat, Richard Kuo

[-- Attachment #1: hexagon-use-generic-idle-thread-allocation.patch --]
[-- Type: text/plain, Size: 1514 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Richard Kuo <rkuo@codeaurora.org>
---
 arch/hexagon/Kconfig      |    1 +
 arch/hexagon/kernel/smp.c |   11 ++---------
 2 files changed, 3 insertions(+), 9 deletions(-)

Index: linux-2.6/arch/hexagon/Kconfig
===================================================================
--- linux-2.6.orig/arch/hexagon/Kconfig
+++ linux-2.6/arch/hexagon/Kconfig
@@ -27,6 +27,7 @@ config HEXAGON
 	select HAVE_ARCH_TRACEHOOK
 	select NO_IOPORT
 	select GENERIC_IOMAP
+	select GENERIC_SMP_IDLE_THREAD
 	# mostly generic routines, with some accelerated ones
 	---help---
 	  Qualcomm Hexagon is a processor architecture designed for high
Index: linux-2.6/arch/hexagon/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/hexagon/kernel/smp.c
+++ linux-2.6/arch/hexagon/kernel/smp.c
@@ -190,18 +190,11 @@ void __cpuinit start_secondary(void)
  * maintains control until "cpu_online(cpu)" is set.
  */
 
-int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
 {
-	struct task_struct *idle;
-	struct thread_info *thread;
+	struct thread_info *thread = (struct thread_info *)idle->stack;
 	void *stack_start;
 
-	/*  Create new init task for the CPU  */
-	idle = fork_idle(cpu);
-	if (IS_ERR(idle))
-		panic(KERN_ERR "fork_idle failed\n");
-
-	thread = (struct thread_info *)idle->stack;
 	thread->cpu = cpu;
 
 	/*  Boot to the head.  */



^ permalink raw reply	[flat|nested] 75+ messages in thread

* [patch 12/18] s390: Use generic idle thread allocation
  2012-04-20 13:05 [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
                   ` (10 preceding siblings ...)
  2012-04-20 13:05 ` [patch 10/18] mips: " Thomas Gleixner
@ 2012-04-20 13:05 ` Thomas Gleixner
  2012-04-23  7:09   ` Martin Schwidefsky
  2012-04-28  9:11   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
  2012-04-20 13:05 ` [patch 13/18] blackfin: " Thomas Gleixner
                   ` (15 subsequent siblings)
  27 siblings, 2 replies; 75+ messages in thread
From: Thomas Gleixner @ 2012-04-20 13:05 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Peter Zijlstra, Rusty Russell, Paul E. McKenney,
	Ingo Molnar, Srivatsa S. Bhat, Martin Schwidefsky

[-- Attachment #1: s390-use-generic-idle-thread-allocation.patch --]
[-- Type: text/plain, Size: 2820 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
---
 arch/s390/Kconfig      |    1 +
 arch/s390/kernel/smp.c |   33 ++-------------------------------
 2 files changed, 3 insertions(+), 31 deletions(-)

Index: linux-2.6/arch/s390/Kconfig
===================================================================
--- linux-2.6.orig/arch/s390/Kconfig
+++ linux-2.6/arch/s390/Kconfig
@@ -122,6 +122,7 @@ config S390
 	select ARCH_INLINE_WRITE_UNLOCK_BH
 	select ARCH_INLINE_WRITE_UNLOCK_IRQ
 	select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE
+	select GENERIC_SMP_IDLE_THREAD
 
 config SCHED_OMIT_FRAME_POINTER
 	def_bool y
Index: linux-2.6/arch/s390/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/s390/kernel/smp.c
+++ linux-2.6/arch/s390/kernel/smp.c
@@ -85,7 +85,6 @@ enum {
 
 struct pcpu {
 	struct cpu cpu;
-	struct task_struct *idle;	/* idle process for the cpu */
 	struct _lowcore *lowcore;	/* lowcore page(s) for the cpu */
 	unsigned long async_stack;	/* async stack for the cpu */
 	unsigned long panic_stack;	/* panic stack for the cpu */
@@ -721,26 +720,9 @@ static void __cpuinit smp_start_secondar
 	cpu_idle();
 }
 
-struct create_idle {
-	struct work_struct work;
-	struct task_struct *idle;
-	struct completion done;
-	int cpu;
-};
-
-static void __cpuinit smp_fork_idle(struct work_struct *work)
-{
-	struct create_idle *c_idle;
-
-	c_idle = container_of(work, struct create_idle, work);
-	c_idle->idle = fork_idle(c_idle->cpu);
-	complete(&c_idle->done);
-}
-
 /* Upping and downing of CPUs */
 int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
-	struct create_idle c_idle;
 	struct pcpu *pcpu;
 	int rc;
 
@@ -750,22 +732,12 @@ int __cpuinit __cpu_up(unsigned int cpu,
 	if (pcpu_sigp_retry(pcpu, sigp_initial_cpu_reset, 0) !=
 	    sigp_order_code_accepted)
 		return -EIO;
-	if (!pcpu->idle) {
-		c_idle.done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done);
-		INIT_WORK_ONSTACK(&c_idle.work, smp_fork_idle);
-		c_idle.cpu = cpu;
-		schedule_work(&c_idle.work);
-		wait_for_completion(&c_idle.done);
-		if (IS_ERR(c_idle.idle))
-			return PTR_ERR(c_idle.idle);
-		pcpu->idle = c_idle.idle;
-	}
-	init_idle(pcpu->idle, cpu);
+
 	rc = pcpu_alloc_lowcore(pcpu, cpu);
 	if (rc)
 		return rc;
 	pcpu_prepare_secondary(pcpu, cpu);
-	pcpu_attach_task(pcpu, pcpu->idle);
+	pcpu_attach_task(pcpu, tidle);
 	pcpu_start_fn(pcpu, smp_start_secondary, NULL);
 	while (!cpu_online(cpu))
 		cpu_relax();
@@ -852,7 +824,6 @@ void __init smp_prepare_boot_cpu(void)
 	struct pcpu *pcpu = pcpu_devices;
 
 	boot_cpu_address = stap();
-	pcpu->idle = current;
 	pcpu->state = CPU_STATE_CONFIGURED;
 	pcpu->address = boot_cpu_address;
 	pcpu->lowcore = (struct _lowcore *)(unsigned long) store_prefix();



^ permalink raw reply	[flat|nested] 75+ messages in thread

* [patch 14/18] cris: Use generic idle thread allocation
  2012-04-20 13:05 [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
                   ` (12 preceding siblings ...)
  2012-04-20 13:05 ` [patch 13/18] blackfin: " Thomas Gleixner
@ 2012-04-20 13:05 ` Thomas Gleixner
  2012-04-23  7:57   ` Jesper Nilsson
  2012-04-28  9:12   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
  2012-04-20 13:05 ` [patch 15/18] sh: " Thomas Gleixner
                   ` (13 subsequent siblings)
  27 siblings, 2 replies; 75+ messages in thread
From: Thomas Gleixner @ 2012-04-20 13:05 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Peter Zijlstra, Rusty Russell, Paul E. McKenney,
	Ingo Molnar, Srivatsa S. Bhat, Jesper Nilsson

[-- Attachment #1: cris-use-generic-idle-thread-allocation.patch --]
[-- Type: text/plain, Size: 1718 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Jesper Nilsson <jesper.nilsson@axis.com>
---
 arch/cris/Kconfig               |    1 +
 arch/cris/arch-v32/kernel/smp.c |   12 ++----------
 2 files changed, 3 insertions(+), 10 deletions(-)

Index: linux-2.6/arch/cris/Kconfig
===================================================================
--- linux-2.6.orig/arch/cris/Kconfig
+++ linux-2.6/arch/cris/Kconfig
@@ -49,6 +49,7 @@ config CRIS
 	select HAVE_GENERIC_HARDIRQS
 	select GENERIC_IRQ_SHOW
 	select GENERIC_IOMAP
+	select GENERIC_SMP_IDLE_THREAD if ETRAX_ARCH_V32
 
 config HZ
 	int
Index: linux-2.6/arch/cris/arch-v32/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/cris/arch-v32/kernel/smp.c
+++ linux-2.6/arch/cris/arch-v32/kernel/smp.c
@@ -108,17 +108,12 @@ void __init smp_cpus_done(unsigned int m
 
 /* Bring one cpu online.*/
 static int __init
-smp_boot_one_cpu(int cpuid)
+smp_boot_one_cpu(int cpuid, struct task_struct idle)
 {
 	unsigned timeout;
-	struct task_struct *idle;
 	cpumask_t cpu_mask;
 
 	cpumask_clear(&cpu_mask);
-	idle = fork_idle(cpuid);
-	if (IS_ERR(idle))
-		panic("SMP: fork failed for CPU:%d", cpuid);
-
 	task_thread_info(idle)->cpu = cpuid;
 
 	/* Information to the CPU that is about to boot */
@@ -142,9 +137,6 @@ smp_boot_one_cpu(int cpuid)
 		barrier();
 	}
 
-	put_task_struct(idle);
-	idle = NULL;
-
 	printk(KERN_CRIT "SMP: CPU:%d is stuck.\n", cpuid);
 	return -1;
 }
@@ -209,7 +201,7 @@ unsigned long cache_decay_ticks = 1;
 
 int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
-	smp_boot_one_cpu(cpu);
+	smp_boot_one_cpu(cpu, tidle);
 	return cpu_online(cpu) ? 0 : -ENOSYS;
 }
 



^ permalink raw reply	[flat|nested] 75+ messages in thread

* [patch 13/18] blackfin: Use generic idle thread allocation
  2012-04-20 13:05 [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
                   ` (11 preceding siblings ...)
  2012-04-20 13:05 ` [patch 12/18] s390: " Thomas Gleixner
@ 2012-04-20 13:05 ` Thomas Gleixner
  2012-04-28  9:13   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
  2012-04-20 13:05 ` [patch 14/18] cris: " Thomas Gleixner
                   ` (14 subsequent siblings)
  27 siblings, 1 reply; 75+ messages in thread
From: Thomas Gleixner @ 2012-04-20 13:05 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Peter Zijlstra, Rusty Russell, Paul E. McKenney,
	Ingo Molnar, Srivatsa S. Bhat, Mike Frysinger

[-- Attachment #1: blackfin-use-generic-idle-thread-allocation.patch --]
[-- Type: text/plain, Size: 1527 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Mike Frysinger <vapier@gentoo.org>
---
 arch/blackfin/Kconfig           |    1 +
 arch/blackfin/mach-common/smp.c |   19 +------------------
 2 files changed, 2 insertions(+), 18 deletions(-)

Index: linux-2.6/arch/blackfin/Kconfig
===================================================================
--- linux-2.6.orig/arch/blackfin/Kconfig
+++ linux-2.6/arch/blackfin/Kconfig
@@ -37,6 +37,7 @@ config BLACKFIN
 	select GENERIC_IRQ_PROBE
 	select IRQ_PER_CPU if SMP
 	select HAVE_NMI_WATCHDOG if NMI_WATCHDOG
+	select GENERIC_SMP_IDLE_THREAD
 
 config GENERIC_CSUM
 	def_bool y
Index: linux-2.6/arch/blackfin/mach-common/smp.c
===================================================================
--- linux-2.6.orig/arch/blackfin/mach-common/smp.c
+++ linux-2.6/arch/blackfin/mach-common/smp.c
@@ -340,27 +340,10 @@ void smp_send_stop(void)
 	return;
 }
 
-int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
 {
 	int ret;
-	struct blackfin_cpudata *ci = &per_cpu(cpu_data, cpu);
-	struct task_struct *idle = ci->idle;
 
-	if (idle) {
-		free_task(idle);
-		idle = NULL;
-	}
-
-	if (!idle) {
-		idle = fork_idle(cpu);
-		if (IS_ERR(idle)) {
-			printk(KERN_ERR "CPU%u: fork() failed\n", cpu);
-			return PTR_ERR(idle);
-		}
-		ci->idle = idle;
-	} else {
-		init_idle(idle, cpu);
-	}
 	secondary_stack = task_stack_page(idle) + THREAD_SIZE;
 
 	ret = platform_boot_secondary(cpu, idle);



^ permalink raw reply	[flat|nested] 75+ messages in thread

* [patch 15/18] sh: Use generic idle thread allocation
  2012-04-20 13:05 [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
                   ` (13 preceding siblings ...)
  2012-04-20 13:05 ` [patch 14/18] cris: " Thomas Gleixner
@ 2012-04-20 13:05 ` Thomas Gleixner
  2012-04-21  3:18   ` Paul Mundt
  2012-04-28  9:14   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
  2012-04-20 13:05 ` [patch 16/18] alpha: " Thomas Gleixner
                   ` (12 subsequent siblings)
  27 siblings, 2 replies; 75+ messages in thread
From: Thomas Gleixner @ 2012-04-20 13:05 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Peter Zijlstra, Rusty Russell, Paul E. McKenney,
	Ingo Molnar, Srivatsa S. Bhat, Paul Mundt

[-- Attachment #1: sh-use-generic-idle-thread-allocation.patch --]
[-- Type: text/plain, Size: 1953 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Paul Mundt <lethal@linux-sh.org>
---
 arch/sh/Kconfig                 |    1 +
 arch/sh/include/asm/processor.h |    4 ----
 arch/sh/kernel/smp.c            |   14 +-------------
 3 files changed, 2 insertions(+), 17 deletions(-)

Index: linux-2.6/arch/sh/Kconfig
===================================================================
--- linux-2.6.orig/arch/sh/Kconfig
+++ linux-2.6/arch/sh/Kconfig
@@ -28,6 +28,7 @@ config SUPERH
 	select RTC_LIB
 	select GENERIC_ATOMIC64
 	select GENERIC_IRQ_SHOW
+	select GENERIC_SMP_IDLE_THREAD
 	help
 	  The SuperH is a RISC processor targeted for use in embedded systems
 	  and consumer electronics; it was also used in the Sega Dreamcast
Index: linux-2.6/arch/sh/include/asm/processor.h
===================================================================
--- linux-2.6.orig/arch/sh/include/asm/processor.h
+++ linux-2.6/arch/sh/include/asm/processor.h
@@ -85,10 +85,6 @@ struct sh_cpuinfo {
 	struct tlb_info itlb;
 	struct tlb_info dtlb;
 
-#ifdef CONFIG_SMP
-	struct task_struct *idle;
-#endif
-
 	unsigned int phys_bits;
 	unsigned long flags;
 } __attribute__ ((aligned(L1_CACHE_BYTES)));
Index: linux-2.6/arch/sh/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/sh/kernel/smp.c
+++ linux-2.6/arch/sh/kernel/smp.c
@@ -220,22 +220,10 @@ extern struct {
 	void *thread_info;
 } stack_start;
 
-int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tsk)
 {
-	struct task_struct *tsk;
 	unsigned long timeout;
 
-	tsk = cpu_data[cpu].idle;
-	if (!tsk) {
-		tsk = fork_idle(cpu);
-		if (IS_ERR(tsk)) {
-			pr_err("Failed forking idle task for cpu %d\n", cpu);
-			return PTR_ERR(tsk);
-		}
-
-		cpu_data[cpu].idle = tsk;
-	}
-
 	per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
 
 	/* Fill in data in head.S for secondary cpus */



^ permalink raw reply	[flat|nested] 75+ messages in thread

* [patch 16/18] alpha: Use generic idle thread allocation
  2012-04-20 13:05 [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
                   ` (14 preceding siblings ...)
  2012-04-20 13:05 ` [patch 15/18] sh: " Thomas Gleixner
@ 2012-04-20 13:05 ` Thomas Gleixner
  2012-04-28  9:15   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
  2012-04-20 13:05 ` [patch 17/18] parisc: " Thomas Gleixner
                   ` (11 subsequent siblings)
  27 siblings, 1 reply; 75+ messages in thread
From: Thomas Gleixner @ 2012-04-20 13:05 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Peter Zijlstra, Rusty Russell, Paul E. McKenney,
	Ingo Molnar, Srivatsa S. Bhat, Matt Turner

[-- Attachment #1: alpha-use-generic-idle-thread-allocation.patch --]
[-- Type: text/plain, Size: 1999 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Matt Turner <mattst88@gmail.com>
---
 arch/alpha/Kconfig      |    1 +
 arch/alpha/kernel/smp.c |   18 ++----------------
 2 files changed, 3 insertions(+), 16 deletions(-)

Index: linux-2.6/arch/alpha/Kconfig
===================================================================
--- linux-2.6.orig/arch/alpha/Kconfig
+++ linux-2.6/arch/alpha/Kconfig
@@ -15,6 +15,7 @@ config ALPHA
 	select GENERIC_IRQ_SHOW
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
+	select GENERIC_SMP_IDLE_THREAD
 	help
 	  The Alpha is a 64-bit general-purpose processor designed and
 	  marketed by the Digital Equipment Corporation of blessed memory,
Index: linux-2.6/arch/alpha/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/alpha/kernel/smp.c
+++ linux-2.6/arch/alpha/kernel/smp.c
@@ -357,24 +357,10 @@ secondary_cpu_start(int cpuid, struct ta
  * Bring one cpu online.
  */
 static int __cpuinit
-smp_boot_one_cpu(int cpuid)
+smp_boot_one_cpu(int cpuid, struct task_struct *idle)
 {
-	struct task_struct *idle;
 	unsigned long timeout;
 
-	/* Cook up an idler for this guy.  Note that the address we
-	   give to kernel_thread is irrelevant -- it's going to start
-	   where HWRPB.CPU_restart says to start.  But this gets all
-	   the other task-y sort of data structures set up like we
-	   wish.  We can't use kernel_thread since we must avoid
-	   rescheduling the child.  */
-	idle = fork_idle(cpuid);
-	if (IS_ERR(idle))
-		panic("failed fork for CPU %d", cpuid);
-
-	DBGS(("smp_boot_one_cpu: CPU %d state 0x%lx flags 0x%lx\n",
-	      cpuid, idle->state, idle->flags));
-
 	/* Signal the secondary to wait a moment.  */
 	smp_secondary_alive = -1;
 
@@ -489,7 +475,7 @@ smp_prepare_boot_cpu(void)
 int __cpuinit
 __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
-	smp_boot_one_cpu(cpu);
+	smp_boot_one_cpu(cpu, tidle);
 
 	return cpu_online(cpu) ? 0 : -ENOSYS;
 }



^ permalink raw reply	[flat|nested] 75+ messages in thread

* [patch 18/18] sparc: Use generic idle thread allocation
  2012-04-20 13:05 [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
                   ` (16 preceding siblings ...)
  2012-04-20 13:05 ` [patch 17/18] parisc: " Thomas Gleixner
@ 2012-04-20 13:05 ` Thomas Gleixner
  2012-04-22 19:52   ` David Miller
  2012-04-28  9:15   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
  2012-04-20 13:16 ` [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
                   ` (9 subsequent siblings)
  27 siblings, 2 replies; 75+ messages in thread
From: Thomas Gleixner @ 2012-04-20 13:05 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Peter Zijlstra, Rusty Russell, Paul E. McKenney,
	Ingo Molnar, Srivatsa S. Bhat, David S. Miller

[-- Attachment #1: sparc-use-generic-idle-thread-allocation.patch --]
[-- Type: text/plain, Size: 6439 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: "David S. Miller" <davem@davemloft.net>
---
 arch/sparc/Kconfig            |    1 +
 arch/sparc/include/asm/leon.h |    5 +++--
 arch/sparc/kernel/leon_smp.c  |    9 ++-------
 arch/sparc/kernel/smp_32.c    |   10 +++++-----
 arch/sparc/kernel/smp_64.c    |   10 +++-------
 arch/sparc/kernel/sun4d_smp.c |    8 ++------
 arch/sparc/kernel/sun4m_smp.c |    7 ++-----
 7 files changed, 18 insertions(+), 32 deletions(-)

Index: linux-2.6/arch/sparc/Kconfig
===================================================================
--- linux-2.6.orig/arch/sparc/Kconfig
+++ linux-2.6/arch/sparc/Kconfig
@@ -30,6 +30,7 @@ config SPARC
 	select USE_GENERIC_SMP_HELPERS if SMP
 	select GENERIC_PCI_IOMAP
 	select HAVE_NMI_WATCHDOG if SPARC64
+	select GENERIC_SMP_IDLE_THREAD
 
 config SPARC32
 	def_bool !64BIT
Index: linux-2.6/arch/sparc/include/asm/leon.h
===================================================================
--- linux-2.6.orig/arch/sparc/include/asm/leon.h
+++ linux-2.6/arch/sparc/include/asm/leon.h
@@ -315,6 +315,7 @@ struct leon2_cacheregs {
 #include <linux/interrupt.h>
 
 struct device_node;
+struct task_struct;
 extern unsigned int leon_build_device_irq(unsigned int real_irq,
 					   irq_flow_handler_t flow_handler,
 					   const char *name, int do_ack);
@@ -344,7 +345,7 @@ extern int leon_smp_nrcpus(void);
 extern void leon_clear_profile_irq(int cpu);
 extern void leon_smp_done(void);
 extern void leon_boot_cpus(void);
-extern int leon_boot_one_cpu(int i);
+extern int leon_boot_one_cpu(int i, struct task_struct *);
 void leon_init_smp(void);
 extern void cpu_idle(void);
 extern void init_IRQ(void);
@@ -380,7 +381,7 @@ extern int leon_ipi_irq;
 #define init_leon() do {} while (0)
 #define leon_smp_done() do {} while (0)
 #define leon_boot_cpus() do {} while (0)
-#define leon_boot_one_cpu(i) 1
+#define leon_boot_one_cpu(i, t) 1
 #define leon_init_smp() do {} while (0)
 
 #endif /* !defined(CONFIG_SPARC_LEON) */
Index: linux-2.6/arch/sparc/kernel/leon_smp.c
===================================================================
--- linux-2.6.orig/arch/sparc/kernel/leon_smp.c
+++ linux-2.6/arch/sparc/kernel/leon_smp.c
@@ -201,16 +201,11 @@ void __init leon_boot_cpus(void)
 
 }
 
-int __cpuinit leon_boot_one_cpu(int i)
+int __cpuinit leon_boot_one_cpu(int i, struct task_struct *idle)
 {
-
-	struct task_struct *p;
 	int timeout;
 
-	/* Cook up an idler for this guy. */
-	p = fork_idle(i);
-
-	current_set[i] = task_thread_info(p);
+	current_set[i] = task_thread_info(idle);
 
 	/* See trampoline.S:leon_smp_cpu_startup for details...
 	 * Initialize the contexts table
Index: linux-2.6/arch/sparc/kernel/smp_32.c
===================================================================
--- linux-2.6.orig/arch/sparc/kernel/smp_32.c
+++ linux-2.6/arch/sparc/kernel/smp_32.c
@@ -413,8 +413,8 @@ void __init smp_prepare_boot_cpu(void)
 
 int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
-	extern int __cpuinit smp4m_boot_one_cpu(int);
-	extern int __cpuinit smp4d_boot_one_cpu(int);
+	extern int __cpuinit smp4m_boot_one_cpu(int, struct task_struct *);
+	extern int __cpuinit smp4d_boot_one_cpu(int, struct task_struct *);
 	int ret=0;
 
 	switch(sparc_cpu_model) {
@@ -427,13 +427,13 @@ int __cpuinit __cpu_up(unsigned int cpu,
 		BUG();
 		break;
 	case sun4m:
-		ret = smp4m_boot_one_cpu(cpu);
+		ret = smp4m_boot_one_cpu(cpu, tidle);
 		break;
 	case sun4d:
-		ret = smp4d_boot_one_cpu(cpu);
+		ret = smp4d_boot_one_cpu(cpu, tidle);
 		break;
 	case sparc_leon:
-		ret = leon_boot_one_cpu(cpu);
+		ret = leon_boot_one_cpu(cpu, tidle);
 		break;
 	case sun4e:
 		printk("SUN4E\n");
Index: linux-2.6/arch/sparc/kernel/smp_64.c
===================================================================
--- linux-2.6.orig/arch/sparc/kernel/smp_64.c
+++ linux-2.6/arch/sparc/kernel/smp_64.c
@@ -343,21 +343,17 @@ extern unsigned long sparc64_cpu_startup
  */
 static struct thread_info *cpu_new_thread = NULL;
 
-static int __cpuinit smp_boot_one_cpu(unsigned int cpu)
+static int __cpuinit smp_boot_one_cpu(unsigned int cpu, struct task_struct *idle)
 {
 	unsigned long entry =
 		(unsigned long)(&sparc64_cpu_startup);
 	unsigned long cookie =
 		(unsigned long)(&cpu_new_thread);
-	struct task_struct *p;
 	void *descr = NULL;
 	int timeout, ret;
 
-	p = fork_idle(cpu);
-	if (IS_ERR(p))
-		return PTR_ERR(p);
 	callin_flag = 0;
-	cpu_new_thread = task_thread_info(p);
+	cpu_new_thread = task_thread_info(idle);
 
 	if (tlb_type == hypervisor) {
 #if defined(CONFIG_SUN_LDOMS) && defined(CONFIG_HOTPLUG_CPU)
@@ -1229,7 +1225,7 @@ void __devinit smp_fill_in_sib_core_maps
 
 int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
-	int ret = smp_boot_one_cpu(cpu);
+	int ret = smp_boot_one_cpu(cpu, tidle);
 
 	if (!ret) {
 		cpumask_set_cpu(cpu, &smp_commenced_mask);
Index: linux-2.6/arch/sparc/kernel/sun4d_smp.c
===================================================================
--- linux-2.6.orig/arch/sparc/kernel/sun4d_smp.c
+++ linux-2.6/arch/sparc/kernel/sun4d_smp.c
@@ -127,18 +127,14 @@ void __init smp4d_boot_cpus(void)
 	local_flush_cache_all();
 }
 
-int __cpuinit smp4d_boot_one_cpu(int i)
+int __cpuinit smp4d_boot_one_cpu(int i, struct task_struct *idle)
 {
 	unsigned long *entry = &sun4d_cpu_startup;
-	struct task_struct *p;
 	int timeout;
 	int cpu_node;
 
 	cpu_find_by_instance(i, &cpu_node, NULL);
-	/* Cook up an idler for this guy. */
-	p = fork_idle(i);
-	current_set[i] = task_thread_info(p);
-
+	current_set[i] = task_thread_info(idle);
 	/*
 	 * Initialize the contexts table
 	 * Since the call to prom_startcpu() trashes the structure,
Index: linux-2.6/arch/sparc/kernel/sun4m_smp.c
===================================================================
--- linux-2.6.orig/arch/sparc/kernel/sun4m_smp.c
+++ linux-2.6/arch/sparc/kernel/sun4m_smp.c
@@ -91,18 +91,15 @@ void __init smp4m_boot_cpus(void)
 	local_flush_cache_all();
 }
 
-int __cpuinit smp4m_boot_one_cpu(int i)
+int __cpuinit smp4m_boot_one_cpu(int i, struct task_struct *idle)
 {
 	unsigned long *entry = &sun4m_cpu_startup;
-	struct task_struct *p;
 	int timeout;
 	int cpu_node;
 
 	cpu_find_by_mid(i, &cpu_node);
+	current_set[i] = task_thread_info(idle);
 
-	/* Cook up an idler for this guy. */
-	p = fork_idle(i);
-	current_set[i] = task_thread_info(p);
 	/* See trampoline.S for details... */
 	entry += ((i - 1) * 3);
 



^ permalink raw reply	[flat|nested] 75+ messages in thread

* [patch 17/18] parisc: Use generic idle thread allocation
  2012-04-20 13:05 [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
                   ` (15 preceding siblings ...)
  2012-04-20 13:05 ` [patch 16/18] alpha: " Thomas Gleixner
@ 2012-04-20 13:05 ` Thomas Gleixner
  2012-04-28  9:16   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
  2012-04-20 13:05 ` [patch 18/18] sparc: " Thomas Gleixner
                   ` (10 subsequent siblings)
  27 siblings, 1 reply; 75+ messages in thread
From: Thomas Gleixner @ 2012-04-20 13:05 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Peter Zijlstra, Rusty Russell, Paul E. McKenney,
	Ingo Molnar, Srivatsa S. Bhat, James E.J. Bottomley

[-- Attachment #1: parisc-use-generic-idle-thread-allocation.patch --]
[-- Type: text/plain, Size: 2258 bytes --]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: "James E.J. Bottomley" <jejb@parisc-linux.org>
---
 arch/parisc/Kconfig      |    1 +
 arch/parisc/kernel/smp.c |   23 ++---------------------
 2 files changed, 3 insertions(+), 21 deletions(-)

Index: linux-2.6/arch/parisc/Kconfig
===================================================================
--- linux-2.6.orig/arch/parisc/Kconfig
+++ linux-2.6/arch/parisc/Kconfig
@@ -17,6 +17,7 @@ config PARISC
 	select GENERIC_PCI_IOMAP
 	select IRQ_PER_CPU
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
+	select GENERIC_SMP_IDLE_THREAD
 
 	help
 	  The PA-RISC microprocessor is designed by Hewlett-Packard and used
Index: linux-2.6/arch/parisc/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/parisc/kernel/smp.c
+++ linux-2.6/arch/parisc/kernel/smp.c
@@ -334,26 +334,11 @@ void __init smp_callin(void)
 /*
  * Bring one cpu online.
  */
-int __cpuinit smp_boot_one_cpu(int cpuid)
+int __cpuinit smp_boot_one_cpu(int cpuid, struct task_struct *idle)
 {
 	const struct cpuinfo_parisc *p = &per_cpu(cpu_data, cpuid);
-	struct task_struct *idle;
 	long timeout;
 
-	/* 
-	 * Create an idle task for this CPU.  Note the address wed* give 
-	 * to kernel_thread is irrelevant -- it's going to start
-	 * where OS_BOOT_RENDEVZ vector in SAL says to start.  But
-	 * this gets all the other task-y sort of data structures set
-	 * up like we wish.   We need to pull the just created idle task 
-	 * off the run queue and stuff it into the init_tasks[] array.  
-	 * Sheesh . . .
-	 */
-
-	idle = fork_idle(cpuid);
-	if (IS_ERR(idle))
-		panic("SMP: fork failed for CPU:%d", cpuid);
-
 	task_thread_info(idle)->cpu = cpuid;
 
 	/* Let _start know what logical CPU we're booting
@@ -397,10 +382,6 @@ int __cpuinit smp_boot_one_cpu(int cpuid
 		udelay(100);
 		barrier();
 	}
-
-	put_task_struct(idle);
-	idle = NULL;
-
 	printk(KERN_CRIT "SMP: CPU:%d is stuck.\n", cpuid);
 	return -1;
 
@@ -452,7 +433,7 @@ void smp_cpus_done(unsigned int cpu_max)
 int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	if (cpu != 0 && cpu < parisc_max_cpus)
-		smp_boot_one_cpu(cpu);
+		smp_boot_one_cpu(cpu, tidle);
 
 	return cpu_online(cpu) ? 0 : -ENOSYS;
 }



^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1
  2012-04-20 13:05 [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
                   ` (17 preceding siblings ...)
  2012-04-20 13:05 ` [patch 18/18] sparc: " Thomas Gleixner
@ 2012-04-20 13:16 ` Thomas Gleixner
  2012-04-20 13:21 ` Peter Zijlstra
                   ` (8 subsequent siblings)
  27 siblings, 0 replies; 75+ messages in thread
From: Thomas Gleixner @ 2012-04-20 13:16 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, Peter Zijlstra, Rusty Russell, Paul E. McKenney,
	Ingo Molnar, Srivatsa S. Bhat

On Fri, 20 Apr 2012, Thomas Gleixner wrote:
> This converts all architectures except m32r, mn10300, tile and UM to
> the new core facility. These architecture are calling fork_idle() in
> the very early boot code in smp_prepare_cpus() for unknown reasons.
> I haven't analyzed yet, whether this is on purpose or can be moved
> over to the generic facility. It'd be nice if the responsible maintainers
> could look into that as well.

Forgot to add a diffstat for the full series.

 arch/Kconfig                    |    3 +
 arch/alpha/Kconfig              |    1 
 arch/alpha/kernel/smp.c         |   20 +-------
 arch/arm/Kconfig                |    1 
 arch/arm/include/asm/cpu.h      |    1 
 arch/arm/kernel/smp.c           |   26 ----------
 arch/blackfin/Kconfig           |    1 
 arch/blackfin/mach-common/smp.c |   19 --------
 arch/cris/Kconfig               |    1 
 arch/cris/arch-v32/kernel/smp.c |   14 +----
 arch/hexagon/Kconfig            |    1 
 arch/hexagon/kernel/smp.c       |   11 ----
 arch/ia64/Kconfig               |    1 
 arch/ia64/kernel/smpboot.c      |   63 +-------------------------
 arch/m32r/kernel/smpboot.c      |    6 --
 arch/mips/Kconfig               |    1 
 arch/mips/kernel/smp.c          |   56 -----------------------
 arch/mn10300/kernel/smp.c       |    2 
 arch/parisc/Kconfig             |    1 
 arch/parisc/kernel/smp.c        |   25 +---------
 arch/powerpc/Kconfig            |    1 
 arch/powerpc/kernel/smp.c       |   76 ++------------------------------
 arch/s390/Kconfig               |    1 
 arch/s390/include/asm/smp.h     |    2 
 arch/s390/kernel/smp.c          |   35 +-------------
 arch/sh/Kconfig                 |    1 
 arch/sh/include/asm/processor.h |    4 -
 arch/sh/kernel/smp.c            |   14 -----
 arch/sparc/Kconfig              |    1 
 arch/sparc/include/asm/leon.h   |    5 +-
 arch/sparc/kernel/leon_smp.c    |    9 ---
 arch/sparc/kernel/smp_32.c      |   12 ++---
 arch/sparc/kernel/smp_64.c      |   12 +----
 arch/sparc/kernel/sun4d_smp.c   |    8 ---
 arch/sparc/kernel/sun4m_smp.c   |    7 --
 arch/tile/kernel/smpboot.c      |    2 
 arch/um/kernel/smp.c            |    2 
 arch/x86/Kconfig                |    1 
 arch/x86/include/asm/smp.h      |   11 ++--
 arch/x86/kernel/smpboot.c       |   83 ++++------------------------------
 arch/x86/xen/smp.c              |   19 +-------
 include/linux/smp.h             |    2 
 kernel/Makefile                 |    1 
 kernel/cpu.c                    |   10 +++-
 kernel/sched/core.c             |    2 
 kernel/smpboot.c                |   95 ++++++++++++++++++++++++++++++++++++++++
 kernel/smpboot.h                |   16 ++++++
 47 files changed, 215 insertions(+), 471 deletions(-)

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1
  2012-04-20 13:05 [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
                   ` (18 preceding siblings ...)
  2012-04-20 13:16 ` [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
@ 2012-04-20 13:21 ` Peter Zijlstra
  2012-04-20 13:47   ` Thomas Gleixner
  2012-04-20 15:42   ` [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Tejun Heo
  2012-04-20 13:56 ` Srivatsa S. Bhat
                   ` (7 subsequent siblings)
  27 siblings, 2 replies; 75+ messages in thread
From: Peter Zijlstra @ 2012-04-20 13:21 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Rusty Russell, Paul E. McKenney, Ingo Molnar,
	Srivatsa S. Bhat, Tejun Heo, David Rientjes

On Fri, 2012-04-20 at 13:05 +0000, Thomas Gleixner wrote:
> This first part moves the idle thread management for non-boot cpus
> into the core. fork_idle() is called in a workqueue as it is
> implemented in a few architectures already. This is necessary when not
> all cpus are brought up by the early boot code as otherwise we would
> take a ref on the user task VM of the thread which brings the cpu up
> via the sysfs interface. 

So I was thinking about this and I think we should make that kthreadd
instead of a random workqueue thread due to all that cgroup crap. People
are wanting to place all sorts of kernel threads in cgroups and I'm
still arguing that kthreadd should not be allowed in cgroups.

Tejun, what's the status of that patch? Afaict David Rientjes's use-case
is insane and mostly a side effect of memcg broken-ness.


^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1
  2012-04-20 13:21 ` Peter Zijlstra
@ 2012-04-20 13:47   ` Thomas Gleixner
  2012-04-21  0:08     ` Suresh Siddha
  2012-04-20 15:42   ` [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Tejun Heo
  1 sibling, 1 reply; 75+ messages in thread
From: Thomas Gleixner @ 2012-04-20 13:47 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: LKML, linux-arch, Rusty Russell, Paul E. McKenney, Ingo Molnar,
	Srivatsa S. Bhat, Tejun Heo, David Rientjes

On Fri, 20 Apr 2012, Peter Zijlstra wrote:

> On Fri, 2012-04-20 at 13:05 +0000, Thomas Gleixner wrote:
> > This first part moves the idle thread management for non-boot cpus
> > into the core. fork_idle() is called in a workqueue as it is
> > implemented in a few architectures already. This is necessary when not
> > all cpus are brought up by the early boot code as otherwise we would
> > take a ref on the user task VM of the thread which brings the cpu up
> > via the sysfs interface. 
> 
> So I was thinking about this and I think we should make that kthreadd
> instead of a random workqueue thread due to all that cgroup crap. People
> are wanting to place all sorts of kernel threads in cgroups and I'm
> still arguing that kthreadd should not be allowed in cgroups.

So your fear is that the idle_thread will end up in some random cgroup
because some illdesigned user space code decided to stick kernel
threads into cgroups.

Can we please have some sanity restrictions on this cgroup muck? I
don't care when user space creates cgroups in circles, but holding the
whole kernel hostage of this madness is going too far.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1
  2012-04-20 13:05 [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
                   ` (19 preceding siblings ...)
  2012-04-20 13:21 ` Peter Zijlstra
@ 2012-04-20 13:56 ` Srivatsa S. Bhat
  2012-04-20 14:18   ` Thomas Gleixner
  2012-04-20 14:06 ` richard -rw- weinberger
                   ` (6 subsequent siblings)
  27 siblings, 1 reply; 75+ messages in thread
From: Srivatsa S. Bhat @ 2012-04-20 13:56 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Peter Zijlstra, Rusty Russell,
	Paul E. McKenney, Ingo Molnar, Nikunj A Dadhania, Steven Rostedt

Hi Thomas,

On 04/20/2012 06:35 PM, Thomas Gleixner wrote:

> Dear all,
> 
> I'm working on refactoring the SMP boot and CPU hotplug implementation.
>


Awesome!

[Unfortunately I got stuck with some other issues recently and couldn't
dedicate enough time (to come up with working code) so far :-( ]

 
> The current code has evolved over time into a conglomerate of
> warts. My main goals are to:
> 
>  - reduce the architecture code by moving repeating constructs to the
>    core
> 
>  - redesigning the handling of per cpu threads. There is no point to
>    tear down the threads just to create them again.
> 
>  - restructuring the notifier facility into a proper tree with
>    dependencies to avoid the gazillion of callbacks and moving
>    setup/teardown code into the context of the upcoming/dying cpu
> 
> The motivation behind this work is the cpu hotplug nightmare which we
> are facing in the RT kernel and the requests from several groups
> (e.g. ARM) to make hotplug more lightweight and faster.
> 
> This first part moves the idle thread management for non-boot cpus
> into the core. fork_idle() is called in a workqueue as it is
> implemented in a few architectures already. This is necessary when not
> all cpus are brought up by the early boot code as otherwise we would
> take a ref on the user task VM of the thread which brings the cpu up
> via the sysfs interface.
> 


Do you have a git tree where you have made these patches available?
That would be pretty useful, so that we can build on whatever you have
already done.. Myself and Nikunj had some initial design/ideas on reducing
the duplication in architecture code, related to managing the setting
of the cpu in the online mask, sending out CPU_STARTING notifiers etc
from generic code..

Regards,
Srivatsa S. Bhat 


^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1
  2012-04-20 13:05 [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
                   ` (20 preceding siblings ...)
  2012-04-20 13:56 ` Srivatsa S. Bhat
@ 2012-04-20 14:06 ` richard -rw- weinberger
  2012-04-20 14:19   ` Thomas Gleixner
  2012-04-20 14:27 ` James Bottomley
                   ` (5 subsequent siblings)
  27 siblings, 1 reply; 75+ messages in thread
From: richard -rw- weinberger @ 2012-04-20 14:06 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Peter Zijlstra, Rusty Russell,
	Paul E. McKenney, Ingo Molnar, Srivatsa S. Bhat

On Fri, Apr 20, 2012 at 3:05 PM, Thomas Gleixner <tglx@linutronix.de> wrote:
> This converts all architectures except m32r, mn10300, tile and UM to
> the new core facility. These architecture are calling fork_idle() in
> the very early boot code in smp_prepare_cpus() for unknown reasons.
> I haven't analyzed yet, whether this is on purpose or can be moved
> over to the generic facility. It'd be nice if the responsible maintainers
> could look into that as well.

SMP is marked as broken on UM, so I don't have any objections. :-)

-- 
Thanks,
//richard

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1
  2012-04-20 13:56 ` Srivatsa S. Bhat
@ 2012-04-20 14:18   ` Thomas Gleixner
  2012-04-24 18:44     ` Konrad Rzeszutek Wilk
  2012-05-21  1:42     ` Rusty Russell
  0 siblings, 2 replies; 75+ messages in thread
From: Thomas Gleixner @ 2012-04-20 14:18 UTC (permalink / raw)
  To: Srivatsa S. Bhat
  Cc: LKML, linux-arch, Peter Zijlstra, Rusty Russell,
	Paul E. McKenney, Ingo Molnar, Nikunj A Dadhania, Steven Rostedt

On Fri, 20 Apr 2012, Srivatsa S. Bhat wrote:
> > This first part moves the idle thread management for non-boot cpus
> > into the core. fork_idle() is called in a workqueue as it is
> > implemented in a few architectures already. This is necessary when not
> > all cpus are brought up by the early boot code as otherwise we would
> > take a ref on the user task VM of the thread which brings the cpu up
> > via the sysfs interface.
> > 
> 
> 
> Do you have a git tree where you have made these patches available?
> That would be pretty useful, so that we can build on whatever you have

Not yet, but I'll stick that into a tip/ branch.

> already done.. Myself and Nikunj had some initial design/ideas on reducing
> the duplication in architecture code, related to managing the setting
> of the cpu in the online mask, sending out CPU_STARTING notifiers etc
> from generic code..

The whole notifier business needs a redesign as well, because we don't
have a way to express proper dependencies, we add random notifier
points and the teardown path is ass backwards. The whole thing wants
to be a tree which can be walked in either direction and from any
point. Right now we cut the trunk first and keep the single limb up
with a helicopter and start dismantling it.

Flat notifiers are not working for this as they do not allow a tree
structure and prevent us to do things in parallel.

That really needs to be completely reworked. There is also a lot of
stuff which wants to be moved into the starting/dying CPU
context. Right now we kinda do that by trampling on the CPU with a
high prio stomper thread, but that's really just a bandaid and steady
cause of trouble.

If you look at facilities which use kthreads, then there is lots other
setup which does not need a notifier at all, as it can be done in the
context of the thread when we have a way to start/park those threads
at the right time in the up/down process.

I've already done a prototype for kthread park/unpark and converted
softirq over to use it. That makes the complete softirq notifier go
away and let the core code handle the thread creation / start / park /
unpark. It's pretty hacky right now, but I'm going to push on this
next, once I have a better idea how to express the dependency tree.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1
  2012-04-20 14:06 ` richard -rw- weinberger
@ 2012-04-20 14:19   ` Thomas Gleixner
  0 siblings, 0 replies; 75+ messages in thread
From: Thomas Gleixner @ 2012-04-20 14:19 UTC (permalink / raw)
  To: richard -rw- weinberger
  Cc: LKML, linux-arch, Peter Zijlstra, Rusty Russell,
	Paul E. McKenney, Ingo Molnar, Srivatsa S. Bhat

On Fri, 20 Apr 2012, richard -rw- weinberger wrote:

> On Fri, Apr 20, 2012 at 3:05 PM, Thomas Gleixner <tglx@linutronix.de> wrote:
> > This converts all architectures except m32r, mn10300, tile and UM to
> > the new core facility. These architecture are calling fork_idle() in
> > the very early boot code in smp_prepare_cpus() for unknown reasons.
> > I haven't analyzed yet, whether this is on purpose or can be moved
> > over to the generic facility. It'd be nice if the responsible maintainers
> > could look into that as well.
> 
> SMP is marked as broken on UM, so I don't have any objections. :-)

Great. So we can break it some more and let the poor sod who tries to
fix UM SMP deal with it :)

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1
  2012-04-20 13:05 [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
                   ` (21 preceding siblings ...)
  2012-04-20 14:06 ` richard -rw- weinberger
@ 2012-04-20 14:27 ` James Bottomley
  2012-04-20 17:55 ` Paul E. McKenney
                   ` (4 subsequent siblings)
  27 siblings, 0 replies; 75+ messages in thread
From: James Bottomley @ 2012-04-20 14:27 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Peter Zijlstra, Rusty Russell,
	Paul E. McKenney, Ingo Molnar, Srivatsa S. Bhat

On Fri, 2012-04-20 at 13:05 +0000, Thomas Gleixner wrote:
> Dear all,
> 
> I'm working on refactoring the SMP boot and CPU hotplug implementation.
> 
> The current code has evolved over time into a conglomerate of
> warts. My main goals are to:
> 
>  - reduce the architecture code by moving repeating constructs to the
>    core
> 
>  - redesigning the handling of per cpu threads. There is no point to
>    tear down the threads just to create them again.
> 
>  - restructuring the notifier facility into a proper tree with
>    dependencies to avoid the gazillion of callbacks and moving
>    setup/teardown code into the context of the upcoming/dying cpu
> 
> The motivation behind this work is the cpu hotplug nightmare which we
> are facing in the RT kernel and the requests from several groups
> (e.g. ARM) to make hotplug more lightweight and faster.
> 
> This first part moves the idle thread management for non-boot cpus
> into the core. fork_idle() is called in a workqueue as it is
> implemented in a few architectures already. This is necessary when not
> all cpus are brought up by the early boot code as otherwise we would
> take a ref on the user task VM of the thread which brings the cpu up
> via the sysfs interface.
> 
> This converts all architectures except m32r, mn10300, tile and UM to
> the new core facility. These architecture are calling fork_idle() in
> the very early boot code in smp_prepare_cpus() for unknown reasons.
> I haven't analyzed yet, whether this is on purpose or can be moved
> over to the generic facility. It'd be nice if the responsible maintainers
> could look into that as well.

Do you have a git tree we can try?  If you do, I promise to test as soon
as I can get my parisc systems nursed back to health after their
apparently trying voyage across the atlantic.

James



^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1
  2012-04-20 13:21 ` Peter Zijlstra
  2012-04-20 13:47   ` Thomas Gleixner
@ 2012-04-20 15:42   ` Tejun Heo
  2012-04-20 15:49     ` Peter Zijlstra
  1 sibling, 1 reply; 75+ messages in thread
From: Tejun Heo @ 2012-04-20 15:42 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Thomas Gleixner, LKML, linux-arch, Rusty Russell,
	Paul E. McKenney, Ingo Molnar, Srivatsa S. Bhat, David Rientjes

Hello,

On Fri, Apr 20, 2012 at 03:21:38PM +0200, Peter Zijlstra wrote:
> On Fri, 2012-04-20 at 13:05 +0000, Thomas Gleixner wrote:
> > This first part moves the idle thread management for non-boot cpus
> > into the core. fork_idle() is called in a workqueue as it is
> > implemented in a few architectures already. This is necessary when not
> > all cpus are brought up by the early boot code as otherwise we would
> > take a ref on the user task VM of the thread which brings the cpu up
> > via the sysfs interface. 
> 
> So I was thinking about this and I think we should make that kthreadd
> instead of a random workqueue thread due to all that cgroup crap. People
> are wanting to place all sorts of kernel threads in cgroups and I'm
> still arguing that kthreadd should not be allowed in cgroups.
>
> Tejun, what's the status of that patch? Afaict David Rientjes's use-case
> is insane and mostly a side effect of memcg broken-ness.

I'm still leaning towards restricting kthreadd and any PF_THREAD_BOUND
threads in the root cgroup.  I'm not sure about !BOUND kthreads tho.
It doesn't make sense for the most part but there are cases
(e.g. crypto kthreads) which might make some sense.

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1
  2012-04-20 15:42   ` [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Tejun Heo
@ 2012-04-20 15:49     ` Peter Zijlstra
  2012-04-20 15:56       ` Thomas Gleixner
  0 siblings, 1 reply; 75+ messages in thread
From: Peter Zijlstra @ 2012-04-20 15:49 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Thomas Gleixner, LKML, linux-arch, Rusty Russell,
	Paul E. McKenney, Ingo Molnar, Srivatsa S. Bhat, David Rientjes

On Fri, 2012-04-20 at 08:42 -0700, Tejun Heo wrote:
> I'm still leaning towards restricting kthreadd and any PF_THREAD_BOUND
> threads in the root cgroup.  

I'd definitely agree with restricting those. 

> I'm not sure about !BOUND kthreads tho.
> It doesn't make sense for the most part but there are cases
> (e.g. crypto kthreads) which might make some sense.
> 
Agreed as well. There are a few nasty corner cases with unbound
workqueues vs allowing cgroups (as how to place new worker threads
correctly etc..). Sorting that is a 'fun' next problem.

Could we merge the kthreadd/PF_THREAD_BOUND restriction? You've got my
ACK and I'm fairly sure tglx will ACK it as well.


^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1
  2012-04-20 15:49     ` Peter Zijlstra
@ 2012-04-20 15:56       ` Thomas Gleixner
  0 siblings, 0 replies; 75+ messages in thread
From: Thomas Gleixner @ 2012-04-20 15:56 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Tejun Heo, LKML, linux-arch, Rusty Russell, Paul E. McKenney,
	Ingo Molnar, Srivatsa S. Bhat, David Rientjes

On Fri, 20 Apr 2012, Peter Zijlstra wrote:

> On Fri, 2012-04-20 at 08:42 -0700, Tejun Heo wrote:
> > I'm still leaning towards restricting kthreadd and any PF_THREAD_BOUND
> > threads in the root cgroup.  
> 
> I'd definitely agree with restricting those. 
> 
> > I'm not sure about !BOUND kthreads tho.
> > It doesn't make sense for the most part but there are cases
> > (e.g. crypto kthreads) which might make some sense.
> > 
> Agreed as well. There are a few nasty corner cases with unbound
> workqueues vs allowing cgroups (as how to place new worker threads
> correctly etc..). Sorting that is a 'fun' next problem.
> 
> Could we merge the kthreadd/PF_THREAD_BOUND restriction? You've got my
> ACK and I'm fairly sure tglx will ACK it as well.

Acked-and-appreciated-by-me

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 04/18] smp: Provide generic idle thread allocation
  2012-04-20 13:05 ` [patch 04/18] smp: Provide generic idle thread allocation Thomas Gleixner
@ 2012-04-20 16:21   ` Sam Ravnborg
  2012-04-20 18:55     ` Thomas Gleixner
  2012-04-21  2:20   ` Stephen Rothwell
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 75+ messages in thread
From: Sam Ravnborg @ 2012-04-20 16:21 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Peter Zijlstra, Rusty Russell,
	Paul E. McKenney, Ingo Molnar, Srivatsa S. Bhat, Matt Turner,
	Russell King, Mike Frysinger, Jesper Nilsson, Richard Kuo,
	Tony Luck, Hirokazu Takata, Ralf Baechle, David Howells,
	James E.J. Bottomley, Benjamin Herrenschmidt, Martin Schwidefsky,
	Paul Mundt, David S. Miller, Chris Metcalf, Richard Weinberger,
	x86

On Fri, Apr 20, 2012 at 01:05:45PM -0000, Thomas Gleixner wrote:
> All SMP architectures have magic to fork the idle task and to store it
> for reusage when cpu hotplug is enabled. Provide a generic
> infrastructure for it.
> 
> Create/reinit the idle thread for the cpu which is brought up in the
> generic code and hand the thread pointer to the architecture code via
> __cpu_up().
> 
> Note, that fork_idle() is called via a workqueue, because this
> guarantees that the idle thread does not get a reference to a user
> space VM. This can happen when the boot process did not bring up all
> possible cpus and a later cpu_up() is initiated via the sysfs
> interface. In that case fork_idle() would be called in the context of
> the user space task and take a reference on the user space VM.
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Cc: Matt Turner <mattst88@gmail.com>
> Cc: Russell King <linux@arm.linux.org.uk>
> Cc: Mike Frysinger <vapier@gentoo.org>
> Cc: Jesper Nilsson <jesper.nilsson@axis.com>
> Cc: Richard Kuo <rkuo@codeaurora.org>
> Cc: Tony Luck <tony.luck@intel.com>
> Cc: Hirokazu Takata <takata@linux-m32r.org>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: David Howells <dhowells@redhat.com>
> Cc: "James E.J. Bottomley" <jejb@parisc-linux.org>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
> Cc: Paul Mundt <lethal@linux-sh.org>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: Chris Metcalf <cmetcalf@tilera.com>
> Cc: Richard Weinberger <richard@nod.at>
> Cc: x86@kernel.org
> ---
>  arch/Kconfig        |    3 +
>  kernel/cpu.c        |    2 -
>  kernel/sched/core.c |    2 +
>  kernel/smpboot.c    |   83 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  kernel/smpboot.h    |   10 ++++++
>  5 files changed, 99 insertions(+), 1 deletion(-)
> 
> Index: linux-2.6/arch/Kconfig
> ===================================================================
> --- linux-2.6.orig/arch/Kconfig
> +++ linux-2.6/arch/Kconfig
> @@ -145,6 +145,9 @@ config HAVE_DMA_ATTRS
>  config USE_GENERIC_SMP_HELPERS
>  	bool
>  
> +config GENERIC_SMP_IDLE_THREAD
> +       bool
> +

Symbols we select in arch Kconfig files are often named HAVE_*
And no matter the name - a comment preceeding the definition of the symbol
would be nice so it is possible to deduct the use of the symbol
in a few years time when this thread is long forgotten.

	Sam

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1
  2012-04-20 13:05 [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
                   ` (22 preceding siblings ...)
  2012-04-20 14:27 ` James Bottomley
@ 2012-04-20 17:55 ` Paul E. McKenney
  2012-04-20 23:11 ` Venki Pallipadi
                   ` (3 subsequent siblings)
  27 siblings, 0 replies; 75+ messages in thread
From: Paul E. McKenney @ 2012-04-20 17:55 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Peter Zijlstra, Rusty Russell, Ingo Molnar,
	Srivatsa S. Bhat

On Fri, Apr 20, 2012 at 01:05:41PM -0000, Thomas Gleixner wrote:
> Dear all,
> 
> I'm working on refactoring the SMP boot and CPU hotplug implementation.
> 
> The current code has evolved over time into a conglomerate of
> warts. My main goals are to:
> 
>  - reduce the architecture code by moving repeating constructs to the
>    core
> 
>  - redesigning the handling of per cpu threads. There is no point to
>    tear down the threads just to create them again.
> 
>  - restructuring the notifier facility into a proper tree with
>    dependencies to avoid the gazillion of callbacks and moving
>    setup/teardown code into the context of the upcoming/dying cpu
> 
> The motivation behind this work is the cpu hotplug nightmare which we
> are facing in the RT kernel and the requests from several groups
> (e.g. ARM) to make hotplug more lightweight and faster.
> 
> This first part moves the idle thread management for non-boot cpus
> into the core. fork_idle() is called in a workqueue as it is
> implemented in a few architectures already. This is necessary when not
> all cpus are brought up by the early boot code as otherwise we would
> take a ref on the user task VM of the thread which brings the cpu up
> via the sysfs interface.
> 
> This converts all architectures except m32r, mn10300, tile and UM to
> the new core facility. These architecture are calling fork_idle() in
> the very early boot code in smp_prepare_cpus() for unknown reasons.
> I haven't analyzed yet, whether this is on purpose or can be moved
> over to the generic facility. It'd be nice if the responsible maintainers
> could look into that as well.

Looks good to me!  Ran some brief rcutorture+hotplug tests, and it
did fine on KVM on 32-bit x86.

							Thanx, Paul


^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 04/18] smp: Provide generic idle thread allocation
  2012-04-20 16:21   ` Sam Ravnborg
@ 2012-04-20 18:55     ` Thomas Gleixner
  0 siblings, 0 replies; 75+ messages in thread
From: Thomas Gleixner @ 2012-04-20 18:55 UTC (permalink / raw)
  To: Sam Ravnborg
  Cc: LKML, linux-arch, Peter Zijlstra, Rusty Russell,
	Paul E. McKenney, Ingo Molnar, Srivatsa S. Bhat, Matt Turner,
	Russell King, Mike Frysinger, Jesper Nilsson, Richard Kuo,
	Tony Luck, Hirokazu Takata, Ralf Baechle, David Howells,
	James E.J. Bottomley, Benjamin Herrenschmidt, Martin Schwidefsky,
	Paul Mundt, David S. Miller, Chris Metcalf, Richard Weinberger,
	x86

On Fri, 20 Apr 2012, Sam Ravnborg wrote:
> On Fri, Apr 20, 2012 at 01:05:45PM -0000, Thomas Gleixner wrote:
> > +config GENERIC_SMP_IDLE_THREAD
> > +       bool
> > +
> 
> Symbols we select in arch Kconfig files are often named HAVE_*
> And no matter the name - a comment preceeding the definition of the symbol
> would be nice so it is possible to deduct the use of the symbol
> in a few years time when this thread is long forgotten.

Fair enough. Though I hope that this can go away, when we can convert
the 3 remaining archs over.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 03/18] smp: Add generic smpboot facility
  2012-04-20 13:05 ` [patch 03/18] smp: Add generic smpboot facility Thomas Gleixner
@ 2012-04-20 20:07   ` Yinghai Lu
  2012-04-21  2:07   ` Stephen Rothwell
  2012-04-28  9:04   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
  2 siblings, 0 replies; 75+ messages in thread
From: Yinghai Lu @ 2012-04-20 20:07 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Peter Zijlstra, Rusty Russell,
	Paul E. McKenney, Ingo Molnar, Srivatsa S. Bhat, Matt Turner,
	Russell King, Mike Frysinger, Jesper Nilsson, Richard Kuo,
	Tony Luck, Hirokazu Takata, Ralf Baechle, David Howells,
	James E.J. Bottomley, Benjamin Herrenschmidt, Martin Schwidefsky,
	Paul Mundt, David S. Miller, Chris Metcalf, Richard Weinberger,
	x86

On Fri, Apr 20, 2012 at 6:05 AM, Thomas Gleixner <tglx@linutronix.de> wrote:
> Start a new file, which will hold SMP and CPU hotplug related generic
> infrastructure.
>
===================================================================
> --- linux-2.6.orig/kernel/cpu.c
> +++ linux-2.6/kernel/cpu.c
> @@ -17,6 +17,8 @@
>  #include <linux/gfp.h>
>  #include <linux/suspend.h>
>
> +#include "smpboot.h"
> +
>  #ifdef CONFIG_SMP
>  /* Serializes the updates to cpu_online_mask, cpu_present_mask */
>  static DEFINE_MUTEX(cpu_add_remove_lock);
> @@ -300,6 +302,11 @@ static int __cpuinit _cpu_up(unsigned in
>                return -EINVAL;
>
>        cpu_hotplug_begin();
> +
> +       ret = smpboot_prepare(cpu);
> +       if (ret)
> +               goto out;
> +
>        ret = __cpu_notify(CPU_UP_PREPARE | mod, hcpu, -1, &nr_calls);
>        if (ret) {
>                nr_calls--;
> @@ -320,6 +327,7 @@ static int __cpuinit _cpu_up(unsigned in
>  out_notify:
>        if (ret != 0)
>                __cpu_notify(CPU_UP_CANCELED | mod, hcpu, nr_calls, NULL);
> +out:
>        cpu_hotplug_done();
>
>        return ret;
> Index: linux-2.6/kernel/smpboot.c
> ===================================================================
> --- /dev/null
> +++ linux-2.6/kernel/smpboot.c
> @@ -0,0 +1,12 @@
> +/*
> + * Common SMP CPU bringup/teardown functions
> + */
> +
> +#include "smpboot.h"
> +
> +/**
> + * smpboot_prepare - generic smpboot preparation
> + */
> +int __cpuinit smpboot_prepare(unsigned int cpu)
> +{
         return 0;
> +}

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1
  2012-04-20 13:05 [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
                   ` (23 preceding siblings ...)
  2012-04-20 17:55 ` Paul E. McKenney
@ 2012-04-20 23:11 ` Venki Pallipadi
  2012-04-21  1:04 ` Frank Rowand
                   ` (2 subsequent siblings)
  27 siblings, 0 replies; 75+ messages in thread
From: Venki Pallipadi @ 2012-04-20 23:11 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Peter Zijlstra, Rusty Russell,
	Paul E. McKenney, Ingo Molnar, Srivatsa S. Bhat

On Fri, Apr 20, 2012 at 6:05 AM, Thomas Gleixner <tglx@linutronix.de> wrote:
> Dear all,
>
> I'm working on refactoring the SMP boot and CPU hotplug implementation.
>
> The current code has evolved over time into a conglomerate of
> warts. My main goals are to:
>
>  - reduce the architecture code by moving repeating constructs to the
>   core
>
>  - redesigning the handling of per cpu threads. There is no point to
>   tear down the threads just to create them again.
>
>  - restructuring the notifier facility into a proper tree with
>   dependencies to avoid the gazillion of callbacks and moving
>   setup/teardown code into the context of the upcoming/dying cpu
>
> The motivation behind this work is the cpu hotplug nightmare which we
> are facing in the RT kernel and the requests from several groups
> (e.g. ARM) to make hotplug more lightweight and faster.
>
> This first part moves the idle thread management for non-boot cpus
> into the core. fork_idle() is called in a workqueue as it is
> implemented in a few architectures already. This is necessary when not
> all cpus are brought up by the early boot code as otherwise we would
> take a ref on the user task VM of the thread which brings the cpu up
> via the sysfs interface.
>

I had sent out a patchset that did this cleanup here:
https://lkml.org/lkml/2012/3/6/466

This patchset is clean and more exhaustive than what I had. So,

Acked-by: Venkatesh Pallipadi <venki@google.com>

> This converts all architectures except m32r, mn10300, tile and UM to
> the new core facility. These architecture are calling fork_idle() in
> the very early boot code in smp_prepare_cpus() for unknown reasons.
> I haven't analyzed yet, whether this is on purpose or can be moved
> over to the generic facility. It'd be nice if the responsible maintainers
> could look into that as well.
>
> Thanks,
>
>        tglx
>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1
  2012-04-20 13:47   ` Thomas Gleixner
@ 2012-04-21  0:08     ` Suresh Siddha
  2012-05-03  9:41       ` Thomas Gleixner
  2012-05-03 17:43       ` [tip:smp/hotplug] smp, idle: Allocate idle thread for each possible cpu during boot tip-bot for Suresh Siddha
  0 siblings, 2 replies; 75+ messages in thread
From: Suresh Siddha @ 2012-04-21  0:08 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Peter Zijlstra, LKML, linux-arch, Rusty Russell,
	Paul E. McKenney, Ingo Molnar, Srivatsa S. Bhat, Tejun Heo,
	David Rientjes, venki

On Fri, 2012-04-20 at 15:47 +0200, Thomas Gleixner wrote:
> On Fri, 20 Apr 2012, Peter Zijlstra wrote:
> 
> > On Fri, 2012-04-20 at 13:05 +0000, Thomas Gleixner wrote:
> > > This first part moves the idle thread management for non-boot cpus
> > > into the core. fork_idle() is called in a workqueue as it is
> > > implemented in a few architectures already. This is necessary when not
> > > all cpus are brought up by the early boot code as otherwise we would
> > > take a ref on the user task VM of the thread which brings the cpu up
> > > via the sysfs interface. 
> > 
> > So I was thinking about this and I think we should make that kthreadd
> > instead of a random workqueue thread due to all that cgroup crap. People
> > are wanting to place all sorts of kernel threads in cgroups and I'm
> > still arguing that kthreadd should not be allowed in cgroups.
> 
> So your fear is that the idle_thread will end up in some random cgroup
> because some illdesigned user space code decided to stick kernel
> threads into cgroups.
> 
> Can we please have some sanity restrictions on this cgroup muck? I
> don't care when user space creates cgroups in circles, but holding the
> whole kernel hostage of this madness is going too far.
> 

Also, do we really need the workqueue/kthreadd based allocation? Just
like the percpu areas getting allocated for each possible cpu during
boot, shouldn't we extend this to the per-cpu idle threads too? So
something like the appended should be ok to?

In the context of Venki's fork_idle patches, Ingo mentioned of moving
the percpu idle threads into percpu areas. While we can easily do that
for non-boot cpu's, 'init_task' will be special. So for now, does the
appended (ontop of your other patches) look ok?
---

From: Suresh Siddha <suresh.b.siddha@intel.com>
Subject: smp, idle: allocate idle thread for each possible cpu during boot

percpu areas are already allocated during boot for each possible cpu.
percpu idle threads can be considered as an extension of the percpu areas,
and allocate them for each possible cpu during boot.

This will eliminate the need for workqueue based idle thread allocation.
In future we can move the idle thread area into the percpu area too.

Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
---
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 05c46ba..a5144ab 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -303,10 +303,6 @@ static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen)
 
 	cpu_hotplug_begin();
 
-	ret = smpboot_prepare(cpu);
-	if (ret)
-		goto out;
-
 	ret = __cpu_notify(CPU_UP_PREPARE | mod, hcpu, -1, &nr_calls);
 	if (ret) {
 		nr_calls--;
@@ -327,7 +323,6 @@ static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen)
 out_notify:
 	if (ret != 0)
 		__cpu_notify(CPU_UP_CANCELED | mod, hcpu, nr_calls, NULL);
-out:
 	cpu_hotplug_done();
 
 	return ret;
diff --git a/kernel/smp.c b/kernel/smp.c
index 2f8b10e..e755fc6 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -13,6 +13,8 @@
 #include <linux/smp.h>
 #include <linux/cpu.h>
 
+#include "smpboot.h"
+
 #ifdef CONFIG_USE_GENERIC_SMP_HELPERS
 static struct {
 	struct list_head	queue;
@@ -669,6 +671,10 @@ void __init smp_init(void)
 {
 	unsigned int cpu;
 
+	for_each_possible_cpu(cpu)
+		if (cpu != smp_processor_id())
+			smpboot_prepare(cpu);
+
 	/* FIXME: This should be done in userspace --RR */
 	for_each_present_cpu(cpu) {
 		if (num_online_cpus() >= setup_max_cpus)
diff --git a/kernel/smpboot.c b/kernel/smpboot.c
index a24ddbe..72b49fc 100644
--- a/kernel/smpboot.c
+++ b/kernel/smpboot.c
@@ -5,40 +5,10 @@
 #include <linux/smp.h>
 #include <linux/sched.h>
 #include <linux/percpu.h>
-#include <linux/workqueue.h>
 
 #include "smpboot.h"
 
 #ifdef CONFIG_GENERIC_SMP_IDLE_THREAD
-struct create_idle {
-	struct work_struct	work;
-	struct task_struct	*idle;
-	struct completion	done;
-	unsigned int cpu;
-};
-
-static void __cpuinit do_fork_idle(struct work_struct *work)
-{
-	struct create_idle *c = container_of(work, struct create_idle, work);
-
-	c->idle = fork_idle(c->cpu);
-	complete(&c->done);
-}
-
-static struct task_struct * __cpuinit idle_thread_create(unsigned int cpu)
-{
-	struct create_idle c_idle = {
-		.cpu	= cpu,
-		.done	= COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
-	};
-
-	INIT_WORK_ONSTACK(&c_idle.work, do_fork_idle);
-	schedule_work(&c_idle.work);
-	wait_for_completion(&c_idle.done);
-	destroy_work_on_stack(&c_idle.work);
-	return c_idle.idle;
-}
-
 /*
  * For the hotplug case we keep the task structs around and reuse
  * them.
@@ -50,7 +20,7 @@ static inline struct task_struct *get_idle_for_cpu(unsigned int cpu)
 	struct task_struct *tsk = per_cpu(idle_threads, cpu);
 
 	if (!tsk)
-		return idle_thread_create(cpu);
+		return fork_idle(cpu);
 	init_idle(tsk, cpu);
 	return tsk;
 }



^ permalink raw reply related	[flat|nested] 75+ messages in thread

* Re: [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1
  2012-04-20 13:05 [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
                   ` (24 preceding siblings ...)
  2012-04-20 23:11 ` Venki Pallipadi
@ 2012-04-21  1:04 ` Frank Rowand
  2012-04-21  1:55   ` Frank Rowand
  2012-04-22 21:01 ` Chris Metcalf
  2012-04-30  8:05 ` Santosh Shilimkar
  27 siblings, 1 reply; 75+ messages in thread
From: Frank Rowand @ 2012-04-21  1:04 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Peter Zijlstra, Rusty Russell,
	Paul E. McKenney, Ingo Molnar, Srivatsa S. Bhat

On 04/20/12 06:05, Thomas Gleixner wrote:
> Dear all,
> 
> I'm working on refactoring the SMP boot and CPU hotplug implementation.

Smoke test #1 successful.  Builds and boots on ARM Panda for:

  linux-3.4-rc3       CONFIG_PREEMPT_NONE

  linux-3.4-rc3-rt5   CONFIG_PREEMPT_RT_FULL


-Frank


^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1
  2012-04-21  1:04 ` Frank Rowand
@ 2012-04-21  1:55   ` Frank Rowand
  0 siblings, 0 replies; 75+ messages in thread
From: Frank Rowand @ 2012-04-21  1:55 UTC (permalink / raw)
  To: Rowand, Frank
  Cc: Thomas Gleixner, LKML, linux-arch, Peter Zijlstra, Rusty Russell,
	Paul E. McKenney, Ingo Molnar, Srivatsa S. Bhat

On 04/20/12 18:04, Frank Rowand wrote:
> On 04/20/12 06:05, Thomas Gleixner wrote:
>> Dear all,
>>
>> I'm working on refactoring the SMP boot and CPU hotplug implementation.
> 
> Smoke test #1 successful.  Builds and boots on ARM Panda for:
> 
>   linux-3.4-rc3       CONFIG_PREEMPT_NONE
> 
>   linux-3.4-rc3-rt5   CONFIG_PREEMPT_RT_FULL


Further smoke testing successful.  Also builds and boots on ARM Realview for:

  linux-3.4-rc3      SMP, PREEMPT_NONE
  linux-3.4-rc3-rt5  SMP, PREEMPT_RT_FULL

  linux-3.4-rc3-rt5  UP,  PREEMPT_RT_FULL


-Frank




^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 03/18] smp: Add generic smpboot facility
  2012-04-20 13:05 ` [patch 03/18] smp: Add generic smpboot facility Thomas Gleixner
  2012-04-20 20:07   ` Yinghai Lu
@ 2012-04-21  2:07   ` Stephen Rothwell
  2012-04-28  9:04   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
  2 siblings, 0 replies; 75+ messages in thread
From: Stephen Rothwell @ 2012-04-21  2:07 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Peter Zijlstra, Rusty Russell,
	Paul E. McKenney, Ingo Molnar, Srivatsa S. Bhat, Matt Turner,
	Russell King, Mike Frysinger, Jesper Nilsson, Richard Kuo,
	Tony Luck, Hirokazu Takata, Ralf Baechle, David Howells,
	James E.J. Bottomley, Benjamin Herrenschmidt, Martin Schwidefsky,
	Paul Mundt, David S. Miller, Chris Metcalf, Richard Weinberger,
	x86

[-- Attachment #1: Type: text/plain, Size: 657 bytes --]

Hi Thomas,

On Fri, 20 Apr 2012 13:05:44 -0000 Thomas Gleixner <tglx@linutronix.de> wrote:
>
> Index: linux-2.6/kernel/smpboot.c
> ===================================================================
> --- /dev/null
> +++ linux-2.6/kernel/smpboot.c
> @@ -0,0 +1,12 @@
> +/*
> + * Common SMP CPU bringup/teardown functions
> + */
> +
> +#include "smpboot.h"
> +
> +/**
> + * smpboot_prepare - generic smpboot preparation
> + */
> +int __cpuinit smpboot_prepare(unsigned int cpu)

Where does this get its definition of __cpuinit?

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 04/18] smp: Provide generic idle thread allocation
  2012-04-20 13:05 ` [patch 04/18] smp: Provide generic idle thread allocation Thomas Gleixner
  2012-04-20 16:21   ` Sam Ravnborg
@ 2012-04-21  2:20   ` Stephen Rothwell
  2012-04-21  2:25   ` Frank Rowand
  2012-04-28  9:05   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
  3 siblings, 0 replies; 75+ messages in thread
From: Stephen Rothwell @ 2012-04-21  2:20 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Peter Zijlstra, Rusty Russell,
	Paul E. McKenney, Ingo Molnar, Srivatsa S. Bhat, Matt Turner,
	Russell King, Mike Frysinger, Jesper Nilsson, Richard Kuo,
	Tony Luck, Hirokazu Takata, Ralf Baechle, David Howells,
	James E.J. Bottomley, Benjamin Herrenschmidt, Martin Schwidefsky,
	Paul Mundt, David S. Miller, Chris Metcalf, Richard Weinberger,
	x86

[-- Attachment #1: Type: text/plain, Size: 744 bytes --]

Hi Thomas,

On Fri, 20 Apr 2012 13:05:45 -0000 Thomas Gleixner <tglx@linutronix.de> wrote:
>
> Index: linux-2.6/kernel/smpboot.c
> ===================================================================
> --- linux-2.6.orig/kernel/smpboot.c
> +++ linux-2.6/kernel/smpboot.c
> @@ -1,12 +1,95 @@
>  /*
>   * Common SMP CPU bringup/teardown functions
>   */
> +#include <linux/err.h>
> +#include <linux/smp.h>
> +#include <linux/sched.h>
> +#include <linux/percpu.h>
> +#include <linux/workqueue.h>

#include <linux/init.h>	/* should have been in previous patch */
#include <linux/kernel.h>
#include <linux/completion.h>

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 04/18] smp: Provide generic idle thread allocation
  2012-04-20 13:05 ` [patch 04/18] smp: Provide generic idle thread allocation Thomas Gleixner
  2012-04-20 16:21   ` Sam Ravnborg
  2012-04-21  2:20   ` Stephen Rothwell
@ 2012-04-21  2:25   ` Frank Rowand
  2012-04-28  9:05   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
  3 siblings, 0 replies; 75+ messages in thread
From: Frank Rowand @ 2012-04-21  2:25 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Peter Zijlstra, Rusty Russell,
	Paul E. McKenney, Ingo Molnar, Srivatsa S. Bhat, Matt Turner,
	Russell King, Mike Frysinger, Jesper Nilsson, Richard Kuo,
	Tony Luck, Hirokazu Takata, Ralf Baechle, David Howells,
	James E.J. Bottomley, Benjamin Herrenschmidt, Martin Schwidefsky,
	Paul Mundt, David S. Miller, Chris Metcalf, Richard Weinberger,
	x86

On 04/20/12 06:05, Thomas Gleixner wrote:
> All SMP architectures have magic to fork the idle task and to store it
> for reusage when cpu hotplug is enabled. Provide a generic
> infrastructure for it.
> 
> Create/reinit the idle thread for the cpu which is brought up in the
> generic code and hand the thread pointer to the architecture code via
> __cpu_up().
> 
> Note, that fork_idle() is called via a workqueue, because this
> guarantees that the idle thread does not get a reference to a user
> space VM. This can happen when the boot process did not bring up all
> possible cpus and a later cpu_up() is initiated via the sysfs
> interface. In that case fork_idle() would be called in the context of
> the user space task and take a reference on the user space VM.
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Cc: Matt Turner <mattst88@gmail.com>
> Cc: Russell King <linux@arm.linux.org.uk>
> Cc: Mike Frysinger <vapier@gentoo.org>
> Cc: Jesper Nilsson <jesper.nilsson@axis.com>
> Cc: Richard Kuo <rkuo@codeaurora.org>
> Cc: Tony Luck <tony.luck@intel.com>
> Cc: Hirokazu Takata <takata@linux-m32r.org>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: David Howells <dhowells@redhat.com>
> Cc: "James E.J. Bottomley" <jejb@parisc-linux.org>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
> Cc: Paul Mundt <lethal@linux-sh.org>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: Chris Metcalf <cmetcalf@tilera.com>
> Cc: Richard Weinberger <richard@nod.at>
> Cc: x86@kernel.org
> ---
>  arch/Kconfig        |    3 +
>  kernel/cpu.c        |    2 -
>  kernel/sched/core.c |    2 +
>  kernel/smpboot.c    |   83 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  kernel/smpboot.h    |   10 ++++++
>  5 files changed, 99 insertions(+), 1 deletion(-)
> 
> Index: linux-2.6/arch/Kconfig
> ===================================================================
> --- linux-2.6.orig/arch/Kconfig
> +++ linux-2.6/arch/Kconfig
> @@ -145,6 +145,9 @@ config HAVE_DMA_ATTRS
>  config USE_GENERIC_SMP_HELPERS
>  	bool
>  
> +config GENERIC_SMP_IDLE_THREAD
> +       bool

    ^^^^^  This _appears_ to be spaces instead of a tab.  Hopefully not a false alarm, I know
           my mail servers randomly change tabs to spaces, just to mess with me, but I double
           checked at the lkml archive.

> +
>  config HAVE_REGS_AND_STACK_ACCESS_API
>  	bool
>  	help

< snip >

- Frank


^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 15/18] sh: Use generic idle thread allocation
  2012-04-20 13:05 ` [patch 15/18] sh: " Thomas Gleixner
@ 2012-04-21  3:18   ` Paul Mundt
  2012-04-28  9:14   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
  1 sibling, 0 replies; 75+ messages in thread
From: Paul Mundt @ 2012-04-21  3:18 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Peter Zijlstra, Rusty Russell,
	Paul E. McKenney, Ingo Molnar, Srivatsa S. Bhat

On Fri, Apr 20, 2012 at 01:05:54PM -0000, Thomas Gleixner wrote:
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Cc: Paul Mundt <lethal@linux-sh.org>
> ---
>  arch/sh/Kconfig                 |    1 +
>  arch/sh/include/asm/processor.h |    4 ----
>  arch/sh/kernel/smp.c            |   14 +-------------
>  3 files changed, 2 insertions(+), 17 deletions(-)
> 
Looks good to me.

Acked-by: Paul Mundt <lethal@linux-sh.org>

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 18/18] sparc: Use generic idle thread allocation
  2012-04-20 13:05 ` [patch 18/18] sparc: " Thomas Gleixner
@ 2012-04-22 19:52   ` David Miller
  2012-04-28  9:15   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
  1 sibling, 0 replies; 75+ messages in thread
From: David Miller @ 2012-04-22 19:52 UTC (permalink / raw)
  To: tglx
  Cc: linux-kernel, linux-arch, peterz, rusty, paulmck, mingo, srivatsa.bhat

From: Thomas Gleixner <tglx@linutronix.de>
Date: Fri, 20 Apr 2012 13:05:56 -0000

> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Cc: "David S. Miller" <davem@davemloft.net>

Tested-by: David S. Miller <davem@davemloft.net>
Signed-off-by: David S. Miller <davem@davemloft.net>

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1
  2012-04-20 13:05 [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
                   ` (25 preceding siblings ...)
  2012-04-21  1:04 ` Frank Rowand
@ 2012-04-22 21:01 ` Chris Metcalf
  2012-04-30  8:05 ` Santosh Shilimkar
  27 siblings, 0 replies; 75+ messages in thread
From: Chris Metcalf @ 2012-04-22 21:01 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Peter Zijlstra, Rusty Russell,
	Paul E. McKenney, Ingo Molnar, Srivatsa S. Bhat

On Fri, 2012-04-20 at 13:05 +0000, Thomas Gleixner wrote:
> [...]
> This first part moves the idle thread management for non-boot cpus
> into the core. fork_idle() is called in a workqueue as it is
> implemented in a few architectures already. This is necessary when not
> all cpus are brought up by the early boot code as otherwise we would
> take a ref on the user task VM of the thread which brings the cpu up
> via the sysfs interface.
> 
> This converts all architectures except m32r, mn10300, tile and UM to
> the new core facility. These architecture are calling fork_idle() in
> the very early boot code in smp_prepare_cpus() for unknown reasons.
> I haven't analyzed yet, whether this is on purpose or can be moved
> over to the generic facility. It'd be nice if the responsible maintainers
> could look into that as well.

I will take a look at this for the tile architecture later this week; I'm
out on vacation until Wednesday.

-- 
Chris Metcalf, Tilera Corp.
http://www.tilera.com

--
To unsubscribe from this list: send the line "unsubscribe linux-arch" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 12/18] s390: Use generic idle thread allocation
  2012-04-20 13:05 ` [patch 12/18] s390: " Thomas Gleixner
@ 2012-04-23  7:09   ` Martin Schwidefsky
  2012-04-28  9:11   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
  1 sibling, 0 replies; 75+ messages in thread
From: Martin Schwidefsky @ 2012-04-23  7:09 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Peter Zijlstra, Rusty Russell,
	Paul E. McKenney, Ingo Molnar, Srivatsa S. Bhat

On Fri, 20 Apr 2012 13:05:52 -0000
Thomas Gleixner <tglx@linutronix.de> wrote:

> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
> ---
>  arch/s390/Kconfig      |    1 +
>  arch/s390/kernel/smp.c |   33 ++-------------------------------
>  2 files changed, 3 insertions(+), 31 deletions(-)

Compile, boots & survives a few rounds of cpu hotplug stress.
Looks good.
Acked-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 14/18] cris: Use generic idle thread allocation
  2012-04-20 13:05 ` [patch 14/18] cris: " Thomas Gleixner
@ 2012-04-23  7:57   ` Jesper Nilsson
  2012-04-28  9:12   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
  1 sibling, 0 replies; 75+ messages in thread
From: Jesper Nilsson @ 2012-04-23  7:57 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Peter Zijlstra, Rusty Russell,
	Paul E. McKenney, Ingo Molnar, Srivatsa S. Bhat

On Fri, Apr 20, 2012 at 03:05:53PM +0200, Thomas Gleixner wrote:
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

Looks good:

Acked-by: Jesper Nilsson <jesper.nilsson@axis.com>

/^JN - Jesper Nilsson
-- 
               Jesper Nilsson -- jesper.nilsson@axis.com

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 02/18] smp: Add task_struct argument to __cpu_up()
  2012-04-20 13:05 ` [patch 02/18] smp: Add task_struct argument to __cpu_up() Thomas Gleixner
@ 2012-04-23  7:58   ` Jesper Nilsson
  2012-04-28  9:02   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
  1 sibling, 0 replies; 75+ messages in thread
From: Jesper Nilsson @ 2012-04-23  7:58 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Peter Zijlstra, Rusty Russell,
	Paul E. McKenney, Ingo Molnar, Srivatsa S. Bhat, Matt Turner,
	Russell King, Mike Frysinger, Richard Kuo, Tony Luck,
	Hirokazu Takata, Ralf Baechle, David Howells,
	James E.J. Bottomley, Benjamin Herrenschmidt, Martin Schwidefsky,
	Paul Mundt, David S. Miller, Chris Metcalf, Richard Weinberger,
	x86

On Fri, Apr 20, 2012 at 03:05:42PM +0200, Thomas Gleixner wrote:
> Preparatory patch to make the idle thread allocation for secondary
> cpus generic.
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Cc: Matt Turner <mattst88@gmail.com>
> Cc: Russell King <linux@arm.linux.org.uk>
> Cc: Mike Frysinger <vapier@gentoo.org>

For the CRIS part:

Acked-by: Jesper Nilsson <jesper.nilsson@axis.com>

/^JN - Jesper Nilsson
-- 
               Jesper Nilsson -- jesper.nilsson@axis.com

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 11/18] hexagon: Use generic idle thread allocation
  2012-04-20 13:05 ` [patch 11/18] hexagon: " Thomas Gleixner
@ 2012-04-24 16:47   ` Richard Kuo
  2012-04-28  9:10   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
  1 sibling, 0 replies; 75+ messages in thread
From: Richard Kuo @ 2012-04-24 16:47 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Peter Zijlstra, Rusty Russell,
	Paul E. McKenney, Ingo Molnar, Srivatsa S. Bhat, linux-hexagon

On Fri, Apr 20, 2012 at 01:05:51PM -0000, Thomas Gleixner wrote:
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Cc: Richard Kuo <rkuo@codeaurora.org>
> ---
>  arch/hexagon/Kconfig      |    1 +
>  arch/hexagon/kernel/smp.c |   11 ++---------
>  2 files changed, 3 insertions(+), 9 deletions(-)

Tested; works for me.

Acked-by: Richard Kuo <rkuo@codeaurora.org>


-- 

Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1
  2012-04-20 14:18   ` Thomas Gleixner
@ 2012-04-24 18:44     ` Konrad Rzeszutek Wilk
  2012-05-21  1:42     ` Rusty Russell
  1 sibling, 0 replies; 75+ messages in thread
From: Konrad Rzeszutek Wilk @ 2012-04-24 18:44 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Srivatsa S. Bhat, LKML, linux-arch, Peter Zijlstra,
	Rusty Russell, Paul E. McKenney, Ingo Molnar, Nikunj A Dadhania,
	Steven Rostedt

On Fri, Apr 20, 2012 at 04:18:04PM +0200, Thomas Gleixner wrote:
> On Fri, 20 Apr 2012, Srivatsa S. Bhat wrote:
> > > This first part moves the idle thread management for non-boot cpus
> > > into the core. fork_idle() is called in a workqueue as it is
> > > implemented in a few architectures already. This is necessary when not
> > > all cpus are brought up by the early boot code as otherwise we would
> > > take a ref on the user task VM of the thread which brings the cpu up
> > > via the sysfs interface.
> > > 
> > 
> > 
> > Do you have a git tree where you have made these patches available?
> > That would be pretty useful, so that we can build on whatever you have
> 
> Not yet, but I'll stick that into a tip/ branch.

Looking at the patch from the Xen side it looks OK. But would like to test
to make sure - is there a git branch I could pull to run this?

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [tip:smp/hotplug] m32r: Remove pointless function prototypes
  2012-04-20 13:05 ` [patch 01/18] m32r: Remove pointless function prototypes Thomas Gleixner
@ 2012-04-28  9:01   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 75+ messages in thread
From: tip-bot for Thomas Gleixner @ 2012-04-28  9:01 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, rusty, peterz, srivatsa.bhat, paulmck,
	tglx, takata

Commit-ID:  bda3bdc9afce46302810e12ca1790ce08b9c40ce
Gitweb:     http://git.kernel.org/tip/bda3bdc9afce46302810e12ca1790ce08b9c40ce
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 20 Apr 2012 13:05:41 +0000
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 26 Apr 2012 12:06:08 +0200

m32r: Remove pointless function prototypes

Already declared in include/linux/smp.h

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Cc: Hirokazu Takata <takata@linux-m32r.org>
Link: http://lkml.kernel.org/r/20120420124556.899547554@linutronix.de
---
 arch/m32r/kernel/smpboot.c |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/arch/m32r/kernel/smpboot.c b/arch/m32r/kernel/smpboot.c
index cfdbe5d..31541c9 100644
--- a/arch/m32r/kernel/smpboot.c
+++ b/arch/m32r/kernel/smpboot.c
@@ -109,12 +109,8 @@ static unsigned int calibration_result;
 /* Function Prototypes                                                       */
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
 
-void smp_prepare_boot_cpu(void);
-void smp_prepare_cpus(unsigned int);
 static void init_ipi_lock(void);
 static void do_boot_cpu(int);
-int __cpu_up(unsigned int);
-void smp_cpus_done(unsigned int);
 
 int start_secondary(void *);
 static void smp_callin(void);

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [tip:smp/hotplug] smp: Add task_struct argument to __cpu_up()
  2012-04-20 13:05 ` [patch 02/18] smp: Add task_struct argument to __cpu_up() Thomas Gleixner
  2012-04-23  7:58   ` Jesper Nilsson
@ 2012-04-28  9:02   ` tip-bot for Thomas Gleixner
  1 sibling, 0 replies; 75+ messages in thread
From: tip-bot for Thomas Gleixner @ 2012-04-28  9:02 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: mingo, jesper.nilsson, rusty, schwidefsky, peterz, cmetcalf,
	tony.luck, ralf, linux, vapier, tglx, linux-kernel, hpa, richard,
	lethal, srivatsa.bhat, davem, paulmck, benh, dhowells, mattst88,
	jejb, takata, rkuo

Commit-ID:  8239c25f47d2b318156993b15f33900a86ea5e17
Gitweb:     http://git.kernel.org/tip/8239c25f47d2b318156993b15f33900a86ea5e17
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 20 Apr 2012 13:05:42 +0000
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 26 Apr 2012 12:06:09 +0200

smp: Add task_struct argument to __cpu_up()

Preparatory patch to make the idle thread allocation for secondary
cpus generic.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Cc: Matt Turner <mattst88@gmail.com>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Mike Frysinger <vapier@gentoo.org>
Cc: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: Richard Kuo <rkuo@codeaurora.org>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Hirokazu Takata <takata@linux-m32r.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: David Howells <dhowells@redhat.com>
Cc: James E.J. Bottomley <jejb@parisc-linux.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: David S. Miller <davem@davemloft.net>
Cc: Chris Metcalf <cmetcalf@tilera.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: x86@kernel.org
Link: http://lkml.kernel.org/r/20120420124556.964170564@linutronix.de

---
 arch/alpha/kernel/smp.c         |    2 +-
 arch/arm/kernel/smp.c           |    2 +-
 arch/blackfin/mach-common/smp.c |    2 +-
 arch/cris/arch-v32/kernel/smp.c |    2 +-
 arch/hexagon/kernel/smp.c       |    2 +-
 arch/ia64/kernel/smpboot.c      |    2 +-
 arch/m32r/kernel/smpboot.c      |    2 +-
 arch/mips/kernel/smp.c          |    2 +-
 arch/mn10300/kernel/smp.c       |    2 +-
 arch/parisc/kernel/smp.c        |    2 +-
 arch/powerpc/kernel/smp.c       |    2 +-
 arch/s390/include/asm/smp.h     |    2 +-
 arch/s390/kernel/smp.c          |    2 +-
 arch/sh/kernel/smp.c            |    2 +-
 arch/sparc/kernel/smp_32.c      |    2 +-
 arch/sparc/kernel/smp_64.c      |    2 +-
 arch/tile/kernel/smpboot.c      |    2 +-
 arch/um/kernel/smp.c            |    2 +-
 arch/x86/include/asm/smp.h      |    4 +++-
 include/linux/smp.h             |    2 +-
 kernel/cpu.c                    |    2 +-
 21 files changed, 23 insertions(+), 21 deletions(-)

diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index 50d438d..68d3947 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -487,7 +487,7 @@ smp_prepare_boot_cpu(void)
 }
 
 int __cpuinit
-__cpu_up(unsigned int cpu)
+__cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	smp_boot_one_cpu(cpu);
 
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index addbbe8..f0e2cbb 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -60,7 +60,7 @@ enum ipi_msg_type {
 
 static DECLARE_COMPLETION(cpu_running);
 
-int __cpuinit __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	struct cpuinfo_arm *ci = &per_cpu(cpu_data, cpu);
 	struct task_struct *idle = ci->idle;
diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c
index ac8f8a4..d0cddd9 100644
--- a/arch/blackfin/mach-common/smp.c
+++ b/arch/blackfin/mach-common/smp.c
@@ -340,7 +340,7 @@ void smp_send_stop(void)
 	return;
 }
 
-int __cpuinit __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	int ret;
 	struct blackfin_cpudata *ci = &per_cpu(cpu_data, cpu);
diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c
index 0b99df7..125ee2d 100644
--- a/arch/cris/arch-v32/kernel/smp.c
+++ b/arch/cris/arch-v32/kernel/smp.c
@@ -207,7 +207,7 @@ int setup_profiling_timer(unsigned int multiplier)
  */
 unsigned long cache_decay_ticks = 1;
 
-int __cpuinit __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	smp_boot_one_cpu(cpu);
 	return cpu_online(cpu) ? 0 : -ENOSYS;
diff --git a/arch/hexagon/kernel/smp.c b/arch/hexagon/kernel/smp.c
index 1298141..93e77e2 100644
--- a/arch/hexagon/kernel/smp.c
+++ b/arch/hexagon/kernel/smp.c
@@ -196,7 +196,7 @@ void __cpuinit start_secondary(void)
  * maintains control until "cpu_online(cpu)" is set.
  */
 
-int __cpuinit __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	struct task_struct *idle;
 	struct thread_info *thread;
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index 796f6a5..03e4ef3 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -793,7 +793,7 @@ set_cpu_sibling_map(int cpu)
 }
 
 int __cpuinit
-__cpu_up (unsigned int cpu)
+__cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	int ret;
 	int sapicid;
diff --git a/arch/m32r/kernel/smpboot.c b/arch/m32r/kernel/smpboot.c
index 31541c9..a2cfc0a 100644
--- a/arch/m32r/kernel/smpboot.c
+++ b/arch/m32r/kernel/smpboot.c
@@ -343,7 +343,7 @@ static void __init do_boot_cpu(int phys_id)
 	}
 }
 
-int __cpuinit __cpu_up(unsigned int cpu_id)
+int __cpuinit __cpu_up(unsigned int cpu_id, struct task_struct *tidle)
 {
 	int timeout;
 
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index ba9376b..41079b2 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -209,7 +209,7 @@ static void __cpuinit do_fork_idle(struct work_struct *work)
 	complete(&c_idle->done);
 }
 
-int __cpuinit __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	struct task_struct *idle;
 
diff --git a/arch/mn10300/kernel/smp.c b/arch/mn10300/kernel/smp.c
index 910dddf..c6b40da 100644
--- a/arch/mn10300/kernel/smp.c
+++ b/arch/mn10300/kernel/smp.c
@@ -921,7 +921,7 @@ void initialize_secondary(void)
  * __cpu_up - Set smp_commenced_mask for the nominated CPU
  * @cpu: The target CPU.
  */
-int __devinit __cpu_up(unsigned int cpu)
+int __devinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	int timeout;
 
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index 0bb1d63..eae8cd8 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -449,7 +449,7 @@ void smp_cpus_done(unsigned int cpu_max)
 }
 
 
-int __cpuinit __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	if (cpu != 0 && cpu < parisc_max_cpus)
 		smp_boot_one_cpu(cpu);
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index d9f9441..d38030f 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -482,7 +482,7 @@ static int __cpuinit create_idle(unsigned int cpu)
 	return 0;
 }
 
-int __cpuinit __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	int rc, c;
 
diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h
index c77c6de..0b6f586 100644
--- a/arch/s390/include/asm/smp.h
+++ b/arch/s390/include/asm/smp.h
@@ -16,7 +16,7 @@
 extern struct mutex smp_cpu_state_mutex;
 extern struct save_area *zfcpdump_save_areas[NR_CPUS + 1];
 
-extern int __cpu_up(unsigned int cpu);
+extern int __cpu_up(unsigned int cpu, struct task_struct *tidle);
 
 extern void arch_send_call_function_single_ipi(int cpu);
 extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 1f77227..fc827aa 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -738,7 +738,7 @@ static void __cpuinit smp_fork_idle(struct work_struct *work)
 }
 
 /* Upping and downing of CPUs */
-int __cpuinit __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	struct create_idle c_idle;
 	struct pcpu *pcpu;
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
index eaebdf6..ebb76e2 100644
--- a/arch/sh/kernel/smp.c
+++ b/arch/sh/kernel/smp.c
@@ -220,7 +220,7 @@ extern struct {
 	void *thread_info;
 } stack_start;
 
-int __cpuinit __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	struct task_struct *tsk;
 	unsigned long timeout;
diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c
index f671e7f..1f397ae 100644
--- a/arch/sparc/kernel/smp_32.c
+++ b/arch/sparc/kernel/smp_32.c
@@ -411,7 +411,7 @@ void __init smp_prepare_boot_cpu(void)
 	set_cpu_possible(cpuid, true);
 }
 
-int __cpuinit __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	extern int __cpuinit smp4m_boot_one_cpu(int);
 	extern int __cpuinit smp4d_boot_one_cpu(int);
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c
index 3b1bd7c..2f9948c 100644
--- a/arch/sparc/kernel/smp_64.c
+++ b/arch/sparc/kernel/smp_64.c
@@ -1227,7 +1227,7 @@ void __devinit smp_fill_in_sib_core_maps(void)
 	}
 }
 
-int __cpuinit __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	int ret = smp_boot_one_cpu(cpu);
 
diff --git a/arch/tile/kernel/smpboot.c b/arch/tile/kernel/smpboot.c
index 172aef7..84873fb 100644
--- a/arch/tile/kernel/smpboot.c
+++ b/arch/tile/kernel/smpboot.c
@@ -222,7 +222,7 @@ void __cpuinit online_secondary(void)
 	cpu_idle();
 }
 
-int __cpuinit __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	/* Wait 5s total for all CPUs for them to come online */
 	static int timeout;
diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c
index 6f588e1..a02b7e9 100644
--- a/arch/um/kernel/smp.c
+++ b/arch/um/kernel/smp.c
@@ -140,7 +140,7 @@ void smp_prepare_boot_cpu(void)
 	set_cpu_online(smp_processor_id(), true);
 }
 
-int __cpu_up(unsigned int cpu)
+int __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	cpu_set(cpu, smp_commenced_mask);
 	while (!cpu_online(cpu))
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
index 0434c40..4eb3a74 100644
--- a/arch/x86/include/asm/smp.h
+++ b/arch/x86/include/asm/smp.h
@@ -62,6 +62,8 @@ DECLARE_EARLY_PER_CPU(int, x86_cpu_to_logical_apicid);
 /* Static state in head.S used to set up a CPU */
 extern unsigned long stack_start; /* Initial stack pointer address */
 
+struct task_struct;
+
 struct smp_ops {
 	void (*smp_prepare_boot_cpu)(void);
 	void (*smp_prepare_cpus)(unsigned max_cpus);
@@ -113,7 +115,7 @@ static inline void smp_cpus_done(unsigned int max_cpus)
 	smp_ops.smp_cpus_done(max_cpus);
 }
 
-static inline int __cpu_up(unsigned int cpu)
+static inline int __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	return smp_ops.cpu_up(cpu);
 }
diff --git a/include/linux/smp.h b/include/linux/smp.h
index 10530d9..24360de 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -61,7 +61,7 @@ extern void smp_prepare_cpus(unsigned int max_cpus);
 /*
  * Bring a CPU up
  */
-extern int __cpu_up(unsigned int cpunum);
+extern int __cpu_up(unsigned int cpunum, struct task_struct *tidle);
 
 /*
  * Final polishing of CPUs
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 2060c6e..e711aef 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -309,7 +309,7 @@ static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen)
 	}
 
 	/* Arch-specific enabling code. */
-	ret = __cpu_up(cpu);
+	ret = __cpu_up(cpu, NULL);
 	if (ret != 0)
 		goto out_notify;
 	BUG_ON(!cpu_online(cpu));

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [tip:smp/hotplug] smp: Add generic smpboot facility
  2012-04-20 13:05 ` [patch 03/18] smp: Add generic smpboot facility Thomas Gleixner
  2012-04-20 20:07   ` Yinghai Lu
  2012-04-21  2:07   ` Stephen Rothwell
@ 2012-04-28  9:04   ` tip-bot for Thomas Gleixner
  2 siblings, 0 replies; 75+ messages in thread
From: tip-bot for Thomas Gleixner @ 2012-04-28  9:04 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: mingo, jesper.nilsson, rusty, schwidefsky, peterz, cmetcalf,
	tony.luck, ralf, linux, vapier, tglx, linux-kernel, hpa, richard,
	lethal, srivatsa.bhat, davem, paulmck, benh, dhowells, mattst88,
	jejb, takata, rkuo

Commit-ID:  38498a67aa2cf8c80754b8d304bfacc10bc582b5
Gitweb:     http://git.kernel.org/tip/38498a67aa2cf8c80754b8d304bfacc10bc582b5
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 20 Apr 2012 13:05:44 +0000
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 26 Apr 2012 12:06:09 +0200

smp: Add generic smpboot facility

Start a new file, which will hold SMP and CPU hotplug related generic
infrastructure.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Cc: Matt Turner <mattst88@gmail.com>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Mike Frysinger <vapier@gentoo.org>
Cc: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: Richard Kuo <rkuo@codeaurora.org>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Hirokazu Takata <takata@linux-m32r.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: David Howells <dhowells@redhat.com>
Cc: James E.J. Bottomley <jejb@parisc-linux.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: David S. Miller <davem@davemloft.net>
Cc: Chris Metcalf <cmetcalf@tilera.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: x86@kernel.org
Link: http://lkml.kernel.org/r/20120420124557.035417523@linutronix.de

---
 kernel/Makefile  |    1 +
 kernel/cpu.c     |    8 ++++++++
 kernel/smpboot.c |   14 ++++++++++++++
 kernel/smpboot.h |    6 ++++++
 4 files changed, 29 insertions(+), 0 deletions(-)

diff --git a/kernel/Makefile b/kernel/Makefile
index cb41b95..6c07f30 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_DEBUG_RT_MUTEXES) += rtmutex-debug.o
 obj-$(CONFIG_RT_MUTEX_TESTER) += rtmutex-tester.o
 obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
 obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_SMP) += smpboot.o
 ifneq ($(CONFIG_SMP),y)
 obj-y += up.o
 endif
diff --git a/kernel/cpu.c b/kernel/cpu.c
index e711aef..e58b99a 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -17,6 +17,8 @@
 #include <linux/gfp.h>
 #include <linux/suspend.h>
 
+#include "smpboot.h"
+
 #ifdef CONFIG_SMP
 /* Serializes the updates to cpu_online_mask, cpu_present_mask */
 static DEFINE_MUTEX(cpu_add_remove_lock);
@@ -300,6 +302,11 @@ static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen)
 		return -EINVAL;
 
 	cpu_hotplug_begin();
+
+	ret = smpboot_prepare(cpu);
+	if (ret)
+		goto out;
+
 	ret = __cpu_notify(CPU_UP_PREPARE | mod, hcpu, -1, &nr_calls);
 	if (ret) {
 		nr_calls--;
@@ -320,6 +327,7 @@ static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen)
 out_notify:
 	if (ret != 0)
 		__cpu_notify(CPU_UP_CANCELED | mod, hcpu, nr_calls, NULL);
+out:
 	cpu_hotplug_done();
 
 	return ret;
diff --git a/kernel/smpboot.c b/kernel/smpboot.c
new file mode 100644
index 0000000..6dae6a3
--- /dev/null
+++ b/kernel/smpboot.c
@@ -0,0 +1,14 @@
+/*
+ * Common SMP CPU bringup/teardown functions
+ */
+#include <linux/init.h>
+
+#include "smpboot.h"
+
+/**
+ * smpboot_prepare - generic smpboot preparation
+ */
+int __cpuinit smpboot_prepare(unsigned int cpu)
+{
+	return 0;
+}
diff --git a/kernel/smpboot.h b/kernel/smpboot.h
new file mode 100644
index 0000000..d88e771
--- /dev/null
+++ b/kernel/smpboot.h
@@ -0,0 +1,6 @@
+#ifndef SMPBOOT_H
+#define SMPBOOT_H
+
+int smpboot_prepare(unsigned int cpu);
+
+#endif

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [tip:smp/hotplug] smp: Provide generic idle thread allocation
  2012-04-20 13:05 ` [patch 04/18] smp: Provide generic idle thread allocation Thomas Gleixner
                     ` (2 preceding siblings ...)
  2012-04-21  2:25   ` Frank Rowand
@ 2012-04-28  9:05   ` tip-bot for Thomas Gleixner
  3 siblings, 0 replies; 75+ messages in thread
From: tip-bot for Thomas Gleixner @ 2012-04-28  9:05 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: mingo, jesper.nilsson, rusty, schwidefsky, peterz, cmetcalf,
	tony.luck, ralf, linux, vapier, tglx, venki, linux-kernel, hpa,
	richard, lethal, srivatsa.bhat, davem, paulmck, benh, dhowells,
	mattst88, jejb, takata, rkuo

Commit-ID:  29d5e0476e1c4a513859e7858845ad172f560389
Gitweb:     http://git.kernel.org/tip/29d5e0476e1c4a513859e7858845ad172f560389
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 20 Apr 2012 13:05:45 +0000
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 26 Apr 2012 12:06:09 +0200

smp: Provide generic idle thread allocation

All SMP architectures have magic to fork the idle task and to store it
for reusage when cpu hotplug is enabled. Provide a generic
infrastructure for it.

Create/reinit the idle thread for the cpu which is brought up in the
generic code and hand the thread pointer to the architecture code via
__cpu_up().

Note, that fork_idle() is called via a workqueue, because this
guarantees that the idle thread does not get a reference to a user
space VM. This can happen when the boot process did not bring up all
possible cpus and a later cpu_up() is initiated via the sysfs
interface. In that case fork_idle() would be called in the context of
the user space task and take a reference on the user space VM.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Cc: Matt Turner <mattst88@gmail.com>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Mike Frysinger <vapier@gentoo.org>
Cc: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: Richard Kuo <rkuo@codeaurora.org>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Hirokazu Takata <takata@linux-m32r.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: David Howells <dhowells@redhat.com>
Cc: James E.J. Bottomley <jejb@parisc-linux.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: David S. Miller <davem@davemloft.net>
Cc: Chris Metcalf <cmetcalf@tilera.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: x86@kernel.org
Acked-by: Venkatesh Pallipadi <venki@google.com>
Link: http://lkml.kernel.org/r/20120420124557.102478630@linutronix.de
---
 arch/Kconfig        |    3 ++
 kernel/cpu.c        |    2 +-
 kernel/sched/core.c |    2 +
 kernel/smpboot.c    |   84 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 kernel/smpboot.h    |   10 ++++++
 5 files changed, 99 insertions(+), 2 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index 684eb5a..4f0d0f7 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -145,6 +145,9 @@ config HAVE_DMA_ATTRS
 config USE_GENERIC_SMP_HELPERS
 	bool
 
+config GENERIC_SMP_IDLE_THREAD
+       bool
+
 config HAVE_REGS_AND_STACK_ACCESS_API
 	bool
 	help
diff --git a/kernel/cpu.c b/kernel/cpu.c
index e58b99a..05c46ba 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -316,7 +316,7 @@ static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen)
 	}
 
 	/* Arch-specific enabling code. */
-	ret = __cpu_up(cpu, NULL);
+	ret = __cpu_up(cpu, idle_thread_get(cpu));
 	if (ret != 0)
 		goto out_notify;
 	BUG_ON(!cpu_online(cpu));
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 4603b9d..6a63cde 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -83,6 +83,7 @@
 
 #include "sched.h"
 #include "../workqueue_sched.h"
+#include "../smpboot.h"
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/sched.h>
@@ -7049,6 +7050,7 @@ void __init sched_init(void)
 	/* May be allocated at isolcpus cmdline parse time */
 	if (cpu_isolated_map == NULL)
 		zalloc_cpumask_var(&cpu_isolated_map, GFP_NOWAIT);
+	idle_thread_set_boot_cpu();
 #endif
 	init_sched_fair_class();
 
diff --git a/kernel/smpboot.c b/kernel/smpboot.c
index 6dae6a3..ed15769 100644
--- a/kernel/smpboot.c
+++ b/kernel/smpboot.c
@@ -1,14 +1,96 @@
 /*
  * Common SMP CPU bringup/teardown functions
  */
+#include <linux/err.h>
+#include <linux/smp.h>
 #include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/percpu.h>
+#include <linux/workqueue.h>
 
 #include "smpboot.h"
 
+#ifdef CONFIG_GENERIC_SMP_IDLE_THREAD
+struct create_idle {
+	struct work_struct	work;
+	struct task_struct	*idle;
+	struct completion	done;
+	unsigned int cpu;
+};
+
+static void __cpuinit do_fork_idle(struct work_struct *work)
+{
+	struct create_idle *c = container_of(work, struct create_idle, work);
+
+	c->idle = fork_idle(c->cpu);
+	complete(&c->done);
+}
+
+static struct task_struct * __cpuinit idle_thread_create(unsigned int cpu)
+{
+	struct create_idle c_idle = {
+		.cpu	= cpu,
+		.done	= COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
+	};
+
+	INIT_WORK_ONSTACK(&c_idle.work, do_fork_idle);
+	schedule_work(&c_idle.work);
+	wait_for_completion(&c_idle.done);
+	destroy_work_on_stack(&c_idle.work);
+	return c_idle.idle;
+}
+
+/*
+ * For the hotplug case we keep the task structs around and reuse
+ * them.
+ */
+static DEFINE_PER_CPU(struct task_struct *, idle_threads);
+
+static inline struct task_struct *get_idle_for_cpu(unsigned int cpu)
+{
+	struct task_struct *tsk = per_cpu(idle_threads, cpu);
+
+	if (!tsk)
+		return idle_thread_create(cpu);
+	init_idle(tsk, cpu);
+	return tsk;
+}
+
+struct task_struct * __cpuinit idle_thread_get(unsigned int cpu)
+{
+	return per_cpu(idle_threads, cpu);
+}
+
+void __init idle_thread_set_boot_cpu(void)
+{
+	per_cpu(idle_threads, smp_processor_id()) = current;
+}
+
+/**
+ * idle_thread_init - Initialize the idle thread for a cpu
+ * @cpu:	The cpu for which the idle thread should be initialized
+ *
+ * Creates the thread if it does not exist.
+ */
+static int __cpuinit idle_thread_init(unsigned int cpu)
+{
+	struct task_struct *idle = get_idle_for_cpu(cpu);
+
+	if (IS_ERR(idle)) {
+		printk(KERN_ERR "failed fork for CPU %u\n", cpu);
+		return PTR_ERR(idle);
+	}
+	per_cpu(idle_threads, cpu) = idle;
+	return 0;
+}
+#else
+static inline int idle_thread_init(unsigned int cpu) { return 0; }
+#endif
+
 /**
  * smpboot_prepare - generic smpboot preparation
  */
 int __cpuinit smpboot_prepare(unsigned int cpu)
 {
-	return 0;
+	return idle_thread_init(cpu);
 }
diff --git a/kernel/smpboot.h b/kernel/smpboot.h
index d88e771..7943bbb 100644
--- a/kernel/smpboot.h
+++ b/kernel/smpboot.h
@@ -1,6 +1,16 @@
 #ifndef SMPBOOT_H
 #define SMPBOOT_H
 
+struct task_struct;
+
 int smpboot_prepare(unsigned int cpu);
 
+#ifdef CONFIG_GENERIC_SMP_IDLE_THREAD
+struct task_struct *idle_thread_get(unsigned int cpu);
+void idle_thread_set_boot_cpu(void);
+#else
+static inline struct task_struct *idle_thread_get(unsigned int cpu) { return NULL; }
+static inline void idle_thread_set_boot_cpu(void) { }
+#endif
+
 #endif

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [tip:smp/hotplug] x86: Add task_struct argument to smp_ops.cpu_up
  2012-04-20 13:05 ` [patch 05/18] x86: Add task_struct argument to smp_ops.cpu_up Thomas Gleixner
@ 2012-04-28  9:05   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 75+ messages in thread
From: tip-bot for Thomas Gleixner @ 2012-04-28  9:05 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, rusty, peterz, srivatsa.bhat, paulmck,
	jeremy, tglx

Commit-ID:  5cdaf1834f43b0edc4a3aa683aa4ec98f6bfe8a7
Gitweb:     http://git.kernel.org/tip/5cdaf1834f43b0edc4a3aa683aa4ec98f6bfe8a7
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 20 Apr 2012 13:05:47 +0000
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 26 Apr 2012 12:06:10 +0200

x86: Add task_struct argument to smp_ops.cpu_up

Preparatory patch to use the generic idle thread allocation.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>
Cc: x86@kernel.org
Link: http://lkml.kernel.org/r/20120420124557.176604405@linutronix.de
---
 arch/x86/include/asm/smp.h |    6 +++---
 arch/x86/kernel/smpboot.c  |    2 +-
 arch/x86/xen/smp.c         |    6 +++---
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
index 4eb3a74..f3ed338 100644
--- a/arch/x86/include/asm/smp.h
+++ b/arch/x86/include/asm/smp.h
@@ -72,7 +72,7 @@ struct smp_ops {
 	void (*stop_other_cpus)(int wait);
 	void (*smp_send_reschedule)(int cpu);
 
-	int (*cpu_up)(unsigned cpu);
+	int (*cpu_up)(unsigned cpu, struct task_struct *tidle);
 	int (*cpu_disable)(void);
 	void (*cpu_die)(unsigned int cpu);
 	void (*play_dead)(void);
@@ -117,7 +117,7 @@ static inline void smp_cpus_done(unsigned int max_cpus)
 
 static inline int __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
-	return smp_ops.cpu_up(cpu);
+	return smp_ops.cpu_up(cpu, tidle);
 }
 
 static inline int __cpu_disable(void)
@@ -154,7 +154,7 @@ void cpu_disable_common(void);
 void native_smp_prepare_boot_cpu(void);
 void native_smp_prepare_cpus(unsigned int max_cpus);
 void native_smp_cpus_done(unsigned int max_cpus);
-int native_cpu_up(unsigned int cpunum);
+int native_cpu_up(unsigned int cpunum, struct task_struct *tidle);
 int native_cpu_disable(void);
 void native_cpu_die(unsigned int cpu);
 void native_play_dead(void);
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 6e1e406..def235b 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -818,7 +818,7 @@ do_rest:
 	return boot_error;
 }
 
-int __cpuinit native_cpu_up(unsigned int cpu)
+int __cpuinit native_cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	int apicid = apic->cpu_present_to_apicid(cpu);
 	unsigned long flags;
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 5fac691..64d3bbc 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -331,7 +331,7 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
 	return 0;
 }
 
-static int __cpuinit xen_cpu_up(unsigned int cpu)
+static int __cpuinit xen_cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	struct task_struct *idle = idle_task(cpu);
 	int rc;
@@ -547,10 +547,10 @@ static void __init xen_hvm_smp_prepare_cpus(unsigned int max_cpus)
 	xen_init_lock_cpu(0);
 }
 
-static int __cpuinit xen_hvm_cpu_up(unsigned int cpu)
+static int __cpuinit xen_hvm_cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	int rc;
-	rc = native_cpu_up(cpu);
+	rc = native_cpu_up(cpu, tidle);
 	WARN_ON (xen_smp_intr_init(cpu));
 	return rc;
 }

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [tip:smp/hotplug] x86: Use generic idle thread allocation
  2012-04-20 13:05 ` [patch 06/18] x86: Use generic idle thread allocation Thomas Gleixner
@ 2012-04-28  9:06   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 75+ messages in thread
From: tip-bot for Thomas Gleixner @ 2012-04-28  9:06 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, rusty, peterz, srivatsa.bhat, paulmck,
	jeremy, tglx

Commit-ID:  7eb43a6d232bfa46464b501cd1987ec2d705d8cf
Gitweb:     http://git.kernel.org/tip/7eb43a6d232bfa46464b501cd1987ec2d705d8cf
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 20 Apr 2012 13:05:48 +0000
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 26 Apr 2012 12:06:10 +0200

x86: Use generic idle thread allocation

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>
Cc: x86@kernel.org
Link: http://lkml.kernel.org/r/20120420124557.246929343@linutronix.de

---
 arch/x86/Kconfig           |    1 +
 arch/x86/include/asm/smp.h |    1 +
 arch/x86/kernel/smpboot.c  |   81 +++++--------------------------------------
 arch/x86/xen/smp.c         |   15 +-------
 4 files changed, 14 insertions(+), 84 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 1d14cc6..046bf4b 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -82,6 +82,7 @@ config X86
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select GENERIC_IOMAP
 	select DCACHE_WORD_ACCESS if !DEBUG_PAGEALLOC
+	select GENERIC_SMP_IDLE_THREAD
 
 config INSTRUCTION_DECODER
 	def_bool (KPROBES || PERF_EVENTS)
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
index f3ed338..f8cbc6f 100644
--- a/arch/x86/include/asm/smp.h
+++ b/arch/x86/include/asm/smp.h
@@ -164,6 +164,7 @@ int wbinvd_on_all_cpus(void);
 
 void native_send_call_func_ipi(const struct cpumask *mask);
 void native_send_call_func_single_ipi(int cpu);
+void x86_idle_thread_init(unsigned int cpu, struct task_struct *idle);
 
 void smp_store_cpu_info(int id);
 #define cpu_physical_id(cpu)	per_cpu(x86_cpu_to_apicid, cpu)
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index def235b..3acaf51 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -76,20 +76,8 @@
 /* State of each CPU */
 DEFINE_PER_CPU(int, cpu_state) = { 0 };
 
-/* Store all idle threads, this can be reused instead of creating
-* a new thread. Also avoids complicated thread destroy functionality
-* for idle threads.
-*/
 #ifdef CONFIG_HOTPLUG_CPU
 /*
- * Needed only for CONFIG_HOTPLUG_CPU because __cpuinitdata is
- * removed after init for !CONFIG_HOTPLUG_CPU.
- */
-static DEFINE_PER_CPU(struct task_struct *, idle_thread_array);
-#define get_idle_for_cpu(x)      (per_cpu(idle_thread_array, x))
-#define set_idle_for_cpu(x, p)   (per_cpu(idle_thread_array, x) = (p))
-
-/*
  * We need this for trampoline_base protection from concurrent accesses when
  * off- and onlining cores wildly.
  */
@@ -97,20 +85,16 @@ static DEFINE_MUTEX(x86_cpu_hotplug_driver_mutex);
 
 void cpu_hotplug_driver_lock(void)
 {
-        mutex_lock(&x86_cpu_hotplug_driver_mutex);
+	mutex_lock(&x86_cpu_hotplug_driver_mutex);
 }
 
 void cpu_hotplug_driver_unlock(void)
 {
-        mutex_unlock(&x86_cpu_hotplug_driver_mutex);
+	mutex_unlock(&x86_cpu_hotplug_driver_mutex);
 }
 
 ssize_t arch_cpu_probe(const char *buf, size_t count) { return -1; }
 ssize_t arch_cpu_release(const char *buf, size_t count) { return -1; }
-#else
-static struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ;
-#define get_idle_for_cpu(x)      (idle_thread_array[(x)])
-#define set_idle_for_cpu(x, p)   (idle_thread_array[(x)] = (p))
 #endif
 
 /* Number of siblings per CPU package */
@@ -618,22 +602,6 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
 	return (send_status | accept_status);
 }
 
-struct create_idle {
-	struct work_struct work;
-	struct task_struct *idle;
-	struct completion done;
-	int cpu;
-};
-
-static void __cpuinit do_fork_idle(struct work_struct *work)
-{
-	struct create_idle *c_idle =
-		container_of(work, struct create_idle, work);
-
-	c_idle->idle = fork_idle(c_idle->cpu);
-	complete(&c_idle->done);
-}
-
 /* reduce the number of lines printed when booting a large cpu count system */
 static void __cpuinit announce_cpu(int cpu, int apicid)
 {
@@ -660,58 +628,31 @@ static void __cpuinit announce_cpu(int cpu, int apicid)
  * Returns zero if CPU booted OK, else error code from
  * ->wakeup_secondary_cpu.
  */
-static int __cpuinit do_boot_cpu(int apicid, int cpu)
+static int __cpuinit do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
 {
 	unsigned long boot_error = 0;
 	unsigned long start_ip;
 	int timeout;
-	struct create_idle c_idle = {
-		.cpu	= cpu,
-		.done	= COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
-	};
-
-	INIT_WORK_ONSTACK(&c_idle.work, do_fork_idle);
 
 	alternatives_smp_switch(1);
 
-	c_idle.idle = get_idle_for_cpu(cpu);
-
-	/*
-	 * We can't use kernel_thread since we must avoid to
-	 * reschedule the child.
-	 */
-	if (c_idle.idle) {
-		c_idle.idle->thread.sp = (unsigned long) (((struct pt_regs *)
-			(THREAD_SIZE +  task_stack_page(c_idle.idle))) - 1);
-		init_idle(c_idle.idle, cpu);
-		goto do_rest;
-	}
+	idle->thread.sp = (unsigned long) (((struct pt_regs *)
+			  (THREAD_SIZE +  task_stack_page(idle))) - 1);
+	per_cpu(current_task, cpu) = idle;
 
-	schedule_work(&c_idle.work);
-	wait_for_completion(&c_idle.done);
-
-	if (IS_ERR(c_idle.idle)) {
-		printk("failed fork for CPU %d\n", cpu);
-		destroy_work_on_stack(&c_idle.work);
-		return PTR_ERR(c_idle.idle);
-	}
-
-	set_idle_for_cpu(cpu, c_idle.idle);
-do_rest:
-	per_cpu(current_task, cpu) = c_idle.idle;
 #ifdef CONFIG_X86_32
 	/* Stack for startup_32 can be just as for start_secondary onwards */
 	irq_ctx_init(cpu);
 #else
-	clear_tsk_thread_flag(c_idle.idle, TIF_FORK);
+	clear_tsk_thread_flag(idle, TIF_FORK);
 	initial_gs = per_cpu_offset(cpu);
 	per_cpu(kernel_stack, cpu) =
-		(unsigned long)task_stack_page(c_idle.idle) -
+		(unsigned long)task_stack_page(idle) -
 		KERNEL_STACK_OFFSET + THREAD_SIZE;
 #endif
 	early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
 	initial_code = (unsigned long)start_secondary;
-	stack_start  = c_idle.idle->thread.sp;
+	stack_start  = idle->thread.sp;
 
 	/* start_ip had better be page-aligned! */
 	start_ip = trampoline_address();
@@ -813,8 +754,6 @@ do_rest:
 		 */
 		smpboot_restore_warm_reset_vector();
 	}
-
-	destroy_work_on_stack(&c_idle.work);
 	return boot_error;
 }
 
@@ -851,7 +790,7 @@ int __cpuinit native_cpu_up(unsigned int cpu, struct task_struct *tidle)
 
 	per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
 
-	err = do_boot_cpu(apicid, cpu);
+	err = do_boot_cpu(apicid, cpu, tidle);
 	if (err) {
 		pr_debug("do_boot_cpu failed %d\n", err);
 		return -EIO;
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 64d3bbc..8f44cc1 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -250,18 +250,8 @@ static void __init xen_smp_prepare_cpus(unsigned int max_cpus)
 		set_cpu_possible(cpu, false);
 	}
 
-	for_each_possible_cpu (cpu) {
-		struct task_struct *idle;
-
-		if (cpu == 0)
-			continue;
-
-		idle = fork_idle(cpu);
-		if (IS_ERR(idle))
-			panic("failed fork for CPU %d", cpu);
-
+	for_each_possible_cpu(cpu)
 		set_cpu_present(cpu, true);
-	}
 }
 
 static int __cpuinit
@@ -331,9 +321,8 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
 	return 0;
 }
 
-static int __cpuinit xen_cpu_up(unsigned int cpu, struct task_struct *tidle)
+static int __cpuinit xen_cpu_up(unsigned int cpu, struct task_struct *idle)
 {
-	struct task_struct *idle = idle_task(cpu);
 	int rc;
 
 	per_cpu(current_task, cpu) = idle;

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [tip:smp/hotplug] powerpc: Use generic idle thread allocation
  2012-04-20 13:05 ` [patch 07/18] powerpc: " Thomas Gleixner
@ 2012-04-28  9:07   ` tip-bot for Thomas Gleixner
  2012-04-28 22:51     ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 75+ messages in thread
From: tip-bot for Thomas Gleixner @ 2012-04-28  9:07 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, rusty, peterz, srivatsa.bhat, paulmck,
	benh, tglx

Commit-ID:  17e32eacc3543c25a4377bb7ce54026e38db7d20
Gitweb:     http://git.kernel.org/tip/17e32eacc3543c25a4377bb7ce54026e38db7d20
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 20 Apr 2012 13:05:48 +0000
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 26 Apr 2012 12:06:10 +0200

powerpc: Use generic idle thread allocation

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Link: http://lkml.kernel.org/r/20120420124557.311212868@linutronix.de
---
 arch/powerpc/Kconfig      |    1 +
 arch/powerpc/kernel/smp.c |   74 +++-----------------------------------------
 2 files changed, 6 insertions(+), 69 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index feab3ba..c815535 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -144,6 +144,7 @@ config PPC
 	select HAVE_BPF_JIT if (PPC64 && NET)
 	select HAVE_ARCH_JUMP_LABEL
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
+	select GENERIC_SMP_IDLE_THREAD
 
 config EARLY_PRINTK
 	bool
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index d38030f..e4cb343 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -57,27 +57,9 @@
 #define DBG(fmt...)
 #endif
 
-
-/* Store all idle threads, this can be reused instead of creating
-* a new thread. Also avoids complicated thread destroy functionality
-* for idle threads.
-*/
 #ifdef CONFIG_HOTPLUG_CPU
-/*
- * Needed only for CONFIG_HOTPLUG_CPU because __cpuinitdata is
- * removed after init for !CONFIG_HOTPLUG_CPU.
- */
-static DEFINE_PER_CPU(struct task_struct *, idle_thread_array);
-#define get_idle_for_cpu(x)      (per_cpu(idle_thread_array, x))
-#define set_idle_for_cpu(x, p)   (per_cpu(idle_thread_array, x) = (p))
-
 /* State of each CPU during hotplug phases */
 static DEFINE_PER_CPU(int, cpu_state) = { 0 };
-
-#else
-static struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ;
-#define get_idle_for_cpu(x)      (idle_thread_array[(x)])
-#define set_idle_for_cpu(x, p)   (idle_thread_array[(x)] = (p))
 #endif
 
 struct thread_info *secondary_ti;
@@ -429,57 +411,16 @@ int generic_check_cpu_restart(unsigned int cpu)
 }
 #endif
 
-struct create_idle {
-	struct work_struct work;
-	struct task_struct *idle;
-	struct completion done;
-	int cpu;
-};
-
-static void __cpuinit do_fork_idle(struct work_struct *work)
+static void cpu_idle_thread_init(unsigned int cpu, struct task_struct *idle)
 {
-	struct create_idle *c_idle =
-		container_of(work, struct create_idle, work);
-
-	c_idle->idle = fork_idle(c_idle->cpu);
-	complete(&c_idle->done);
-}
-
-static int __cpuinit create_idle(unsigned int cpu)
-{
-	struct thread_info *ti;
-	struct create_idle c_idle = {
-		.cpu	= cpu,
-		.done	= COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
-	};
-	INIT_WORK_ONSTACK(&c_idle.work, do_fork_idle);
-
-	c_idle.idle = get_idle_for_cpu(cpu);
-
-	/* We can't use kernel_thread since we must avoid to
-	 * reschedule the child. We use a workqueue because
-	 * we want to fork from a kernel thread, not whatever
-	 * userspace process happens to be trying to online us.
-	 */
-	if (!c_idle.idle) {
-		schedule_work(&c_idle.work);
-		wait_for_completion(&c_idle.done);
-	} else
-		init_idle(c_idle.idle, cpu);
-	if (IS_ERR(c_idle.idle)) {		
-		pr_err("Failed fork for CPU %u: %li", cpu, PTR_ERR(c_idle.idle));
-		return PTR_ERR(c_idle.idle);
-	}
-	ti = task_thread_info(c_idle.idle);
+	struct thread_info *ti = task_thread_info(idle);
 
 #ifdef CONFIG_PPC64
-	paca[cpu].__current = c_idle.idle;
+	paca[cpu].__current = idle;
 	paca[cpu].kstack = (unsigned long)ti + THREAD_SIZE - STACK_FRAME_OVERHEAD;
 #endif
 	ti->cpu = cpu;
-	current_set[cpu] = ti;
-
-	return 0;
+	secondary_ti = current_set[cpu] = ti;
 }
 
 int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
@@ -490,12 +431,7 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 	    (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)))
 		return -EINVAL;
 
-	/* Make sure we have an idle thread */
-	rc = create_idle(cpu);
-	if (rc)
-		return rc;
-
-	secondary_ti = current_set[cpu];
+	cpu_idle_thread_init(cpu, tidle);
 
 	/* Make sure callin-map entry is 0 (can be leftover a CPU
 	 * hotplug

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [tip:smp/hotplug] ia64: Use generic idle thread allocation
  2012-04-20 13:05 ` [patch 08/18] ia64: " Thomas Gleixner
@ 2012-04-28  9:08   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 75+ messages in thread
From: tip-bot for Thomas Gleixner @ 2012-04-28  9:08 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, rusty, peterz, tony.luck,
	srivatsa.bhat, paulmck, tglx

Commit-ID:  13583bf15eb1e890e03d46b6f2753e4b64af21c9
Gitweb:     http://git.kernel.org/tip/13583bf15eb1e890e03d46b6f2753e4b64af21c9
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 20 Apr 2012 13:05:49 +0000
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 26 Apr 2012 12:06:10 +0200

ia64: Use generic idle thread allocation

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Cc: Tony Luck <tony.luck@intel.com>
Link: http://lkml.kernel.org/r/20120420124557.380965133@linutronix.de
---
 arch/ia64/Kconfig          |    1 +
 arch/ia64/kernel/smpboot.c |   61 ++-----------------------------------------
 2 files changed, 4 insertions(+), 58 deletions(-)

diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index bd72669..1197547 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -33,6 +33,7 @@ config IA64
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select GENERIC_IOMAP
+	select GENERIC_SMP_IDLE_THREAD
 	default y
 	help
 	  The Itanium Processor Family is Intel's 64-bit successor to
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index 03e4ef3..1113b8a 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -75,13 +75,6 @@
 #endif
 
 /*
- * Store all idle threads, this can be reused instead of creating
- * a new thread. Also avoids complicated thread destroy functionality
- * for idle threads.
- */
-struct task_struct *idle_thread_array[NR_CPUS];
-
-/*
  * Global array allocated for NR_CPUS at boot time
  */
 struct sal_to_os_boot sal_boot_rendez_state[NR_CPUS];
@@ -94,13 +87,7 @@ struct sal_to_os_boot *sal_state_for_booting_cpu = &sal_boot_rendez_state[0];
 
 #define set_brendez_area(x) (sal_state_for_booting_cpu = &sal_boot_rendez_state[(x)]);
 
-#define get_idle_for_cpu(x)		(idle_thread_array[(x)])
-#define set_idle_for_cpu(x,p)	(idle_thread_array[(x)] = (p))
-
 #else
-
-#define get_idle_for_cpu(x)		(NULL)
-#define set_idle_for_cpu(x,p)
 #define set_brendez_area(x)
 #endif
 
@@ -480,54 +467,12 @@ struct pt_regs * __cpuinit idle_regs(struct pt_regs *regs)
 	return NULL;
 }
 
-struct create_idle {
-	struct work_struct work;
-	struct task_struct *idle;
-	struct completion done;
-	int cpu;
-};
-
-void __cpuinit
-do_fork_idle(struct work_struct *work)
-{
-	struct create_idle *c_idle =
-		container_of(work, struct create_idle, work);
-
-	c_idle->idle = fork_idle(c_idle->cpu);
-	complete(&c_idle->done);
-}
-
 static int __cpuinit
-do_boot_cpu (int sapicid, int cpu)
+do_boot_cpu (int sapicid, int cpu, struct task_struct *idle)
 {
 	int timeout;
-	struct create_idle c_idle = {
-		.work = __WORK_INITIALIZER(c_idle.work, do_fork_idle),
-		.cpu	= cpu,
-		.done	= COMPLETION_INITIALIZER(c_idle.done),
-	};
-
-	/*
-	 * We can't use kernel_thread since we must avoid to
-	 * reschedule the child.
-	 */
- 	c_idle.idle = get_idle_for_cpu(cpu);
- 	if (c_idle.idle) {
-		init_idle(c_idle.idle, cpu);
- 		goto do_rest;
-	}
-
-	schedule_work(&c_idle.work);
-	wait_for_completion(&c_idle.done);
-
-	if (IS_ERR(c_idle.idle))
-		panic("failed fork for CPU %d", cpu);
-
-	set_idle_for_cpu(cpu, c_idle.idle);
-
-do_rest:
-	task_for_booting_cpu = c_idle.idle;
 
+	task_for_booting_cpu = idle;
 	Dprintk("Sending wakeup vector %lu to AP 0x%x/0x%x.\n", ap_wakeup_vector, cpu, sapicid);
 
 	set_brendez_area(cpu);
@@ -811,7 +756,7 @@ __cpu_up(unsigned int cpu, struct task_struct *tidle)
 
 	per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
 	/* Processor goes to start_secondary(), sets online flag */
-	ret = do_boot_cpu(sapicid, cpu);
+	ret = do_boot_cpu(sapicid, cpu, tidle);
 	if (ret < 0)
 		return ret;
 

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [tip:smp/hotplug] arm: Use generic idle thread allocation
  2012-04-20 13:05 ` [patch 09/18] arm: " Thomas Gleixner
@ 2012-04-28  9:09   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 75+ messages in thread
From: tip-bot for Thomas Gleixner @ 2012-04-28  9:09 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, rusty, peterz, srivatsa.bhat, paulmck,
	linux, frank.rowand, tglx

Commit-ID:  84ec6d5796e095e2f8698bd2b5d33849ed26d9e2
Gitweb:     http://git.kernel.org/tip/84ec6d5796e095e2f8698bd2b5d33849ed26d9e2
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 20 Apr 2012 13:05:50 +0000
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 26 Apr 2012 12:06:11 +0200

arm: Use generic idle thread allocation

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Cc: Russell King <linux@arm.linux.org.uk>
Tested-by: Frank Rowand <frank.rowand@am.sony.com>
Link: http://lkml.kernel.org/r/20120420124557.448826362@linutronix.de
---
 arch/arm/Kconfig           |    1 +
 arch/arm/include/asm/cpu.h |    1 -
 arch/arm/kernel/smp.c      |   26 +-------------------------
 3 files changed, 2 insertions(+), 26 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index cf006d4..cb253ce 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -34,6 +34,7 @@ config ARM
 	select CPU_PM if (SUSPEND || CPU_IDLE)
 	select GENERIC_PCI_IOMAP
 	select HAVE_BPF_JIT if NET
+	select GENERIC_SMP_IDLE_THREAD
 	help
 	  The ARM series is a line of low-power-consumption RISC chip designs
 	  licensed by ARM Ltd and targeted at embedded applications and
diff --git a/arch/arm/include/asm/cpu.h b/arch/arm/include/asm/cpu.h
index 7939681..d797223 100644
--- a/arch/arm/include/asm/cpu.h
+++ b/arch/arm/include/asm/cpu.h
@@ -16,7 +16,6 @@
 struct cpuinfo_arm {
 	struct cpu	cpu;
 #ifdef CONFIG_SMP
-	struct task_struct *idle;
 	unsigned int	loops_per_jiffy;
 #endif
 };
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index f0e2cbb..5e86f7c 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -60,32 +60,11 @@ enum ipi_msg_type {
 
 static DECLARE_COMPLETION(cpu_running);
 
-int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
 {
-	struct cpuinfo_arm *ci = &per_cpu(cpu_data, cpu);
-	struct task_struct *idle = ci->idle;
 	int ret;
 
 	/*
-	 * Spawn a new process manually, if not already done.
-	 * Grab a pointer to its task struct so we can mess with it
-	 */
-	if (!idle) {
-		idle = fork_idle(cpu);
-		if (IS_ERR(idle)) {
-			printk(KERN_ERR "CPU%u: fork() failed\n", cpu);
-			return PTR_ERR(idle);
-		}
-		ci->idle = idle;
-	} else {
-		/*
-		 * Since this idle thread is being re-used, call
-		 * init_idle() to reinitialize the thread structure.
-		 */
-		init_idle(idle, cpu);
-	}
-
-	/*
 	 * We need to tell the secondary core where to find
 	 * its stack and the page tables.
 	 */
@@ -318,9 +297,6 @@ void __init smp_cpus_done(unsigned int max_cpus)
 
 void __init smp_prepare_boot_cpu(void)
 {
-	unsigned int cpu = smp_processor_id();
-
-	per_cpu(cpu_data, cpu).idle = current;
 }
 
 void __init smp_prepare_cpus(unsigned int max_cpus)

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [tip:smp/hotplug] mips: Use generic idle thread allocation
  2012-04-20 13:05 ` [patch 10/18] mips: " Thomas Gleixner
@ 2012-04-28  9:10   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 75+ messages in thread
From: tip-bot for Thomas Gleixner @ 2012-04-28  9:10 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, rusty, peterz, srivatsa.bhat, paulmck,
	ralf, tglx

Commit-ID:  360014a36170464ebd9935514f0e0e3d558b0e56
Gitweb:     http://git.kernel.org/tip/360014a36170464ebd9935514f0e0e3d558b0e56
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 20 Apr 2012 13:05:51 +0000
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 26 Apr 2012 12:06:11 +0200

mips: Use generic idle thread allocation

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Link: http://lkml.kernel.org/r/20120420124557.512158271@linutronix.de

---
 arch/mips/Kconfig      |    1 +
 arch/mips/kernel/smp.c |   54 +-----------------------------------------------
 2 files changed, 2 insertions(+), 53 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index ce30e2f..186fc8c 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -29,6 +29,7 @@ config MIPS
 	select HAVE_MEMBLOCK
 	select HAVE_MEMBLOCK_NODE_MAP
 	select ARCH_DISCARD_MEMBLOCK
+	select GENERIC_SMP_IDLE_THREAD
 
 menu "Machine selection"
 
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 41079b2..71a95f5 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -186,61 +186,9 @@ void __devinit smp_prepare_boot_cpu(void)
 	cpu_set(0, cpu_callin_map);
 }
 
-/*
- * Called once for each "cpu_possible(cpu)".  Needs to spin up the cpu
- * and keep control until "cpu_online(cpu)" is set.  Note: cpu is
- * physical, not logical.
- */
-static struct task_struct *cpu_idle_thread[NR_CPUS];
-
-struct create_idle {
-	struct work_struct work;
-	struct task_struct *idle;
-	struct completion done;
-	int cpu;
-};
-
-static void __cpuinit do_fork_idle(struct work_struct *work)
-{
-	struct create_idle *c_idle =
-		container_of(work, struct create_idle, work);
-
-	c_idle->idle = fork_idle(c_idle->cpu);
-	complete(&c_idle->done);
-}
-
 int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
-	struct task_struct *idle;
-
-	/*
-	 * Processor goes to start_secondary(), sets online flag
-	 * The following code is purely to make sure
-	 * Linux can schedule processes on this slave.
-	 */
-	if (!cpu_idle_thread[cpu]) {
-		/*
-		 * Schedule work item to avoid forking user task
-		 * Ported from arch/x86/kernel/smpboot.c
-		 */
-		struct create_idle c_idle = {
-			.cpu    = cpu,
-			.done   = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
-		};
-
-		INIT_WORK_ONSTACK(&c_idle.work, do_fork_idle);
-		schedule_work(&c_idle.work);
-		wait_for_completion(&c_idle.done);
-		idle = cpu_idle_thread[cpu] = c_idle.idle;
-
-		if (IS_ERR(idle))
-			panic(KERN_ERR "Fork failed for CPU %d", cpu);
-	} else {
-		idle = cpu_idle_thread[cpu];
-		init_idle(idle, cpu);
-	}
-
-	mp_ops->boot_secondary(cpu, idle);
+	mp_ops->boot_secondary(cpu, tidle);
 
 	/*
 	 * Trust is futile.  We should really have timeouts ...

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [tip:smp/hotplug] hexagon: Use generic idle thread allocation
  2012-04-20 13:05 ` [patch 11/18] hexagon: " Thomas Gleixner
  2012-04-24 16:47   ` Richard Kuo
@ 2012-04-28  9:10   ` tip-bot for Thomas Gleixner
  1 sibling, 0 replies; 75+ messages in thread
From: tip-bot for Thomas Gleixner @ 2012-04-28  9:10 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, rusty, peterz, srivatsa.bhat, paulmck,
	tglx, rkuo

Commit-ID:  3b0132ce4fff68b30abdfcb74cffc283af711076
Gitweb:     http://git.kernel.org/tip/3b0132ce4fff68b30abdfcb74cffc283af711076
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 20 Apr 2012 13:05:51 +0000
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 26 Apr 2012 12:06:11 +0200

hexagon: Use generic idle thread allocation

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Acked-and-tested-by: Richard Kuo <rkuo@codeaurora.org>
Link: http://lkml.kernel.org/r/20120420124557.581762105@linutronix.de
---
 arch/hexagon/Kconfig      |    1 +
 arch/hexagon/kernel/smp.c |   11 ++---------
 2 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig
index 9059e39..d2e4a33 100644
--- a/arch/hexagon/Kconfig
+++ b/arch/hexagon/Kconfig
@@ -27,6 +27,7 @@ config HEXAGON
 	select HAVE_ARCH_TRACEHOOK
 	select NO_IOPORT
 	select GENERIC_IOMAP
+	select GENERIC_SMP_IDLE_THREAD
 	# mostly generic routines, with some accelerated ones
 	---help---
 	  Qualcomm Hexagon is a processor architecture designed for high
diff --git a/arch/hexagon/kernel/smp.c b/arch/hexagon/kernel/smp.c
index 93e77e2..f726462 100644
--- a/arch/hexagon/kernel/smp.c
+++ b/arch/hexagon/kernel/smp.c
@@ -196,18 +196,11 @@ void __cpuinit start_secondary(void)
  * maintains control until "cpu_online(cpu)" is set.
  */
 
-int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
 {
-	struct task_struct *idle;
-	struct thread_info *thread;
+	struct thread_info *thread = (struct thread_info *)idle->stack;
 	void *stack_start;
 
-	/*  Create new init task for the CPU  */
-	idle = fork_idle(cpu);
-	if (IS_ERR(idle))
-		panic(KERN_ERR "fork_idle failed\n");
-
-	thread = (struct thread_info *)idle->stack;
 	thread->cpu = cpu;
 
 	/*  Boot to the head.  */

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [tip:smp/hotplug] s390: Use generic idle thread allocation
  2012-04-20 13:05 ` [patch 12/18] s390: " Thomas Gleixner
  2012-04-23  7:09   ` Martin Schwidefsky
@ 2012-04-28  9:11   ` tip-bot for Thomas Gleixner
  1 sibling, 0 replies; 75+ messages in thread
From: tip-bot for Thomas Gleixner @ 2012-04-28  9:11 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, rusty, schwidefsky, peterz,
	srivatsa.bhat, paulmck, tglx

Commit-ID:  e80e7813cd772cf30597024b371e73df9736de8d
Gitweb:     http://git.kernel.org/tip/e80e7813cd772cf30597024b371e73df9736de8d
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 20 Apr 2012 13:05:52 +0000
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 26 Apr 2012 12:06:11 +0200

s390: Use generic idle thread allocation

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Acked-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Link: http://lkml.kernel.org/r/20120420124557.652574928@linutronix.de

---
 arch/s390/Kconfig      |    1 +
 arch/s390/kernel/smp.c |   33 ++-------------------------------
 2 files changed, 3 insertions(+), 31 deletions(-)

diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 9015060..15cab3e 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -122,6 +122,7 @@ config S390
 	select ARCH_INLINE_WRITE_UNLOCK_BH
 	select ARCH_INLINE_WRITE_UNLOCK_IRQ
 	select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE
+	select GENERIC_SMP_IDLE_THREAD
 
 config SCHED_OMIT_FRAME_POINTER
 	def_bool y
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index fc827aa..992b7b9 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -85,7 +85,6 @@ enum {
 
 struct pcpu {
 	struct cpu cpu;
-	struct task_struct *idle;	/* idle process for the cpu */
 	struct _lowcore *lowcore;	/* lowcore page(s) for the cpu */
 	unsigned long async_stack;	/* async stack for the cpu */
 	unsigned long panic_stack;	/* panic stack for the cpu */
@@ -721,26 +720,9 @@ static void __cpuinit smp_start_secondary(void *cpuvoid)
 	cpu_idle();
 }
 
-struct create_idle {
-	struct work_struct work;
-	struct task_struct *idle;
-	struct completion done;
-	int cpu;
-};
-
-static void __cpuinit smp_fork_idle(struct work_struct *work)
-{
-	struct create_idle *c_idle;
-
-	c_idle = container_of(work, struct create_idle, work);
-	c_idle->idle = fork_idle(c_idle->cpu);
-	complete(&c_idle->done);
-}
-
 /* Upping and downing of CPUs */
 int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
-	struct create_idle c_idle;
 	struct pcpu *pcpu;
 	int rc;
 
@@ -750,22 +732,12 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 	if (pcpu_sigp_retry(pcpu, sigp_initial_cpu_reset, 0) !=
 	    sigp_order_code_accepted)
 		return -EIO;
-	if (!pcpu->idle) {
-		c_idle.done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done);
-		INIT_WORK_ONSTACK(&c_idle.work, smp_fork_idle);
-		c_idle.cpu = cpu;
-		schedule_work(&c_idle.work);
-		wait_for_completion(&c_idle.done);
-		if (IS_ERR(c_idle.idle))
-			return PTR_ERR(c_idle.idle);
-		pcpu->idle = c_idle.idle;
-	}
-	init_idle(pcpu->idle, cpu);
+
 	rc = pcpu_alloc_lowcore(pcpu, cpu);
 	if (rc)
 		return rc;
 	pcpu_prepare_secondary(pcpu, cpu);
-	pcpu_attach_task(pcpu, pcpu->idle);
+	pcpu_attach_task(pcpu, tidle);
 	pcpu_start_fn(pcpu, smp_start_secondary, NULL);
 	while (!cpu_online(cpu))
 		cpu_relax();
@@ -852,7 +824,6 @@ void __init smp_prepare_boot_cpu(void)
 	struct pcpu *pcpu = pcpu_devices;
 
 	boot_cpu_address = stap();
-	pcpu->idle = current;
 	pcpu->state = CPU_STATE_CONFIGURED;
 	pcpu->address = boot_cpu_address;
 	pcpu->lowcore = (struct _lowcore *)(unsigned long) store_prefix();

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [tip:smp/hotplug] cris: Use generic idle thread allocation
  2012-04-20 13:05 ` [patch 14/18] cris: " Thomas Gleixner
  2012-04-23  7:57   ` Jesper Nilsson
@ 2012-04-28  9:12   ` tip-bot for Thomas Gleixner
  1 sibling, 0 replies; 75+ messages in thread
From: tip-bot for Thomas Gleixner @ 2012-04-28  9:12 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, jesper.nilsson, rusty, peterz,
	srivatsa.bhat, paulmck, tglx

Commit-ID:  a4cfc31da34eacafd9f6b16e149448bf0ef6d0b2
Gitweb:     http://git.kernel.org/tip/a4cfc31da34eacafd9f6b16e149448bf0ef6d0b2
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 20 Apr 2012 13:05:53 +0000
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 26 Apr 2012 12:06:11 +0200

cris: Use generic idle thread allocation

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Acked-by: Jesper Nilsson <jesper.nilsson@axis.com>
Link: http://lkml.kernel.org/r/20120420124557.789657793@linutronix.de

---
 arch/cris/Kconfig               |    1 +
 arch/cris/arch-v32/kernel/smp.c |   12 ++----------
 2 files changed, 3 insertions(+), 10 deletions(-)

diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index b3abfb0..2995035 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -49,6 +49,7 @@ config CRIS
 	select HAVE_GENERIC_HARDIRQS
 	select GENERIC_IRQ_SHOW
 	select GENERIC_IOMAP
+	select GENERIC_SMP_IDLE_THREAD if ETRAX_ARCH_V32
 
 config HZ
 	int
diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c
index 125ee2d..ebe2cb3 100644
--- a/arch/cris/arch-v32/kernel/smp.c
+++ b/arch/cris/arch-v32/kernel/smp.c
@@ -108,17 +108,12 @@ void __init smp_cpus_done(unsigned int max_cpus)
 
 /* Bring one cpu online.*/
 static int __init
-smp_boot_one_cpu(int cpuid)
+smp_boot_one_cpu(int cpuid, struct task_struct idle)
 {
 	unsigned timeout;
-	struct task_struct *idle;
 	cpumask_t cpu_mask;
 
 	cpumask_clear(&cpu_mask);
-	idle = fork_idle(cpuid);
-	if (IS_ERR(idle))
-		panic("SMP: fork failed for CPU:%d", cpuid);
-
 	task_thread_info(idle)->cpu = cpuid;
 
 	/* Information to the CPU that is about to boot */
@@ -142,9 +137,6 @@ smp_boot_one_cpu(int cpuid)
 		barrier();
 	}
 
-	put_task_struct(idle);
-	idle = NULL;
-
 	printk(KERN_CRIT "SMP: CPU:%d is stuck.\n", cpuid);
 	return -1;
 }
@@ -209,7 +201,7 @@ unsigned long cache_decay_ticks = 1;
 
 int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
-	smp_boot_one_cpu(cpu);
+	smp_boot_one_cpu(cpu, tidle);
 	return cpu_online(cpu) ? 0 : -ENOSYS;
 }
 

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [tip:smp/hotplug] blackfin: Use generic idle thread allocation
  2012-04-20 13:05 ` [patch 13/18] blackfin: " Thomas Gleixner
@ 2012-04-28  9:13   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 75+ messages in thread
From: tip-bot for Thomas Gleixner @ 2012-04-28  9:13 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, rusty, peterz, srivatsa.bhat, paulmck,
	vapier, tglx

Commit-ID:  6bba2682c62e432eaf7b82f8ca182e8c73256e74
Gitweb:     http://git.kernel.org/tip/6bba2682c62e432eaf7b82f8ca182e8c73256e74
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 20 Apr 2012 13:05:53 +0000
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 26 Apr 2012 12:06:12 +0200

blackfin: Use generic idle thread allocation

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Cc: Mike Frysinger <vapier@gentoo.org>
Link: http://lkml.kernel.org/r/20120420124557.717064871@linutronix.de

---
 arch/blackfin/Kconfig           |    1 +
 arch/blackfin/mach-common/smp.c |   19 +------------------
 2 files changed, 2 insertions(+), 18 deletions(-)

diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index 373a690..779b9c8 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -37,6 +37,7 @@ config BLACKFIN
 	select GENERIC_IRQ_PROBE
 	select IRQ_PER_CPU if SMP
 	select HAVE_NMI_WATCHDOG if NMI_WATCHDOG
+	select GENERIC_SMP_IDLE_THREAD
 
 config GENERIC_CSUM
 	def_bool y
diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c
index d0cddd9..00bbe67 100644
--- a/arch/blackfin/mach-common/smp.c
+++ b/arch/blackfin/mach-common/smp.c
@@ -340,27 +340,10 @@ void smp_send_stop(void)
 	return;
 }
 
-int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
 {
 	int ret;
-	struct blackfin_cpudata *ci = &per_cpu(cpu_data, cpu);
-	struct task_struct *idle = ci->idle;
 
-	if (idle) {
-		free_task(idle);
-		idle = NULL;
-	}
-
-	if (!idle) {
-		idle = fork_idle(cpu);
-		if (IS_ERR(idle)) {
-			printk(KERN_ERR "CPU%u: fork() failed\n", cpu);
-			return PTR_ERR(idle);
-		}
-		ci->idle = idle;
-	} else {
-		init_idle(idle, cpu);
-	}
 	secondary_stack = task_stack_page(idle) + THREAD_SIZE;
 
 	ret = platform_boot_secondary(cpu, idle);

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [tip:smp/hotplug] sh: Use generic idle thread allocation
  2012-04-20 13:05 ` [patch 15/18] sh: " Thomas Gleixner
  2012-04-21  3:18   ` Paul Mundt
@ 2012-04-28  9:14   ` tip-bot for Thomas Gleixner
  1 sibling, 0 replies; 75+ messages in thread
From: tip-bot for Thomas Gleixner @ 2012-04-28  9:14 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, rusty, peterz, lethal, srivatsa.bhat,
	paulmck, tglx

Commit-ID:  ea0588cb6b201c38b0120c4ad38bc548d5dde29a
Gitweb:     http://git.kernel.org/tip/ea0588cb6b201c38b0120c4ad38bc548d5dde29a
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 20 Apr 2012 13:05:54 +0000
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 26 Apr 2012 12:06:12 +0200

sh: Use generic idle thread allocation

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Acked-by: Paul Mundt <lethal@linux-sh.org>
Link: http://lkml.kernel.org/r/20120420124557.855203626@linutronix.de
---
 arch/sh/Kconfig                 |    1 +
 arch/sh/include/asm/processor.h |    4 ----
 arch/sh/kernel/smp.c            |   14 +-------------
 3 files changed, 2 insertions(+), 17 deletions(-)

diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index ff9e033..244cfd0 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -28,6 +28,7 @@ config SUPERH
 	select RTC_LIB
 	select GENERIC_ATOMIC64
 	select GENERIC_IRQ_SHOW
+	select GENERIC_SMP_IDLE_THREAD
 	help
 	  The SuperH is a RISC processor targeted for use in embedded systems
 	  and consumer electronics; it was also used in the Sega Dreamcast
diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h
index a229c39..6d87912 100644
--- a/arch/sh/include/asm/processor.h
+++ b/arch/sh/include/asm/processor.h
@@ -85,10 +85,6 @@ struct sh_cpuinfo {
 	struct tlb_info itlb;
 	struct tlb_info dtlb;
 
-#ifdef CONFIG_SMP
-	struct task_struct *idle;
-#endif
-
 	unsigned int phys_bits;
 	unsigned long flags;
 } __attribute__ ((aligned(L1_CACHE_BYTES)));
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
index ebb76e2..b86e9ca 100644
--- a/arch/sh/kernel/smp.c
+++ b/arch/sh/kernel/smp.c
@@ -220,22 +220,10 @@ extern struct {
 	void *thread_info;
 } stack_start;
 
-int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tsk)
 {
-	struct task_struct *tsk;
 	unsigned long timeout;
 
-	tsk = cpu_data[cpu].idle;
-	if (!tsk) {
-		tsk = fork_idle(cpu);
-		if (IS_ERR(tsk)) {
-			pr_err("Failed forking idle task for cpu %d\n", cpu);
-			return PTR_ERR(tsk);
-		}
-
-		cpu_data[cpu].idle = tsk;
-	}
-
 	per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
 
 	/* Fill in data in head.S for secondary cpus */

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [tip:smp/hotplug] alpha: Use generic idle thread allocation
  2012-04-20 13:05 ` [patch 16/18] alpha: " Thomas Gleixner
@ 2012-04-28  9:15   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 75+ messages in thread
From: tip-bot for Thomas Gleixner @ 2012-04-28  9:15 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, rusty, peterz, srivatsa.bhat, paulmck,
	mattst88, tglx

Commit-ID:  2ec9415c71a1ddad969602e690a9c848b81256b3
Gitweb:     http://git.kernel.org/tip/2ec9415c71a1ddad969602e690a9c848b81256b3
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 20 Apr 2012 13:05:55 +0000
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 26 Apr 2012 12:06:12 +0200

alpha: Use generic idle thread allocation

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Cc: Matt Turner <mattst88@gmail.com>
Link: http://lkml.kernel.org/r/20120420124557.914631081@linutronix.de
---
 arch/alpha/Kconfig      |    1 +
 arch/alpha/kernel/smp.c |   18 ++----------------
 2 files changed, 3 insertions(+), 16 deletions(-)

diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 56a4df9..991b8bb 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -15,6 +15,7 @@ config ALPHA
 	select GENERIC_IRQ_SHOW
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
+	select GENERIC_SMP_IDLE_THREAD
 	help
 	  The Alpha is a 64-bit general-purpose processor designed and
 	  marketed by the Digital Equipment Corporation of blessed memory,
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index 68d3947..35ddc02 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -357,24 +357,10 @@ secondary_cpu_start(int cpuid, struct task_struct *idle)
  * Bring one cpu online.
  */
 static int __cpuinit
-smp_boot_one_cpu(int cpuid)
+smp_boot_one_cpu(int cpuid, struct task_struct *idle)
 {
-	struct task_struct *idle;
 	unsigned long timeout;
 
-	/* Cook up an idler for this guy.  Note that the address we
-	   give to kernel_thread is irrelevant -- it's going to start
-	   where HWRPB.CPU_restart says to start.  But this gets all
-	   the other task-y sort of data structures set up like we
-	   wish.  We can't use kernel_thread since we must avoid
-	   rescheduling the child.  */
-	idle = fork_idle(cpuid);
-	if (IS_ERR(idle))
-		panic("failed fork for CPU %d", cpuid);
-
-	DBGS(("smp_boot_one_cpu: CPU %d state 0x%lx flags 0x%lx\n",
-	      cpuid, idle->state, idle->flags));
-
 	/* Signal the secondary to wait a moment.  */
 	smp_secondary_alive = -1;
 
@@ -489,7 +475,7 @@ smp_prepare_boot_cpu(void)
 int __cpuinit
 __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
-	smp_boot_one_cpu(cpu);
+	smp_boot_one_cpu(cpu, tidle);
 
 	return cpu_online(cpu) ? 0 : -ENOSYS;
 }

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [tip:smp/hotplug] sparc: Use generic idle thread allocation
  2012-04-20 13:05 ` [patch 18/18] sparc: " Thomas Gleixner
  2012-04-22 19:52   ` David Miller
@ 2012-04-28  9:15   ` tip-bot for Thomas Gleixner
  1 sibling, 0 replies; 75+ messages in thread
From: tip-bot for Thomas Gleixner @ 2012-04-28  9:15 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, rusty, peterz, srivatsa.bhat, davem,
	paulmck, tglx

Commit-ID:  f0a2bc7e54bb51f64d4c2cd5942ba6018a13d762
Gitweb:     http://git.kernel.org/tip/f0a2bc7e54bb51f64d4c2cd5942ba6018a13d762
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 20 Apr 2012 13:05:56 +0000
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 26 Apr 2012 12:06:12 +0200

sparc: Use generic idle thread allocation

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Tested-by: David S. Miller <davem@davemloft.net>
Link: http://lkml.kernel.org/r/20120420124558.055198736@linutronix.de
---
 arch/sparc/Kconfig            |    1 +
 arch/sparc/include/asm/leon.h |    5 +++--
 arch/sparc/kernel/leon_smp.c  |    9 ++-------
 arch/sparc/kernel/smp_32.c    |   10 +++++-----
 arch/sparc/kernel/smp_64.c    |   10 +++-------
 arch/sparc/kernel/sun4d_smp.c |    8 ++------
 arch/sparc/kernel/sun4m_smp.c |    7 ++-----
 7 files changed, 18 insertions(+), 32 deletions(-)

diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 6c0683d..e417f35 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -30,6 +30,7 @@ config SPARC
 	select USE_GENERIC_SMP_HELPERS if SMP
 	select GENERIC_PCI_IOMAP
 	select HAVE_NMI_WATCHDOG if SPARC64
+	select GENERIC_SMP_IDLE_THREAD
 
 config SPARC32
 	def_bool !64BIT
diff --git a/arch/sparc/include/asm/leon.h b/arch/sparc/include/asm/leon.h
index a4e457f..6a1585b 100644
--- a/arch/sparc/include/asm/leon.h
+++ b/arch/sparc/include/asm/leon.h
@@ -315,6 +315,7 @@ struct leon2_cacheregs {
 #include <linux/interrupt.h>
 
 struct device_node;
+struct task_struct;
 extern unsigned int leon_build_device_irq(unsigned int real_irq,
 					   irq_flow_handler_t flow_handler,
 					   const char *name, int do_ack);
@@ -344,7 +345,7 @@ extern int leon_smp_nrcpus(void);
 extern void leon_clear_profile_irq(int cpu);
 extern void leon_smp_done(void);
 extern void leon_boot_cpus(void);
-extern int leon_boot_one_cpu(int i);
+extern int leon_boot_one_cpu(int i, struct task_struct *);
 void leon_init_smp(void);
 extern void cpu_idle(void);
 extern void init_IRQ(void);
@@ -380,7 +381,7 @@ extern int leon_ipi_irq;
 #define init_leon() do {} while (0)
 #define leon_smp_done() do {} while (0)
 #define leon_boot_cpus() do {} while (0)
-#define leon_boot_one_cpu(i) 1
+#define leon_boot_one_cpu(i, t) 1
 #define leon_init_smp() do {} while (0)
 
 #endif /* !defined(CONFIG_SPARC_LEON) */
diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c
index 160cac9..b34c93c 100644
--- a/arch/sparc/kernel/leon_smp.c
+++ b/arch/sparc/kernel/leon_smp.c
@@ -204,16 +204,11 @@ void __init leon_boot_cpus(void)
 
 }
 
-int __cpuinit leon_boot_one_cpu(int i)
+int __cpuinit leon_boot_one_cpu(int i, struct task_struct *idle)
 {
-
-	struct task_struct *p;
 	int timeout;
 
-	/* Cook up an idler for this guy. */
-	p = fork_idle(i);
-
-	current_set[i] = task_thread_info(p);
+	current_set[i] = task_thread_info(idle);
 
 	/* See trampoline.S:leon_smp_cpu_startup for details...
 	 * Initialize the contexts table
diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c
index 1f397ae..9028566 100644
--- a/arch/sparc/kernel/smp_32.c
+++ b/arch/sparc/kernel/smp_32.c
@@ -413,8 +413,8 @@ void __init smp_prepare_boot_cpu(void)
 
 int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
-	extern int __cpuinit smp4m_boot_one_cpu(int);
-	extern int __cpuinit smp4d_boot_one_cpu(int);
+	extern int __cpuinit smp4m_boot_one_cpu(int, struct task_struct *);
+	extern int __cpuinit smp4d_boot_one_cpu(int, struct task_struct *);
 	int ret=0;
 
 	switch(sparc_cpu_model) {
@@ -427,13 +427,13 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 		BUG();
 		break;
 	case sun4m:
-		ret = smp4m_boot_one_cpu(cpu);
+		ret = smp4m_boot_one_cpu(cpu, tidle);
 		break;
 	case sun4d:
-		ret = smp4d_boot_one_cpu(cpu);
+		ret = smp4d_boot_one_cpu(cpu, tidle);
 		break;
 	case sparc_leon:
-		ret = leon_boot_one_cpu(cpu);
+		ret = leon_boot_one_cpu(cpu, tidle);
 		break;
 	case sun4e:
 		printk("SUN4E\n");
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c
index 2f9948c..f591598 100644
--- a/arch/sparc/kernel/smp_64.c
+++ b/arch/sparc/kernel/smp_64.c
@@ -343,21 +343,17 @@ extern unsigned long sparc64_cpu_startup;
  */
 static struct thread_info *cpu_new_thread = NULL;
 
-static int __cpuinit smp_boot_one_cpu(unsigned int cpu)
+static int __cpuinit smp_boot_one_cpu(unsigned int cpu, struct task_struct *idle)
 {
 	unsigned long entry =
 		(unsigned long)(&sparc64_cpu_startup);
 	unsigned long cookie =
 		(unsigned long)(&cpu_new_thread);
-	struct task_struct *p;
 	void *descr = NULL;
 	int timeout, ret;
 
-	p = fork_idle(cpu);
-	if (IS_ERR(p))
-		return PTR_ERR(p);
 	callin_flag = 0;
-	cpu_new_thread = task_thread_info(p);
+	cpu_new_thread = task_thread_info(idle);
 
 	if (tlb_type == hypervisor) {
 #if defined(CONFIG_SUN_LDOMS) && defined(CONFIG_HOTPLUG_CPU)
@@ -1229,7 +1225,7 @@ void __devinit smp_fill_in_sib_core_maps(void)
 
 int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
-	int ret = smp_boot_one_cpu(cpu);
+	int ret = smp_boot_one_cpu(cpu, tidle);
 
 	if (!ret) {
 		cpumask_set_cpu(cpu, &smp_commenced_mask);
diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c
index 540b2fe..4c11030 100644
--- a/arch/sparc/kernel/sun4d_smp.c
+++ b/arch/sparc/kernel/sun4d_smp.c
@@ -127,18 +127,14 @@ void __init smp4d_boot_cpus(void)
 	local_flush_cache_all();
 }
 
-int __cpuinit smp4d_boot_one_cpu(int i)
+int __cpuinit smp4d_boot_one_cpu(int i, struct task_struct *idle)
 {
 	unsigned long *entry = &sun4d_cpu_startup;
-	struct task_struct *p;
 	int timeout;
 	int cpu_node;
 
 	cpu_find_by_instance(i, &cpu_node, NULL);
-	/* Cook up an idler for this guy. */
-	p = fork_idle(i);
-	current_set[i] = task_thread_info(p);
-
+	current_set[i] = task_thread_info(idle);
 	/*
 	 * Initialize the contexts table
 	 * Since the call to prom_startcpu() trashes the structure,
diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c
index 02db9a0..5794273 100644
--- a/arch/sparc/kernel/sun4m_smp.c
+++ b/arch/sparc/kernel/sun4m_smp.c
@@ -91,18 +91,15 @@ void __init smp4m_boot_cpus(void)
 	local_flush_cache_all();
 }
 
-int __cpuinit smp4m_boot_one_cpu(int i)
+int __cpuinit smp4m_boot_one_cpu(int i, struct task_struct *idle)
 {
 	unsigned long *entry = &sun4m_cpu_startup;
-	struct task_struct *p;
 	int timeout;
 	int cpu_node;
 
 	cpu_find_by_mid(i, &cpu_node);
+	current_set[i] = task_thread_info(idle);
 
-	/* Cook up an idler for this guy. */
-	p = fork_idle(i);
-	current_set[i] = task_thread_info(p);
 	/* See trampoline.S for details... */
 	entry += ((i - 1) * 3);
 

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [tip:smp/hotplug] parisc: Use generic idle thread allocation
  2012-04-20 13:05 ` [patch 17/18] parisc: " Thomas Gleixner
@ 2012-04-28  9:16   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 75+ messages in thread
From: tip-bot for Thomas Gleixner @ 2012-04-28  9:16 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, rusty, peterz, srivatsa.bhat, paulmck,
	jejb, tglx

Commit-ID:  9a1347237492f273f84ec39962b5806c70b2806a
Gitweb:     http://git.kernel.org/tip/9a1347237492f273f84ec39962b5806c70b2806a
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Fri, 20 Apr 2012 13:05:56 +0000
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 26 Apr 2012 12:06:13 +0200

parisc: Use generic idle thread allocation

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Cc: James E.J. Bottomley <jejb@parisc-linux.org>
Link: http://lkml.kernel.org/r/20120420124557.988947805@linutronix.de
---
 arch/parisc/Kconfig      |    1 +
 arch/parisc/kernel/smp.c |   23 ++---------------------
 2 files changed, 3 insertions(+), 21 deletions(-)

diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 242a1b7..ddb8b24 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -17,6 +17,7 @@ config PARISC
 	select GENERIC_PCI_IOMAP
 	select IRQ_PER_CPU
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
+	select GENERIC_SMP_IDLE_THREAD
 
 	help
 	  The PA-RISC microprocessor is designed by Hewlett-Packard and used
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index eae8cd8..f64f381 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -334,26 +334,11 @@ void __init smp_callin(void)
 /*
  * Bring one cpu online.
  */
-int __cpuinit smp_boot_one_cpu(int cpuid)
+int __cpuinit smp_boot_one_cpu(int cpuid, struct task_struct *idle)
 {
 	const struct cpuinfo_parisc *p = &per_cpu(cpu_data, cpuid);
-	struct task_struct *idle;
 	long timeout;
 
-	/* 
-	 * Create an idle task for this CPU.  Note the address wed* give 
-	 * to kernel_thread is irrelevant -- it's going to start
-	 * where OS_BOOT_RENDEVZ vector in SAL says to start.  But
-	 * this gets all the other task-y sort of data structures set
-	 * up like we wish.   We need to pull the just created idle task 
-	 * off the run queue and stuff it into the init_tasks[] array.  
-	 * Sheesh . . .
-	 */
-
-	idle = fork_idle(cpuid);
-	if (IS_ERR(idle))
-		panic("SMP: fork failed for CPU:%d", cpuid);
-
 	task_thread_info(idle)->cpu = cpuid;
 
 	/* Let _start know what logical CPU we're booting
@@ -397,10 +382,6 @@ int __cpuinit smp_boot_one_cpu(int cpuid)
 		udelay(100);
 		barrier();
 	}
-
-	put_task_struct(idle);
-	idle = NULL;
-
 	printk(KERN_CRIT "SMP: CPU:%d is stuck.\n", cpuid);
 	return -1;
 
@@ -452,7 +433,7 @@ void smp_cpus_done(unsigned int cpu_max)
 int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	if (cpu != 0 && cpu < parisc_max_cpus)
-		smp_boot_one_cpu(cpu);
+		smp_boot_one_cpu(cpu, tidle);
 
 	return cpu_online(cpu) ? 0 : -ENOSYS;
 }

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* Re: [tip:smp/hotplug] powerpc: Use generic idle thread allocation
  2012-04-28  9:07   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
@ 2012-04-28 22:51     ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 75+ messages in thread
From: Benjamin Herrenschmidt @ 2012-04-28 22:51 UTC (permalink / raw)
  To: mingo, hpa, linux-kernel, rusty, peterz, srivatsa.bhat, paulmck, tglx
  Cc: linux-tip-commits

On Sat, 2012-04-28 at 02:07 -0700, tip-bot for Thomas Gleixner wrote:
> Commit-ID:  17e32eacc3543c25a4377bb7ce54026e38db7d20
> Gitweb:     http://git.kernel.org/tip/17e32eacc3543c25a4377bb7ce54026e38db7d20
> Author:     Thomas Gleixner <tglx@linutronix.de>
> AuthorDate: Fri, 20 Apr 2012 13:05:48 +0000
> Committer:  Thomas Gleixner <tglx@linutronix.de>
> CommitDate: Thu, 26 Apr 2012 12:06:10 +0200
> 
> powerpc: Use generic idle thread allocation

Ah good, sorry I missed the previous batch. This is the logical
next step after I changed us to do the same as x86 :)

I'll give it a spin tomorrow (monday my time).

Cheers,
Ben.

> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Rusty Russell <rusty@rustcorp.com.au>
> Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
> Cc: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Link: http://lkml.kernel.org/r/20120420124557.311212868@linutronix.de
> ---
>  arch/powerpc/Kconfig      |    1 +
>  arch/powerpc/kernel/smp.c |   74 +++-----------------------------------------
>  2 files changed, 6 insertions(+), 69 deletions(-)
> 
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index feab3ba..c815535 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -144,6 +144,7 @@ config PPC
>  	select HAVE_BPF_JIT if (PPC64 && NET)
>  	select HAVE_ARCH_JUMP_LABEL
>  	select ARCH_HAVE_NMI_SAFE_CMPXCHG
> +	select GENERIC_SMP_IDLE_THREAD
>  
>  config EARLY_PRINTK
>  	bool
> diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
> index d38030f..e4cb343 100644
> --- a/arch/powerpc/kernel/smp.c
> +++ b/arch/powerpc/kernel/smp.c
> @@ -57,27 +57,9 @@
>  #define DBG(fmt...)
>  #endif
>  
> -
> -/* Store all idle threads, this can be reused instead of creating
> -* a new thread. Also avoids complicated thread destroy functionality
> -* for idle threads.
> -*/
>  #ifdef CONFIG_HOTPLUG_CPU
> -/*
> - * Needed only for CONFIG_HOTPLUG_CPU because __cpuinitdata is
> - * removed after init for !CONFIG_HOTPLUG_CPU.
> - */
> -static DEFINE_PER_CPU(struct task_struct *, idle_thread_array);
> -#define get_idle_for_cpu(x)      (per_cpu(idle_thread_array, x))
> -#define set_idle_for_cpu(x, p)   (per_cpu(idle_thread_array, x) = (p))
> -
>  /* State of each CPU during hotplug phases */
>  static DEFINE_PER_CPU(int, cpu_state) = { 0 };
> -
> -#else
> -static struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ;
> -#define get_idle_for_cpu(x)      (idle_thread_array[(x)])
> -#define set_idle_for_cpu(x, p)   (idle_thread_array[(x)] = (p))
>  #endif
>  
>  struct thread_info *secondary_ti;
> @@ -429,57 +411,16 @@ int generic_check_cpu_restart(unsigned int cpu)
>  }
>  #endif
>  
> -struct create_idle {
> -	struct work_struct work;
> -	struct task_struct *idle;
> -	struct completion done;
> -	int cpu;
> -};
> -
> -static void __cpuinit do_fork_idle(struct work_struct *work)
> +static void cpu_idle_thread_init(unsigned int cpu, struct task_struct *idle)
>  {
> -	struct create_idle *c_idle =
> -		container_of(work, struct create_idle, work);
> -
> -	c_idle->idle = fork_idle(c_idle->cpu);
> -	complete(&c_idle->done);
> -}
> -
> -static int __cpuinit create_idle(unsigned int cpu)
> -{
> -	struct thread_info *ti;
> -	struct create_idle c_idle = {
> -		.cpu	= cpu,
> -		.done	= COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
> -	};
> -	INIT_WORK_ONSTACK(&c_idle.work, do_fork_idle);
> -
> -	c_idle.idle = get_idle_for_cpu(cpu);
> -
> -	/* We can't use kernel_thread since we must avoid to
> -	 * reschedule the child. We use a workqueue because
> -	 * we want to fork from a kernel thread, not whatever
> -	 * userspace process happens to be trying to online us.
> -	 */
> -	if (!c_idle.idle) {
> -		schedule_work(&c_idle.work);
> -		wait_for_completion(&c_idle.done);
> -	} else
> -		init_idle(c_idle.idle, cpu);
> -	if (IS_ERR(c_idle.idle)) {		
> -		pr_err("Failed fork for CPU %u: %li", cpu, PTR_ERR(c_idle.idle));
> -		return PTR_ERR(c_idle.idle);
> -	}
> -	ti = task_thread_info(c_idle.idle);
> +	struct thread_info *ti = task_thread_info(idle);
>  
>  #ifdef CONFIG_PPC64
> -	paca[cpu].__current = c_idle.idle;
> +	paca[cpu].__current = idle;
>  	paca[cpu].kstack = (unsigned long)ti + THREAD_SIZE - STACK_FRAME_OVERHEAD;
>  #endif
>  	ti->cpu = cpu;
> -	current_set[cpu] = ti;
> -
> -	return 0;
> +	secondary_ti = current_set[cpu] = ti;
>  }
>  
>  int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
> @@ -490,12 +431,7 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
>  	    (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)))
>  		return -EINVAL;
>  
> -	/* Make sure we have an idle thread */
> -	rc = create_idle(cpu);
> -	if (rc)
> -		return rc;
> -
> -	secondary_ti = current_set[cpu];
> +	cpu_idle_thread_init(cpu, tidle);
>  
>  	/* Make sure callin-map entry is 0 (can be leftover a CPU
>  	 * hotplug
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/



^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1
  2012-04-20 13:05 [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
                   ` (26 preceding siblings ...)
  2012-04-22 21:01 ` Chris Metcalf
@ 2012-04-30  8:05 ` Santosh Shilimkar
  27 siblings, 0 replies; 75+ messages in thread
From: Santosh Shilimkar @ 2012-04-30  8:05 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, linux-arch, Peter Zijlstra, Rusty Russell,
	Paul E. McKenney, Ingo Molnar, Srivatsa S. Bhat

On Friday 20 April 2012 06:35 PM, Thomas Gleixner wrote:
> Dear all,
> 
> I'm working on refactoring the SMP boot and CPU hotplug implementation.
> 
> The current code has evolved over time into a conglomerate of
> warts. My main goals are to:
> 
>  - reduce the architecture code by moving repeating constructs to the
>    core
> 
>  - redesigning the handling of per cpu threads. There is no point to
>    tear down the threads just to create them again.
> 
>  - restructuring the notifier facility into a proper tree with
>    dependencies to avoid the gazillion of callbacks and moving
>    setup/teardown code into the context of the upcoming/dying cpu
> 
> The motivation behind this work is the cpu hotplug nightmare which we
> are facing in the RT kernel and the requests from several groups
> (e.g. ARM) to make hotplug more lightweight and faster.
> 
> This first part moves the idle thread management for non-boot cpus
> into the core. fork_idle() is called in a workqueue as it is
> implemented in a few architectures already. This is necessary when not
> all cpus are brought up by the early boot code as otherwise we would
> take a ref on the user task VM of the thread which brings the cpu up
> via the sysfs interface.
> 
> This converts all architectures except m32r, mn10300, tile and UM to
> the new core facility. These architecture are calling fork_idle() in
> the very early boot code in smp_prepare_cpus() for unknown reasons.
> I haven't analyzed yet, whether this is on purpose or can be moved
> over to the generic facility. It'd be nice if the responsible maintainers
> could look into that as well.
> 

Tried this series on OMAP4 (Dual Core ARM machine) and did some
some testing with CPU hot-plug by creating variable CPU loads and
running CPU hot-plug script in the background.
No issue observed in 2 hours of testing.

Not sure your stand on Suresh's patch[1], but I did another
round of testing with [1] included. I thought this patch
might be considered since it eliminate the need for work-queue
based idle thread allocation which can be a problem as
discussed on this thread.

Regards
Santosh

[1] https://lkml.org/lkml/2012/4/20/524






^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1
  2012-04-21  0:08     ` Suresh Siddha
@ 2012-05-03  9:41       ` Thomas Gleixner
  2012-05-03 23:42         ` Suresh Siddha
  2012-05-03 17:43       ` [tip:smp/hotplug] smp, idle: Allocate idle thread for each possible cpu during boot tip-bot for Suresh Siddha
  1 sibling, 1 reply; 75+ messages in thread
From: Thomas Gleixner @ 2012-05-03  9:41 UTC (permalink / raw)
  To: Suresh Siddha
  Cc: Peter Zijlstra, LKML, linux-arch, Rusty Russell,
	Paul E. McKenney, Ingo Molnar, Srivatsa S. Bhat, Tejun Heo,
	David Rientjes, venki

On Fri, 20 Apr 2012, Suresh Siddha wrote:
> On Fri, 2012-04-20 at 15:47 +0200, Thomas Gleixner wrote:
> > On Fri, 20 Apr 2012, Peter Zijlstra wrote:
> > 
> > > On Fri, 2012-04-20 at 13:05 +0000, Thomas Gleixner wrote:
> > > > This first part moves the idle thread management for non-boot cpus
> > > > into the core. fork_idle() is called in a workqueue as it is
> > > > implemented in a few architectures already. This is necessary when not
> > > > all cpus are brought up by the early boot code as otherwise we would
> > > > take a ref on the user task VM of the thread which brings the cpu up
> > > > via the sysfs interface. 
> > > 
> > > So I was thinking about this and I think we should make that kthreadd
> > > instead of a random workqueue thread due to all that cgroup crap. People
> > > are wanting to place all sorts of kernel threads in cgroups and I'm
> > > still arguing that kthreadd should not be allowed in cgroups.
> > 
> > So your fear is that the idle_thread will end up in some random cgroup
> > because some illdesigned user space code decided to stick kernel
> > threads into cgroups.
> > 
> > Can we please have some sanity restrictions on this cgroup muck? I
> > don't care when user space creates cgroups in circles, but holding the
> > whole kernel hostage of this madness is going too far.
> > 
> 
> Also, do we really need the workqueue/kthreadd based allocation? Just
> like the percpu areas getting allocated for each possible cpu during
> boot, shouldn't we extend this to the per-cpu idle threads too? So
> something like the appended should be ok to?

The idea is correct, there are just a few problems :)
 
> Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
> ---
> diff --git a/kernel/cpu.c b/kernel/cpu.c
> index 05c46ba..a5144ab 100644
> --- a/kernel/cpu.c
> +++ b/kernel/cpu.c
> @@ -303,10 +303,6 @@ static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen)
>  
>  	cpu_hotplug_begin();
>  
> -	ret = smpboot_prepare(cpu);
> -	if (ret)
> -		goto out;
> -

If we failed to allocate an idle_thread for this cpu in smp_init()
then we unconditionally call __cpu_up() with a NULL pointer. That
might surprise the arch code :)

Aside of that, we now miss to reinitialize the idle thread. We call
init_idle() once when we allocate the thread, but not after a cpu
offline operation. That might leave stuff in weird state.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [tip:smp/hotplug] smp, idle: Allocate idle thread for each possible cpu during boot
  2012-04-21  0:08     ` Suresh Siddha
  2012-05-03  9:41       ` Thomas Gleixner
@ 2012-05-03 17:43       ` tip-bot for Suresh Siddha
  1 sibling, 0 replies; 75+ messages in thread
From: tip-bot for Suresh Siddha @ 2012-05-03 17:43 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, rusty, peterz, srivatsa.bhat, paulmck,
	tj, suresh.b.siddha, tglx, rientjes

Commit-ID:  3bb5d2ee396aabaa4e318f17e94d13e2ee0e5a88
Gitweb:     http://git.kernel.org/tip/3bb5d2ee396aabaa4e318f17e94d13e2ee0e5a88
Author:     Suresh Siddha <suresh.b.siddha@intel.com>
AuthorDate: Fri, 20 Apr 2012 17:08:50 -0700
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 3 May 2012 19:32:34 +0200

smp, idle: Allocate idle thread for each possible cpu during boot

percpu areas are already allocated during boot for each possible cpu.
percpu idle threads can be considered as an extension of the percpu areas,
and allocate them for each possible cpu during boot.

This will eliminate the need for workqueue based idle thread allocation.
In future we can move the idle thread area into the percpu area too.

[ tglx: Moved the loop into smpboot.c and added an error check when
  the init code failed to allocate an idle thread for a cpu which
  should be onlined ]

Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: David Rientjes <rientjes@google.com>
Cc: venki@google.com
Link: http://lkml.kernel.org/r/1334966930.28674.245.camel@sbsiddha-desk.sc.intel.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/cpu.c     |    9 ++++--
 kernel/smp.c     |    4 +++
 kernel/smpboot.c |   72 ++++++++++++++---------------------------------------
 kernel/smpboot.h |    2 +
 4 files changed, 31 insertions(+), 56 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 05c46ba..0e6353c 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -297,15 +297,18 @@ static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen)
 	int ret, nr_calls = 0;
 	void *hcpu = (void *)(long)cpu;
 	unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0;
+	struct task_struct *idle;
 
 	if (cpu_online(cpu) || !cpu_present(cpu))
 		return -EINVAL;
 
 	cpu_hotplug_begin();
 
-	ret = smpboot_prepare(cpu);
-	if (ret)
+	idle = idle_thread_get(cpu);
+	if (IS_ERR(idle)) {
+		ret = PTR_ERR(idle);
 		goto out;
+	}
 
 	ret = __cpu_notify(CPU_UP_PREPARE | mod, hcpu, -1, &nr_calls);
 	if (ret) {
@@ -316,7 +319,7 @@ static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen)
 	}
 
 	/* Arch-specific enabling code. */
-	ret = __cpu_up(cpu, idle_thread_get(cpu));
+	ret = __cpu_up(cpu, idle);
 	if (ret != 0)
 		goto out_notify;
 	BUG_ON(!cpu_online(cpu));
diff --git a/kernel/smp.c b/kernel/smp.c
index 2f8b10e..a61294c 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -13,6 +13,8 @@
 #include <linux/smp.h>
 #include <linux/cpu.h>
 
+#include "smpboot.h"
+
 #ifdef CONFIG_USE_GENERIC_SMP_HELPERS
 static struct {
 	struct list_head	queue;
@@ -669,6 +671,8 @@ void __init smp_init(void)
 {
 	unsigned int cpu;
 
+	idle_threads_init();
+
 	/* FIXME: This should be done in userspace --RR */
 	for_each_present_cpu(cpu) {
 		if (num_online_cpus() >= setup_max_cpus)
diff --git a/kernel/smpboot.c b/kernel/smpboot.c
index ed15769..e1a797e 100644
--- a/kernel/smpboot.c
+++ b/kernel/smpboot.c
@@ -6,64 +6,42 @@
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/percpu.h>
-#include <linux/workqueue.h>
 
 #include "smpboot.h"
 
 #ifdef CONFIG_GENERIC_SMP_IDLE_THREAD
-struct create_idle {
-	struct work_struct	work;
-	struct task_struct	*idle;
-	struct completion	done;
-	unsigned int cpu;
-};
-
-static void __cpuinit do_fork_idle(struct work_struct *work)
-{
-	struct create_idle *c = container_of(work, struct create_idle, work);
-
-	c->idle = fork_idle(c->cpu);
-	complete(&c->done);
-}
-
-static struct task_struct * __cpuinit idle_thread_create(unsigned int cpu)
-{
-	struct create_idle c_idle = {
-		.cpu	= cpu,
-		.done	= COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
-	};
-
-	INIT_WORK_ONSTACK(&c_idle.work, do_fork_idle);
-	schedule_work(&c_idle.work);
-	wait_for_completion(&c_idle.done);
-	destroy_work_on_stack(&c_idle.work);
-	return c_idle.idle;
-}
-
 /*
  * For the hotplug case we keep the task structs around and reuse
  * them.
  */
 static DEFINE_PER_CPU(struct task_struct *, idle_threads);
 
-static inline struct task_struct *get_idle_for_cpu(unsigned int cpu)
+struct task_struct * __cpuinit idle_thread_get(unsigned int cpu)
 {
 	struct task_struct *tsk = per_cpu(idle_threads, cpu);
 
 	if (!tsk)
-		return idle_thread_create(cpu);
+		return ERR_PTR(-ENOMEM);
 	init_idle(tsk, cpu);
 	return tsk;
 }
 
-struct task_struct * __cpuinit idle_thread_get(unsigned int cpu)
+void __init idle_thread_set_boot_cpu(void)
 {
-	return per_cpu(idle_threads, cpu);
+	per_cpu(idle_threads, smp_processor_id()) = current;
 }
 
-void __init idle_thread_set_boot_cpu(void)
+static inline void idle_init(unsigned int cpu)
 {
-	per_cpu(idle_threads, smp_processor_id()) = current;
+	struct task_struct *tsk = per_cpu(idle_threads, cpu);
+
+	if (!tsk) {
+		tsk = fork_idle(cpu);
+		if (IS_ERR(tsk))
+			pr_err("SMP: fork_idle() failed for CPU %u\n", cpu);
+		else
+			per_cpu(idle_threads, cpu) = tsk;
+	}
 }
 
 /**
@@ -72,25 +50,13 @@ void __init idle_thread_set_boot_cpu(void)
  *
  * Creates the thread if it does not exist.
  */
-static int __cpuinit idle_thread_init(unsigned int cpu)
+void __init idle_threads_init(void)
 {
-	struct task_struct *idle = get_idle_for_cpu(cpu);
+	unsigned int cpu;
 
-	if (IS_ERR(idle)) {
-		printk(KERN_ERR "failed fork for CPU %u\n", cpu);
-		return PTR_ERR(idle);
+	for_each_possible_cpu(cpu) {
+		if (cpu != smp_processor_id())
+			idle_init(cpu);
 	}
-	per_cpu(idle_threads, cpu) = idle;
-	return 0;
 }
-#else
-static inline int idle_thread_init(unsigned int cpu) { return 0; }
 #endif
-
-/**
- * smpboot_prepare - generic smpboot preparation
- */
-int __cpuinit smpboot_prepare(unsigned int cpu)
-{
-	return idle_thread_init(cpu);
-}
diff --git a/kernel/smpboot.h b/kernel/smpboot.h
index 7943bbb..4cfbcb8 100644
--- a/kernel/smpboot.h
+++ b/kernel/smpboot.h
@@ -8,9 +8,11 @@ int smpboot_prepare(unsigned int cpu);
 #ifdef CONFIG_GENERIC_SMP_IDLE_THREAD
 struct task_struct *idle_thread_get(unsigned int cpu);
 void idle_thread_set_boot_cpu(void);
+void idle_threads_init(void);
 #else
 static inline struct task_struct *idle_thread_get(unsigned int cpu) { return NULL; }
 static inline void idle_thread_set_boot_cpu(void) { }
+static inline void idle_threads_init(unsigned int cpu) { }
 #endif
 
 #endif

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* Re: [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1
  2012-05-03  9:41       ` Thomas Gleixner
@ 2012-05-03 23:42         ` Suresh Siddha
  0 siblings, 0 replies; 75+ messages in thread
From: Suresh Siddha @ 2012-05-03 23:42 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Peter Zijlstra, LKML, linux-arch, Rusty Russell,
	Paul E. McKenney, Ingo Molnar, Srivatsa S. Bhat, Tejun Heo,
	David Rientjes, venki

On Thu, 2012-05-03 at 11:41 +0200, Thomas Gleixner wrote:
> On Fri, 20 Apr 2012, Suresh Siddha wrote:
> > Also, do we really need the workqueue/kthreadd based allocation? Just
> > like the percpu areas getting allocated for each possible cpu during
> > boot, shouldn't we extend this to the per-cpu idle threads too? So
> > something like the appended should be ok to?
> 
> The idea is correct, there are just a few problems :)
>  
> > Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
> > ---
> > diff --git a/kernel/cpu.c b/kernel/cpu.c
> > index 05c46ba..a5144ab 100644
> > --- a/kernel/cpu.c
> > +++ b/kernel/cpu.c
> > @@ -303,10 +303,6 @@ static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen)
> >  
> >  	cpu_hotplug_begin();
> >  
> > -	ret = smpboot_prepare(cpu);
> > -	if (ret)
> > -		goto out;
> > -
> 
> If we failed to allocate an idle_thread for this cpu in smp_init()
> then we unconditionally call __cpu_up() with a NULL pointer. That
> might surprise the arch code :)
> 
> Aside of that, we now miss to reinitialize the idle thread. We call
> init_idle() once when we allocate the thread, but not after a cpu
> offline operation. That might leave stuff in weird state.

Second one slipped through and wasn't intentional. Anyways your
modifications look good.

While I am here, noticed that we could do 'node' aware idle task struct
allocations. Appended the patch for this. Thanks.
---

From: Suresh Siddha <suresh.b.siddha@intel.com>
Subject: idle: allocate percpu idle taks from the local node

Use the arch specific early_cpu_to_node() to find out the local node for a
given 'cpu' and use that info while allocating memory for that cpu's idle task.

Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
---
 arch/x86/include/asm/topology.h |    8 +++++---
 arch/x86/mm/numa.c              |    2 +-
 include/asm-generic/topology.h  |    4 ++++
 include/linux/kthread.h         |    9 ++++++++-
 kernel/fork.c                   |    9 ++++++---
 kernel/kthread.c                |    8 +++-----
 6 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index b9676ae..bdbcee2 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h
@@ -57,12 +57,12 @@ DECLARE_EARLY_PER_CPU(int, x86_cpu_to_node_map);
 extern int __cpu_to_node(int cpu);
 #define cpu_to_node __cpu_to_node
 
-extern int early_cpu_to_node(int cpu);
+extern int __early_cpu_to_node(int cpu);
 
 #else	/* !CONFIG_DEBUG_PER_CPU_MAPS */
 
 /* Same function but used if called before per_cpu areas are setup */
-static inline int early_cpu_to_node(int cpu)
+static inline int __early_cpu_to_node(int cpu)
 {
 	return early_per_cpu(x86_cpu_to_node_map, cpu);
 }
@@ -144,7 +144,7 @@ static inline int numa_node_id(void)
  */
 #define numa_node_id numa_node_id
 
-static inline int early_cpu_to_node(int cpu)
+static inline int __early_cpu_to_node(int cpu)
 {
 	return 0;
 }
@@ -153,6 +153,8 @@ static inline void setup_node_to_cpumask_map(void) { }
 
 #endif
 
+#define early_cpu_to_node(cpu)	__early_cpu_to_node(cpu)
+
 #include <asm-generic/topology.h>
 
 extern const struct cpumask *cpu_coregroup_mask(int cpu);
diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
index 19d3fa0..142738e 100644
--- a/arch/x86/mm/numa.c
+++ b/arch/x86/mm/numa.c
@@ -734,7 +734,7 @@ EXPORT_SYMBOL(__cpu_to_node);
  * Same function as cpu_to_node() but used if called before the
  * per_cpu areas are setup.
  */
-int early_cpu_to_node(int cpu)
+int __early_cpu_to_node(int cpu)
 {
 	if (early_per_cpu_ptr(x86_cpu_to_node_map))
 		return early_per_cpu_ptr(x86_cpu_to_node_map)[cpu];
diff --git a/include/asm-generic/topology.h b/include/asm-generic/topology.h
index fc824e2..9ace6da 100644
--- a/include/asm-generic/topology.h
+++ b/include/asm-generic/topology.h
@@ -73,4 +73,8 @@
 
 #endif	/* !CONFIG_NUMA || !CONFIG_HAVE_MEMORYLESS_NODES */
 
+#ifndef early_cpu_to_node
+#define early_cpu_to_node(cpu)	((void)(cpu), -1)
+#endif
+
 #endif /* _ASM_GENERIC_TOPOLOGY_H */
diff --git a/include/linux/kthread.h b/include/linux/kthread.h
index 0714b24..c1f05e3 100644
--- a/include/linux/kthread.h
+++ b/include/linux/kthread.h
@@ -40,7 +40,7 @@ void *kthread_data(struct task_struct *k);
 
 int kthreadd(void *unused);
 extern struct task_struct *kthreadd_task;
-extern int tsk_fork_get_node(struct task_struct *tsk);
+extern int tsk_fork_get_node(struct task_struct *tsk, int idle_tsk);
 
 /*
  * Simple work processor based on kthread.
@@ -131,4 +131,11 @@ bool queue_kthread_work(struct kthread_worker *worker,
 void flush_kthread_work(struct kthread_work *work);
 void flush_kthread_worker(struct kthread_worker *worker);
 
+static inline void set_fork_pref_node(int node)
+{
+#ifdef CONFIG_NUMA
+	current->pref_node_fork = node;
+#endif
+}
+
 #endif /* _LINUX_KTHREAD_H */
diff --git a/kernel/fork.c b/kernel/fork.c
index ca9a384..108d566 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -253,12 +253,13 @@ int __attribute__((weak)) arch_dup_task_struct(struct task_struct *dst,
 	return 0;
 }
 
-static struct task_struct *dup_task_struct(struct task_struct *orig)
+static struct task_struct *dup_task_struct(struct task_struct *orig,
+					   int idle_tsk)
 {
 	struct task_struct *tsk;
 	struct thread_info *ti;
 	unsigned long *stackend;
-	int node = tsk_fork_get_node(orig);
+	int node = tsk_fork_get_node(orig, idle_tsk);
 	int err;
 
 	prepare_to_copy(orig);
@@ -1165,7 +1166,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
 		goto fork_out;
 
 	retval = -ENOMEM;
-	p = dup_task_struct(current);
+	p = dup_task_struct(current, pid == &init_struct_pid);
 	if (!p)
 		goto fork_out;
 
@@ -1531,6 +1532,8 @@ struct task_struct * __cpuinit fork_idle(int cpu)
 	struct task_struct *task;
 	struct pt_regs regs;
 
+	set_fork_pref_node(early_cpu_to_node(cpu));
+
 	task = copy_process(CLONE_VM, 0, idle_regs(&regs), 0, NULL,
 			    &init_struct_pid, 0);
 	if (!IS_ERR(task)) {
diff --git a/kernel/kthread.c b/kernel/kthread.c
index 3d3de63..3d74ab1 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -125,10 +125,10 @@ static int kthread(void *_create)
 }
 
 /* called from do_fork() to get node information for about to be created task */
-int tsk_fork_get_node(struct task_struct *tsk)
+int tsk_fork_get_node(struct task_struct *tsk, int idle_tsk)
 {
 #ifdef CONFIG_NUMA
-	if (tsk == kthreadd_task)
+	if (tsk == kthreadd_task || idle_tsk)
 		return tsk->pref_node_fork;
 #endif
 	return numa_node_id();
@@ -138,9 +138,7 @@ static void create_kthread(struct kthread_create_info *create)
 {
 	int pid;
 
-#ifdef CONFIG_NUMA
-	current->pref_node_fork = create->node;
-#endif
+	set_fork_pref_node(create->node);
 	/* We want our own signal handler (we take no signals by default). */
 	pid = kernel_thread(kthread, create, CLONE_FS | CLONE_FILES | SIGCHLD);
 	if (pid < 0) {




^ permalink raw reply related	[flat|nested] 75+ messages in thread

* Re: [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1
  2012-04-20 14:18   ` Thomas Gleixner
  2012-04-24 18:44     ` Konrad Rzeszutek Wilk
@ 2012-05-21  1:42     ` Rusty Russell
  2012-05-21  8:25       ` Thomas Gleixner
  1 sibling, 1 reply; 75+ messages in thread
From: Rusty Russell @ 2012-05-21  1:42 UTC (permalink / raw)
  To: Thomas Gleixner, Srivatsa S. Bhat
  Cc: LKML, linux-arch, Peter Zijlstra, Paul E. McKenney, Ingo Molnar,
	Nikunj A Dadhania, Steven Rostedt

On Fri, 20 Apr 2012 16:18:04 +0200 (CEST), Thomas Gleixner <tglx@linutronix.de> wrote:
> On Fri, 20 Apr 2012, Srivatsa S. Bhat wrote:
> > already done.. Myself and Nikunj had some initial design/ideas on reducing
> > the duplication in architecture code, related to managing the setting
> > of the cpu in the online mask, sending out CPU_STARTING notifiers etc
> > from generic code..
> 
> The whole notifier business needs a redesign as well, because we don't
> have a way to express proper dependencies, we add random notifier
> points and the teardown path is ass backwards. The whole thing wants
> to be a tree which can be walked in either direction and from any
> point. Right now we cut the trunk first and keep the single limb up
> with a helicopter and start dismantling it.

But there are two ways to do it.  One is to eliminate the need for
callbacks.  The other is to make a full dependency-based callback
system.

Let's try the first before the second.  I implemented a full dep-based
system for initcalls once, and it was not as nice as I'd hoped.

> Flat notifiers are not working for this as they do not allow a tree
> structure and prevent us to do things in parallel.

Not sure whether calling notifiers in parallel is going to be a big win:
they'll end up fighting over the cpu we're taking down.  But I could be
wrong.

> That really needs to be completely reworked. There is also a lot of
> stuff which wants to be moved into the starting/dying CPU
> context. Right now we kinda do that by trampling on the CPU with a
> high prio stomper thread, but that's really just a bandaid and steady
> cause of trouble.
> 
> If you look at facilities which use kthreads, then there is lots other
> setup which does not need a notifier at all, as it can be done in the
> context of the thread when we have a way to start/park those threads
> at the right time in the up/down process.

That's a very nice idea.  Should be simpler for kthreads park/unpark
themselves, rather than having some notifier to kill them.

The original concept of stopping the machine for cpu hotplug and trying
not to effect any other kernel code has jumped the shark: I think we
need to look seriously at a complete rewrite where we don't use
stop_machine.

Cheers,
Rusty.

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1
  2012-05-21  1:42     ` Rusty Russell
@ 2012-05-21  8:25       ` Thomas Gleixner
  2012-05-22  0:53         ` Rusty Russell
  0 siblings, 1 reply; 75+ messages in thread
From: Thomas Gleixner @ 2012-05-21  8:25 UTC (permalink / raw)
  To: Rusty Russell
  Cc: Srivatsa S. Bhat, LKML, linux-arch, Peter Zijlstra,
	Paul E. McKenney, Ingo Molnar, Nikunj A Dadhania, Steven Rostedt

On Mon, 21 May 2012, Rusty Russell wrote:

> On Fri, 20 Apr 2012 16:18:04 +0200 (CEST), Thomas Gleixner <tglx@linutronix.de> wrote:
> > On Fri, 20 Apr 2012, Srivatsa S. Bhat wrote:
> > The whole notifier business needs a redesign as well, because we don't
> > have a way to express proper dependencies, we add random notifier
> > points and the teardown path is ass backwards. The whole thing wants
> > to be a tree which can be walked in either direction and from any
> > point. Right now we cut the trunk first and keep the single limb up
> > with a helicopter and start dismantling it.
> 
> But there are two ways to do it.  One is to eliminate the need for
> callbacks.  The other is to make a full dependency-based callback

What do you mean with fully eliminating the need for callbacks. Do you
want to put the necessary bringup/shutdown function calls just in the
core code so we get rid of the notifiers or do you have something
different in mind ?

> system.
> 
> Let's try the first before the second.  I implemented a full dep-based
> system for initcalls once, and it was not as nice as I'd hoped.

Yeah, a full dependency thing might be overkill.

> > Flat notifiers are not working for this as they do not allow a tree
> > structure and prevent us to do things in parallel.
> 
> Not sure whether calling notifiers in parallel is going to be a big win:
> they'll end up fighting over the cpu we're taking down.  But I could be
> wrong.

I'm not going to aim for parallel in the first place. That was just an
idea and if we chose the right implementation then parallelism can be
added later.
 
> > That really needs to be completely reworked. There is also a lot of
> > stuff which wants to be moved into the starting/dying CPU
> > context. Right now we kinda do that by trampling on the CPU with a
> > high prio stomper thread, but that's really just a bandaid and steady
> > cause of trouble.
> > 
> > If you look at facilities which use kthreads, then there is lots other
> > setup which does not need a notifier at all, as it can be done in the
> > context of the thread when we have a way to start/park those threads
> > at the right time in the up/down process.
> 
> That's a very nice idea.  Should be simpler for kthreads park/unpark
> themselves, rather than having some notifier to kill them.

Well, something needs to tell them to park/unpark, but what should
move into the thread is the setup/teardown of context.
 
> The original concept of stopping the machine for cpu hotplug and trying
> not to effect any other kernel code has jumped the shark: I think we
> need to look seriously at a complete rewrite where we don't use
> stop_machine.

Yep. Working on it. :)

Thanks,

	tglx
 

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1
  2012-05-21  8:25       ` Thomas Gleixner
@ 2012-05-22  0:53         ` Rusty Russell
  0 siblings, 0 replies; 75+ messages in thread
From: Rusty Russell @ 2012-05-22  0:53 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Srivatsa S. Bhat, LKML, linux-arch, Peter Zijlstra,
	Paul E. McKenney, Ingo Molnar, Nikunj A Dadhania, Steven Rostedt

On Mon, 21 May 2012 10:25:21 +0200 (CEST), Thomas Gleixner <tglx@linutronix.de> wrote:
> On Mon, 21 May 2012, Rusty Russell wrote:
> 
> > On Fri, 20 Apr 2012 16:18:04 +0200 (CEST), Thomas Gleixner <tglx@linutronix.de> wrote:
> > > On Fri, 20 Apr 2012, Srivatsa S. Bhat wrote:
> > > The whole notifier business needs a redesign as well, because we don't
> > > have a way to express proper dependencies, we add random notifier
> > > points and the teardown path is ass backwards. The whole thing wants
> > > to be a tree which can be walked in either direction and from any
> > > point. Right now we cut the trunk first and keep the single limb up
> > > with a helicopter and start dismantling it.
> > 
> > But there are two ways to do it.  One is to eliminate the need for
> > callbacks.  The other is to make a full dependency-based callback
> 
> What do you mean with fully eliminating the need for callbacks. Do you
> want to put the necessary bringup/shutdown function calls just in the
> core code so we get rid of the notifiers or do you have something
> different in mind ?

Eliminate is probably too hard, but with park/unpark I can see it
getting less common.  Maybe few enough that we can simplify.

> > Not sure whether calling notifiers in parallel is going to be a big win:
> > they'll end up fighting over the cpu we're taking down.  But I could be
> > wrong.
> 
> I'm not going to aim for parallel in the first place. That was just an
> idea and if we chose the right implementation then parallelism can be
> added later.

Parallel CPUs going offline/online is probably a bigger win.  Both for
suspend/resume and powersaving.

> > The original concept of stopping the machine for cpu hotplug and trying
> > not to effect any other kernel code has jumped the shark: I think we
> > need to look seriously at a complete rewrite where we don't use
> > stop_machine.
> 
> Yep. Working on it. :)

I thought you might be :)

I'd love to review once you've got something.

Cheers,
Rusty.

^ permalink raw reply	[flat|nested] 75+ messages in thread

end of thread, other threads:[~2012-05-22  3:03 UTC | newest]

Thread overview: 75+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-20 13:05 [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
2012-04-20 13:05 ` [patch 01/18] m32r: Remove pointless function prototypes Thomas Gleixner
2012-04-28  9:01   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
2012-04-20 13:05 ` [patch 02/18] smp: Add task_struct argument to __cpu_up() Thomas Gleixner
2012-04-23  7:58   ` Jesper Nilsson
2012-04-28  9:02   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
2012-04-20 13:05 ` [patch 03/18] smp: Add generic smpboot facility Thomas Gleixner
2012-04-20 20:07   ` Yinghai Lu
2012-04-21  2:07   ` Stephen Rothwell
2012-04-28  9:04   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
2012-04-20 13:05 ` [patch 04/18] smp: Provide generic idle thread allocation Thomas Gleixner
2012-04-20 16:21   ` Sam Ravnborg
2012-04-20 18:55     ` Thomas Gleixner
2012-04-21  2:20   ` Stephen Rothwell
2012-04-21  2:25   ` Frank Rowand
2012-04-28  9:05   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
2012-04-20 13:05 ` [patch 05/18] x86: Add task_struct argument to smp_ops.cpu_up Thomas Gleixner
2012-04-28  9:05   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
2012-04-20 13:05 ` [patch 06/18] x86: Use generic idle thread allocation Thomas Gleixner
2012-04-28  9:06   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
2012-04-20 13:05 ` [patch 07/18] powerpc: " Thomas Gleixner
2012-04-28  9:07   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
2012-04-28 22:51     ` Benjamin Herrenschmidt
2012-04-20 13:05 ` [patch 08/18] ia64: " Thomas Gleixner
2012-04-28  9:08   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
2012-04-20 13:05 ` [patch 09/18] arm: " Thomas Gleixner
2012-04-28  9:09   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
2012-04-20 13:05 ` [patch 11/18] hexagon: " Thomas Gleixner
2012-04-24 16:47   ` Richard Kuo
2012-04-28  9:10   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
2012-04-20 13:05 ` [patch 10/18] mips: " Thomas Gleixner
2012-04-28  9:10   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
2012-04-20 13:05 ` [patch 12/18] s390: " Thomas Gleixner
2012-04-23  7:09   ` Martin Schwidefsky
2012-04-28  9:11   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
2012-04-20 13:05 ` [patch 13/18] blackfin: " Thomas Gleixner
2012-04-28  9:13   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
2012-04-20 13:05 ` [patch 14/18] cris: " Thomas Gleixner
2012-04-23  7:57   ` Jesper Nilsson
2012-04-28  9:12   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
2012-04-20 13:05 ` [patch 15/18] sh: " Thomas Gleixner
2012-04-21  3:18   ` Paul Mundt
2012-04-28  9:14   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
2012-04-20 13:05 ` [patch 16/18] alpha: " Thomas Gleixner
2012-04-28  9:15   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
2012-04-20 13:05 ` [patch 17/18] parisc: " Thomas Gleixner
2012-04-28  9:16   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
2012-04-20 13:05 ` [patch 18/18] sparc: " Thomas Gleixner
2012-04-22 19:52   ` David Miller
2012-04-28  9:15   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
2012-04-20 13:16 ` [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Thomas Gleixner
2012-04-20 13:21 ` Peter Zijlstra
2012-04-20 13:47   ` Thomas Gleixner
2012-04-21  0:08     ` Suresh Siddha
2012-05-03  9:41       ` Thomas Gleixner
2012-05-03 23:42         ` Suresh Siddha
2012-05-03 17:43       ` [tip:smp/hotplug] smp, idle: Allocate idle thread for each possible cpu during boot tip-bot for Suresh Siddha
2012-04-20 15:42   ` [patch 00/18] SMP: Boot and CPU hotplug refactoring - Part 1 Tejun Heo
2012-04-20 15:49     ` Peter Zijlstra
2012-04-20 15:56       ` Thomas Gleixner
2012-04-20 13:56 ` Srivatsa S. Bhat
2012-04-20 14:18   ` Thomas Gleixner
2012-04-24 18:44     ` Konrad Rzeszutek Wilk
2012-05-21  1:42     ` Rusty Russell
2012-05-21  8:25       ` Thomas Gleixner
2012-05-22  0:53         ` Rusty Russell
2012-04-20 14:06 ` richard -rw- weinberger
2012-04-20 14:19   ` Thomas Gleixner
2012-04-20 14:27 ` James Bottomley
2012-04-20 17:55 ` Paul E. McKenney
2012-04-20 23:11 ` Venki Pallipadi
2012-04-21  1:04 ` Frank Rowand
2012-04-21  1:55   ` Frank Rowand
2012-04-22 21:01 ` Chris Metcalf
2012-04-30  8:05 ` Santosh Shilimkar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).