Merge branch 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[sfrench/cifs-2.6.git] / kernel / sched / core.c
index 1b61cf48eee89eba7386916afbb4c85b962fea49..7880f4f64d0eea19dab03a0408625a505b4454ed 100644 (file)
@@ -255,7 +255,7 @@ static void __hrtick_restart(struct rq *rq)
 {
        struct hrtimer *timer = &rq->hrtick_timer;
 
-       hrtimer_start_expires(timer, HRTIMER_MODE_ABS_PINNED);
+       hrtimer_start_expires(timer, HRTIMER_MODE_ABS_PINNED_HARD);
 }
 
 /*
@@ -314,7 +314,7 @@ void hrtick_start(struct rq *rq, u64 delay)
         */
        delay = max_t(u64, delay, 10000LL);
        hrtimer_start(&rq->hrtick_timer, ns_to_ktime(delay),
-                     HRTIMER_MODE_REL_PINNED);
+                     HRTIMER_MODE_REL_PINNED_HARD);
 }
 #endif /* CONFIG_SMP */
 
@@ -328,7 +328,7 @@ static void hrtick_rq_init(struct rq *rq)
        rq->hrtick_csd.info = rq;
 #endif
 
-       hrtimer_init(&rq->hrtick_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+       hrtimer_init(&rq->hrtick_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_HARD);
        rq->hrtick_timer.function = hrtick;
 }
 #else  /* CONFIG_SCHED_HRTICK */
@@ -3871,13 +3871,22 @@ static noinline void __schedule_bug(struct task_struct *prev)
 /*
  * Various schedule()-time debugging checks and statistics:
  */
-static inline void schedule_debug(struct task_struct *prev)
+static inline void schedule_debug(struct task_struct *prev, bool preempt)
 {
 #ifdef CONFIG_SCHED_STACK_END_CHECK
        if (task_stack_end_corrupted(prev))
                panic("corrupted stack end detected inside scheduler\n");
 #endif
 
+#ifdef CONFIG_DEBUG_ATOMIC_SLEEP
+       if (!preempt && prev->state && prev->non_block_count) {
+               printk(KERN_ERR "BUG: scheduling in a non-blocking section: %s/%d/%i\n",
+                       prev->comm, prev->pid, prev->non_block_count);
+               dump_stack();
+               add_taint(TAINT_WARN, LOCKDEP_STILL_OK);
+       }
+#endif
+
        if (unlikely(in_atomic_preempt_off())) {
                __schedule_bug(prev);
                preempt_count_set(PREEMPT_DISABLED);
@@ -3989,7 +3998,7 @@ static void __sched notrace __schedule(bool preempt)
        rq = cpu_rq(cpu);
        prev = rq->curr;
 
-       schedule_debug(prev);
+       schedule_debug(prev, preempt);
 
        if (sched_feat(HRTICK))
                hrtick_clear(rq);
@@ -6765,7 +6774,7 @@ void ___might_sleep(const char *file, int line, int preempt_offset)
        rcu_sleep_check();
 
        if ((preempt_count_equals(preempt_offset) && !irqs_disabled() &&
-            !is_idle_task(current)) ||
+            !is_idle_task(current) && !current->non_block_count) ||
            system_state == SYSTEM_BOOTING || system_state > SYSTEM_RUNNING ||
            oops_in_progress)
                return;
@@ -6781,8 +6790,8 @@ void ___might_sleep(const char *file, int line, int preempt_offset)
                "BUG: sleeping function called from invalid context at %s:%d\n",
                        file, line);
        printk(KERN_ERR
-               "in_atomic(): %d, irqs_disabled(): %d, pid: %d, name: %s\n",
-                       in_atomic(), irqs_disabled(),
+               "in_atomic(): %d, irqs_disabled(): %d, non_block: %d, pid: %d, name: %s\n",
+                       in_atomic(), irqs_disabled(), current->non_block_count,
                        current->pid, current->comm);
 
        if (task_stack_end_corrupted(current))