--- 2.6.15-x86/kernel/sched.c 2006-01-07 15:18:31.000000000 +0100 +++ 2.6.15-ipipe/kernel/sched.c 2006-01-30 15:15:27.000000000 +0100 @@ -2963,7 +2963,7 @@ * Otherwise, whine if we are scheduling when we should not be. */ if (likely(!current->exit_state)) { - if (unlikely(in_atomic())) { + if (unlikely(!(current->state & TASK_ATOMICSWITCH) && in_atomic())) { printk(KERN_ERR "scheduling while atomic: " "%s/0x%08x/%d\n", current->comm, preempt_count(), current->pid); @@ -2972,8 +2972,13 @@ } profile_hit(SCHED_PROFILING, __builtin_return_address(0)); + if (unlikely(current->state & TASK_ATOMICSWITCH)) { + current->state &= ~TASK_ATOMICSWITCH; + goto preemption_off; + } need_resched: preempt_disable(); +preemption_off: #ifdef CONFIG_IPIPE if (unlikely(ipipe_current_domain != ipipe_root_domain)) { preempt_enable(); --- 2.6.15-x86/include/linux/sched.h 2006-01-07 15:18:31.000000000 +0100 +++ 2.6.15-ipipe/include/linux/sched.h 2006-01-30 15:14:43.000000000 +0100 @@ -128,6 +128,11 @@ #define EXIT_DEAD 32 /* in tsk->state again */ #define TASK_NONINTERACTIVE 64 +#ifdef CONFIG_IPIPE +#define TASK_ATOMICSWITCH 512 +#else /* !CONFIG_IPIPE */ +#define TASK_ATOMICSWITCH 0 +#endif /* CONFIG_IPIPE */ #define __set_task_state(tsk, state_value) \ do { (tsk)->state = (state_value); } while (0)