svn commit: r204126 - head/sys/powerpc/booke

Nathan Whitehorn nwhitehorn at freebsd.org
Sat Feb 20 18:24:27 UTC 2010


Rafal Jaworowski wrote:
> On 2010-02-20, at 17:13, Nathan Whitehorn wrote:
>
>   
>> 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.
>>     
>
> Have you got a particular test case when this was breaking, so I can test?
>   
This typically shows up with heavy lock contention on umtx operations. I 
discovered this because running csup died for me 100% of the time on my 
Xserve, by hanging forever in some umtx code.

This change explicitly preserves the semantics of casuword -- it is just 
the code for atomic_cmpset_32 copied from atomic.h, but returning the 
value loading with lwarx, instead of replacing it with a success code. 
This closes a race between val = *addr and atomic_cmpset. With the old 
code, another CPU could change the value at addr between val = *addr and 
atomic_cmpset, causing casuword to return the wrong value.
>> 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) */
>>     
>
> The 74xx comment reference is somewhat confusing as the clear reservation operation is pretty uniform accross 32-bit PowerPC I guess, and not 74xx specific.
>   
That's true. It should also be updated in atomic.h.
-Nathan


More information about the svn-src-all mailing list