From: Tony Luck Date: Tue, 21 Mar 2006 16:21:26 +0000 (-0800) Subject: Pull sn2-mmio-writes into release branch X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=409761bb6a06bd61e2d8e27a1af534371d9537ed;p=openwrt%2Fstaging%2Fblogic.git 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 b2e1e746b47f,1b33fd5e4e3a..d9d306c79f2d --- 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); }