Commit | Line | Data |
---|---|---|
297d9c03 JF |
1 | /* |
2 | * SMP stuff which is common to all sub-architectures. | |
3 | */ | |
4 | #include <linux/module.h> | |
5 | #include <asm/smp.h> | |
6 | ||
7 | DEFINE_PER_CPU(unsigned long, this_cpu_off); | |
8 | EXPORT_PER_CPU_SYMBOL(this_cpu_off); | |
9 | ||
10 | /* Initialize the CPU's GDT. This is either the boot CPU doing itself | |
11 | (still using the master per-cpu area), or a CPU doing it for a | |
12 | secondary which will soon come up. */ | |
13 | __cpuinit void init_gdt(int cpu) | |
14 | { | |
15 | struct desc_struct *gdt = get_cpu_gdt_table(cpu); | |
16 | ||
17 | pack_descriptor((u32 *)&gdt[GDT_ENTRY_PERCPU].a, | |
18 | (u32 *)&gdt[GDT_ENTRY_PERCPU].b, | |
19 | __per_cpu_offset[cpu], 0xFFFFF, | |
20 | 0x80 | DESCTYPE_S | 0x2, 0x8); | |
21 | ||
22 | per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu]; | |
23 | per_cpu(cpu_number, cpu) = cpu; | |
24 | } | |
25 | ||
26 | ||
27 | /** | |
28 | * smp_call_function(): Run a function on all other CPUs. | |
29 | * @func: The function to run. This must be fast and non-blocking. | |
30 | * @info: An arbitrary pointer to pass to the function. | |
31 | * @nonatomic: Unused. | |
32 | * @wait: If true, wait (atomically) until function has completed on other CPUs. | |
33 | * | |
34 | * Returns 0 on success, else a negative status code. | |
35 | * | |
36 | * If @wait is true, then returns once @func has returned; otherwise | |
37 | * it returns just before the target cpu calls @func. | |
38 | * | |
39 | * You must not call this function with disabled interrupts or from a | |
40 | * hardware interrupt handler or from a bottom half handler. | |
41 | */ | |
42 | int smp_call_function(void (*func) (void *info), void *info, int nonatomic, | |
43 | int wait) | |
44 | { | |
45 | return smp_call_function_mask(cpu_online_map, func, info, wait); | |
46 | } | |
47 | EXPORT_SYMBOL(smp_call_function); | |
48 | ||
49 | /** | |
de489353 | 50 | * smp_call_function_single - Run a function on a specific CPU |
297d9c03 JF |
51 | * @cpu: The target CPU. Cannot be the calling CPU. |
52 | * @func: The function to run. This must be fast and non-blocking. | |
53 | * @info: An arbitrary pointer to pass to the function. | |
54 | * @nonatomic: Unused. | |
55 | * @wait: If true, wait until function has completed on other CPUs. | |
56 | * | |
57 | * Returns 0 on success, else a negative status code. | |
58 | * | |
59 | * If @wait is true, then returns once @func has returned; otherwise | |
60 | * it returns just before the target cpu calls @func. | |
61 | */ | |
62 | int smp_call_function_single(int cpu, void (*func) (void *info), void *info, | |
63 | int nonatomic, int wait) | |
64 | { | |
65 | /* prevent preemption and reschedule on another processor */ | |
66 | int ret; | |
67 | int me = get_cpu(); | |
68 | if (cpu == me) { | |
de489353 AK |
69 | local_irq_disable(); |
70 | func(info); | |
71 | local_irq_enable(); | |
297d9c03 | 72 | put_cpu(); |
de489353 | 73 | return 0; |
297d9c03 JF |
74 | } |
75 | ||
76 | ret = smp_call_function_mask(cpumask_of_cpu(cpu), func, info, wait); | |
77 | ||
78 | put_cpu(); | |
79 | return ret; | |
80 | } | |
81 | EXPORT_SYMBOL(smp_call_function_single); |