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;
 
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to