From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13491 invoked by alias); 24 Mar 2006 10:06:36 -0000 Received: (qmail 13471 invoked by uid 22791); 24 Mar 2006 10:06:36 -0000 X-Spam-Check-By: sourceware.org Received: from dsl027-180-168.sfo1.dsl.speakeasy.net (HELO sunset.davemloft.net) (216.27.180.168) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 24 Mar 2006 10:06:35 +0000 Received: from localhost ([127.0.0.1] ident=davem) by sunset.davemloft.net with esmtp (Exim 4.60) (envelope-from ) id 1FMjBe-0006cP-Pi; Fri, 24 Mar 2006 02:06:30 -0800 Date: Fri, 24 Mar 2006 10:06:00 -0000 Message-Id: <20060324.020630.43672826.davem@davemloft.net> To: libc-hacker@sources.redhat.com CC: jakub@redhat.com Subject: [PATCH]: Fix sparc atomic operations From: "David S. Miller" Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Mailing-List: contact libc-hacker-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-hacker-owner@sourceware.org X-SW-Source: 2006-03/txt/msg00037.txt.bz2 The sparc atomics were missing "memory" clobbers in their asm statements. This caused miscompilation of the various pthread atomic primitives. In one case, pthread_mutex_lock() was miscompiled such that the ->owner field of the mutex was sampled before we acquired the lock, thus triggering the "owner == 0" assertion if things were just right. Surprisingly nothing in the nptl tests caught this, instead I discovered it when trying to build MONO, which seemed to be able to trigger this case quite readily. :-) Please apply, thanks. 2006-03-24 David S. Miller * sysdeps/sparc/sparc32/bits/atomic.h (__v9_compare_and_exchange_val_32_acq): Add "memory" clobber. * sysdeps/sparc/sparc32/sparcv9/bits/atomic.h (__arch_compare_and_exchange_val_32_acq, atomic_exchange_acq): Likewise. * sysdeps/sparc/sparc64/bits/atomic.h (__arch_compare_and_exchange_val_32_acq, __arch_compare_and_exchange_val_64_acq, atomic_exchange_acq): Likewise. --- ./sysdeps/sparc/sparc32/bits/atomic.h.~1~ 2006-01-03 16:05:07.000000000 -0800 +++ ./sysdeps/sparc/sparc32/bits/atomic.h 2006-03-24 00:00:06.000000000 -0800 @@ -122,7 +122,7 @@ volatile unsigned char __sparc32_atomic_ __asm __volatile (".word 0xcde05005" \ : "+r" (__acev_tmp), "=m" (*__acev_mem) \ : "r" (__acev_oldval), "m" (*__acev_mem), \ - "r" (__acev_mem)); \ + "r" (__acev_mem) : "memory"); \ __acev_tmp; }) #endif --- ./sysdeps/sparc/sparc32/sparcv9/bits/atomic.h.~1~ 2006-01-03 16:05:07.000000000 -0800 +++ ./sysdeps/sparc/sparc32/sparcv9/bits/atomic.h 2006-03-24 00:00:32.000000000 -0800 @@ -59,7 +59,7 @@ typedef uintmax_t uatomic_max_t; __asm __volatile ("cas [%4], %2, %0" \ : "=r" (__acev_tmp), "=m" (*__acev_mem) \ : "r" (oldval), "m" (*__acev_mem), "r" (__acev_mem), \ - "0" (newval)); \ + "0" (newval) : "memory"); \ __acev_tmp; }) /* This can be implemented if needed. */ @@ -74,7 +74,7 @@ typedef uintmax_t uatomic_max_t; if (sizeof (*(mem)) == 4) \ __asm ("swap %0, %1" \ : "=m" (*__memp), "=r" (__oldval) \ - : "m" (*__memp), "1" (__value)); \ + : "m" (*__memp), "1" (__value) : "memory"); \ else \ abort (); \ __oldval; }) --- ./sysdeps/sparc/sparc64/bits/atomic.h.~1~ 2006-01-03 16:05:07.000000000 -0800 +++ ./sysdeps/sparc/sparc64/bits/atomic.h 2006-03-24 00:01:04.000000000 -0800 @@ -59,7 +59,7 @@ typedef uintmax_t uatomic_max_t; __asm __volatile ("cas [%4], %2, %0" \ : "=r" (__acev_tmp), "=m" (*__acev_mem) \ : "r" (oldval), "m" (*__acev_mem), "r" (__acev_mem), \ - "0" (newval)); \ + "0" (newval) : "memory"); \ __acev_tmp; }) #define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \ @@ -69,7 +69,7 @@ typedef uintmax_t uatomic_max_t; __asm __volatile ("casx [%4], %2, %0" \ : "=r" (__acev_tmp), "=m" (*__acev_mem) \ : "r" ((long) (oldval)), "m" (*__acev_mem), \ - "r" (__acev_mem), "0" ((long) (newval))); \ + "r" (__acev_mem), "0" ((long) (newval)) : "memory"); \ __acev_tmp; }) #define atomic_exchange_acq(mem, newvalue) \ @@ -80,7 +80,7 @@ typedef uintmax_t uatomic_max_t; if (sizeof (*(mem)) == 4) \ __asm ("swap %0, %1" \ : "=m" (*__memp), "=r" (__oldval) \ - : "m" (*__memp), "1" (__value)); \ + : "m" (*__memp), "1" (__value) : "memory"); \ else \ { \ __val = *__memp; \