Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e4aafea2 authored by Frederic Weisbecker's avatar Frederic Weisbecker Committed by Ingo Molnar
Browse files

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: default avatarFrederic Weisbecker <fweisbec@gmail.com>
[ Move and rename preempt_count_equals() ]
Signed-off-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <1247725694-6082-4-git-send-email-fweisbec@gmail.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent e09758fa
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -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

+11 −4
Original line number Diff line number Diff line
@@ -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,12 +9429,19 @@ 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()) ||
	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)