sched, arch: Create asm/preempt.h
Peter Zijlstra [Wed, 14 Aug 2013 12:55:40 +0000 (14:55 +0200)]
In order to prepare to per-arch implementations of preempt_count move
the required bits into an asm-generic header and use this for all
archs.
(cherry picked from commit a787870924dbd6f321661e06d4ec1c7a408c9ccf)

Conflicts:
arch/c6x/include/asm/Kbuild
arch/cris/include/asm/Kbuild
arch/h8300/include/asm/Kbuild
arch/ia64/include/asm/Kbuild
arch/mips/include/asm/Kbuild
arch/openrisc/include/asm/Kbuild
arch/powerpc/include/asm/Kbuild
arch/score/include/asm/Kbuild
include/linux/preempt.h

Change-Id: I544914d3c23cc50da658296a34f9f2796854e259

Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/n/tip-h5j0c1r3e3fk015m30h8f1zx@git.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Ishan Mittal <imittal@nvidia.com>

32 files changed:
arch/alpha/include/asm/Kbuild
arch/arc/include/asm/Kbuild
arch/arm/include/asm/Kbuild
arch/arm64/include/asm/Kbuild
arch/avr32/include/asm/Kbuild
arch/blackfin/include/asm/Kbuild
arch/c6x/include/asm/Kbuild
arch/cris/include/asm/Kbuild
arch/frv/include/asm/Kbuild
arch/h8300/include/asm/Kbuild
arch/hexagon/include/asm/Kbuild
arch/ia64/include/asm/Kbuild
arch/m32r/include/asm/Kbuild
arch/m68k/include/asm/Kbuild
arch/metag/include/asm/Kbuild
arch/microblaze/include/asm/Kbuild
arch/mips/include/asm/Kbuild
arch/mn10300/include/asm/Kbuild
arch/openrisc/include/asm/Kbuild
arch/parisc/include/asm/Kbuild
arch/powerpc/include/asm/Kbuild
arch/s390/include/asm/Kbuild
arch/score/include/asm/Kbuild
arch/sh/include/asm/Kbuild
arch/sparc/include/asm/Kbuild
arch/tile/include/asm/Kbuild
arch/um/include/asm/Kbuild
arch/unicore32/include/asm/Kbuild
arch/x86/include/asm/Kbuild
arch/xtensa/include/asm/Kbuild
include/asm-generic/preempt.h [new file with mode: 0644]
include/linux/preempt.h

index a6e85f4..f01fb50 100644 (file)
@@ -3,3 +3,4 @@ generic-y += clkdev.h
 
 generic-y += exec.h
 generic-y += trace_clock.h
+generic-y += preempt.h
index d8dd660..5943f7f 100644 (file)
@@ -46,3 +46,4 @@ generic-y += ucontext.h
 generic-y += user.h
 generic-y += vga.h
 generic-y += xor.h
+generic-y += preempt.h
index d3db398..4e6838d 100644 (file)
@@ -33,3 +33,4 @@ generic-y += timex.h
 generic-y += trace_clock.h
 generic-y += types.h
 generic-y += unaligned.h
+generic-y += preempt.h
index 79a642d..519f89f 100644 (file)
@@ -50,3 +50,4 @@ generic-y += unaligned.h
 generic-y += user.h
 generic-y += vga.h
 generic-y += xor.h
+generic-y += preempt.h
index d22af85..b946080 100644 (file)
@@ -3,3 +3,4 @@ generic-y       += clkdev.h
 generic-y      += exec.h
 generic-y      += trace_clock.h
 generic-y      += param.h
+generic-y += preempt.h
index 127826f..f2b4347 100644 (file)
@@ -44,3 +44,4 @@ generic-y += ucontext.h
 generic-y += unaligned.h
 generic-y += user.h
 generic-y += xor.h
+generic-y += preempt.h
index 4258b08..5121a4e 100644 (file)
@@ -55,3 +55,8 @@ generic-y += types.h
 generic-y += ucontext.h
 generic-y += user.h
 generic-y += vga.h
+<<<<<<< HEAD
+=======
+generic-y += xor.h
+generic-y += preempt.h
+>>>>>>> a787870... sched, arch: Create asm/preempt.h
index f1e79ed..ad66a69 100644 (file)
@@ -7,3 +7,9 @@ generic-y += clkdev.h
 generic-y += exec.h
 generic-y += module.h
 generic-y += trace_clock.h
+<<<<<<< HEAD
+=======
+generic-y += vga.h
+generic-y += xor.h
+generic-y += preempt.h
+>>>>>>> a787870... sched, arch: Create asm/preempt.h
index c5d7670..74742dc 100644 (file)
@@ -2,3 +2,4 @@
 generic-y += clkdev.h
 generic-y += exec.h
 generic-y += trace_clock.h
+generic-y += preempt.h
index 995eb47..1eaa0aa 100644 (file)
@@ -4,3 +4,8 @@ generic-y += exec.h
 generic-y += mmu.h
 generic-y += module.h
 generic-y += trace_clock.h
+<<<<<<< HEAD
+=======
+generic-y += xor.h
+generic-y += preempt.h
+>>>>>>> a787870... sched, arch: Create asm/preempt.h
index 1da17ca..67c3450 100644 (file)
@@ -53,3 +53,4 @@ generic-y += types.h
 generic-y += ucontext.h
 generic-y += unaligned.h
 generic-y += xor.h
+generic-y += preempt.h
index 05b03ec..5cff315 100644 (file)
@@ -3,3 +3,8 @@ generic-y += clkdev.h
 generic-y += exec.h
 generic-y += kvm_para.h
 generic-y += trace_clock.h
+<<<<<<< HEAD
+=======
+generic-y += preempt.h
+generic-y += vtime.h
+>>>>>>> a787870... sched, arch: Create asm/preempt.h
index bebdc36..2b58c5f 100644 (file)
@@ -3,3 +3,4 @@ generic-y += clkdev.h
 generic-y += exec.h
 generic-y += module.h
 generic-y += trace_clock.h
+generic-y += preempt.h
index 09d77a8..a5d27f2 100644 (file)
@@ -31,3 +31,4 @@ generic-y += trace_clock.h
 generic-y += types.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += preempt.h
index 6ae0ccb..84d0c1d 100644 (file)
@@ -52,3 +52,4 @@ generic-y += unaligned.h
 generic-y += user.h
 generic-y += vga.h
 generic-y += xor.h
+generic-y += preempt.h
index d3c51a6..ce0bbf8 100644 (file)
@@ -3,3 +3,4 @@ generic-y += clkdev.h
 generic-y += exec.h
 generic-y += trace_clock.h
 generic-y += syscalls.h
+generic-y += preempt.h
index 9b54b7a..77084ec 100644 (file)
@@ -1,2 +1,8 @@
 # MIPS headers
 generic-y += trace_clock.h
+<<<<<<< HEAD
+=======
+generic-y += preempt.h
+generic-y += ucontext.h
+generic-y += xor.h
+>>>>>>> a787870... sched, arch: Create asm/preempt.h
index c5d7670..74742dc 100644 (file)
@@ -2,3 +2,4 @@
 generic-y += clkdev.h
 generic-y += exec.h
 generic-y += trace_clock.h
+generic-y += preempt.h
index f20d01d..24898c0 100644 (file)
@@ -66,3 +66,8 @@ generic-y += types.h
 generic-y += ucontext.h
 generic-y += user.h
 generic-y += word-at-a-time.h
+<<<<<<< HEAD
+=======
+generic-y += xor.h
+generic-y += preempt.h
+>>>>>>> a787870... sched, arch: Create asm/preempt.h
index ff4c9fa..a603b9e 100644 (file)
@@ -4,3 +4,4 @@ generic-y += word-at-a-time.h auxvec.h user.h cputime.h emergency-restart.h \
          div64.h irq_regs.h kdebug.h kvm_para.h local64.h local.h param.h \
          poll.h xor.h clkdev.h exec.h
 generic-y += trace_clock.h
+generic-y += preempt.h
index 650757c..e941674 100644 (file)
@@ -2,3 +2,8 @@
 generic-y += clkdev.h
 generic-y += rwsem.h
 generic-y += trace_clock.h
+<<<<<<< HEAD
+=======
+generic-y += preempt.h
+generic-y += vtime.h
+>>>>>>> a787870... sched, arch: Create asm/preempt.h
index f313f9c..7a5288f 100644 (file)
@@ -2,3 +2,4 @@
 
 generic-y += clkdev.h
 generic-y += trace_clock.h
+generic-y += preempt.h
index cebaff8..194574f 100644 (file)
@@ -3,3 +3,8 @@ header-y +=
 
 generic-y += clkdev.h
 generic-y += trace_clock.h
+<<<<<<< HEAD
+=======
+generic-y += xor.h
+generic-y += preempt.h
+>>>>>>> a787870... sched, arch: Create asm/preempt.h
index 280bea9..231efbb 100644 (file)
@@ -34,3 +34,4 @@ generic-y += termios.h
 generic-y += trace_clock.h
 generic-y += ucontext.h
 generic-y += xor.h
+generic-y += preempt.h
index 7e4a97f..bf39066 100644 (file)
@@ -16,3 +16,4 @@ generic-y += serial.h
 generic-y += trace_clock.h
 generic-y += types.h
 generic-y += word-at-a-time.h
+generic-y += preempt.h
index b17b9b8..4ad9df9 100644 (file)
@@ -37,3 +37,4 @@ generic-y += termios.h
 generic-y += trace_clock.h
 generic-y += types.h
 generic-y += xor.h
+generic-y += preempt.h
index b30f34a..fdde187 100644 (file)
@@ -3,3 +3,4 @@ generic-y += hw_irq.h irq_regs.h kdebug.h percpu.h sections.h topology.h xor.h
 generic-y += ftrace.h pci.h io.h param.h delay.h mutex.h current.h exec.h
 generic-y += switch_to.h clkdev.h
 generic-y += trace_clock.h
+generic-y += preempt.h
index 89d8b6c..00045cb 100644 (file)
@@ -60,3 +60,4 @@ generic-y += unaligned.h
 generic-y += user.h
 generic-y += vga.h
 generic-y += xor.h
+generic-y += preempt.h
index 7f66985..eca2028 100644 (file)
@@ -5,3 +5,4 @@ genhdr-y += unistd_64.h
 genhdr-y += unistd_x32.h
 
 generic-y += clkdev.h
+generic-y += preempt.h
index 1b98264..228d6ae 100644 (file)
@@ -28,3 +28,4 @@ generic-y += termios.h
 generic-y += topology.h
 generic-y += trace_clock.h
 generic-y += xor.h
+generic-y += preempt.h
diff --git a/include/asm-generic/preempt.h b/include/asm-generic/preempt.h
new file mode 100644 (file)
index 0000000..a1fc659
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef __ASM_PREEMPT_H
+#define __ASM_PREEMPT_H
+
+#include <linux/thread_info.h>
+
+/*
+ * We mask the PREEMPT_NEED_RESCHED bit so as not to confuse all current users
+ * that think a non-zero value indicates we cannot preempt.
+ */
+static __always_inline int preempt_count(void)
+{
+       return current_thread_info()->preempt_count & ~PREEMPT_NEED_RESCHED;
+}
+
+static __always_inline int *preempt_count_ptr(void)
+{
+       return &current_thread_info()->preempt_count;
+}
+
+/*
+ * We now loose PREEMPT_NEED_RESCHED and cause an extra reschedule; however the
+ * alternative is loosing a reschedule. Better schedule too often -- also this
+ * should be a very rare operation.
+ */
+static __always_inline void preempt_count_set(int pc)
+{
+       *preempt_count_ptr() = pc;
+}
+
+/*
+ * We fold the NEED_RESCHED bit into the preempt count such that
+ * preempt_enable() can decrement and test for needing to reschedule with a
+ * single instruction.
+ *
+ * We invert the actual bit, so that when the decrement hits 0 we know we both
+ * need to resched (the bit is cleared) and can resched (no preempt count).
+ */
+
+static __always_inline void set_preempt_need_resched(void)
+{
+       *preempt_count_ptr() &= ~PREEMPT_NEED_RESCHED;
+}
+
+static __always_inline void clear_preempt_need_resched(void)
+{
+       *preempt_count_ptr() |= PREEMPT_NEED_RESCHED;
+}
+
+static __always_inline bool test_preempt_need_resched(void)
+{
+       return !(*preempt_count_ptr() & PREEMPT_NEED_RESCHED);
+}
+
+#endif /* __ASM_PREEMPT_H */
index f5d4723..116bba0 100644 (file)
@@ -6,10 +6,17 @@
  * preempt_count (used for kernel preemption, interrupt count, etc.)
  */
 
-#include <linux/thread_info.h>
 #include <linux/linkage.h>
 #include <linux/list.h>
 
+/*
+ * We use the MSB mostly because its available; see <linux/preempt_mask.h> for
+ * the other bits -- can't include that header due to inclusion hell.
+ */
+#define PREEMPT_NEED_RESCHED   0x80000000
+
+#include <asm/preempt.h>
+
 #if defined(CONFIG_DEBUG_PREEMPT) || defined(CONFIG_PREEMPT_TRACER)
   extern void add_preempt_count(int val);
   extern void sub_preempt_count(int val);