From: Tony Luck Date: Tue, 21 Mar 2006 16:21:26 +0000 (-0800) Subject: Pull sn2-mmio-writes into release branch X-Git-Tag: v2.6.17-rc1~1130^2^2~3 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=409761bb6a06bd61e2d8e27a1af534371d9537ed;p=linux-2.6 Pull sn2-mmio-writes into release branch Hand-fixed conflicts: include/asm-ia64/machvec_sn2.h Signed-off-by: Tony Luck --- 409761bb6a06bd61e2d8e27a1af534371d9537ed diff --cc arch/ia64/sn/kernel/sn2/sn2_smp.c index b2e1e746b4,1b33fd5e4e..d9d306c79f --- a/arch/ia64/sn/kernel/sn2/sn2_smp.c +++ b/arch/ia64/sn/kernel/sn2/sn2_smp.c @@@ -90,13 -166,33 +90,34 @@@ static inline unsigned long wait_piowc( do { cpu_relax(); } while (((ws = *piows) & SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK) != zeroval); - return ws; + return (ws & SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK) != 0; } + /** + * sn_migrate - SN-specific task migration actions + * @task: Task being migrated to new CPU + * + * SN2 PIO writes from separate CPUs are not guaranteed to arrive in order. + * Context switching user threads which have memory-mapped MMIO may cause + * PIOs to issue from seperate CPUs, thus the PIO writes must be drained + * from the previous CPU's Shub before execution resumes on the new CPU. + */ + void sn_migrate(struct task_struct *task) + { + pda_t *last_pda = pdacpu(task_thread_info(task)->last_cpu); + volatile unsigned long *adr = last_pda->pio_write_status_addr; + unsigned long val = last_pda->pio_write_status_val; + + /* Drain PIO writes from old CPU's Shub */ + while (unlikely((*adr & SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK) + != val)) + cpu_relax(); + } + void sn_tlb_migrate_finish(struct mm_struct *mm) { - if (mm == current->mm) + /* flush_tlb_mm is inefficient if more than 1 users of mm */ + if (mm == current->mm && mm && atomic_read(&mm->mm_users) == 1) flush_tlb_mm(mm); }