aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/ia64/sn/kernel/setup.c6
-rw-r--r--arch/ia64/sn/kernel/sn2/sn2_smp.c23
-rw-r--r--include/asm-ia64/machvec.h13
-rw-r--r--include/asm-ia64/machvec_sn2.h4
-rw-r--r--include/asm-ia64/processor.h3
-rw-r--r--include/asm-ia64/system.h7
-rw-r--r--include/asm-ia64/thread_info.h1
7 files changed, 52 insertions, 5 deletions
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index e510dce9971f..f1c1338b10b4 100644
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -3,7 +3,7 @@
3 * License. See the file "COPYING" in the main directory of this archive 3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (C) 1999,2001-2005 Silicon Graphics, Inc. All rights reserved. 6 * Copyright (C) 1999,2001-2006 Silicon Graphics, Inc. All rights reserved.
7 */ 7 */
8 8
9#include <linux/config.h> 9#include <linux/config.h>
@@ -496,6 +496,7 @@ void __init sn_setup(char **cmdline_p)
496 * for sn. 496 * for sn.
497 */ 497 */
498 pm_power_off = ia64_sn_power_down; 498 pm_power_off = ia64_sn_power_down;
499 current->thread.flags |= IA64_THREAD_MIGRATION;
499} 500}
500 501
501/** 502/**
@@ -654,7 +655,8 @@ void __init sn_cpu_init(void)
654 SH2_PIO_WRITE_STATUS_1, SH2_PIO_WRITE_STATUS_3}; 655 SH2_PIO_WRITE_STATUS_1, SH2_PIO_WRITE_STATUS_3};
655 u64 *pio; 656 u64 *pio;
656 pio = is_shub1() ? pio1 : pio2; 657 pio = is_shub1() ? pio1 : pio2;
657 pda->pio_write_status_addr = (volatile unsigned long *) LOCAL_MMR_ADDR(pio[slice]); 658 pda->pio_write_status_addr =
659 (volatile unsigned long *)GLOBAL_MMR_ADDR(nasid, pio[slice]);
658 pda->pio_write_status_val = is_shub1() ? SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK : 0; 660 pda->pio_write_status_val = is_shub1() ? SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK : 0;
659 } 661 }
660 662
diff --git a/arch/ia64/sn/kernel/sn2/sn2_smp.c b/arch/ia64/sn/kernel/sn2/sn2_smp.c
index 471bbaa65d1b..1b33fd5e4e3a 100644
--- a/arch/ia64/sn/kernel/sn2/sn2_smp.c
+++ b/arch/ia64/sn/kernel/sn2/sn2_smp.c
@@ -5,7 +5,7 @@
5 * License. See the file "COPYING" in the main directory of this archive 5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details. 6 * for more details.
7 * 7 *
8 * Copyright (C) 2000-2005 Silicon Graphics, Inc. All rights reserved. 8 * Copyright (C) 2000-2006 Silicon Graphics, Inc. All rights reserved.
9 */ 9 */
10 10
11#include <linux/init.h> 11#include <linux/init.h>
@@ -169,6 +169,27 @@ static inline unsigned long wait_piowc(void)
169 return ws; 169 return ws;
170} 170}
171 171
172/**
173 * sn_migrate - SN-specific task migration actions
174 * @task: Task being migrated to new CPU
175 *
176 * SN2 PIO writes from separate CPUs are not guaranteed to arrive in order.
177 * Context switching user threads which have memory-mapped MMIO may cause
178 * PIOs to issue from seperate CPUs, thus the PIO writes must be drained
179 * from the previous CPU's Shub before execution resumes on the new CPU.
180 */
181void sn_migrate(struct task_struct *task)
182{
183 pda_t *last_pda = pdacpu(task_thread_info(task)->last_cpu);
184 volatile unsigned long *adr = last_pda->pio_write_status_addr;
185 unsigned long val = last_pda->pio_write_status_val;
186
187 /* Drain PIO writes from old CPU's Shub */
188 while (unlikely((*adr & SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK)
189 != val))
190 cpu_relax();
191}
192
172void sn_tlb_migrate_finish(struct mm_struct *mm) 193void sn_tlb_migrate_finish(struct mm_struct *mm)
173{ 194{
174 if (mm == current->mm) 195 if (mm == current->mm)
diff --git a/include/asm-ia64/machvec.h b/include/asm-ia64/machvec.h
index ca5ea994d688..c3e4ed8a3e17 100644
--- a/include/asm-ia64/machvec.h
+++ b/include/asm-ia64/machvec.h
@@ -20,6 +20,7 @@ struct scatterlist;
20struct page; 20struct page;
21struct mm_struct; 21struct mm_struct;
22struct pci_bus; 22struct pci_bus;
23struct task_struct;
23 24
24typedef void ia64_mv_setup_t (char **); 25typedef void ia64_mv_setup_t (char **);
25typedef void ia64_mv_cpu_init_t (void); 26typedef void ia64_mv_cpu_init_t (void);
@@ -34,6 +35,7 @@ typedef int ia64_mv_pci_legacy_read_t (struct pci_bus *, u16 port, u32 *val,
34 u8 size); 35 u8 size);
35typedef int ia64_mv_pci_legacy_write_t (struct pci_bus *, u16 port, u32 val, 36typedef int ia64_mv_pci_legacy_write_t (struct pci_bus *, u16 port, u32 val,
36 u8 size); 37 u8 size);
38typedef void ia64_mv_migrate_t(struct task_struct * task);
37 39
38/* DMA-mapping interface: */ 40/* DMA-mapping interface: */
39typedef void ia64_mv_dma_init (void); 41typedef void ia64_mv_dma_init (void);
@@ -85,6 +87,11 @@ machvec_noop_mm (struct mm_struct *mm)
85{ 87{
86} 88}
87 89
90static inline void
91machvec_noop_task (struct task_struct *task)
92{
93}
94
88extern void machvec_setup (char **); 95extern void machvec_setup (char **);
89extern void machvec_timer_interrupt (int, void *, struct pt_regs *); 96extern void machvec_timer_interrupt (int, void *, struct pt_regs *);
90extern void machvec_dma_sync_single (struct device *, dma_addr_t, size_t, int); 97extern void machvec_dma_sync_single (struct device *, dma_addr_t, size_t, int);
@@ -146,6 +153,7 @@ extern void machvec_tlb_migrate_finish (struct mm_struct *);
146# define platform_readw_relaxed ia64_mv.readw_relaxed 153# define platform_readw_relaxed ia64_mv.readw_relaxed
147# define platform_readl_relaxed ia64_mv.readl_relaxed 154# define platform_readl_relaxed ia64_mv.readl_relaxed
148# define platform_readq_relaxed ia64_mv.readq_relaxed 155# define platform_readq_relaxed ia64_mv.readq_relaxed
156# define platform_migrate ia64_mv.migrate
149# endif 157# endif
150 158
151/* __attribute__((__aligned__(16))) is required to make size of the 159/* __attribute__((__aligned__(16))) is required to make size of the
@@ -194,6 +202,7 @@ struct ia64_machine_vector {
194 ia64_mv_readw_relaxed_t *readw_relaxed; 202 ia64_mv_readw_relaxed_t *readw_relaxed;
195 ia64_mv_readl_relaxed_t *readl_relaxed; 203 ia64_mv_readl_relaxed_t *readl_relaxed;
196 ia64_mv_readq_relaxed_t *readq_relaxed; 204 ia64_mv_readq_relaxed_t *readq_relaxed;
205 ia64_mv_migrate_t *migrate;
197} __attribute__((__aligned__(16))); /* align attrib? see above comment */ 206} __attribute__((__aligned__(16))); /* align attrib? see above comment */
198 207
199#define MACHVEC_INIT(name) \ 208#define MACHVEC_INIT(name) \
@@ -238,6 +247,7 @@ struct ia64_machine_vector {
238 platform_readw_relaxed, \ 247 platform_readw_relaxed, \
239 platform_readl_relaxed, \ 248 platform_readl_relaxed, \
240 platform_readq_relaxed, \ 249 platform_readq_relaxed, \
250 platform_migrate, \
241} 251}
242 252
243extern struct ia64_machine_vector ia64_mv; 253extern struct ia64_machine_vector ia64_mv;
@@ -386,5 +396,8 @@ extern ia64_mv_dma_supported swiotlb_dma_supported;
386#ifndef platform_readq_relaxed 396#ifndef platform_readq_relaxed
387# define platform_readq_relaxed __ia64_readq_relaxed 397# define platform_readq_relaxed __ia64_readq_relaxed
388#endif 398#endif
399#ifndef platform_migrate
400# define platform_migrate machvec_noop_task
401#endif
389 402
390#endif /* _ASM_IA64_MACHVEC_H */ 403#endif /* _ASM_IA64_MACHVEC_H */
diff --git a/include/asm-ia64/machvec_sn2.h b/include/asm-ia64/machvec_sn2.h
index e1b6cd63f49e..6f0021bb3874 100644
--- a/include/asm-ia64/machvec_sn2.h
+++ b/include/asm-ia64/machvec_sn2.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2002-2003 Silicon Graphics, Inc. All Rights Reserved. 2 * Copyright (c) 2002-2003,2006 Silicon Graphics, Inc. All Rights Reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License 5 * under the terms of version 2 of the GNU General Public License
@@ -71,6 +71,7 @@ extern ia64_mv_dma_sync_single_for_device sn_dma_sync_single_for_device;
71extern ia64_mv_dma_sync_sg_for_device sn_dma_sync_sg_for_device; 71extern ia64_mv_dma_sync_sg_for_device sn_dma_sync_sg_for_device;
72extern ia64_mv_dma_mapping_error sn_dma_mapping_error; 72extern ia64_mv_dma_mapping_error sn_dma_mapping_error;
73extern ia64_mv_dma_supported sn_dma_supported; 73extern ia64_mv_dma_supported sn_dma_supported;
74extern ia64_mv_migrate_t sn_migrate;
74 75
75/* 76/*
76 * This stuff has dual use! 77 * This stuff has dual use!
@@ -120,6 +121,7 @@ extern ia64_mv_dma_supported sn_dma_supported;
120#define platform_dma_sync_sg_for_device sn_dma_sync_sg_for_device 121#define platform_dma_sync_sg_for_device sn_dma_sync_sg_for_device
121#define platform_dma_mapping_error sn_dma_mapping_error 122#define platform_dma_mapping_error sn_dma_mapping_error
122#define platform_dma_supported sn_dma_supported 123#define platform_dma_supported sn_dma_supported
124#define platform_migrate sn_migrate
123 125
124#include <asm/sn/io.h> 126#include <asm/sn/io.h>
125 127
diff --git a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h
index 09b99029ac1a..29d5574d4375 100644
--- a/include/asm-ia64/processor.h
+++ b/include/asm-ia64/processor.h
@@ -50,7 +50,8 @@
50#define IA64_THREAD_PM_VALID (__IA64_UL(1) << 2) /* performance registers valid? */ 50#define IA64_THREAD_PM_VALID (__IA64_UL(1) << 2) /* performance registers valid? */
51#define IA64_THREAD_UAC_NOPRINT (__IA64_UL(1) << 3) /* don't log unaligned accesses */ 51#define IA64_THREAD_UAC_NOPRINT (__IA64_UL(1) << 3) /* don't log unaligned accesses */
52#define IA64_THREAD_UAC_SIGBUS (__IA64_UL(1) << 4) /* generate SIGBUS on unaligned acc. */ 52#define IA64_THREAD_UAC_SIGBUS (__IA64_UL(1) << 4) /* generate SIGBUS on unaligned acc. */
53 /* bit 5 is currently unused */ 53#define IA64_THREAD_MIGRATION (__IA64_UL(1) << 5) /* require migration
54 sync at ctx sw */
54#define IA64_THREAD_FPEMU_NOPRINT (__IA64_UL(1) << 6) /* don't log any fpswa faults */ 55#define IA64_THREAD_FPEMU_NOPRINT (__IA64_UL(1) << 6) /* don't log any fpswa faults */
55#define IA64_THREAD_FPEMU_SIGFPE (__IA64_UL(1) << 7) /* send a SIGFPE for fpswa faults */ 56#define IA64_THREAD_FPEMU_SIGFPE (__IA64_UL(1) << 7) /* send a SIGFPE for fpswa faults */
56 57
diff --git a/include/asm-ia64/system.h b/include/asm-ia64/system.h
index 80c5a234e259..99b6f307e94b 100644
--- a/include/asm-ia64/system.h
+++ b/include/asm-ia64/system.h
@@ -244,6 +244,13 @@ extern void ia64_load_extra (struct task_struct *task);
244 __ia64_save_fpu((prev)->thread.fph); \ 244 __ia64_save_fpu((prev)->thread.fph); \
245 } \ 245 } \
246 __switch_to(prev, next, last); \ 246 __switch_to(prev, next, last); \
247 /* "next" in old context is "current" in new context */ \
248 if (unlikely((current->thread.flags & IA64_THREAD_MIGRATION) && \
249 (task_cpu(current) != \
250 task_thread_info(current)->last_cpu))) { \
251 platform_migrate(current); \
252 task_thread_info(current)->last_cpu = task_cpu(current); \
253 } \
247} while (0) 254} while (0)
248#else 255#else
249# define switch_to(prev,next,last) __switch_to(prev, next, last) 256# define switch_to(prev,next,last) __switch_to(prev, next, last)
diff --git a/include/asm-ia64/thread_info.h b/include/asm-ia64/thread_info.h
index 1d6518fe1f02..81641a6905d1 100644
--- a/include/asm-ia64/thread_info.h
+++ b/include/asm-ia64/thread_info.h
@@ -26,6 +26,7 @@ struct thread_info {
26 struct exec_domain *exec_domain;/* execution domain */ 26 struct exec_domain *exec_domain;/* execution domain */
27 __u32 flags; /* thread_info flags (see TIF_*) */ 27 __u32 flags; /* thread_info flags (see TIF_*) */
28 __u32 cpu; /* current CPU */ 28 __u32 cpu; /* current CPU */
29 __u32 last_cpu; /* Last CPU thread ran on */
29 mm_segment_t addr_limit; /* user-level address space limit */ 30 mm_segment_t addr_limit; /* user-level address space limit */
30 int preempt_count; /* 0=premptable, <0=BUG; will also serve as bh-counter */ 31 int preempt_count; /* 0=premptable, <0=BUG; will also serve as bh-counter */
31 struct restart_block restart_block; 32 struct restart_block restart_block;