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>
This commit is contained in:
Родитель
e09758fae8
Коммит
e4aafea2d4
|
@ -125,7 +125,7 @@ extern int _cond_resched(void);
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_DEBUG_SPINLOCK_SLEEP
|
||||
void __might_sleep(char *file, int line);
|
||||
void __might_sleep(char *file, int line, int preempt_offset);
|
||||
/**
|
||||
* might_sleep - annotation for functions that can sleep
|
||||
*
|
||||
|
@ -137,9 +137,9 @@ extern int _cond_resched(void);
|
|||
* supposed to.
|
||||
*/
|
||||
# define might_sleep() \
|
||||
do { __might_sleep(__FILE__, __LINE__); might_resched(); } while (0)
|
||||
do { __might_sleep(__FILE__, __LINE__, 0); might_resched(); } while (0)
|
||||
#else
|
||||
static inline void __might_sleep(char *file, int line) { }
|
||||
static inline void __might_sleep(char *file, int line, int preempt_offset) { }
|
||||
# define might_sleep() do { might_resched(); } while (0)
|
||||
#endif
|
||||
|
||||
|
|
|
@ -6610,7 +6610,7 @@ static inline int should_resched(void)
|
|||
|
||||
static void __cond_resched(void)
|
||||
{
|
||||
__might_sleep(__FILE__, __LINE__);
|
||||
__might_sleep(__FILE__, __LINE__, 0);
|
||||
|
||||
add_preempt_count(PREEMPT_ACTIVE);
|
||||
schedule();
|
||||
|
@ -9429,13 +9429,20 @@ void __init sched_init(void)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_SPINLOCK_SLEEP
|
||||
void __might_sleep(char *file, int line)
|
||||
static inline int preempt_count_equals(int preempt_offset)
|
||||
{
|
||||
int nested = preempt_count() & ~PREEMPT_ACTIVE;
|
||||
|
||||
return (nested == PREEMPT_INATOMIC_BASE + preempt_offset);
|
||||
}
|
||||
|
||||
void __might_sleep(char *file, int line, int preempt_offset)
|
||||
{
|
||||
#ifdef in_atomic
|
||||
static unsigned long prev_jiffy; /* ratelimiting */
|
||||
|
||||
if ((!in_atomic() && !irqs_disabled()) ||
|
||||
system_state != SYSTEM_RUNNING || oops_in_progress)
|
||||
if ((preempt_count_equals(preempt_offset) && !irqs_disabled()) ||
|
||||
system_state != SYSTEM_RUNNING || oops_in_progress)
|
||||
return;
|
||||
if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy)
|
||||
return;
|
||||
|
|
Загрузка…
Ссылка в новой задаче