aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-21 22:43:57 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-21 22:43:57 -0400
commitbf67f3a5c456a18f2e8d062f7e88506ef2cd9837 (patch)
tree2a2324b2572162059307db82f9238eeb25673a77 /arch/powerpc
parent226da0dbc84ed97f448523e2a4cb91c27fa68ed9 (diff)
parent203dacbdca977bedaba61ad2fca75d934060a5d5 (diff)
Merge branch 'smp-hotplug-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull smp hotplug cleanups from Thomas Gleixner: "This series is merily a cleanup of code copied around in arch/* and not changing any of the real cpu hotplug horrors yet. I wish I'd had something more substantial for 3.5, but I underestimated the lurking horror..." Fix up trivial conflicts in arch/{arm,sparc,x86}/Kconfig and arch/sparc/include/asm/thread_info_32.h * 'smp-hotplug-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (79 commits) um: Remove leftover declaration of alloc_task_struct_node() task_allocator: Use config switches instead of magic defines sparc: Use common threadinfo allocator score: Use common threadinfo allocator sh-use-common-threadinfo-allocator mn10300: Use common threadinfo allocator powerpc: Use common threadinfo allocator mips: Use common threadinfo allocator hexagon: Use common threadinfo allocator m32r: Use common threadinfo allocator frv: Use common threadinfo allocator cris: Use common threadinfo allocator x86: Use common threadinfo allocator c6x: Use common threadinfo allocator fork: Provide kmemcache based thread_info allocator tile: Use common threadinfo allocator fork: Provide weak arch_release_[task_struct|thread_info] functions fork: Move thread info gfp flags to header fork: Remove the weak insanity sh: Remove cpu_idle_wait() ...
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/Kconfig5
-rw-r--r--arch/powerpc/include/asm/processor.h1
-rw-r--r--arch/powerpc/include/asm/thread_info.h13
-rw-r--r--arch/powerpc/kernel/Makefile2
-rw-r--r--arch/powerpc/kernel/idle.c23
-rw-r--r--arch/powerpc/kernel/init_task.c29
-rw-r--r--arch/powerpc/kernel/process.c31
-rw-r--r--arch/powerpc/kernel/smp.c76
8 files changed, 8 insertions, 172 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 73ec03945717..8a01098eaaca 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -87,10 +87,6 @@ config ARCH_HAS_ILOG2_U64
87 bool 87 bool
88 default y if 64BIT 88 default y if 64BIT
89 89
90config ARCH_HAS_CPU_IDLE_WAIT
91 bool
92 default y
93
94config GENERIC_HWEIGHT 90config GENERIC_HWEIGHT
95 bool 91 bool
96 default y 92 default y
@@ -144,6 +140,7 @@ config PPC
144 select HAVE_BPF_JIT if PPC64 140 select HAVE_BPF_JIT if PPC64
145 select HAVE_ARCH_JUMP_LABEL 141 select HAVE_ARCH_JUMP_LABEL
146 select ARCH_HAVE_NMI_SAFE_CMPXCHG 142 select ARCH_HAVE_NMI_SAFE_CMPXCHG
143 select GENERIC_SMP_IDLE_THREAD
147 144
148config EARLY_PRINTK 145config EARLY_PRINTK
149 bool 146 bool
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index 8e2d0371fe1e..48a26d379222 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -386,7 +386,6 @@ extern unsigned long cpuidle_disable;
386enum idle_boot_override {IDLE_NO_OVERRIDE = 0, IDLE_POWERSAVE_OFF}; 386enum idle_boot_override {IDLE_NO_OVERRIDE = 0, IDLE_POWERSAVE_OFF};
387 387
388extern int powersave_nap; /* set if nap mode can be used in idle loop */ 388extern int powersave_nap; /* set if nap mode can be used in idle loop */
389void cpu_idle_wait(void);
390 389
391#ifdef CONFIG_PSERIES_IDLE 390#ifdef CONFIG_PSERIES_IDLE
392extern void update_smt_snooze_delay(int snooze); 391extern void update_smt_snooze_delay(int snooze);
diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h
index 4a741c7efd02..1a1bb00f061a 100644
--- a/arch/powerpc/include/asm/thread_info.h
+++ b/arch/powerpc/include/asm/thread_info.h
@@ -62,21 +62,8 @@ struct thread_info {
62#define init_thread_info (init_thread_union.thread_info) 62#define init_thread_info (init_thread_union.thread_info)
63#define init_stack (init_thread_union.stack) 63#define init_stack (init_thread_union.stack)
64 64
65/* thread information allocation */
66
67#if THREAD_SHIFT >= PAGE_SHIFT
68
69#define THREAD_SIZE_ORDER (THREAD_SHIFT - PAGE_SHIFT) 65#define THREAD_SIZE_ORDER (THREAD_SHIFT - PAGE_SHIFT)
70 66
71#else /* THREAD_SHIFT < PAGE_SHIFT */
72
73#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
74
75extern struct thread_info *alloc_thread_info_node(struct task_struct *tsk, int node);
76extern void free_thread_info(struct thread_info *ti);
77
78#endif /* THREAD_SHIFT < PAGE_SHIFT */
79
80/* how to get the thread information struct from C */ 67/* how to get the thread information struct from C */
81static inline struct thread_info *current_thread_info(void) 68static inline struct thread_info *current_thread_info(void)
82{ 69{
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index f5808a35688c..83afacd3ba7b 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -28,7 +28,7 @@ endif
28 28
29obj-y := cputable.o ptrace.o syscalls.o \ 29obj-y := cputable.o ptrace.o syscalls.o \
30 irq.o align.o signal_32.o pmc.o vdso.o \ 30 irq.o align.o signal_32.o pmc.o vdso.o \
31 init_task.o process.o systbl.o idle.o \ 31 process.o systbl.o idle.o \
32 signal.o sysfs.o cacheinfo.o time.o \ 32 signal.o sysfs.o cacheinfo.o time.o \
33 prom.o traps.o setup-common.o \ 33 prom.o traps.o setup-common.o \
34 udbg.o misc.o io.o dma.o \ 34 udbg.o misc.o io.o dma.o \
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c
index 6d2209ac0c44..2099d9a879e8 100644
--- a/arch/powerpc/kernel/idle.c
+++ b/arch/powerpc/kernel/idle.c
@@ -113,29 +113,6 @@ void cpu_idle(void)
113 } 113 }
114} 114}
115 115
116
117/*
118 * cpu_idle_wait - Used to ensure that all the CPUs come out of the old
119 * idle loop and start using the new idle loop.
120 * Required while changing idle handler on SMP systems.
121 * Caller must have changed idle handler to the new value before the call.
122 * This window may be larger on shared systems.
123 */
124void cpu_idle_wait(void)
125{
126 int cpu;
127 smp_mb();
128
129 /* kick all the CPUs so that they exit out of old idle routine */
130 get_online_cpus();
131 for_each_online_cpu(cpu) {
132 if (cpu != smp_processor_id())
133 smp_send_reschedule(cpu);
134 }
135 put_online_cpus();
136}
137EXPORT_SYMBOL_GPL(cpu_idle_wait);
138
139int powersave_nap; 116int powersave_nap;
140 117
141#ifdef CONFIG_SYSCTL 118#ifdef CONFIG_SYSCTL
diff --git a/arch/powerpc/kernel/init_task.c b/arch/powerpc/kernel/init_task.c
deleted file mode 100644
index d076d465dbd1..000000000000
--- a/arch/powerpc/kernel/init_task.c
+++ /dev/null
@@ -1,29 +0,0 @@
1#include <linux/mm.h>
2#include <linux/export.h>
3#include <linux/sched.h>
4#include <linux/init.h>
5#include <linux/init_task.h>
6#include <linux/fs.h>
7#include <linux/mqueue.h>
8#include <asm/uaccess.h>
9
10static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
11static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
12/*
13 * Initial thread structure.
14 *
15 * We need to make sure that this is 16384-byte aligned due to the
16 * way process stacks are handled. This is done by having a special
17 * "init_task" linker map entry..
18 */
19union thread_union init_thread_union __init_task_data =
20 { INIT_THREAD_INFO(init_task) };
21
22/*
23 * Initial task structure.
24 *
25 * All other task structs will be allocated on slabs in fork.c
26 */
27struct task_struct init_task = INIT_TASK(init_task);
28
29EXPORT_SYMBOL(init_task);
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 4937c9690090..aa05935b6947 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1252,37 +1252,6 @@ void __ppc64_runlatch_off(void)
1252} 1252}
1253#endif /* CONFIG_PPC64 */ 1253#endif /* CONFIG_PPC64 */
1254 1254
1255#if THREAD_SHIFT < PAGE_SHIFT
1256
1257static struct kmem_cache *thread_info_cache;
1258
1259struct thread_info *alloc_thread_info_node(struct task_struct *tsk, int node)
1260{
1261 struct thread_info *ti;
1262
1263 ti = kmem_cache_alloc_node(thread_info_cache, GFP_KERNEL, node);
1264 if (unlikely(ti == NULL))
1265 return NULL;
1266#ifdef CONFIG_DEBUG_STACK_USAGE
1267 memset(ti, 0, THREAD_SIZE);
1268#endif
1269 return ti;
1270}
1271
1272void free_thread_info(struct thread_info *ti)
1273{
1274 kmem_cache_free(thread_info_cache, ti);
1275}
1276
1277void thread_info_cache_init(void)
1278{
1279 thread_info_cache = kmem_cache_create("thread_info", THREAD_SIZE,
1280 THREAD_SIZE, 0, NULL);
1281 BUG_ON(thread_info_cache == NULL);
1282}
1283
1284#endif /* THREAD_SHIFT < PAGE_SHIFT */
1285
1286unsigned long arch_align_stack(unsigned long sp) 1255unsigned long arch_align_stack(unsigned long sp)
1287{ 1256{
1288 if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) 1257 if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index d9f94410fd7f..e4cb34322de4 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -57,27 +57,9 @@
57#define DBG(fmt...) 57#define DBG(fmt...)
58#endif 58#endif
59 59
60
61/* Store all idle threads, this can be reused instead of creating
62* a new thread. Also avoids complicated thread destroy functionality
63* for idle threads.
64*/
65#ifdef CONFIG_HOTPLUG_CPU 60#ifdef CONFIG_HOTPLUG_CPU
66/*
67 * Needed only for CONFIG_HOTPLUG_CPU because __cpuinitdata is
68 * removed after init for !CONFIG_HOTPLUG_CPU.
69 */
70static DEFINE_PER_CPU(struct task_struct *, idle_thread_array);
71#define get_idle_for_cpu(x) (per_cpu(idle_thread_array, x))
72#define set_idle_for_cpu(x, p) (per_cpu(idle_thread_array, x) = (p))
73
74/* State of each CPU during hotplug phases */ 61/* State of each CPU during hotplug phases */
75static DEFINE_PER_CPU(int, cpu_state) = { 0 }; 62static DEFINE_PER_CPU(int, cpu_state) = { 0 };
76
77#else
78static struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ;
79#define get_idle_for_cpu(x) (idle_thread_array[(x)])
80#define set_idle_for_cpu(x, p) (idle_thread_array[(x)] = (p))
81#endif 63#endif
82 64
83struct thread_info *secondary_ti; 65struct thread_info *secondary_ti;
@@ -429,60 +411,19 @@ int generic_check_cpu_restart(unsigned int cpu)
429} 411}
430#endif 412#endif
431 413
432struct create_idle { 414static void cpu_idle_thread_init(unsigned int cpu, struct task_struct *idle)
433 struct work_struct work;
434 struct task_struct *idle;
435 struct completion done;
436 int cpu;
437};
438
439static void __cpuinit do_fork_idle(struct work_struct *work)
440{ 415{
441 struct create_idle *c_idle = 416 struct thread_info *ti = task_thread_info(idle);
442 container_of(work, struct create_idle, work);
443
444 c_idle->idle = fork_idle(c_idle->cpu);
445 complete(&c_idle->done);
446}
447
448static int __cpuinit create_idle(unsigned int cpu)
449{
450 struct thread_info *ti;
451 struct create_idle c_idle = {
452 .cpu = cpu,
453 .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
454 };
455 INIT_WORK_ONSTACK(&c_idle.work, do_fork_idle);
456
457 c_idle.idle = get_idle_for_cpu(cpu);
458
459 /* We can't use kernel_thread since we must avoid to
460 * reschedule the child. We use a workqueue because
461 * we want to fork from a kernel thread, not whatever
462 * userspace process happens to be trying to online us.
463 */
464 if (!c_idle.idle) {
465 schedule_work(&c_idle.work);
466 wait_for_completion(&c_idle.done);
467 } else
468 init_idle(c_idle.idle, cpu);
469 if (IS_ERR(c_idle.idle)) {
470 pr_err("Failed fork for CPU %u: %li", cpu, PTR_ERR(c_idle.idle));
471 return PTR_ERR(c_idle.idle);
472 }
473 ti = task_thread_info(c_idle.idle);
474 417
475#ifdef CONFIG_PPC64 418#ifdef CONFIG_PPC64
476 paca[cpu].__current = c_idle.idle; 419 paca[cpu].__current = idle;
477 paca[cpu].kstack = (unsigned long)ti + THREAD_SIZE - STACK_FRAME_OVERHEAD; 420 paca[cpu].kstack = (unsigned long)ti + THREAD_SIZE - STACK_FRAME_OVERHEAD;
478#endif 421#endif
479 ti->cpu = cpu; 422 ti->cpu = cpu;
480 current_set[cpu] = ti; 423 secondary_ti = current_set[cpu] = ti;
481
482 return 0;
483} 424}
484 425
485int __cpuinit __cpu_up(unsigned int cpu) 426int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
486{ 427{
487 int rc, c; 428 int rc, c;
488 429
@@ -490,12 +431,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
490 (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu))) 431 (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)))
491 return -EINVAL; 432 return -EINVAL;
492 433
493 /* Make sure we have an idle thread */ 434 cpu_idle_thread_init(cpu, tidle);
494 rc = create_idle(cpu);
495 if (rc)
496 return rc;
497
498 secondary_ti = current_set[cpu];
499 435
500 /* Make sure callin-map entry is 0 (can be leftover a CPU 436 /* Make sure callin-map entry is 0 (can be leftover a CPU
501 * hotplug 437 * hotplug