aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/DocBook/kernel-hacking.tmpl2
-rw-r--r--Documentation/SubmitChecklist2
-rw-r--r--Documentation/development-process/4.Coding2
-rw-r--r--Documentation/ja_JP/SubmitChecklist2
-rw-r--r--Documentation/zh_CN/SubmitChecklist2
-rw-r--r--include/linux/bit_spinlock.h2
-rw-r--r--include/linux/hardirq.h4
-rw-r--r--include/linux/kernel.h2
-rw-r--r--include/linux/pagemap.h4
-rw-r--r--include/linux/preempt.h26
-rw-r--r--include/linux/rcupdate.h12
-rw-r--r--include/linux/sched.h2
-rw-r--r--kernel/Kconfig.preempt3
-rw-r--r--kernel/sched.c6
-rw-r--r--lib/Kconfig.debug9
15 files changed, 46 insertions, 34 deletions
diff --git a/Documentation/DocBook/kernel-hacking.tmpl b/Documentation/DocBook/kernel-hacking.tmpl
index 7b3f49363413..07a9c48de5a2 100644
--- a/Documentation/DocBook/kernel-hacking.tmpl
+++ b/Documentation/DocBook/kernel-hacking.tmpl
@@ -409,7 +409,7 @@ cond_resched(); /* Will sleep */
409 409
410 <para> 410 <para>
411 You should always compile your kernel 411 You should always compile your kernel
412 <symbol>CONFIG_DEBUG_SPINLOCK_SLEEP</symbol> on, and it will warn 412 <symbol>CONFIG_DEBUG_ATOMIC_SLEEP</symbol> on, and it will warn
413 you if you break these rules. If you <emphasis>do</emphasis> break 413 you if you break these rules. If you <emphasis>do</emphasis> break
414 the rules, you will eventually lock up your box. 414 the rules, you will eventually lock up your box.
415 </para> 415 </para>
diff --git a/Documentation/SubmitChecklist b/Documentation/SubmitChecklist
index da0382daa395..7b13be41c085 100644
--- a/Documentation/SubmitChecklist
+++ b/Documentation/SubmitChecklist
@@ -53,7 +53,7 @@ kernel patches.
53 53
5412: Has been tested with CONFIG_PREEMPT, CONFIG_DEBUG_PREEMPT, 5412: Has been tested with CONFIG_PREEMPT, CONFIG_DEBUG_PREEMPT,
55 CONFIG_DEBUG_SLAB, CONFIG_DEBUG_PAGEALLOC, CONFIG_DEBUG_MUTEXES, 55 CONFIG_DEBUG_SLAB, CONFIG_DEBUG_PAGEALLOC, CONFIG_DEBUG_MUTEXES,
56 CONFIG_DEBUG_SPINLOCK, CONFIG_DEBUG_SPINLOCK_SLEEP all simultaneously 56 CONFIG_DEBUG_SPINLOCK, CONFIG_DEBUG_ATOMIC_SLEEP all simultaneously
57 enabled. 57 enabled.
58 58
5913: Has been build- and runtime tested with and without CONFIG_SMP and 5913: Has been build- and runtime tested with and without CONFIG_SMP and
diff --git a/Documentation/development-process/4.Coding b/Documentation/development-process/4.Coding
index f3f1a469443c..83f5f5b365a3 100644
--- a/Documentation/development-process/4.Coding
+++ b/Documentation/development-process/4.Coding
@@ -244,7 +244,7 @@ testing purposes. In particular, you should turn on:
244 - DEBUG_SLAB can find a variety of memory allocation and use errors; it 244 - DEBUG_SLAB can find a variety of memory allocation and use errors; it
245 should be used on most development kernels. 245 should be used on most development kernels.
246 246
247 - DEBUG_SPINLOCK, DEBUG_SPINLOCK_SLEEP, and DEBUG_MUTEXES will find a 247 - DEBUG_SPINLOCK, DEBUG_ATOMIC_SLEEP, and DEBUG_MUTEXES will find a
248 number of common locking errors. 248 number of common locking errors.
249 249
250There are quite a few other debugging options, some of which will be 250There are quite a few other debugging options, some of which will be
diff --git a/Documentation/ja_JP/SubmitChecklist b/Documentation/ja_JP/SubmitChecklist
index 2df4576f1173..cb5507b1ac81 100644
--- a/Documentation/ja_JP/SubmitChecklist
+++ b/Documentation/ja_JP/SubmitChecklist
@@ -68,7 +68,7 @@ Linux カーネルパッチ投稿者向けチェックリスト
68 68
6912: CONFIG_PREEMPT, CONFIG_DEBUG_PREEMPT, CONFIG_DEBUG_SLAB, 6912: CONFIG_PREEMPT, CONFIG_DEBUG_PREEMPT, CONFIG_DEBUG_SLAB,
70 CONFIG_DEBUG_PAGEALLOC, CONFIG_DEBUG_MUTEXES, CONFIG_DEBUG_SPINLOCK, 70 CONFIG_DEBUG_PAGEALLOC, CONFIG_DEBUG_MUTEXES, CONFIG_DEBUG_SPINLOCK,
71 CONFIG_DEBUG_SPINLOCK_SLEEP これら全てを同時に有効にして動作確認を 71 CONFIG_DEBUG_ATOMIC_SLEEP これら全てを同時に有効にして動作確認を
72 行ってください。 72 行ってください。
73 73
7413: CONFIG_SMP, CONFIG_PREEMPT を有効にした場合と無効にした場合の両方で 7413: CONFIG_SMP, CONFIG_PREEMPT を有効にした場合と無効にした場合の両方で
diff --git a/Documentation/zh_CN/SubmitChecklist b/Documentation/zh_CN/SubmitChecklist
index 951415bbab0c..4c741d6bc048 100644
--- a/Documentation/zh_CN/SubmitChecklist
+++ b/Documentation/zh_CN/SubmitChecklist
@@ -67,7 +67,7 @@ Linuxںύ嵥
67 67
6812ѾͨCONFIG_PREEMPT, CONFIG_DEBUG_PREEMPT, 6812ѾͨCONFIG_PREEMPT, CONFIG_DEBUG_PREEMPT,
69 CONFIG_DEBUG_SLAB, CONFIG_DEBUG_PAGEALLOC, CONFIG_DEBUG_MUTEXES, 69 CONFIG_DEBUG_SLAB, CONFIG_DEBUG_PAGEALLOC, CONFIG_DEBUG_MUTEXES,
70 CONFIG_DEBUG_SPINLOCK, CONFIG_DEBUG_SPINLOCK_SLEEPԣͬʱ 70 CONFIG_DEBUG_SPINLOCK, CONFIG_DEBUG_ATOMIC_SLEEPԣͬʱ
71 ʹܡ 71 ʹܡ
72 72
7313Ѿʹû߲ʹ CONFIG_SMP CONFIG_PREEMPTִʱ䡣 7313Ѿʹû߲ʹ CONFIG_SMP CONFIG_PREEMPTִʱ䡣
diff --git a/include/linux/bit_spinlock.h b/include/linux/bit_spinlock.h
index b4326bfa684f..564d997e2168 100644
--- a/include/linux/bit_spinlock.h
+++ b/include/linux/bit_spinlock.h
@@ -88,7 +88,7 @@ static inline int bit_spin_is_locked(int bitnum, unsigned long *addr)
88{ 88{
89#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) 89#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
90 return test_bit(bitnum, addr); 90 return test_bit(bitnum, addr);
91#elif defined CONFIG_PREEMPT 91#elif defined CONFIG_PREEMPT_COUNT
92 return preempt_count(); 92 return preempt_count();
93#else 93#else
94 return 1; 94 return 1;
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h
index ba362171e8ae..f743883f769e 100644
--- a/include/linux/hardirq.h
+++ b/include/linux/hardirq.h
@@ -93,7 +93,7 @@
93 */ 93 */
94#define in_nmi() (preempt_count() & NMI_MASK) 94#define in_nmi() (preempt_count() & NMI_MASK)
95 95
96#if defined(CONFIG_PREEMPT) 96#if defined(CONFIG_PREEMPT_COUNT)
97# define PREEMPT_CHECK_OFFSET 1 97# define PREEMPT_CHECK_OFFSET 1
98#else 98#else
99# define PREEMPT_CHECK_OFFSET 0 99# define PREEMPT_CHECK_OFFSET 0
@@ -115,7 +115,7 @@
115#define in_atomic_preempt_off() \ 115#define in_atomic_preempt_off() \
116 ((preempt_count() & ~PREEMPT_ACTIVE) != PREEMPT_CHECK_OFFSET) 116 ((preempt_count() & ~PREEMPT_ACTIVE) != PREEMPT_CHECK_OFFSET)
117 117
118#ifdef CONFIG_PREEMPT 118#ifdef CONFIG_PREEMPT_COUNT
119# define preemptible() (preempt_count() == 0 && !irqs_disabled()) 119# define preemptible() (preempt_count() == 0 && !irqs_disabled())
120# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1) 120# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
121#else 121#else
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 953352a88336..567a6f7bbeed 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -121,7 +121,7 @@ extern int _cond_resched(void);
121# define might_resched() do { } while (0) 121# define might_resched() do { } while (0)
122#endif 122#endif
123 123
124#ifdef CONFIG_DEBUG_SPINLOCK_SLEEP 124#ifdef CONFIG_DEBUG_ATOMIC_SLEEP
125 void __might_sleep(const char *file, int line, int preempt_offset); 125 void __might_sleep(const char *file, int line, int preempt_offset);
126/** 126/**
127 * might_sleep - annotation for functions that can sleep 127 * might_sleep - annotation for functions that can sleep
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 716875e53520..8e38d4c140ff 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -134,7 +134,7 @@ static inline int page_cache_get_speculative(struct page *page)
134 VM_BUG_ON(in_interrupt()); 134 VM_BUG_ON(in_interrupt());
135 135
136#if !defined(CONFIG_SMP) && defined(CONFIG_TREE_RCU) 136#if !defined(CONFIG_SMP) && defined(CONFIG_TREE_RCU)
137# ifdef CONFIG_PREEMPT 137# ifdef CONFIG_PREEMPT_COUNT
138 VM_BUG_ON(!in_atomic()); 138 VM_BUG_ON(!in_atomic());
139# endif 139# endif
140 /* 140 /*
@@ -172,7 +172,7 @@ static inline int page_cache_add_speculative(struct page *page, int count)
172 VM_BUG_ON(in_interrupt()); 172 VM_BUG_ON(in_interrupt());
173 173
174#if !defined(CONFIG_SMP) && defined(CONFIG_TREE_RCU) 174#if !defined(CONFIG_SMP) && defined(CONFIG_TREE_RCU)
175# ifdef CONFIG_PREEMPT 175# ifdef CONFIG_PREEMPT_COUNT
176 VM_BUG_ON(!in_atomic()); 176 VM_BUG_ON(!in_atomic());
177# endif 177# endif
178 VM_BUG_ON(page_count(page) == 0); 178 VM_BUG_ON(page_count(page) == 0);
diff --git a/include/linux/preempt.h b/include/linux/preempt.h
index 2e681d9555bd..58969b2a8a82 100644
--- a/include/linux/preempt.h
+++ b/include/linux/preempt.h
@@ -27,6 +27,21 @@
27 27
28asmlinkage void preempt_schedule(void); 28asmlinkage void preempt_schedule(void);
29 29
30#define preempt_check_resched() \
31do { \
32 if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \
33 preempt_schedule(); \
34} while (0)
35
36#else /* !CONFIG_PREEMPT */
37
38#define preempt_check_resched() do { } while (0)
39
40#endif /* CONFIG_PREEMPT */
41
42
43#ifdef CONFIG_PREEMPT_COUNT
44
30#define preempt_disable() \ 45#define preempt_disable() \
31do { \ 46do { \
32 inc_preempt_count(); \ 47 inc_preempt_count(); \
@@ -39,12 +54,6 @@ do { \
39 dec_preempt_count(); \ 54 dec_preempt_count(); \
40} while (0) 55} while (0)
41 56
42#define preempt_check_resched() \
43do { \
44 if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \
45 preempt_schedule(); \
46} while (0)
47
48#define preempt_enable() \ 57#define preempt_enable() \
49do { \ 58do { \
50 preempt_enable_no_resched(); \ 59 preempt_enable_no_resched(); \
@@ -80,18 +89,17 @@ do { \
80 preempt_check_resched(); \ 89 preempt_check_resched(); \
81} while (0) 90} while (0)
82 91
83#else 92#else /* !CONFIG_PREEMPT_COUNT */
84 93
85#define preempt_disable() do { } while (0) 94#define preempt_disable() do { } while (0)
86#define preempt_enable_no_resched() do { } while (0) 95#define preempt_enable_no_resched() do { } while (0)
87#define preempt_enable() do { } while (0) 96#define preempt_enable() do { } while (0)
88#define preempt_check_resched() do { } while (0)
89 97
90#define preempt_disable_notrace() do { } while (0) 98#define preempt_disable_notrace() do { } while (0)
91#define preempt_enable_no_resched_notrace() do { } while (0) 99#define preempt_enable_no_resched_notrace() do { } while (0)
92#define preempt_enable_notrace() do { } while (0) 100#define preempt_enable_notrace() do { } while (0)
93 101
94#endif 102#endif /* CONFIG_PREEMPT_COUNT */
95 103
96#ifdef CONFIG_PREEMPT_NOTIFIERS 104#ifdef CONFIG_PREEMPT_NOTIFIERS
97 105
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 99f9aa7c2804..8f4f881a0ad8 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -239,7 +239,7 @@ extern int rcu_read_lock_bh_held(void);
239 * Check debug_lockdep_rcu_enabled() to prevent false positives during boot 239 * Check debug_lockdep_rcu_enabled() to prevent false positives during boot
240 * and while lockdep is disabled. 240 * and while lockdep is disabled.
241 */ 241 */
242#ifdef CONFIG_PREEMPT 242#ifdef CONFIG_PREEMPT_COUNT
243static inline int rcu_read_lock_sched_held(void) 243static inline int rcu_read_lock_sched_held(void)
244{ 244{
245 int lockdep_opinion = 0; 245 int lockdep_opinion = 0;
@@ -250,12 +250,12 @@ static inline int rcu_read_lock_sched_held(void)
250 lockdep_opinion = lock_is_held(&rcu_sched_lock_map); 250 lockdep_opinion = lock_is_held(&rcu_sched_lock_map);
251 return lockdep_opinion || preempt_count() != 0 || irqs_disabled(); 251 return lockdep_opinion || preempt_count() != 0 || irqs_disabled();
252} 252}
253#else /* #ifdef CONFIG_PREEMPT */ 253#else /* #ifdef CONFIG_PREEMPT_COUNT */
254static inline int rcu_read_lock_sched_held(void) 254static inline int rcu_read_lock_sched_held(void)
255{ 255{
256 return 1; 256 return 1;
257} 257}
258#endif /* #else #ifdef CONFIG_PREEMPT */ 258#endif /* #else #ifdef CONFIG_PREEMPT_COUNT */
259 259
260#else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ 260#else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
261 261
@@ -276,17 +276,17 @@ static inline int rcu_read_lock_bh_held(void)
276 return 1; 276 return 1;
277} 277}
278 278
279#ifdef CONFIG_PREEMPT 279#ifdef CONFIG_PREEMPT_COUNT
280static inline int rcu_read_lock_sched_held(void) 280static inline int rcu_read_lock_sched_held(void)
281{ 281{
282 return preempt_count() != 0 || irqs_disabled(); 282 return preempt_count() != 0 || irqs_disabled();
283} 283}
284#else /* #ifdef CONFIG_PREEMPT */ 284#else /* #ifdef CONFIG_PREEMPT_COUNT */
285static inline int rcu_read_lock_sched_held(void) 285static inline int rcu_read_lock_sched_held(void)
286{ 286{
287 return 1; 287 return 1;
288} 288}
289#endif /* #else #ifdef CONFIG_PREEMPT */ 289#endif /* #else #ifdef CONFIG_PREEMPT_COUNT */
290 290
291#endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */ 291#endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
292 292
diff --git a/include/linux/sched.h b/include/linux/sched.h
index a837b20ba190..9a9beef3c0fd 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -2501,7 +2501,7 @@ extern int _cond_resched(void);
2501 2501
2502extern int __cond_resched_lock(spinlock_t *lock); 2502extern int __cond_resched_lock(spinlock_t *lock);
2503 2503
2504#ifdef CONFIG_PREEMPT 2504#ifdef CONFIG_PREEMPT_COUNT
2505#define PREEMPT_LOCK_OFFSET PREEMPT_OFFSET 2505#define PREEMPT_LOCK_OFFSET PREEMPT_OFFSET
2506#else 2506#else
2507#define PREEMPT_LOCK_OFFSET 0 2507#define PREEMPT_LOCK_OFFSET 0
diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt
index bf987b95b356..24e7cb0ba26a 100644
--- a/kernel/Kconfig.preempt
+++ b/kernel/Kconfig.preempt
@@ -35,6 +35,7 @@ config PREEMPT_VOLUNTARY
35 35
36config PREEMPT 36config PREEMPT
37 bool "Preemptible Kernel (Low-Latency Desktop)" 37 bool "Preemptible Kernel (Low-Latency Desktop)"
38 select PREEMPT_COUNT
38 help 39 help
39 This option reduces the latency of the kernel by making 40 This option reduces the latency of the kernel by making
40 all kernel code (that is not executing in a critical section) 41 all kernel code (that is not executing in a critical section)
@@ -52,3 +53,5 @@ config PREEMPT
52 53
53endchoice 54endchoice
54 55
56config PREEMPT_COUNT
57 bool \ No newline at end of file
diff --git a/kernel/sched.c b/kernel/sched.c
index e355ee72e83f..4380a80c1e7a 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -2854,7 +2854,7 @@ void sched_fork(struct task_struct *p)
2854#if defined(CONFIG_SMP) 2854#if defined(CONFIG_SMP)
2855 p->on_cpu = 0; 2855 p->on_cpu = 0;
2856#endif 2856#endif
2857#ifdef CONFIG_PREEMPT 2857#ifdef CONFIG_PREEMPT_COUNT
2858 /* Want to start with kernel preemption disabled. */ 2858 /* Want to start with kernel preemption disabled. */
2859 task_thread_info(p)->preempt_count = 1; 2859 task_thread_info(p)->preempt_count = 1;
2860#endif 2860#endif
@@ -8022,7 +8022,7 @@ void __init sched_init(void)
8022 scheduler_running = 1; 8022 scheduler_running = 1;
8023} 8023}
8024 8024
8025#ifdef CONFIG_DEBUG_SPINLOCK_SLEEP 8025#ifdef CONFIG_DEBUG_ATOMIC_SLEEP
8026static inline int preempt_count_equals(int preempt_offset) 8026static inline int preempt_count_equals(int preempt_offset)
8027{ 8027{
8028 int nested = (preempt_count() & ~PREEMPT_ACTIVE) + rcu_preempt_depth(); 8028 int nested = (preempt_count() & ~PREEMPT_ACTIVE) + rcu_preempt_depth();
@@ -8032,7 +8032,6 @@ static inline int preempt_count_equals(int preempt_offset)
8032 8032
8033void __might_sleep(const char *file, int line, int preempt_offset) 8033void __might_sleep(const char *file, int line, int preempt_offset)
8034{ 8034{
8035#ifdef in_atomic
8036 static unsigned long prev_jiffy; /* ratelimiting */ 8035 static unsigned long prev_jiffy; /* ratelimiting */
8037 8036
8038 if ((preempt_count_equals(preempt_offset) && !irqs_disabled()) || 8037 if ((preempt_count_equals(preempt_offset) && !irqs_disabled()) ||
@@ -8054,7 +8053,6 @@ void __might_sleep(const char *file, int line, int preempt_offset)
8054 if (irqs_disabled()) 8053 if (irqs_disabled())
8055 print_irqtrace_events(current); 8054 print_irqtrace_events(current);
8056 dump_stack(); 8055 dump_stack();
8057#endif
8058} 8056}
8059EXPORT_SYMBOL(__might_sleep); 8057EXPORT_SYMBOL(__might_sleep);
8060#endif 8058#endif
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index dd373c8ee943..9f0d826cadc3 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -648,12 +648,15 @@ config TRACE_IRQFLAGS
648 Enables hooks to interrupt enabling and disabling for 648 Enables hooks to interrupt enabling and disabling for
649 either tracing or lock debugging. 649 either tracing or lock debugging.
650 650
651config DEBUG_SPINLOCK_SLEEP 651config DEBUG_ATOMIC_SLEEP
652 bool "Spinlock debugging: sleep-inside-spinlock checking" 652 bool "Sleep inside atomic section checking"
653 select PREEMPT_COUNT
653 depends on DEBUG_KERNEL 654 depends on DEBUG_KERNEL
654 help 655 help
655 If you say Y here, various routines which may sleep will become very 656 If you say Y here, various routines which may sleep will become very
656 noisy if they are called with a spinlock held. 657 noisy if they are called inside atomic sections: when a spinlock is
658 held, inside an rcu read side critical section, inside preempt disabled
659 sections, inside an interrupt, etc...
657 660
658config DEBUG_LOCKING_API_SELFTESTS 661config DEBUG_LOCKING_API_SELFTESTS
659 bool "Locking API boot-time self-tests" 662 bool "Locking API boot-time self-tests"