From e549372b384c06403286c224856d3c7a35e2a078 Mon Sep 17 00:00:00 2001 From: Jimi Xenidis Date: Tue, 28 Feb 2012 13:27:07 +0000 Subject: [PATCH] --- yaml --- r: 292486 b: refs/heads/master c: de801de139ba2a2f2c74393ea00a321477ecc0dc h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/powerpc/mm/icswx.c | 23 +++++++++++++++++++++-- trunk/arch/powerpc/mm/icswx.h | 6 ++++++ 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/[refs] b/[refs] index cd72d1eeb46b..f4c2d762919f 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: a6cf7ed5119fb22f54584a9f867b638edd3c4384 +refs/heads/master: de801de139ba2a2f2c74393ea00a321477ecc0dc diff --git a/trunk/arch/powerpc/mm/icswx.c b/trunk/arch/powerpc/mm/icswx.c index 5d9a59eaad93..8cdbd8634a58 100644 --- a/trunk/arch/powerpc/mm/icswx.c +++ b/trunk/arch/powerpc/mm/icswx.c @@ -163,7 +163,7 @@ EXPORT_SYMBOL_GPL(drop_cop); static int acop_use_cop(int ct) { - /* todo */ + /* There is no alternate policy, yet */ return -1; } @@ -227,11 +227,30 @@ int acop_handle_fault(struct pt_regs *regs, unsigned long address, ct = (ccw >> 16) & 0x3f; } + /* + * We could be here because another thread has enabled acop + * but the ACOP register has yet to be updated. + * + * This should have been taken care of by the IPI to sync all + * the threads (see smp_call_function(sync_cop, mm, 1)), but + * that could take forever if there are a significant amount + * of threads. + * + * Given the number of threads on some of these systems, + * perhaps this is the best way to sync ACOP rather than whack + * every thread with an IPI. + */ + if ((acop_copro_type_bit(ct) & current->active_mm->context.acop) != 0) { + sync_cop(current->active_mm); + return 0; + } + + /* check for alternate policy */ if (!acop_use_cop(ct)) return 0; /* at this point the CT is unknown to the system */ - pr_warn("%s[%d]: Coprocessor %d is unavailable", + pr_warn("%s[%d]: Coprocessor %d is unavailable\n", current->comm, current->pid, ct); /* get inst if we don't already have it */ diff --git a/trunk/arch/powerpc/mm/icswx.h b/trunk/arch/powerpc/mm/icswx.h index 42176bd0884c..6dedc08e62c8 100644 --- a/trunk/arch/powerpc/mm/icswx.h +++ b/trunk/arch/powerpc/mm/icswx.h @@ -59,4 +59,10 @@ extern void free_cop_pid(int free_pid); extern int acop_handle_fault(struct pt_regs *regs, unsigned long address, unsigned long error_code); + +static inline u64 acop_copro_type_bit(unsigned int type) +{ + return 1ULL << (63 - type); +} + #endif /* !_ARCH_POWERPC_MM_ICSWX_H_ */