aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um
diff options
context:
space:
mode:
authorRichard Weinberger <richard@nod.at>2015-03-18 16:42:54 -0400
committerRichard Weinberger <richard@nod.at>2015-04-13 15:00:58 -0400
commit28fa468f53163bc0b867b4cc75a9e36e7ed4dbbd (patch)
tree5421b0046c8143797630da85db9a9b72c488f9f2 /arch/um
parentd0b5e15f0c0fdd759dd3dd48dc2dc2e7199e0da0 (diff)
um: Remove broken SMP support
At times where UML used the TT mode to operate it had kind of SMP support. It never got finished nor was stable. Let's rip out that cruft and stop confusing developers which do tree-wide SMP cleanups. If someone wants SMP support UML it has do be done from scratch. Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'arch/um')
-rw-r--r--arch/um/Kconfig.um30
-rw-r--r--arch/um/include/asm/processor-generic.h8
-rw-r--r--arch/um/include/asm/smp.h26
-rw-r--r--arch/um/kernel/Makefile2
-rw-r--r--arch/um/kernel/irq.c3
-rw-r--r--arch/um/kernel/process.c11
-rw-r--r--arch/um/kernel/skas/process.c4
-rw-r--r--arch/um/kernel/smp.c238
-rw-r--r--arch/um/kernel/um_arch.c35
9 files changed, 2 insertions, 355 deletions
diff --git a/arch/um/Kconfig.um b/arch/um/Kconfig.um
index a7520c90f62d..ff86fbedc2fc 100644
--- a/arch/um/Kconfig.um
+++ b/arch/um/Kconfig.um
@@ -95,36 +95,6 @@ config MAGIC_SYSRQ
95 The keys are documented in <file:Documentation/sysrq.txt>. Don't say Y 95 The keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
96 unless you really know what this hack does. 96 unless you really know what this hack does.
97 97
98config SMP
99 bool "Symmetric multi-processing support"
100 default n
101 depends on BROKEN
102 help
103 This option enables UML SMP support.
104 It is NOT related to having a real SMP box. Not directly, at least.
105
106 UML implements virtual SMP by allowing as many processes to run
107 simultaneously on the host as there are virtual processors configured.
108
109 Obviously, if the host is a uniprocessor, those processes will
110 timeshare, but, inside UML, will appear to be running simultaneously.
111 If the host is a multiprocessor, then UML processes may run
112 simultaneously, depending on the host scheduler.
113
114 This, however, is supported only in TT mode. So, if you use the SKAS
115 patch on your host, switching to TT mode and enabling SMP usually
116 gives you worse performances.
117 Also, since the support for SMP has been under-developed, there could
118 be some bugs being exposed by enabling SMP.
119
120 If you don't know what to do, say N.
121
122config NR_CPUS
123 int "Maximum number of CPUs (2-32)"
124 range 2 32
125 depends on SMP
126 default "32"
127
128config HIGHMEM 98config HIGHMEM
129 bool "Highmem support" 99 bool "Highmem support"
130 depends on !64BIT && BROKEN 100 depends on !64BIT && BROKEN
diff --git a/arch/um/include/asm/processor-generic.h b/arch/um/include/asm/processor-generic.h
index cbc5edd5a901..2d1e0dd5bb0b 100644
--- a/arch/um/include/asm/processor-generic.h
+++ b/arch/um/include/asm/processor-generic.h
@@ -98,16 +98,8 @@ struct cpuinfo_um {
98 98
99extern struct cpuinfo_um boot_cpu_data; 99extern struct cpuinfo_um boot_cpu_data;
100 100
101#define my_cpu_data cpu_data[smp_processor_id()]
102
103#ifdef CONFIG_SMP
104extern struct cpuinfo_um cpu_data[];
105#define current_cpu_data cpu_data[smp_processor_id()]
106#else
107#define cpu_data (&boot_cpu_data) 101#define cpu_data (&boot_cpu_data)
108#define current_cpu_data boot_cpu_data 102#define current_cpu_data boot_cpu_data
109#endif
110
111 103
112#define KSTK_REG(tsk, reg) get_thread_reg(reg, &tsk->thread.switch_buf) 104#define KSTK_REG(tsk, reg) get_thread_reg(reg, &tsk->thread.switch_buf)
113extern unsigned long get_wchan(struct task_struct *p); 105extern unsigned long get_wchan(struct task_struct *p);
diff --git a/arch/um/include/asm/smp.h b/arch/um/include/asm/smp.h
index e4507938d8cf..9c3be355ed01 100644
--- a/arch/um/include/asm/smp.h
+++ b/arch/um/include/asm/smp.h
@@ -1,32 +1,6 @@
1#ifndef __UM_SMP_H 1#ifndef __UM_SMP_H
2#define __UM_SMP_H 2#define __UM_SMP_H
3 3
4#ifdef CONFIG_SMP
5
6#include <linux/bitops.h>
7#include <asm/current.h>
8#include <linux/cpumask.h>
9
10#define raw_smp_processor_id() (current_thread->cpu)
11
12#define cpu_logical_map(n) (n)
13#define cpu_number_map(n) (n)
14extern int hard_smp_processor_id(void);
15#define NO_PROC_ID -1
16
17extern int ncpus;
18
19
20static inline void smp_cpus_done(unsigned int maxcpus)
21{
22}
23
24extern struct task_struct *idle_threads[NR_CPUS];
25
26#else
27
28#define hard_smp_processor_id() 0 4#define hard_smp_processor_id() 0
29 5
30#endif 6#endif
31
32#endif
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index 2d840a070c8b..b7e31e5a8c0c 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -12,7 +12,7 @@ clean-files :=
12 12
13obj-y = config.o exec.o exitcode.o irq.o ksyms.o mem.o \ 13obj-y = config.o exec.o exitcode.o irq.o ksyms.o mem.o \
14 physmem.o process.o ptrace.o reboot.o sigio.o \ 14 physmem.o process.o ptrace.o reboot.o sigio.o \
15 signal.o smp.o syscall.o sysrq.o time.o tlb.o trap.o \ 15 signal.o syscall.o sysrq.o time.o tlb.o trap.o \
16 um_arch.o umid.o maccess.o skas/ 16 um_arch.o umid.o maccess.o skas/
17 17
18obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o 18obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index 1d8505b1e290..23cb9350d47e 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -35,9 +35,6 @@ void sigio_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs)
35 struct irq_fd *irq_fd; 35 struct irq_fd *irq_fd;
36 int n; 36 int n;
37 37
38 if (smp_sigio_handler())
39 return;
40
41 while (1) { 38 while (1) {
42 n = os_waiting_for_events(active_fds); 39 n = os_waiting_for_events(active_fds);
43 if (n <= 0) { 40 if (n <= 0) {
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index f17bca8ed2ce..68b9119841cd 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -259,17 +259,6 @@ int strlen_user_proc(char __user *str)
259 return strlen_user(str); 259 return strlen_user(str);
260} 260}
261 261
262int smp_sigio_handler(void)
263{
264#ifdef CONFIG_SMP
265 int cpu = current_thread_info()->cpu;
266 IPI_handler(cpu);
267 if (cpu != 0)
268 return 1;
269#endif
270 return 0;
271}
272
273int cpu(void) 262int cpu(void)
274{ 263{
275 return current_thread_info()->cpu; 264 return current_thread_info()->cpu;
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index 082955d694f3..527fa5881915 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -21,9 +21,7 @@ static int __init start_kernel_proc(void *unused)
21 21
22 cpu_tasks[0].pid = pid; 22 cpu_tasks[0].pid = pid;
23 cpu_tasks[0].task = current; 23 cpu_tasks[0].task = current;
24#ifdef CONFIG_SMP 24
25 init_cpu_online(get_cpu_mask(0));
26#endif
27 start_kernel(); 25 start_kernel();
28 return 0; 26 return 0;
29} 27}
diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c
deleted file mode 100644
index 5c8c3ea7db7b..000000000000
--- a/arch/um/kernel/smp.c
+++ /dev/null
@@ -1,238 +0,0 @@
1/*
2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL
4 */
5
6#include <linux/percpu.h>
7#include <asm/pgalloc.h>
8#include <asm/tlb.h>
9
10#ifdef CONFIG_SMP
11
12#include <linux/sched.h>
13#include <linux/module.h>
14#include <linux/threads.h>
15#include <linux/interrupt.h>
16#include <linux/err.h>
17#include <linux/hardirq.h>
18#include <asm/smp.h>
19#include <asm/processor.h>
20#include <asm/spinlock.h>
21#include <kern.h>
22#include <irq_user.h>
23#include <os.h>
24
25/* Per CPU bogomips and other parameters
26 * The only piece used here is the ipi pipe, which is set before SMP is
27 * started and never changed.
28 */
29struct cpuinfo_um cpu_data[NR_CPUS];
30
31/* A statistic, can be a little off */
32int num_reschedules_sent = 0;
33
34/* Not changed after boot */
35struct task_struct *idle_threads[NR_CPUS];
36
37void smp_send_reschedule(int cpu)
38{
39 os_write_file(cpu_data[cpu].ipi_pipe[1], "R", 1);
40 num_reschedules_sent++;
41}
42
43void smp_send_stop(void)
44{
45 int i;
46
47 printk(KERN_INFO "Stopping all CPUs...");
48 for (i = 0; i < num_online_cpus(); i++) {
49 if (i == current_thread->cpu)
50 continue;
51 os_write_file(cpu_data[i].ipi_pipe[1], "S", 1);
52 }
53 printk(KERN_CONT "done\n");
54}
55
56static cpumask_t smp_commenced_mask = CPU_MASK_NONE;
57static cpumask_t cpu_callin_map = CPU_MASK_NONE;
58
59static int idle_proc(void *cpup)
60{
61 int cpu = (int) cpup, err;
62
63 err = os_pipe(cpu_data[cpu].ipi_pipe, 1, 1);
64 if (err < 0)
65 panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err);
66
67 os_set_fd_async(cpu_data[cpu].ipi_pipe[0]);
68
69 wmb();
70 if (cpu_test_and_set(cpu, cpu_callin_map)) {
71 printk(KERN_ERR "huh, CPU#%d already present??\n", cpu);
72 BUG();
73 }
74
75 while (!cpu_isset(cpu, smp_commenced_mask))
76 cpu_relax();
77
78 notify_cpu_starting(cpu);
79 set_cpu_online(cpu, true);
80 default_idle();
81 return 0;
82}
83
84static struct task_struct *idle_thread(int cpu)
85{
86 struct task_struct *new_task;
87
88 current->thread.request.u.thread.proc = idle_proc;
89 current->thread.request.u.thread.arg = (void *) cpu;
90 new_task = fork_idle(cpu);
91 if (IS_ERR(new_task))
92 panic("copy_process failed in idle_thread, error = %ld",
93 PTR_ERR(new_task));
94
95 cpu_tasks[cpu] = ((struct cpu_task)
96 { .pid = new_task->thread.mode.tt.extern_pid,
97 .task = new_task } );
98 idle_threads[cpu] = new_task;
99 panic("skas mode doesn't support SMP");
100 return new_task;
101}
102
103void smp_prepare_cpus(unsigned int maxcpus)
104{
105 struct task_struct *idle;
106 unsigned long waittime;
107 int err, cpu, me = smp_processor_id();
108 int i;
109
110 for (i = 0; i < ncpus; ++i)
111 set_cpu_possible(i, true);
112
113 set_cpu_online(me, true);
114 cpu_set(me, cpu_callin_map);
115
116 err = os_pipe(cpu_data[me].ipi_pipe, 1, 1);
117 if (err < 0)
118 panic("CPU#0 failed to create IPI pipe, errno = %d", -err);
119
120 os_set_fd_async(cpu_data[me].ipi_pipe[0]);
121
122 for (cpu = 1; cpu < ncpus; cpu++) {
123 printk(KERN_INFO "Booting processor %d...\n", cpu);
124
125 idle = idle_thread(cpu);
126
127 init_idle(idle, cpu);
128
129 waittime = 200000000;
130 while (waittime-- && !cpu_isset(cpu, cpu_callin_map))
131 cpu_relax();
132
133 printk(KERN_INFO "%s\n",
134 cpu_isset(cpu, cpu_calling_map) ? "done" : "failed");
135 }
136}
137
138void smp_prepare_boot_cpu(void)
139{
140 set_cpu_online(smp_processor_id(), true);
141}
142
143int __cpu_up(unsigned int cpu, struct task_struct *tidle)
144{
145 cpu_set(cpu, smp_commenced_mask);
146 while (!cpu_online(cpu))
147 mb();
148 return 0;
149}
150
151int setup_profiling_timer(unsigned int multiplier)
152{
153 printk(KERN_INFO "setup_profiling_timer\n");
154 return 0;
155}
156
157void smp_call_function_slave(int cpu);
158
159void IPI_handler(int cpu)
160{
161 unsigned char c;
162 int fd;
163
164 fd = cpu_data[cpu].ipi_pipe[0];
165 while (os_read_file(fd, &c, 1) == 1) {
166 switch (c) {
167 case 'C':
168 smp_call_function_slave(cpu);
169 break;
170
171 case 'R':
172 scheduler_ipi();
173 break;
174
175 case 'S':
176 printk(KERN_INFO "CPU#%d stopping\n", cpu);
177 while (1)
178 pause();
179 break;
180
181 default:
182 printk(KERN_ERR "CPU#%d received unknown IPI [%c]!\n",
183 cpu, c);
184 break;
185 }
186 }
187}
188
189int hard_smp_processor_id(void)
190{
191 return pid_to_processor_id(os_getpid());
192}
193
194static DEFINE_SPINLOCK(call_lock);
195static atomic_t scf_started;
196static atomic_t scf_finished;
197static void (*func)(void *info);
198static void *info;
199
200void smp_call_function_slave(int cpu)
201{
202 atomic_inc(&scf_started);
203 (*func)(info);
204 atomic_inc(&scf_finished);
205}
206
207int smp_call_function(void (*_func)(void *info), void *_info, int wait)
208{
209 int cpus = num_online_cpus() - 1;
210 int i;
211
212 if (!cpus)
213 return 0;
214
215 /* Can deadlock when called with interrupts disabled */
216 WARN_ON(irqs_disabled());
217
218 spin_lock_bh(&call_lock);
219 atomic_set(&scf_started, 0);
220 atomic_set(&scf_finished, 0);
221 func = _func;
222 info = _info;
223
224 for_each_online_cpu(i)
225 os_write_file(cpu_data[i].ipi_pipe[1], "C", 1);
226
227 while (atomic_read(&scf_started) != cpus)
228 barrier();
229
230 if (wait)
231 while (atomic_read(&scf_finished) != cpus)
232 barrier();
233
234 spin_unlock_bh(&call_lock);
235 return 0;
236}
237
238#endif
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index dbd5bda1f184..cd09285facf4 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -66,12 +66,6 @@ static int show_cpuinfo(struct seq_file *m, void *v)
66{ 66{
67 int index = 0; 67 int index = 0;
68 68
69#ifdef CONFIG_SMP
70 index = (struct cpuinfo_um *) v - cpu_data;
71 if (!cpu_online(index))
72 return 0;
73#endif
74
75 seq_printf(m, "processor\t: %d\n", index); 69 seq_printf(m, "processor\t: %d\n", index);
76 seq_printf(m, "vendor_id\t: User Mode Linux\n"); 70 seq_printf(m, "vendor_id\t: User Mode Linux\n");
77 seq_printf(m, "model name\t: UML\n"); 71 seq_printf(m, "model name\t: UML\n");
@@ -168,23 +162,6 @@ __uml_setup("debug", no_skas_debug_setup,
168" this flag is not needed to run gdb on UML in skas mode\n\n" 162" this flag is not needed to run gdb on UML in skas mode\n\n"
169); 163);
170 164
171#ifdef CONFIG_SMP
172static int __init uml_ncpus_setup(char *line, int *add)
173{
174 if (!sscanf(line, "%d", &ncpus)) {
175 printf("Couldn't parse [%s]\n", line);
176 return -1;
177 }
178
179 return 0;
180}
181
182__uml_setup("ncpus=", uml_ncpus_setup,
183"ncpus=<# of desired CPUs>\n"
184" This tells an SMP kernel how many virtual processors to start.\n\n"
185);
186#endif
187
188static int __init Usage(char *line, int *add) 165static int __init Usage(char *line, int *add)
189{ 166{
190 const char **p; 167 const char **p;
@@ -380,15 +357,3 @@ void __init check_bugs(void)
380void apply_alternatives(struct alt_instr *start, struct alt_instr *end) 357void apply_alternatives(struct alt_instr *start, struct alt_instr *end)
381{ 358{
382} 359}
383
384#ifdef CONFIG_SMP
385void alternatives_smp_module_add(struct module *mod, char *name,
386 void *locks, void *locks_end,
387 void *text, void *text_end)
388{
389}
390
391void alternatives_smp_module_del(struct module *mod)
392{
393}
394#endif