diff --git a/lib/lockref.c b/lib/lockref.c index 2afe4c5d8919..56f4419f593d 100644 --- a/lib/lockref.c +++ b/lib/lockref.c @@ -26,6 +26,17 @@ } \ } while (0) +/* + * The compiler isn't smart enough to the the count + * increment in the high 32 bits of the 64-bit value, + * so do this optimization by hand. + */ +#if defined(__LITTLE_ENDIAN) && BITS_PER_LONG == 64 + #define LOCKREF_ADD(n,x) ((n).lock_count += (unsigned long)(x)<<32) +#else + #define LOCKREF_ADD(n,x) ((n).count += (unsigned long)(x)<<32) +#endif + #else #define CMPXCHG_LOOP(CODE, SUCCESS) do { } while (0) @@ -42,7 +53,7 @@ void lockref_get(struct lockref *lockref) { CMPXCHG_LOOP( - new.count++; + LOCKREF_ADD(new,1); , return; ); @@ -63,7 +74,7 @@ int lockref_get_not_zero(struct lockref *lockref) int retval; CMPXCHG_LOOP( - new.count++; + LOCKREF_ADD(new,1); if (old.count <= 0) return 0; , @@ -91,7 +102,7 @@ int lockref_put_not_zero(struct lockref *lockref) int retval; CMPXCHG_LOOP( - new.count--; + LOCKREF_ADD(new,-1); if (old.count <= 1) return 0; , @@ -119,7 +130,7 @@ EXPORT_SYMBOL(lockref_put_not_zero); int lockref_put_return(struct lockref *lockref) { CMPXCHG_LOOP( - new.count--; + LOCKREF_ADD(new,-1); if (old.count <= 0) return -1; , @@ -137,7 +148,7 @@ EXPORT_SYMBOL(lockref_put_return); int lockref_put_or_lock(struct lockref *lockref) { CMPXCHG_LOOP( - new.count--; + LOCKREF_ADD(new,-1); if (old.count <= 1) break; , @@ -174,7 +185,7 @@ int lockref_get_not_dead(struct lockref *lockref) int retval; CMPXCHG_LOOP( - new.count++; + LOCKREF_ADD(new,1); if (old.count < 0) return 0; ,