diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-21 22:43:57 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-21 22:43:57 -0400 |
commit | bf67f3a5c456a18f2e8d062f7e88506ef2cd9837 (patch) | |
tree | 2a2324b2572162059307db82f9238eeb25673a77 /arch/powerpc | |
parent | 226da0dbc84ed97f448523e2a4cb91c27fa68ed9 (diff) | |
parent | 203dacbdca977bedaba61ad2fca75d934060a5d5 (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/Kconfig | 5 | ||||
-rw-r--r-- | arch/powerpc/include/asm/processor.h | 1 | ||||
-rw-r--r-- | arch/powerpc/include/asm/thread_info.h | 13 | ||||
-rw-r--r-- | arch/powerpc/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/idle.c | 23 | ||||
-rw-r--r-- | arch/powerpc/kernel/init_task.c | 29 | ||||
-rw-r--r-- | arch/powerpc/kernel/process.c | 31 | ||||
-rw-r--r-- | arch/powerpc/kernel/smp.c | 76 |
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 | ||
90 | config ARCH_HAS_CPU_IDLE_WAIT | ||
91 | bool | ||
92 | default y | ||
93 | |||
94 | config GENERIC_HWEIGHT | 90 | config 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 | ||
148 | config EARLY_PRINTK | 145 | config 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; | |||
386 | enum idle_boot_override {IDLE_NO_OVERRIDE = 0, IDLE_POWERSAVE_OFF}; | 386 | enum idle_boot_override {IDLE_NO_OVERRIDE = 0, IDLE_POWERSAVE_OFF}; |
387 | 387 | ||
388 | extern int powersave_nap; /* set if nap mode can be used in idle loop */ | 388 | extern int powersave_nap; /* set if nap mode can be used in idle loop */ |
389 | void cpu_idle_wait(void); | ||
390 | 389 | ||
391 | #ifdef CONFIG_PSERIES_IDLE | 390 | #ifdef CONFIG_PSERIES_IDLE |
392 | extern void update_smt_snooze_delay(int snooze); | 391 | extern 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 | |||
75 | extern struct thread_info *alloc_thread_info_node(struct task_struct *tsk, int node); | ||
76 | extern 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 */ |
81 | static inline struct thread_info *current_thread_info(void) | 68 | static 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 | ||
29 | obj-y := cputable.o ptrace.o syscalls.o \ | 29 | obj-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 | */ | ||
124 | void 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 | } | ||
137 | EXPORT_SYMBOL_GPL(cpu_idle_wait); | ||
138 | |||
139 | int powersave_nap; | 116 | int 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 | |||
10 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | ||
11 | static 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 | */ | ||
19 | union 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 | */ | ||
27 | struct task_struct init_task = INIT_TASK(init_task); | ||
28 | |||
29 | EXPORT_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 | |||
1257 | static struct kmem_cache *thread_info_cache; | ||
1258 | |||
1259 | struct 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 | |||
1272 | void free_thread_info(struct thread_info *ti) | ||
1273 | { | ||
1274 | kmem_cache_free(thread_info_cache, ti); | ||
1275 | } | ||
1276 | |||
1277 | void 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 | |||
1286 | unsigned long arch_align_stack(unsigned long sp) | 1255 | unsigned 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 | */ | ||
70 | static 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 */ |
75 | static DEFINE_PER_CPU(int, cpu_state) = { 0 }; | 62 | static DEFINE_PER_CPU(int, cpu_state) = { 0 }; |
76 | |||
77 | #else | ||
78 | static 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 | ||
83 | struct thread_info *secondary_ti; | 65 | struct thread_info *secondary_ti; |
@@ -429,60 +411,19 @@ int generic_check_cpu_restart(unsigned int cpu) | |||
429 | } | 411 | } |
430 | #endif | 412 | #endif |
431 | 413 | ||
432 | struct create_idle { | 414 | static 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 | |||
439 | static 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 | |||
448 | static 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 | ||
485 | int __cpuinit __cpu_up(unsigned int cpu) | 426 | int __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 |