Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sched: Add a preempt count base offset to __might_sleep()

Add a preempt count base offset to compare against the current
preempt level count. It prepares to pull up the might_sleep
check from cond_resched() to cond_resched_lock() and
cond_resched_bh().

For these two helpers, we need to respectively ensure that once
we'll unlock the given spinlock / reenable local softirqs, we
will reach a sleepable state.

Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
[ Move and rename preempt_count_equals() ]
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <1247725694-6082-4-git-send-email-fweisbec@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>

authored by

Frederic Weisbecker and committed by
Ingo Molnar
e4aafea2 e09758fa

+14 -7
+3 -3
include/linux/kernel.h
··· 125 125 #endif 126 126 127 127 #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP 128 - void __might_sleep(char *file, int line); 128 + void __might_sleep(char *file, int line, int preempt_offset); 129 129 /** 130 130 * might_sleep - annotation for functions that can sleep 131 131 * ··· 137 137 * supposed to. 138 138 */ 139 139 # define might_sleep() \ 140 - do { __might_sleep(__FILE__, __LINE__); might_resched(); } while (0) 140 + do { __might_sleep(__FILE__, __LINE__, 0); might_resched(); } while (0) 141 141 #else 142 - static inline void __might_sleep(char *file, int line) { } 142 + static inline void __might_sleep(char *file, int line, int preempt_offset) { } 143 143 # define might_sleep() do { might_resched(); } while (0) 144 144 #endif 145 145
+11 -4
kernel/sched.c
··· 6610 6610 6611 6611 static void __cond_resched(void) 6612 6612 { 6613 - __might_sleep(__FILE__, __LINE__); 6613 + __might_sleep(__FILE__, __LINE__, 0); 6614 6614 6615 6615 add_preempt_count(PREEMPT_ACTIVE); 6616 6616 schedule(); ··· 9429 9429 } 9430 9430 9431 9431 #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP 9432 - void __might_sleep(char *file, int line) 9432 + static inline int preempt_count_equals(int preempt_offset) 9433 + { 9434 + int nested = preempt_count() & ~PREEMPT_ACTIVE; 9435 + 9436 + return (nested == PREEMPT_INATOMIC_BASE + preempt_offset); 9437 + } 9438 + 9439 + void __might_sleep(char *file, int line, int preempt_offset) 9433 9440 { 9434 9441 #ifdef in_atomic 9435 9442 static unsigned long prev_jiffy; /* ratelimiting */ 9436 9443 9437 - if ((!in_atomic() && !irqs_disabled()) || 9438 - system_state != SYSTEM_RUNNING || oops_in_progress) 9444 + if ((preempt_count_equals(preempt_offset) && !irqs_disabled()) || 9445 + system_state != SYSTEM_RUNNING || oops_in_progress) 9439 9446 return; 9440 9447 if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy) 9441 9448 return;