schedule() in_atomic() fix
PATCH 1/1 schedule() in_atomic() fix
Linus,
Attached patch fixes the scheduler in_atomic() problem with kernel preemption enabled (and is also working - when kernel preemption is on, it finds a couple issues during boot).
I hope this approach is to your liking.
Patch is against current BK, please apply.
Robert Love
kernel/sched.c +13 -4
@@ -940,9 +940,6 @@struct list_head *queue;int idx; -if (unlikely (in_atomic ())) -BUG (); -#if CONFIG_DEBUG_HIGHMEM check_highmem_ptes ();#endif
@@ -950,8 +947,20 @@preempt_disable (); prev = current; rq =this_rq (); -release_kernel_lock (prev); + +/* +* Test if we are atomic. Since do_exit() needs to call into +* schedule() atomically, we ignore that for now. Otherwise, +* whine if we are scheduling when we should not be. +*/ +if (likely (current->state !=TASK_ZOMBIE )) { +if (unlikely ((preempt_count () & ~PREEMPT_ACTIVE ) !=1 )) { +printk (KERN_ERR "scheduling while non-atomic!\n" ); +dump_stack (); + } + } + prev->sleep_timestamp = jiffies;spin_lock_irq (&rq->lock);
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 5 lines · Andrew Morton
Quoted 2 lines · Robert Love
+
printk(KERN_ERR "scheduling while non-atomic!\n");When did this become illegal? :-)
Ugh, reality is blurred... thanks.
Linus, this patch reduces the kernel by 4 bytes over the previous. Please, apply.
Robert Love
kernel/sched.c +13 -4
@@ -940,9 +940,6 @@struct list_head *queue;int idx; -if (unlikely (in_atomic ())) -BUG (); -#if CONFIG_DEBUG_HIGHMEM check_highmem_ptes ();#endif
@@ -950,8 +947,20 @@preempt_disable (); prev = current; rq =this_rq (); -release_kernel_lock (prev); + +/* +* Test if we are atomic. Since do_exit() needs to call into +* schedule() atomically, we ignore that for now. Otherwise, +* whine if we are scheduling when we should not be. +*/ +if (likely (current->state !=TASK_ZOMBIE )) { +if (unlikely ((preempt_count () & ~PREEMPT_ACTIVE ) !=1 )) { +printk (KERN_ERR "scheduling while atomic!\n" ); +dump_stack (); + } + } + prev->sleep_timestamp = jiffies;spin_lock_irq (&rq->lock);
Quoted 3 lines · Robert Love
Attached patch fixes the scheduler
in_atomic()problem with kernel preemption enabled (and is also working - when kernel preemption is on, it finds a couple issues during boot).
Attached version works with non-CONFIG_PREEMPT ...
Robert Love
kernel/sched.c +11 -2
@@ -940,8 +940,17 @@struct list_head *queue;int idx; -if (unlikely (in_atomic ())) -BUG (); +/* +* Test if we are atomic. Since do_exit() needs to call into +* schedule() atomically, we ignore that for now. Otherwise, +* whine if we are scheduling when we should not be. +*/ +if (likely (current->state !=TASK_ZOMBIE )) { +if (unlikely (in_atomic ())) { +printk (KERN_ERR "scheduling while atomic!\n" ); +dump_stack (); + } + }#if CONFIG_DEBUG_HIGHMEM check_highmem_ptes ();