--- include/asm-x86/thread_info_64.h | 3 ++- include/linux/preempt.h | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) Index: linux-2.6/include/asm-x86/thread_info_64.h =================================================================== --- linux-2.6.orig/include/asm-x86/thread_info_64.h 2007-11-09 22:07:29.000000000 -0800 +++ linux-2.6/include/asm-x86/thread_info_64.h 2007-11-09 22:10:06.000000000 -0800 @@ -30,7 +30,7 @@ struct thread_info { __u32 status; /* thread synchronous flags */ __u32 cpu; /* current CPU */ int preempt_count; /* 0 => preemptable, <0 => BUG */ - + int interrupt_count;/* Interrupt disable counter */ mm_segment_t addr_limit; struct restart_block restart_block; }; @@ -48,6 +48,7 @@ struct thread_info { .flags = 0, \ .cpu = 0, \ .preempt_count = 1, \ + .interrupt_count = 0, \ .addr_limit = KERNEL_DS, \ .restart_block = { \ .fn = do_no_restart_syscall, \ Index: linux-2.6/include/linux/preempt.h =================================================================== --- linux-2.6.orig/include/linux/preempt.h 2007-11-09 22:10:15.000000000 -0800 +++ linux-2.6/include/linux/preempt.h 2007-11-09 22:18:31.000000000 -0800 @@ -22,6 +22,20 @@ #define dec_preempt_count() sub_preempt_count(1) #define preempt_count() (current_thread_info()->preempt_count) +#define interrupt_count() (current_thread_info()->interrupt_count() + +static inline local_irq_save(unsigned long flags) +{ + interrupt_count()++; + local_irq_disable(); +} + +static inline local_irq_restore(unsigned long flags) +{ + interrupt_count()--; + if (interrupt_count() == 0) + local_irq_enable(); +} #ifdef CONFIG_PREEMPT