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 | ||
014b15be | 17 | pack_descriptor(&gdt[GDT_ENTRY_PERCPU], |
297d9c03 | 18 | __per_cpu_offset[cpu], 0xFFFFF, |
014b15be GOC |
19 | 0x2 | DESCTYPE_S, 0x8); |
20 | ||
21 | gdt[GDT_ENTRY_PERCPU].s = 1; | |
297d9c03 JF |
22 | |
23 | per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu]; | |
24 | per_cpu(cpu_number, cpu) = cpu; | |
25 | } | |
26 | ||
27 | ||
28 | /** | |
29 | * smp_call_function(): Run a function on all other CPUs. | |
30 | * @func: The function to run. This must be fast and non-blocking. | |
31 | * @info: An arbitrary pointer to pass to the function. | |
32 | * @nonatomic: Unused. | |
33 | * @wait: If true, wait (atomically) until function has completed on other CPUs. | |
34 | * | |
35 | * Returns 0 on success, else a negative status code. | |
36 | * | |
37 | * If @wait is true, then returns once @func has returned; otherwise | |
38 | * it returns just before the target cpu calls @func. | |
39 | * | |
40 | * You must not call this function with disabled interrupts or from a | |
41 | * hardware interrupt handler or from a bottom half handler. | |
42 | */ | |
43 | int smp_call_function(void (*func) (void *info), void *info, int nonatomic, | |
44 | int wait) | |
45 | { | |
46 | return smp_call_function_mask(cpu_online_map, func, info, wait); | |
47 | } | |
48 | EXPORT_SYMBOL(smp_call_function); | |
49 | ||
50 | /** | |
de489353 | 51 | * smp_call_function_single - Run a function on a specific CPU |
297d9c03 JF |
52 | * @cpu: The target CPU. Cannot be the calling CPU. |
53 | * @func: The function to run. This must be fast and non-blocking. | |
54 | * @info: An arbitrary pointer to pass to the function. | |
55 | * @nonatomic: Unused. | |
56 | * @wait: If true, wait until function has completed on other CPUs. | |
57 | * | |
58 | * Returns 0 on success, else a negative status code. | |
59 | * | |
60 | * If @wait is true, then returns once @func has returned; otherwise | |
61 | * it returns just before the target cpu calls @func. | |
62 | */ | |
63 | int smp_call_function_single(int cpu, void (*func) (void *info), void *info, | |
64 | int nonatomic, int wait) | |
65 | { | |
66 | /* prevent preemption and reschedule on another processor */ | |
67 | int ret; | |
68 | int me = get_cpu(); | |
69 | if (cpu == me) { | |
de489353 AK |
70 | local_irq_disable(); |
71 | func(info); | |
72 | local_irq_enable(); | |
297d9c03 | 73 | put_cpu(); |
de489353 | 74 | return 0; |
297d9c03 JF |
75 | } |
76 | ||
77 | ret = smp_call_function_mask(cpumask_of_cpu(cpu), func, info, wait); | |
78 | ||
79 | put_cpu(); | |
80 | return ret; | |
81 | } | |
82 | EXPORT_SYMBOL(smp_call_function_single); |