Date: Sat, 20 Feb 2010 16:13:44 +0000 (UTC) From: Nathan Whitehorn <nwhitehorn@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r204126 - head/sys/powerpc/booke Message-ID: <201002201613.o1KGDiiK053065@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: nwhitehorn Date: Sat Feb 20 16:13:43 2010 New Revision: 204126 URL: http://svn.freebsd.org/changeset/base/204126 Log: Merge r198724 to Book-E. casuword() non-atomically read the current value of its argument before atomically replacing it, which could occasionally return the wrong value on an SMP system. This resulted in user mutex operations hanging when using threaded applications. Modified: head/sys/powerpc/booke/copyinout.c Modified: head/sys/powerpc/booke/copyinout.c ============================================================================== --- head/sys/powerpc/booke/copyinout.c Sat Feb 20 16:12:37 2010 (r204125) +++ head/sys/powerpc/booke/copyinout.c Sat Feb 20 16:13:43 2010 (r204126) @@ -295,8 +295,19 @@ casuword(volatile u_long *addr, u_long o return (EFAULT); } - val = *addr; - (void) atomic_cmpset_32((volatile uint32_t *)addr, old, new); + __asm __volatile ( + "1:\tlwarx %0, 0, %2\n\t" /* load old value */ + "cmplw %3, %0\n\t" /* compare */ + "bne 2f\n\t" /* exit if not equal */ + "stwcx. %4, 0, %2\n\t" /* attempt to store */ + "bne- 1b\n\t" /* spin if failed */ + "b 3f\n\t" /* we've succeeded */ + "2:\n\t" + "stwcx. %0, 0, %2\n\t" /* clear reservation (74xx) */ + "3:\n\t" + : "=&r" (val), "=m" (*addr) + : "r" (addr), "r" (old), "r" (new), "m" (*addr) + : "cc", "memory"); td->td_pcb->pcb_onfault = NULL;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201002201613.o1KGDiiK053065>