Merge branch 'x86-atomic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 18 May 2010 15:40:05 +0000 (08:40 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 18 May 2010 15:40:05 +0000 (08:40 -0700)
* 'x86-atomic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86: Fix LOCK_PREFIX_HERE for uniprocessor build
  x86, atomic64: In selftest, distinguish x86-64 from 586+
  x86-32: Fix atomic64_inc_not_zero return value convention
  lib: Fix atomic64_inc_not_zero test
  lib: Fix atomic64_add_unless return value convention
  x86-32: Fix atomic64_add_unless return value convention
  lib: Fix atomic64_add_unless test
  x86: Implement atomic[64]_dec_if_positive()
  lib: Only test atomic64_dec_if_positive on archs having it
  x86-32: Rewrite 32-bit atomic64 functions in assembly
  lib: Add self-test for atomic64_t
  x86-32: Allow UP/SMP lock replacement in cmpxchg64
  x86: Add support for lock prefix in alternatives

1  2 
arch/x86/include/asm/atomic.h
arch/x86/include/asm/atomic64_64.h
arch/x86/lib/Makefile
lib/Kconfig.debug

index 37b39d27abe01ad24aa2b2abfd60467ab0d063ce,706c69492c14ac4ab867457a1b52dace6f79c4b4..952a826ac4e55bf605a05ddad11ae1fb9c315ae9
@@@ -22,7 -22,7 +22,7 @@@
   */
  static inline int atomic_read(const atomic_t *v)
  {
 -      return v->counter;
 +      return (*(volatile int *)&(v)->counter);
  }
  
  /**
@@@ -246,6 -246,29 +246,29 @@@ static inline int atomic_add_unless(ato
  
  #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
  
+ /*
+  * atomic_dec_if_positive - decrement by 1 if old value positive
+  * @v: pointer of type atomic_t
+  *
+  * The function returns the old value of *v minus 1, even if
+  * the atomic variable, v, was not decremented.
+  */
+ static inline int atomic_dec_if_positive(atomic_t *v)
+ {
+       int c, old, dec;
+       c = atomic_read(v);
+       for (;;) {
+               dec = c - 1;
+               if (unlikely(dec < 0))
+                       break;
+               old = atomic_cmpxchg((v), c, dec);
+               if (likely(old == c))
+                       break;
+               c = old;
+       }
+       return dec;
+ }
  /**
   * atomic_inc_short - increment of a short integer
   * @v: pointer to type int
index b014e235ea8dfc31f63520fcab82805dbdc8daa8,4d6e2cd6c88c81ee8c7a7f2ab9642691f6ee3b14..49fd1ea229511632ac849b17f55543e6782da9ae
@@@ -18,7 -18,7 +18,7 @@@
   */
  static inline long atomic64_read(const atomic64_t *v)
  {
 -      return v->counter;
 +      return (*(volatile long *)&(v)->counter);
  }
  
  /**
@@@ -221,4 -221,27 +221,27 @@@ static inline int atomic64_add_unless(a
  
  #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
  
+ /*
+  * atomic64_dec_if_positive - decrement by 1 if old value positive
+  * @v: pointer of type atomic_t
+  *
+  * The function returns the old value of *v minus 1, even if
+  * the atomic variable, v, was not decremented.
+  */
+ static inline long atomic64_dec_if_positive(atomic64_t *v)
+ {
+       long c, old, dec;
+       c = atomic64_read(v);
+       for (;;) {
+               dec = c - 1;
+               if (unlikely(dec < 0))
+                       break;
+               old = atomic64_cmpxchg((v), c, dec);
+               if (likely(old == c))
+                       break;
+               c = old;
+       }
+       return dec;
+ }
  #endif /* _ASM_X86_ATOMIC64_64_H */
diff --combined arch/x86/lib/Makefile
index cbaf8f2b83df34907df786d28892a61e32662148,3ac4a8ade6275c214a3551826eb0a7b89cc3d041..f871e04b6965b828045b08d183dadd0c2aaa487f
@@@ -20,17 -20,18 +20,18 @@@ lib-y := delay.
  lib-y += thunk_$(BITS).o
  lib-y += usercopy_$(BITS).o getuser.o putuser.o
  lib-y += memcpy_$(BITS).o
 -lib-$(CONFIG_KPROBES) += insn.o inat.o
 +lib-$(CONFIG_INSTRUCTION_DECODER) += insn.o inat.o
  
  obj-y += msr.o msr-reg.o msr-reg-export.o
  
  ifeq ($(CONFIG_X86_32),y)
          obj-y += atomic64_32.o
+         lib-y += atomic64_cx8_32.o
          lib-y += checksum_32.o
          lib-y += strstr_32.o
          lib-y += semaphore_32.o string_32.o
  ifneq ($(CONFIG_X86_CMPXCHG64),y)
-         lib-y += cmpxchg8b_emu.o
+         lib-y += cmpxchg8b_emu.o atomic64_386_32.o
  endif
          lib-$(CONFIG_X86_USE_3DNOW) += mmx_32.o
  else
diff --combined lib/Kconfig.debug
index 930a9e5eae08e759a5ad392ab2b5790ad3498e05,231384012a14fa7368f982c2c0a57f1d6d589849..d85be90d5888cb8df619039fb4282e77c9a120ff
@@@ -512,18 -512,6 +512,18 @@@ config PROVE_RC
  
         Say N if you are unsure.
  
 +config PROVE_RCU_REPEATEDLY
 +      bool "RCU debugging: don't disable PROVE_RCU on first splat"
 +      depends on PROVE_RCU
 +      default n
 +      help
 +       By itself, PROVE_RCU will disable checking upon issuing the
 +       first warning (or "splat").  This feature prevents such
 +       disabling, allowing multiple RCU-lockdep warnings to be printed
 +       on a single reboot.
 +
 +       Say N if you are unsure.
 +
  config LOCKDEP
        bool
        depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
@@@ -805,7 -793,7 +805,7 @@@ config RCU_CPU_STALL_DETECTO
  config RCU_CPU_STALL_VERBOSE
        bool "Print additional per-task information for RCU_CPU_STALL_DETECTOR"
        depends on RCU_CPU_STALL_DETECTOR && TREE_PREEMPT_RCU
 -      default n
 +      default y
        help
          This option causes RCU to printk detailed per-task information
          for any tasks that are stalling the current RCU grace period.
@@@ -1098,6 -1086,13 +1098,13 @@@ config DMA_API_DEBU
          This option causes a performance degredation.  Use only if you want
          to debug device drivers. If unsure, say N.
  
+ config ATOMIC64_SELFTEST
+       bool "Perform an atomic64_t self-test at boot"
+       help
+         Enable this option to test the atomic64_t functions at boot.
+         If unsure, say N.
  source "samples/Kconfig"
  
  source "lib/Kconfig.kgdb"