diff options
Diffstat (limited to 'arch/ia64/sn/kernel/sn2')
-rw-r--r-- | arch/ia64/sn/kernel/sn2/sn2_smp.c | 23 |
1 files changed, 22 insertions, 1 deletions
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 | */ | ||
181 | void 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 | |||
172 | void sn_tlb_migrate_finish(struct mm_struct *mm) | 193 | void sn_tlb_migrate_finish(struct mm_struct *mm) |
173 | { | 194 | { |
174 | if (mm == current->mm) | 195 | if (mm == current->mm) |