diff options
author | Chris Metcalf <cmetcalf@tilera.com> | 2013-08-07 11:36:54 -0400 |
---|---|---|
committer | Chris Metcalf <cmetcalf@tilera.com> | 2013-08-13 16:26:01 -0400 |
commit | bc1a298f4e04833db4c430df59b90039f0170515 (patch) | |
tree | 802da739309efeab62317f62ec4f1989f3f7d8dd | |
parent | 1182b69cb24c4f7d7ee8c8afe41b5ab2bc05a15b (diff) |
tile: support CONFIG_PREEMPT
This change adds support for CONFIG_PREEMPT (full kernel preemption).
In addition to the core support, this change includes a number
of places where we fix up uses of smp_processor_id() and per-cpu
variables. I also eliminate the PAGE_HOME_HERE and PAGE_HOME_UNKNOWN
values for page homing, as it turns out they weren't being used.
Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
-rw-r--r-- | arch/tile/Kconfig | 2 | ||||
-rw-r--r-- | arch/tile/include/asm/homecache.h | 8 | ||||
-rw-r--r-- | arch/tile/include/asm/irqflags.h | 21 | ||||
-rw-r--r-- | arch/tile/kernel/asm-offsets.c | 2 | ||||
-rw-r--r-- | arch/tile/kernel/hardwall.c | 18 | ||||
-rw-r--r-- | arch/tile/kernel/intvec_32.S | 27 | ||||
-rw-r--r-- | arch/tile/kernel/intvec_64.S | 30 | ||||
-rw-r--r-- | arch/tile/kernel/irq.c | 1 | ||||
-rw-r--r-- | arch/tile/kernel/smp.c | 2 | ||||
-rw-r--r-- | arch/tile/kernel/smpboot.c | 8 | ||||
-rw-r--r-- | arch/tile/kernel/stack.c | 4 | ||||
-rw-r--r-- | arch/tile/kernel/sys.c | 4 | ||||
-rw-r--r-- | arch/tile/lib/memcpy_tile64.c | 12 | ||||
-rw-r--r-- | arch/tile/mm/homecache.c | 4 |
14 files changed, 98 insertions, 45 deletions
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index 0576e1d8c4f9..1126b9d2f4cc 100644 --- a/arch/tile/Kconfig +++ b/arch/tile/Kconfig | |||
@@ -301,6 +301,8 @@ config PAGE_OFFSET | |||
301 | 301 | ||
302 | source "mm/Kconfig" | 302 | source "mm/Kconfig" |
303 | 303 | ||
304 | source "kernel/Kconfig.preempt" | ||
305 | |||
304 | config CMDLINE_BOOL | 306 | config CMDLINE_BOOL |
305 | bool "Built-in kernel command line" | 307 | bool "Built-in kernel command line" |
306 | default n | 308 | default n |
diff --git a/arch/tile/include/asm/homecache.h b/arch/tile/include/asm/homecache.h index 7b7771328642..49d19dfc0630 100644 --- a/arch/tile/include/asm/homecache.h +++ b/arch/tile/include/asm/homecache.h | |||
@@ -44,16 +44,8 @@ struct zone; | |||
44 | */ | 44 | */ |
45 | #define PAGE_HOME_INCOHERENT -3 | 45 | #define PAGE_HOME_INCOHERENT -3 |
46 | 46 | ||
47 | #if CHIP_HAS_CBOX_HOME_MAP() | ||
48 | /* Home for the page is distributed via hash-for-home. */ | 47 | /* Home for the page is distributed via hash-for-home. */ |
49 | #define PAGE_HOME_HASH -4 | 48 | #define PAGE_HOME_HASH -4 |
50 | #endif | ||
51 | |||
52 | /* Homing is unknown or unspecified. Not valid for page_home(). */ | ||
53 | #define PAGE_HOME_UNKNOWN -5 | ||
54 | |||
55 | /* Home on the current cpu. Not valid for page_home(). */ | ||
56 | #define PAGE_HOME_HERE -6 | ||
57 | 49 | ||
58 | /* Support wrapper to use instead of explicit hv_flush_remote(). */ | 50 | /* Support wrapper to use instead of explicit hv_flush_remote(). */ |
59 | extern void flush_remote(unsigned long cache_pfn, unsigned long cache_length, | 51 | extern void flush_remote(unsigned long cache_pfn, unsigned long cache_length, |
diff --git a/arch/tile/include/asm/irqflags.h b/arch/tile/include/asm/irqflags.h index c96f9bbb760d..71af5747874d 100644 --- a/arch/tile/include/asm/irqflags.h +++ b/arch/tile/include/asm/irqflags.h | |||
@@ -124,6 +124,12 @@ | |||
124 | DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask); | 124 | DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask); |
125 | #define INITIAL_INTERRUPTS_ENABLED (1ULL << INT_MEM_ERROR) | 125 | #define INITIAL_INTERRUPTS_ENABLED (1ULL << INT_MEM_ERROR) |
126 | 126 | ||
127 | #ifdef CONFIG_DEBUG_PREEMPT | ||
128 | /* Due to inclusion issues, we can't rely on <linux/smp.h> here. */ | ||
129 | extern unsigned int debug_smp_processor_id(void); | ||
130 | # define smp_processor_id() debug_smp_processor_id() | ||
131 | #endif | ||
132 | |||
127 | /* Disable interrupts. */ | 133 | /* Disable interrupts. */ |
128 | #define arch_local_irq_disable() \ | 134 | #define arch_local_irq_disable() \ |
129 | interrupt_mask_set_mask(LINUX_MASKABLE_INTERRUPTS) | 135 | interrupt_mask_set_mask(LINUX_MASKABLE_INTERRUPTS) |
@@ -132,9 +138,18 @@ DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask); | |||
132 | #define arch_local_irq_disable_all() \ | 138 | #define arch_local_irq_disable_all() \ |
133 | interrupt_mask_set_mask(-1ULL) | 139 | interrupt_mask_set_mask(-1ULL) |
134 | 140 | ||
141 | /* | ||
142 | * Read the set of maskable interrupts. | ||
143 | * We avoid the preemption warning here via __this_cpu_ptr since even | ||
144 | * if irqs are already enabled, it's harmless to read the wrong cpu's | ||
145 | * enabled mask. | ||
146 | */ | ||
147 | #define arch_local_irqs_enabled() \ | ||
148 | (*__this_cpu_ptr(&interrupts_enabled_mask)) | ||
149 | |||
135 | /* Re-enable all maskable interrupts. */ | 150 | /* Re-enable all maskable interrupts. */ |
136 | #define arch_local_irq_enable() \ | 151 | #define arch_local_irq_enable() \ |
137 | interrupt_mask_reset_mask(__get_cpu_var(interrupts_enabled_mask)) | 152 | interrupt_mask_reset_mask(arch_local_irqs_enabled()) |
138 | 153 | ||
139 | /* Disable or enable interrupts based on flag argument. */ | 154 | /* Disable or enable interrupts based on flag argument. */ |
140 | #define arch_local_irq_restore(disabled) do { \ | 155 | #define arch_local_irq_restore(disabled) do { \ |
@@ -161,7 +176,7 @@ DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask); | |||
161 | 176 | ||
162 | /* Prevent the given interrupt from being enabled next time we enable irqs. */ | 177 | /* Prevent the given interrupt from being enabled next time we enable irqs. */ |
163 | #define arch_local_irq_mask(interrupt) \ | 178 | #define arch_local_irq_mask(interrupt) \ |
164 | (__get_cpu_var(interrupts_enabled_mask) &= ~(1ULL << (interrupt))) | 179 | this_cpu_and(interrupts_enabled_mask, ~(1ULL << (interrupt))) |
165 | 180 | ||
166 | /* Prevent the given interrupt from being enabled immediately. */ | 181 | /* Prevent the given interrupt from being enabled immediately. */ |
167 | #define arch_local_irq_mask_now(interrupt) do { \ | 182 | #define arch_local_irq_mask_now(interrupt) do { \ |
@@ -171,7 +186,7 @@ DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask); | |||
171 | 186 | ||
172 | /* Allow the given interrupt to be enabled next time we enable irqs. */ | 187 | /* Allow the given interrupt to be enabled next time we enable irqs. */ |
173 | #define arch_local_irq_unmask(interrupt) \ | 188 | #define arch_local_irq_unmask(interrupt) \ |
174 | (__get_cpu_var(interrupts_enabled_mask) |= (1ULL << (interrupt))) | 189 | this_cpu_or(interrupts_enabled_mask, (1ULL << (interrupt))) |
175 | 190 | ||
176 | /* Allow the given interrupt to be enabled immediately, if !irqs_disabled. */ | 191 | /* Allow the given interrupt to be enabled immediately, if !irqs_disabled. */ |
177 | #define arch_local_irq_unmask_now(interrupt) do { \ | 192 | #define arch_local_irq_unmask_now(interrupt) do { \ |
diff --git a/arch/tile/kernel/asm-offsets.c b/arch/tile/kernel/asm-offsets.c index 8652b0be4685..97ea6ac0a47b 100644 --- a/arch/tile/kernel/asm-offsets.c +++ b/arch/tile/kernel/asm-offsets.c | |||
@@ -58,6 +58,8 @@ void foo(void) | |||
58 | offsetof(struct thread_info, status)); | 58 | offsetof(struct thread_info, status)); |
59 | DEFINE(THREAD_INFO_HOMECACHE_CPU_OFFSET, | 59 | DEFINE(THREAD_INFO_HOMECACHE_CPU_OFFSET, |
60 | offsetof(struct thread_info, homecache_cpu)); | 60 | offsetof(struct thread_info, homecache_cpu)); |
61 | DEFINE(THREAD_INFO_PREEMPT_COUNT_OFFSET, | ||
62 | offsetof(struct thread_info, preempt_count)); | ||
61 | DEFINE(THREAD_INFO_STEP_STATE_OFFSET, | 63 | DEFINE(THREAD_INFO_STEP_STATE_OFFSET, |
62 | offsetof(struct thread_info, step_state)); | 64 | offsetof(struct thread_info, step_state)); |
63 | #ifdef __tilegx__ | 65 | #ifdef __tilegx__ |
diff --git a/arch/tile/kernel/hardwall.c b/arch/tile/kernel/hardwall.c index 7db8893d4fc5..df27a1fd94a3 100644 --- a/arch/tile/kernel/hardwall.c +++ b/arch/tile/kernel/hardwall.c | |||
@@ -272,9 +272,9 @@ static void hardwall_setup_func(void *info) | |||
272 | struct hardwall_info *r = info; | 272 | struct hardwall_info *r = info; |
273 | struct hardwall_type *hwt = r->type; | 273 | struct hardwall_type *hwt = r->type; |
274 | 274 | ||
275 | int cpu = smp_processor_id(); | 275 | int cpu = smp_processor_id(); /* on_each_cpu disables preemption */ |
276 | int x = cpu % smp_width; | 276 | int x = cpu_x(cpu); |
277 | int y = cpu / smp_width; | 277 | int y = cpu_y(cpu); |
278 | int bits = 0; | 278 | int bits = 0; |
279 | if (x == r->ulhc_x) | 279 | if (x == r->ulhc_x) |
280 | bits |= W_PROTECT; | 280 | bits |= W_PROTECT; |
@@ -317,6 +317,7 @@ static void hardwall_protect_rectangle(struct hardwall_info *r) | |||
317 | on_each_cpu_mask(&rect_cpus, hardwall_setup_func, r, 1); | 317 | on_each_cpu_mask(&rect_cpus, hardwall_setup_func, r, 1); |
318 | } | 318 | } |
319 | 319 | ||
320 | /* Entered from INT_xDN_FIREWALL interrupt vector with irqs disabled. */ | ||
320 | void __kprobes do_hardwall_trap(struct pt_regs* regs, int fault_num) | 321 | void __kprobes do_hardwall_trap(struct pt_regs* regs, int fault_num) |
321 | { | 322 | { |
322 | struct hardwall_info *rect; | 323 | struct hardwall_info *rect; |
@@ -325,7 +326,6 @@ void __kprobes do_hardwall_trap(struct pt_regs* regs, int fault_num) | |||
325 | struct siginfo info; | 326 | struct siginfo info; |
326 | int cpu = smp_processor_id(); | 327 | int cpu = smp_processor_id(); |
327 | int found_processes; | 328 | int found_processes; |
328 | unsigned long flags; | ||
329 | struct pt_regs *old_regs = set_irq_regs(regs); | 329 | struct pt_regs *old_regs = set_irq_regs(regs); |
330 | 330 | ||
331 | irq_enter(); | 331 | irq_enter(); |
@@ -346,7 +346,7 @@ void __kprobes do_hardwall_trap(struct pt_regs* regs, int fault_num) | |||
346 | BUG_ON(hwt->disabled); | 346 | BUG_ON(hwt->disabled); |
347 | 347 | ||
348 | /* This tile trapped a network access; find the rectangle. */ | 348 | /* This tile trapped a network access; find the rectangle. */ |
349 | spin_lock_irqsave(&hwt->lock, flags); | 349 | spin_lock(&hwt->lock); |
350 | list_for_each_entry(rect, &hwt->list, list) { | 350 | list_for_each_entry(rect, &hwt->list, list) { |
351 | if (cpumask_test_cpu(cpu, &rect->cpumask)) | 351 | if (cpumask_test_cpu(cpu, &rect->cpumask)) |
352 | break; | 352 | break; |
@@ -401,7 +401,7 @@ void __kprobes do_hardwall_trap(struct pt_regs* regs, int fault_num) | |||
401 | pr_notice("hardwall: no associated processes!\n"); | 401 | pr_notice("hardwall: no associated processes!\n"); |
402 | 402 | ||
403 | done: | 403 | done: |
404 | spin_unlock_irqrestore(&hwt->lock, flags); | 404 | spin_unlock(&hwt->lock); |
405 | 405 | ||
406 | /* | 406 | /* |
407 | * We have to disable firewall interrupts now, or else when we | 407 | * We have to disable firewall interrupts now, or else when we |
@@ -661,7 +661,7 @@ static int hardwall_deactivate(struct hardwall_type *hwt, | |||
661 | return -EINVAL; | 661 | return -EINVAL; |
662 | 662 | ||
663 | printk(KERN_DEBUG "Pid %d (%s) deactivated for %s hardwall: cpu %d\n", | 663 | printk(KERN_DEBUG "Pid %d (%s) deactivated for %s hardwall: cpu %d\n", |
664 | task->pid, task->comm, hwt->name, smp_processor_id()); | 664 | task->pid, task->comm, hwt->name, raw_smp_processor_id()); |
665 | return 0; | 665 | return 0; |
666 | } | 666 | } |
667 | 667 | ||
@@ -803,8 +803,8 @@ static void reset_xdn_network_state(struct hardwall_type *hwt) | |||
803 | /* Reset UDN coordinates to their standard value */ | 803 | /* Reset UDN coordinates to their standard value */ |
804 | { | 804 | { |
805 | unsigned int cpu = smp_processor_id(); | 805 | unsigned int cpu = smp_processor_id(); |
806 | unsigned int x = cpu % smp_width; | 806 | unsigned int x = cpu_x(cpu); |
807 | unsigned int y = cpu / smp_width; | 807 | unsigned int y = cpu_y(cpu); |
808 | __insn_mtspr(SPR_UDN_TILE_COORD, (x << 18) | (y << 7)); | 808 | __insn_mtspr(SPR_UDN_TILE_COORD, (x << 18) | (y << 7)); |
809 | } | 809 | } |
810 | 810 | ||
diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S index 388061319c4c..10767655689e 100644 --- a/arch/tile/kernel/intvec_32.S +++ b/arch/tile/kernel/intvec_32.S | |||
@@ -28,10 +28,6 @@ | |||
28 | #include <arch/interrupts.h> | 28 | #include <arch/interrupts.h> |
29 | #include <arch/spr_def.h> | 29 | #include <arch/spr_def.h> |
30 | 30 | ||
31 | #ifdef CONFIG_PREEMPT | ||
32 | # error "No support for kernel preemption currently" | ||
33 | #endif | ||
34 | |||
35 | #define PTREGS_PTR(reg, ptreg) addli reg, sp, C_ABI_SAVE_AREA_SIZE + (ptreg) | 31 | #define PTREGS_PTR(reg, ptreg) addli reg, sp, C_ABI_SAVE_AREA_SIZE + (ptreg) |
36 | 32 | ||
37 | #define PTREGS_OFFSET_SYSCALL PTREGS_OFFSET_REG(TREG_SYSCALL_NR) | 33 | #define PTREGS_OFFSET_SYSCALL PTREGS_OFFSET_REG(TREG_SYSCALL_NR) |
@@ -812,17 +808,34 @@ STD_ENTRY(interrupt_return) | |||
812 | } | 808 | } |
813 | lw r29, r29 | 809 | lw r29, r29 |
814 | andi r29, r29, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */ | 810 | andi r29, r29, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */ |
811 | bzt r29, .Lresume_userspace | ||
812 | |||
813 | #ifdef CONFIG_PREEMPT | ||
814 | /* Returning to kernel space. Check if we need preemption. */ | ||
815 | GET_THREAD_INFO(r29) | ||
816 | addli r28, r29, THREAD_INFO_FLAGS_OFFSET | ||
815 | { | 817 | { |
816 | bzt r29, .Lresume_userspace | 818 | lw r28, r28 |
817 | PTREGS_PTR(r29, PTREGS_OFFSET_PC) | 819 | addli r29, r29, THREAD_INFO_PREEMPT_COUNT_OFFSET |
820 | } | ||
821 | { | ||
822 | andi r28, r28, _TIF_NEED_RESCHED | ||
823 | lw r29, r29 | ||
818 | } | 824 | } |
825 | bzt r28, 1f | ||
826 | bnz r29, 1f | ||
827 | jal preempt_schedule_irq | ||
828 | FEEDBACK_REENTER(interrupt_return) | ||
829 | 1: | ||
830 | #endif | ||
819 | 831 | ||
820 | /* If we're resuming to _cpu_idle_nap, bump PC forward by 8. */ | 832 | /* If we're resuming to _cpu_idle_nap, bump PC forward by 8. */ |
821 | { | 833 | { |
822 | lw r28, r29 | 834 | PTREGS_PTR(r29, PTREGS_OFFSET_PC) |
823 | moveli r27, lo16(_cpu_idle_nap) | 835 | moveli r27, lo16(_cpu_idle_nap) |
824 | } | 836 | } |
825 | { | 837 | { |
838 | lw r28, r29 | ||
826 | auli r27, r27, ha16(_cpu_idle_nap) | 839 | auli r27, r27, ha16(_cpu_idle_nap) |
827 | } | 840 | } |
828 | { | 841 | { |
diff --git a/arch/tile/kernel/intvec_64.S b/arch/tile/kernel/intvec_64.S index 884af9ea5bed..38a60f27707c 100644 --- a/arch/tile/kernel/intvec_64.S +++ b/arch/tile/kernel/intvec_64.S | |||
@@ -30,10 +30,6 @@ | |||
30 | #include <arch/interrupts.h> | 30 | #include <arch/interrupts.h> |
31 | #include <arch/spr_def.h> | 31 | #include <arch/spr_def.h> |
32 | 32 | ||
33 | #ifdef CONFIG_PREEMPT | ||
34 | # error "No support for kernel preemption currently" | ||
35 | #endif | ||
36 | |||
37 | #define PTREGS_PTR(reg, ptreg) addli reg, sp, C_ABI_SAVE_AREA_SIZE + (ptreg) | 33 | #define PTREGS_PTR(reg, ptreg) addli reg, sp, C_ABI_SAVE_AREA_SIZE + (ptreg) |
38 | 34 | ||
39 | #define PTREGS_OFFSET_SYSCALL PTREGS_OFFSET_REG(TREG_SYSCALL_NR) | 35 | #define PTREGS_OFFSET_SYSCALL PTREGS_OFFSET_REG(TREG_SYSCALL_NR) |
@@ -820,11 +816,33 @@ STD_ENTRY(interrupt_return) | |||
820 | andi r29, r29, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */ | 816 | andi r29, r29, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */ |
821 | { | 817 | { |
822 | beqzt r29, .Lresume_userspace | 818 | beqzt r29, .Lresume_userspace |
823 | PTREGS_PTR(r29, PTREGS_OFFSET_PC) | 819 | move r29, sp |
820 | } | ||
821 | |||
822 | #ifdef CONFIG_PREEMPT | ||
823 | /* Returning to kernel space. Check if we need preemption. */ | ||
824 | EXTRACT_THREAD_INFO(r29) | ||
825 | addli r28, r29, THREAD_INFO_FLAGS_OFFSET | ||
826 | { | ||
827 | ld r28, r28 | ||
828 | addli r29, r29, THREAD_INFO_PREEMPT_COUNT_OFFSET | ||
824 | } | 829 | } |
830 | { | ||
831 | andi r28, r28, _TIF_NEED_RESCHED | ||
832 | ld4s r29, r29 | ||
833 | } | ||
834 | beqzt r28, 1f | ||
835 | bnez r29, 1f | ||
836 | jal preempt_schedule_irq | ||
837 | FEEDBACK_REENTER(interrupt_return) | ||
838 | 1: | ||
839 | #endif | ||
825 | 840 | ||
826 | /* If we're resuming to _cpu_idle_nap, bump PC forward by 8. */ | 841 | /* If we're resuming to _cpu_idle_nap, bump PC forward by 8. */ |
827 | moveli r27, hw2_last(_cpu_idle_nap) | 842 | { |
843 | moveli r27, hw2_last(_cpu_idle_nap) | ||
844 | PTREGS_PTR(r29, PTREGS_OFFSET_PC) | ||
845 | } | ||
828 | { | 846 | { |
829 | ld r28, r29 | 847 | ld r28, r29 |
830 | shl16insli r27, r27, hw1(_cpu_idle_nap) | 848 | shl16insli r27, r27, hw1(_cpu_idle_nap) |
diff --git a/arch/tile/kernel/irq.c b/arch/tile/kernel/irq.c index 02e628065012..c90de6c3cb7f 100644 --- a/arch/tile/kernel/irq.c +++ b/arch/tile/kernel/irq.c | |||
@@ -74,6 +74,7 @@ static DEFINE_SPINLOCK(available_irqs_lock); | |||
74 | /* | 74 | /* |
75 | * The interrupt handling path, implemented in terms of HV interrupt | 75 | * The interrupt handling path, implemented in terms of HV interrupt |
76 | * emulation on TILE64 and TILEPro, and IPI hardware on TILE-Gx. | 76 | * emulation on TILE64 and TILEPro, and IPI hardware on TILE-Gx. |
77 | * Entered with interrupts disabled. | ||
77 | */ | 78 | */ |
78 | void tile_dev_intr(struct pt_regs *regs, int intnum) | 79 | void tile_dev_intr(struct pt_regs *regs, int intnum) |
79 | { | 80 | { |
diff --git a/arch/tile/kernel/smp.c b/arch/tile/kernel/smp.c index cbc73a8b8fe1..6cc520d71d2b 100644 --- a/arch/tile/kernel/smp.c +++ b/arch/tile/kernel/smp.c | |||
@@ -100,8 +100,8 @@ static void smp_start_cpu_interrupt(void) | |||
100 | /* Handler to stop the current cpu. */ | 100 | /* Handler to stop the current cpu. */ |
101 | static void smp_stop_cpu_interrupt(void) | 101 | static void smp_stop_cpu_interrupt(void) |
102 | { | 102 | { |
103 | set_cpu_online(smp_processor_id(), 0); | ||
104 | arch_local_irq_disable_all(); | 103 | arch_local_irq_disable_all(); |
104 | set_cpu_online(smp_processor_id(), 0); | ||
105 | for (;;) | 105 | for (;;) |
106 | asm("nap; nop"); | 106 | asm("nap; nop"); |
107 | } | 107 | } |
diff --git a/arch/tile/kernel/smpboot.c b/arch/tile/kernel/smpboot.c index 44bab29bf2f3..dee7f13c5854 100644 --- a/arch/tile/kernel/smpboot.c +++ b/arch/tile/kernel/smpboot.c | |||
@@ -142,13 +142,15 @@ static struct cpumask cpu_started __cpuinitdata; | |||
142 | */ | 142 | */ |
143 | static void __cpuinit start_secondary(void) | 143 | static void __cpuinit start_secondary(void) |
144 | { | 144 | { |
145 | int cpuid = smp_processor_id(); | 145 | int cpuid; |
146 | |||
147 | preempt_disable(); | ||
148 | |||
149 | cpuid = smp_processor_id(); | ||
146 | 150 | ||
147 | /* Set our thread pointer appropriately. */ | 151 | /* Set our thread pointer appropriately. */ |
148 | set_my_cpu_offset(__per_cpu_offset[cpuid]); | 152 | set_my_cpu_offset(__per_cpu_offset[cpuid]); |
149 | 153 | ||
150 | preempt_disable(); | ||
151 | |||
152 | /* | 154 | /* |
153 | * In large machines even this will slow us down, since we | 155 | * In large machines even this will slow us down, since we |
154 | * will be contending for for the printk spinlock. | 156 | * will be contending for for the printk spinlock. |
diff --git a/arch/tile/kernel/stack.c b/arch/tile/kernel/stack.c index c972689231ef..176ffe48eee9 100644 --- a/arch/tile/kernel/stack.c +++ b/arch/tile/kernel/stack.c | |||
@@ -194,7 +194,7 @@ static int KBacktraceIterator_next_item_inclusive( | |||
194 | */ | 194 | */ |
195 | static void validate_stack(struct pt_regs *regs) | 195 | static void validate_stack(struct pt_regs *regs) |
196 | { | 196 | { |
197 | int cpu = smp_processor_id(); | 197 | int cpu = raw_smp_processor_id(); |
198 | unsigned long ksp0 = get_current_ksp0(); | 198 | unsigned long ksp0 = get_current_ksp0(); |
199 | unsigned long ksp0_base = ksp0 - THREAD_SIZE; | 199 | unsigned long ksp0_base = ksp0 - THREAD_SIZE; |
200 | unsigned long sp = stack_pointer; | 200 | unsigned long sp = stack_pointer; |
@@ -392,7 +392,7 @@ void tile_show_stack(struct KBacktraceIterator *kbt, int headers) | |||
392 | pr_err("Starting stack dump of tid %d, pid %d (%s)" | 392 | pr_err("Starting stack dump of tid %d, pid %d (%s)" |
393 | " on cpu %d at cycle %lld\n", | 393 | " on cpu %d at cycle %lld\n", |
394 | kbt->task->pid, kbt->task->tgid, kbt->task->comm, | 394 | kbt->task->pid, kbt->task->tgid, kbt->task->comm, |
395 | smp_processor_id(), get_cycles()); | 395 | raw_smp_processor_id(), get_cycles()); |
396 | } | 396 | } |
397 | kbt->verbose = 1; | 397 | kbt->verbose = 1; |
398 | i = 0; | 398 | i = 0; |
diff --git a/arch/tile/kernel/sys.c b/arch/tile/kernel/sys.c index b881a7be24bd..38debe706061 100644 --- a/arch/tile/kernel/sys.c +++ b/arch/tile/kernel/sys.c | |||
@@ -38,8 +38,10 @@ | |||
38 | SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, len, | 38 | SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, len, |
39 | unsigned long, flags) | 39 | unsigned long, flags) |
40 | { | 40 | { |
41 | /* DCACHE is not particularly effective if not bound to one cpu. */ | ||
41 | if (flags & DCACHE) | 42 | if (flags & DCACHE) |
42 | homecache_evict(cpumask_of(smp_processor_id())); | 43 | homecache_evict(cpumask_of(raw_smp_processor_id())); |
44 | |||
43 | if (flags & ICACHE) | 45 | if (flags & ICACHE) |
44 | flush_remote(0, HV_FLUSH_EVICT_L1I, mm_cpumask(current->mm), | 46 | flush_remote(0, HV_FLUSH_EVICT_L1I, mm_cpumask(current->mm), |
45 | 0, 0, 0, NULL, NULL, 0); | 47 | 0, 0, 0, NULL, NULL, 0); |
diff --git a/arch/tile/lib/memcpy_tile64.c b/arch/tile/lib/memcpy_tile64.c index 3bc4b4e40d93..0290c222847b 100644 --- a/arch/tile/lib/memcpy_tile64.c +++ b/arch/tile/lib/memcpy_tile64.c | |||
@@ -65,7 +65,7 @@ static void memcpy_multicache(void *dest, const void *source, | |||
65 | pmd_t *pmdp; | 65 | pmd_t *pmdp; |
66 | pte_t *ptep; | 66 | pte_t *ptep; |
67 | int type0, type1; | 67 | int type0, type1; |
68 | int cpu = get_cpu(); | 68 | int cpu = smp_processor_id(); |
69 | 69 | ||
70 | /* | 70 | /* |
71 | * Disable interrupts so that we don't recurse into memcpy() | 71 | * Disable interrupts so that we don't recurse into memcpy() |
@@ -126,7 +126,6 @@ static void memcpy_multicache(void *dest, const void *source, | |||
126 | kmap_atomic_idx_pop(); | 126 | kmap_atomic_idx_pop(); |
127 | sim_allow_multiple_caching(0); | 127 | sim_allow_multiple_caching(0); |
128 | local_irq_restore(flags); | 128 | local_irq_restore(flags); |
129 | put_cpu(); | ||
130 | } | 129 | } |
131 | 130 | ||
132 | /* | 131 | /* |
@@ -137,6 +136,9 @@ static void memcpy_multicache(void *dest, const void *source, | |||
137 | static unsigned long fast_copy(void *dest, const void *source, int len, | 136 | static unsigned long fast_copy(void *dest, const void *source, int len, |
138 | memcpy_t func) | 137 | memcpy_t func) |
139 | { | 138 | { |
139 | int cpu = get_cpu(); | ||
140 | unsigned long retval; | ||
141 | |||
140 | /* | 142 | /* |
141 | * Check if it's big enough to bother with. We may end up doing a | 143 | * Check if it's big enough to bother with. We may end up doing a |
142 | * small copy via TLB manipulation if we're near a page boundary, | 144 | * small copy via TLB manipulation if we're near a page boundary, |
@@ -158,7 +160,7 @@ retry_source: | |||
158 | !hv_pte_get_readable(src_pte) || | 160 | !hv_pte_get_readable(src_pte) || |
159 | hv_pte_get_mode(src_pte) != HV_PTE_MODE_CACHE_TILE_L3) | 161 | hv_pte_get_mode(src_pte) != HV_PTE_MODE_CACHE_TILE_L3) |
160 | break; | 162 | break; |
161 | if (get_remote_cache_cpu(src_pte) == smp_processor_id()) | 163 | if (get_remote_cache_cpu(src_pte) == cpu) |
162 | break; | 164 | break; |
163 | src_page = pfn_to_page(pte_pfn(src_pte)); | 165 | src_page = pfn_to_page(pte_pfn(src_pte)); |
164 | get_page(src_page); | 166 | get_page(src_page); |
@@ -235,7 +237,9 @@ retry_dest: | |||
235 | len -= copy_size; | 237 | len -= copy_size; |
236 | } | 238 | } |
237 | 239 | ||
238 | return func(dest, source, len); | 240 | retval = func(dest, source, len); |
241 | put_cpu(); | ||
242 | return retval; | ||
239 | } | 243 | } |
240 | 244 | ||
241 | void *memcpy(void *to, const void *from, __kernel_size_t n) | 245 | void *memcpy(void *to, const void *from, __kernel_size_t n) |
diff --git a/arch/tile/mm/homecache.c b/arch/tile/mm/homecache.c index 1ae911939a18..df46a2d5bdf0 100644 --- a/arch/tile/mm/homecache.c +++ b/arch/tile/mm/homecache.c | |||
@@ -172,7 +172,8 @@ void flush_remote(unsigned long cache_pfn, unsigned long cache_control, | |||
172 | 172 | ||
173 | static void homecache_finv_page_va(void* va, int home) | 173 | static void homecache_finv_page_va(void* va, int home) |
174 | { | 174 | { |
175 | if (home == smp_processor_id()) { | 175 | int cpu = get_cpu(); |
176 | if (home == cpu) { | ||
176 | finv_buffer_local(va, PAGE_SIZE); | 177 | finv_buffer_local(va, PAGE_SIZE); |
177 | } else if (home == PAGE_HOME_HASH) { | 178 | } else if (home == PAGE_HOME_HASH) { |
178 | finv_buffer_remote(va, PAGE_SIZE, 1); | 179 | finv_buffer_remote(va, PAGE_SIZE, 1); |
@@ -180,6 +181,7 @@ static void homecache_finv_page_va(void* va, int home) | |||
180 | BUG_ON(home < 0 || home >= NR_CPUS); | 181 | BUG_ON(home < 0 || home >= NR_CPUS); |
181 | finv_buffer_remote(va, PAGE_SIZE, 0); | 182 | finv_buffer_remote(va, PAGE_SIZE, 0); |
182 | } | 183 | } |
184 | put_cpu(); | ||
183 | } | 185 | } |
184 | 186 | ||
185 | void homecache_finv_map_page(struct page *page, int home) | 187 | void homecache_finv_map_page(struct page *page, int home) |