From: Ricardo M. Correia Date: Fri, 17 Sep 2010 23:03:15 +0000 (-0700) Subject: atomic_*_*_nv() functions need to return the new value atomically. X-Git-Tag: zfs-0.8.0-rc1~152^2~528 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a68d91d770c0d4b8b72d9d07e65a79f3f99f03c6;p=zfs atomic_*_*_nv() functions need to return the new value atomically. A local variable must be used for the return value to avoid a potential race once the spin lock is dropped. Signed-off-by: Ricardo M. Correia Signed-off-by: Brian Behlendorf --- diff --git a/include/sys/atomic.h b/include/sys/atomic.h index 9348ab97e..1d1173894 100644 --- a/include/sys/atomic.h +++ b/include/sys/atomic.h @@ -93,41 +93,51 @@ atomic_sub_32(volatile uint32_t *target, int32_t delta) static __inline__ uint32_t atomic_inc_32_nv(volatile uint32_t *target) { + uint32_t nv; + spin_lock(&atomic32_lock); - (*target)++; + nv = ++(*target); spin_unlock(&atomic32_lock); - return *target; + return nv; } static __inline__ uint32_t atomic_dec_32_nv(volatile uint32_t *target) { + uint32_t nv; + spin_lock(&atomic32_lock); - (*target)--; + nv = --(*target); spin_unlock(&atomic32_lock); - return *target; + return nv; } static __inline__ uint32_t atomic_add_32_nv(volatile uint32_t *target, uint32_t delta) { + uint32_t nv; + spin_lock(&atomic32_lock); *target += delta; + nv = *target; spin_unlock(&atomic32_lock); - return *target; + return nv; } static __inline__ uint32_t atomic_sub_32_nv(volatile uint32_t *target, uint32_t delta) { + uint32_t nv; + spin_lock(&atomic32_lock); *target -= delta; + nv = *target; spin_unlock(&atomic32_lock); - return *target; + return nv; } static __inline__ uint32_t @@ -181,41 +191,51 @@ atomic_sub_64(volatile uint64_t *target, uint64_t delta) static __inline__ uint64_t atomic_inc_64_nv(volatile uint64_t *target) { + uint64_t nv; + spin_lock(&atomic64_lock); - (*target)++; + nv = ++(*target); spin_unlock(&atomic64_lock); - return *target; + return nv; } static __inline__ uint64_t atomic_dec_64_nv(volatile uint64_t *target) { + uint64_t nv; + spin_lock(&atomic64_lock); - (*target)--; + nv = --(*target); spin_unlock(&atomic64_lock); - return *target; + return nv; } static __inline__ uint64_t atomic_add_64_nv(volatile uint64_t *target, uint64_t delta) { + uint64_t nv; + spin_lock(&atomic64_lock); *target += delta; + nv = *target; spin_unlock(&atomic64_lock); - return *target; + return nv; } static __inline__ uint64_t atomic_sub_64_nv(volatile uint64_t *target, uint64_t delta) { + uint64_t nv; + spin_lock(&atomic64_lock); *target -= delta; + nv = *target; spin_unlock(&atomic64_lock); - return *target; + return nv; } static __inline__ uint64_t