diff -urN linux-2.6.12-armirq/Makefile linux-2.6.12-armirq-rt/Makefile --- linux-2.6.12-armirq/Makefile 2005-07-13 14:34:11.000000000 +0200 +++ linux-2.6.12-armirq-rt/Makefile 2005-07-16 16:41:52.000000000 +0200 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 12 -EXTRAVERSION = -armirq-A5 +EXTRAVERSION = -armirq-A5-ep-RT-V0.7.51-30 NAME=Woozy Numbat # *DOCUMENTATION* @@ -517,10 +517,14 @@ CFLAGS += $(call add-align,CONFIG_CC_ALIGN_LOOPS,-loops) CFLAGS += $(call add-align,CONFIG_CC_ALIGN_JUMPS,-jumps) -ifdef CONFIG_FRAME_POINTER -CFLAGS += -fno-omit-frame-pointer +ifdef CONFIG_MCOUNT +CFLAGS += -pg -fno-omit-frame-pointer else -CFLAGS += -fomit-frame-pointer + ifdef CONFIG_FRAME_POINTER + CFLAGS += -fno-omit-frame-pointer + else + CFLAGS += -fomit-frame-pointer + endif endif ifdef CONFIG_DEBUG_INFO diff -urN linux-2.6.12-armirq/arch/arm/Kconfig linux-2.6.12-armirq-rt/arch/arm/Kconfig --- linux-2.6.12-armirq/arch/arm/Kconfig 2005-07-13 14:34:11.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/Kconfig 2005-07-16 16:41:52.000000000 +0200 @@ -334,18 +334,7 @@ depends on SMP default "4" -config PREEMPT - bool "Preemptible Kernel (EXPERIMENTAL)" - depends on EXPERIMENTAL - help - This option reduces the latency of the kernel when reacting to - real-time or interactive events by allowing a low priority process to - be preempted even if it is in kernel mode executing a system call. - This allows applications to run more reliably even when the system is - under load. - - Say Y here if you are building a kernel for a desktop, embedded - or real-time system. Say N if you are unsure. +source kernel/Kconfig.preempt config DISCONTIGMEM bool diff -urN linux-2.6.12-armirq/arch/arm/common/dmabounce.c linux-2.6.12-armirq-rt/arch/arm/common/dmabounce.c --- linux-2.6.12-armirq/arch/arm/common/dmabounce.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/common/dmabounce.c 2005-07-16 16:41:52.000000000 +0200 @@ -397,11 +397,11 @@ BUG_ON(dir == DMA_NONE); - local_irq_save(flags); + raw_local_irq_save(flags); dma_addr = map_single(dev, ptr, size, dir); - local_irq_restore(flags); + raw_local_irq_restore(flags); return dma_addr; } @@ -424,11 +424,11 @@ BUG_ON(dir == DMA_NONE); - local_irq_save(flags); + raw_local_irq_save(flags); unmap_single(dev, dma_addr, size, dir); - local_irq_restore(flags); + raw_local_irq_restore(flags); } int @@ -443,7 +443,7 @@ BUG_ON(dir == DMA_NONE); - local_irq_save(flags); + raw_local_irq_save(flags); for (i = 0; i < nents; i++, sg++) { struct page *page = sg->page; @@ -455,7 +455,7 @@ map_single(dev, ptr, length, dir); } - local_irq_restore(flags); + raw_local_irq_restore(flags); return nents; } @@ -472,7 +472,7 @@ BUG_ON(dir == DMA_NONE); - local_irq_save(flags); + raw_local_irq_save(flags); for (i = 0; i < nents; i++, sg++) { dma_addr_t dma_addr = sg->dma_address; @@ -481,7 +481,7 @@ unmap_single(dev, dma_addr, length, dir); } - local_irq_restore(flags); + raw_local_irq_restore(flags); } void @@ -493,11 +493,11 @@ dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", __func__, (void *) dma_addr, size, dir); - local_irq_save(flags); + raw_local_irq_save(flags); sync_single(dev, dma_addr, size, dir); - local_irq_restore(flags); + raw_local_irq_restore(flags); } void @@ -509,11 +509,11 @@ dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", __func__, (void *) dma_addr, size, dir); - local_irq_save(flags); + raw_local_irq_save(flags); sync_single(dev, dma_addr, size, dir); - local_irq_restore(flags); + raw_local_irq_restore(flags); } void @@ -528,7 +528,7 @@ BUG_ON(dir == DMA_NONE); - local_irq_save(flags); + raw_local_irq_save(flags); for (i = 0; i < nents; i++, sg++) { dma_addr_t dma_addr = sg->dma_address; @@ -537,7 +537,7 @@ sync_single(dev, dma_addr, length, dir); } - local_irq_restore(flags); + raw_local_irq_restore(flags); } void @@ -552,7 +552,7 @@ BUG_ON(dir == DMA_NONE); - local_irq_save(flags); + raw_local_irq_save(flags); for (i = 0; i < nents; i++, sg++) { dma_addr_t dma_addr = sg->dma_address; @@ -561,7 +561,7 @@ sync_single(dev, dma_addr, length, dir); } - local_irq_restore(flags); + raw_local_irq_restore(flags); } int diff -urN linux-2.6.12-armirq/arch/arm/common/time-acorn.c linux-2.6.12-armirq-rt/arch/arm/common/time-acorn.c --- linux-2.6.12-armirq/arch/arm/common/time-acorn.c 2005-07-13 14:34:11.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/common/time-acorn.c 2005-07-16 16:41:52.000000000 +0200 @@ -77,7 +77,7 @@ static struct irqaction ioc_timer_irq = { .name = "timer", - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_NODELAY, .handler = ioc_timer_interrupt }; diff -urN linux-2.6.12-armirq/arch/arm/kernel/dma.c linux-2.6.12-armirq-rt/arch/arm/kernel/dma.c --- linux-2.6.12-armirq/arch/arm/kernel/dma.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/kernel/dma.c 2005-07-16 16:41:52.000000000 +0200 @@ -22,7 +22,7 @@ #include -DEFINE_SPINLOCK(dma_spin_lock); +DEFINE_RAW_SPINLOCK(dma_spin_lock); #if MAX_DMA_CHANNELS > 0 diff -urN linux-2.6.12-armirq/arch/arm/kernel/entry-armv.S linux-2.6.12-armirq-rt/arch/arm/kernel/entry-armv.S --- linux-2.6.12-armirq/arch/arm/kernel/entry-armv.S 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/kernel/entry-armv.S 2005-07-16 16:41:52.000000000 +0200 @@ -145,7 +145,7 @@ bne asm_do_IRQ #ifdef CONFIG_PREEMPT ldr r0, [r8, #TI_FLAGS] @ get flags - tst r0, #_TIF_NEED_RESCHED + tst r0, #_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_DELAYED blne svc_preempt preempt_return: ldr r0, [r8, #TI_PREEMPT] @ read preempt value @@ -172,7 +172,7 @@ str r7, [r8, #TI_PREEMPT] @ expects preempt_count == 0 1: bl preempt_schedule_irq @ irq en/disable is done inside ldr r0, [r8, #TI_FLAGS] @ get new tasks TI_FLAGS - tst r0, #_TIF_NEED_RESCHED + tst r0, #_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_DELAYED beq preempt_return @ go again b 1b #endif diff -urN linux-2.6.12-armirq/arch/arm/kernel/entry-common.S linux-2.6.12-armirq-rt/arch/arm/kernel/entry-common.S --- linux-2.6.12-armirq/arch/arm/kernel/entry-common.S 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/kernel/entry-common.S 2005-07-16 16:41:52.000000000 +0200 @@ -41,7 +41,7 @@ fast_work_pending: str r0, [sp, #S_R0+S_OFF]! @ returned r0 work_pending: - tst r1, #_TIF_NEED_RESCHED + tst r1, #_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_DELAYED bne work_resched tst r1, #_TIF_NOTIFY_RESUME | _TIF_SIGPENDING beq no_work_pending @@ -52,7 +52,11 @@ b no_work_pending work_resched: - bl schedule + bl __schedule +#ifdef CONFIG_PREEMPT_RT + bl local_irq_enable_noresched +#endif + /* * "slow" syscall return path. "why" tells us if this was a real syscall. */ diff -urN linux-2.6.12-armirq/arch/arm/kernel/init_task.c linux-2.6.12-armirq-rt/arch/arm/kernel/init_task.c --- linux-2.6.12-armirq/arch/arm/kernel/init_task.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/kernel/init_task.c 2005-07-16 16:41:52.000000000 +0200 @@ -12,8 +12,8 @@ #include #include -static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; +static struct fs_struct init_fs = INIT_FS(init_fs); +static struct files_struct init_files = INIT_FILES(init_files); static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); diff -urN linux-2.6.12-armirq/arch/arm/kernel/irq.c linux-2.6.12-armirq-rt/arch/arm/kernel/irq.c --- linux-2.6.12-armirq/arch/arm/kernel/irq.c 2005-07-13 14:34:11.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/kernel/irq.c 2005-07-16 16:41:52.000000000 +0200 @@ -90,7 +90,7 @@ /* Handle bad interrupts */ static struct irq_desc bad_irq = { .handler = &no_irq_type, - .lock = SPIN_LOCK_UNLOCKED + .lock = RAW_SPIN_LOCK_UNLOCKED }; /* @@ -101,20 +101,32 @@ asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs) { struct irqdesc *desc = irq_desc + irq; - +#ifdef CONFIG_PREEMPT_RT + unsigned long flags; +#endif /* * Some hardware gives randomly wrong interrupts. Rather * than crashing, do something sensible. - * - * TGLX_FIXME */ if (irq >= NR_IRQS) desc = &bad_irq; irq_enter(); +#ifdef CONFIG_PREEMPT_RT + /* + * Disable the soft-irq-flag: + */ + local_irq_save(flags); +#endif + desc_lock_handle_irq(irq, desc, regs); +#ifdef CONFIG_PREEMPT_RT + /* restore the soft IRQ-flag: */ + local_irq_restore(flags); +#endif + irq_exit(); } diff -urN linux-2.6.12-armirq/arch/arm/kernel/process.c linux-2.6.12-armirq-rt/arch/arm/kernel/process.c --- linux-2.6.12-armirq/arch/arm/kernel/process.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/kernel/process.c 2005-07-16 16:41:52.000000000 +0200 @@ -84,10 +84,10 @@ */ void default_idle(void) { - local_irq_disable(); + raw_local_irq_disable(); if (!need_resched() && !hlt_counter) arch_idle(); - local_irq_enable(); + raw_local_irq_enable(); } /* @@ -109,8 +109,8 @@ while (!need_resched()) idle(); leds_event(led_idle_end); - preempt_enable(); - schedule(); + preempt_enable_no_resched(); + __schedule(); } } diff -urN linux-2.6.12-armirq/arch/arm/kernel/semaphore.c linux-2.6.12-armirq-rt/arch/arm/kernel/semaphore.c --- linux-2.6.12-armirq/arch/arm/kernel/semaphore.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/kernel/semaphore.c 2005-07-16 16:41:52.000000000 +0200 @@ -49,14 +49,14 @@ * we cannot lose wakeup events. */ -void __up(struct semaphore *sem) +fastcall void __attribute_used__ __compat_up(struct compat_semaphore *sem) { wake_up(&sem->wait); } static DEFINE_SPINLOCK(semaphore_lock); -void __sched __down(struct semaphore * sem) +fastcall void __attribute_used__ __sched __compat_down(struct compat_semaphore * sem) { struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); @@ -89,7 +89,7 @@ wake_up(&sem->wait); } -int __sched __down_interruptible(struct semaphore * sem) +fastcall int __attribute_used__ __sched __compat_down_interruptible(struct compat_semaphore * sem) { int retval = 0; struct task_struct *tsk = current; @@ -148,7 +148,7 @@ * single "cmpxchg" without failure cases, * but then it wouldn't work on a 386. */ -int __down_trylock(struct semaphore * sem) +fastcall int __attribute_used__ __compat_down_trylock(struct compat_semaphore * sem) { int sleepers; unsigned long flags; @@ -168,6 +168,11 @@ return 1; } +fastcall int compat_sem_is_locked(struct compat_semaphore *sem) +{ + return (int) atomic_read(&sem->count) < 0; +} + /* * The semaphore operations have a special calling sequence that * allow us to do a simpler in-line version of them. These routines @@ -184,7 +189,7 @@ __down_failed: \n\ stmfd sp!, {r0 - r3, lr} \n\ mov r0, ip \n\ - bl __down \n\ + bl __compat_down \n\ ldmfd sp!, {r0 - r3, pc} \n\ \n\ .align 5 \n\ @@ -192,7 +197,7 @@ __down_interruptible_failed: \n\ stmfd sp!, {r0 - r3, lr} \n\ mov r0, ip \n\ - bl __down_interruptible \n\ + bl __compat_down_interruptible \n\ mov ip, r0 \n\ ldmfd sp!, {r0 - r3, pc} \n\ \n\ @@ -201,7 +206,7 @@ __down_trylock_failed: \n\ stmfd sp!, {r0 - r3, lr} \n\ mov r0, ip \n\ - bl __down_trylock \n\ + bl __compat_down_trylock \n\ mov ip, r0 \n\ ldmfd sp!, {r0 - r3, pc} \n\ \n\ @@ -210,7 +215,7 @@ __up_wakeup: \n\ stmfd sp!, {r0 - r3, lr} \n\ mov r0, ip \n\ - bl __up \n\ + bl __compat_up \n\ ldmfd sp!, {r0 - r3, pc} \n\ "); diff -urN linux-2.6.12-armirq/arch/arm/kernel/signal.c linux-2.6.12-armirq-rt/arch/arm/kernel/signal.c --- linux-2.6.12-armirq/arch/arm/kernel/signal.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/kernel/signal.c 2005-07-16 16:41:52.000000000 +0200 @@ -678,7 +678,15 @@ struct k_sigaction ka; siginfo_t info; int signr; - + +#ifdef CONFIG_PREEMPT_RT + /* + * Fully-preemptible kernel does not need interrupts disabled: + */ + raw_local_irq_enable(); + preempt_check_resched(); +#endif + /* * We want the common case to go fast, which * is why we may in certain cases get here from diff -urN linux-2.6.12-armirq/arch/arm/kernel/smp.c linux-2.6.12-armirq-rt/arch/arm/kernel/smp.c --- linux-2.6.12-armirq/arch/arm/kernel/smp.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/kernel/smp.c 2005-07-16 16:41:52.000000000 +0200 @@ -136,7 +136,7 @@ unsigned long flags; unsigned int cpu; - local_irq_save(flags); + raw_local_irq_save(flags); for_each_cpu_mask(cpu, callmap) { struct ipi_data *ipi = &per_cpu(ipi_data, cpu); @@ -151,7 +151,7 @@ */ smp_cross_call(callmap); - local_irq_restore(flags); + raw_local_irq_restore(flags); } /* @@ -299,7 +299,7 @@ cpu_clear(cpu, cpu_online_map); local_fiq_disable(); - local_irq_disable(); + raw_local_irq_disable(); while (1) cpu_relax(); diff -urN linux-2.6.12-armirq/arch/arm/kernel/traps.c linux-2.6.12-armirq-rt/arch/arm/kernel/traps.c --- linux-2.6.12-armirq/arch/arm/kernel/traps.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/kernel/traps.c 2005-07-16 16:41:52.000000000 +0200 @@ -197,7 +197,7 @@ barrier(); } -DEFINE_SPINLOCK(die_lock); +DEFINE_RAW_SPINLOCK(die_lock); /* * This function is protected against re-entrancy. @@ -251,7 +251,7 @@ } static LIST_HEAD(undef_hook); -static DEFINE_SPINLOCK(undef_lock); +static DEFINE_RAW_SPINLOCK(undef_lock); void register_undef_hook(struct undef_hook *hook) { @@ -339,7 +339,7 @@ handler[reason], processor_modes[proc_mode]); die("Oops - bad mode", regs, 0); - local_irq_disable(); + raw_local_irq_disable(); panic("bad mode"); } diff -urN linux-2.6.12-armirq/arch/arm/mach-clps711x/p720t-leds.c linux-2.6.12-armirq-rt/arch/arm/mach-clps711x/p720t-leds.c --- linux-2.6.12-armirq/arch/arm/mach-clps711x/p720t-leds.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-clps711x/p720t-leds.c 2005-07-16 16:41:52.000000000 +0200 @@ -36,7 +36,7 @@ unsigned long flags; u32 pddr; - local_irq_save(flags); + raw_local_irq_save(flags); switch(ledevt) { case led_idle_start: break; @@ -53,7 +53,7 @@ break; } - local_irq_restore(flags); + raw_local_irq_restore(flags); } static int __init leds_init(void) diff -urN linux-2.6.12-armirq/arch/arm/mach-clps711x/time.c linux-2.6.12-armirq-rt/arch/arm/mach-clps711x/time.c --- linux-2.6.12-armirq/arch/arm/mach-clps711x/time.c 2005-07-13 14:34:11.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-clps711x/time.c 2005-07-16 16:41:52.000000000 +0200 @@ -58,7 +58,7 @@ static struct irqaction clps711x_timer_irq = { .name = "CLPS711x Timer Tick", - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_NODELAY, .handler = p720t_timer_interrupt }; diff -urN linux-2.6.12-armirq/arch/arm/mach-clps7500/core.c linux-2.6.12-armirq-rt/arch/arm/mach-clps7500/core.c --- linux-2.6.12-armirq/arch/arm/mach-clps7500/core.c 2005-07-13 14:34:11.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-clps7500/core.c 2005-07-16 16:41:52.000000000 +0200 @@ -297,7 +297,7 @@ static struct irqaction clps7500_timer_irq = { .name = "CLPS7500 Timer Tick", - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_NODELAY, .handler = clps7500_timer_interrupt }; diff -urN linux-2.6.12-armirq/arch/arm/mach-ebsa110/core.c linux-2.6.12-armirq-rt/arch/arm/mach-ebsa110/core.c --- linux-2.6.12-armirq/arch/arm/mach-ebsa110/core.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-ebsa110/core.c 2005-07-16 16:41:52.000000000 +0200 @@ -56,14 +56,14 @@ unsigned long flags; unsigned int irq; - local_irq_save(flags); + raw_local_irq_save(flags); __raw_writeb(0xff, IRQ_MCLR); __raw_writeb(0x55, IRQ_MSET); __raw_writeb(0x00, IRQ_MSET); if (__raw_readb(IRQ_MASK) != 0x55) while (1); __raw_writeb(0xff, IRQ_MCLR); /* clear all interrupt enables */ - local_irq_restore(flags); + raw_local_irq_restore(flags); for (irq = 0; irq < NR_IRQS; irq++) { set_irq_chip(irq, &ebsa110_irq_chip); @@ -173,7 +173,7 @@ static struct irqaction ebsa110_timer_irq = { .name = "EBSA110 Timer Tick", - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_NODELAY, .handler = ebsa110_timer_interrupt }; diff -urN linux-2.6.12-armirq/arch/arm/mach-epxa10db/time.c linux-2.6.12-armirq-rt/arch/arm/mach-epxa10db/time.c --- linux-2.6.12-armirq/arch/arm/mach-epxa10db/time.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-epxa10db/time.c 2005-07-16 16:41:52.000000000 +0200 @@ -56,7 +56,7 @@ static struct irqaction epxa10db_timer_irq = { .name = "Excalibur Timer Tick", - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_NODELAY, .handler = epxa10db_timer_interrupt }; diff -urN linux-2.6.12-armirq/arch/arm/mach-footbridge/dc21285-timer.c linux-2.6.12-armirq-rt/arch/arm/mach-footbridge/dc21285-timer.c --- linux-2.6.12-armirq/arch/arm/mach-footbridge/dc21285-timer.c 2005-07-13 14:34:11.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-footbridge/dc21285-timer.c 2005-07-16 16:41:52.000000000 +0200 @@ -44,7 +44,7 @@ static struct irqaction footbridge_timer_irq = { .name = "Timer1 timer tick", .handler = timer1_interrupt, - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_NODELAY, }; /* diff -urN linux-2.6.12-armirq/arch/arm/mach-footbridge/isa-timer.c linux-2.6.12-armirq-rt/arch/arm/mach-footbridge/isa-timer.c --- linux-2.6.12-armirq/arch/arm/mach-footbridge/isa-timer.c 2005-07-13 14:34:11.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-footbridge/isa-timer.c 2005-07-16 16:41:52.000000000 +0200 @@ -73,7 +73,7 @@ static struct irqaction isa_timer_irq = { .name = "ISA timer tick", .handler = isa_timer_interrupt, - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_NODELAY, }; static void __init isa_timer_init(void) diff -urN linux-2.6.12-armirq/arch/arm/mach-h720x/cpu-h7201.c linux-2.6.12-armirq-rt/arch/arm/mach-h720x/cpu-h7201.c --- linux-2.6.12-armirq/arch/arm/mach-h720x/cpu-h7201.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-h720x/cpu-h7201.c 2005-07-16 16:41:52.000000000 +0200 @@ -41,7 +41,7 @@ static struct irqaction h7201_timer_irq = { .name = "h7201 Timer Tick", - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_NODELAY, .handler = h7201_timer_interrupt }; diff -urN linux-2.6.12-armirq/arch/arm/mach-h720x/cpu-h7202.c linux-2.6.12-armirq-rt/arch/arm/mach-h720x/cpu-h7202.c --- linux-2.6.12-armirq/arch/arm/mach-h720x/cpu-h7202.c 2005-07-13 14:34:11.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-h720x/cpu-h7202.c 2005-07-16 16:41:52.000000000 +0200 @@ -171,7 +171,7 @@ static struct irqaction h7202_timer_irq = { .name = "h7202 Timer Tick", - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_NODELAY, .handler = h7202_timer_interrupt }; diff -urN linux-2.6.12-armirq/arch/arm/mach-imx/dma.c linux-2.6.12-armirq-rt/arch/arm/mach-imx/dma.c --- linux-2.6.12-armirq/arch/arm/mach-imx/dma.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-imx/dma.c 2005-07-16 16:41:52.000000000 +0200 @@ -43,7 +43,7 @@ if (!name || !irq_handler) return -EINVAL; - local_irq_save(flags); + raw_local_irq_save(flags); /* try grabbing a DMA channel with the requested priority */ for (i = prio; i < prio + (prio == DMA_PRIO_LOW) ? 8 : 4; i++) { @@ -75,7 +75,7 @@ i = -ENODEV; } - local_irq_restore(flags); + raw_local_irq_restore(flags); return i; } @@ -91,10 +91,10 @@ return; } - local_irq_save(flags); + raw_local_irq_save(flags); DIMR &= ~(1 << dma_ch); dma_channels[dma_ch].name = NULL; - local_irq_restore(flags); + raw_local_irq_restore(flags); } static irqreturn_t diff -urN linux-2.6.12-armirq/arch/arm/mach-imx/leds-mx1ads.c linux-2.6.12-armirq-rt/arch/arm/mach-imx/leds-mx1ads.c --- linux-2.6.12-armirq/arch/arm/mach-imx/leds-mx1ads.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-imx/leds-mx1ads.c 2005-07-16 16:41:52.000000000 +0200 @@ -30,7 +30,7 @@ { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); switch (ledevt) { #ifdef CONFIG_LEDS_CPU @@ -50,5 +50,5 @@ default: break; } - local_irq_restore(flags); + raw_local_irq_restore(flags); } diff -urN linux-2.6.12-armirq/arch/arm/mach-imx/time.c linux-2.6.12-armirq-rt/arch/arm/mach-imx/time.c --- linux-2.6.12-armirq/arch/arm/mach-imx/time.c 2005-07-13 14:34:11.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-imx/time.c 2005-07-16 16:41:52.000000000 +0200 @@ -73,7 +73,7 @@ static struct irqaction imx_timer_irq = { .name = "i.MX Timer Tick", - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_NODELAY, .handler = imx_timer_interrupt }; diff -urN linux-2.6.12-armirq/arch/arm/mach-integrator/core.c linux-2.6.12-armirq-rt/arch/arm/mach-integrator/core.c --- linux-2.6.12-armirq/arch/arm/mach-integrator/core.c 2005-07-13 14:34:11.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-integrator/core.c 2005-07-16 16:41:52.000000000 +0200 @@ -231,7 +231,7 @@ static struct irqaction integrator_timer_irq = { .name = "Integrator Timer Tick", - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_NODELAY, .handler = integrator_timer_interrupt }; diff -urN linux-2.6.12-armirq/arch/arm/mach-integrator/leds.c linux-2.6.12-armirq-rt/arch/arm/mach-integrator/leds.c --- linux-2.6.12-armirq/arch/arm/mach-integrator/leds.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-integrator/leds.c 2005-07-16 16:41:52.000000000 +0200 @@ -39,7 +39,7 @@ unsigned int update_alpha_leds; // yup, change the LEDs - local_irq_save(flags); + raw_local_irq_save(flags); update_alpha_leds = 0; switch(ledevt) { @@ -74,7 +74,7 @@ while (__raw_readl(dbg_base + INTEGRATOR_DBG_ALPHA_OFFSET) & 1); __raw_writel(saved_leds, dbg_base + INTEGRATOR_DBG_LEDS_OFFSET); } - local_irq_restore(flags); + raw_local_irq_restore(flags); } static int __init leds_init(void) diff -urN linux-2.6.12-armirq/arch/arm/mach-iop3xx/iop321-time.c linux-2.6.12-armirq-rt/arch/arm/mach-iop3xx/iop321-time.c --- linux-2.6.12-armirq/arch/arm/mach-iop3xx/iop321-time.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-iop3xx/iop321-time.c 2005-07-16 16:41:52.000000000 +0200 @@ -86,7 +86,7 @@ static struct irqaction iop321_timer_irq = { .name = "IOP321 Timer Tick", .handler = iop321_timer_interrupt, - .flags = SA_INTERRUPT + .flags = SA_INTERRUPT | SA_NODELAY }; static void __init iop321_timer_init(void) diff -urN linux-2.6.12-armirq/arch/arm/mach-iop3xx/iop331-time.c linux-2.6.12-armirq-rt/arch/arm/mach-iop3xx/iop331-time.c --- linux-2.6.12-armirq/arch/arm/mach-iop3xx/iop331-time.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-iop3xx/iop331-time.c 2005-07-16 16:41:52.000000000 +0200 @@ -83,7 +83,7 @@ static struct irqaction iop331_timer_irq = { .name = "IOP331 Timer Tick", .handler = iop331_timer_interrupt, - .flags = SA_INTERRUPT + .flags = SA_INTERRUPT | SA_NODELAY }; static void __init iop331_timer_init(void) diff -urN linux-2.6.12-armirq/arch/arm/mach-ixp2000/core.c linux-2.6.12-armirq-rt/arch/arm/mach-ixp2000/core.c --- linux-2.6.12-armirq/arch/arm/mach-ixp2000/core.c 2005-07-13 14:34:11.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-ixp2000/core.c 2005-07-16 16:41:52.000000000 +0200 @@ -191,7 +191,7 @@ static struct irqaction ixp2000_timer_irq = { .name = "IXP2000 Timer Tick", - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_NODELAY, .handler = ixp2000_timer_interrupt }; @@ -229,7 +229,7 @@ { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); if(style == GPIO_OUT) { /* if it's an output, it ain't an interrupt anymore */ @@ -247,7 +247,7 @@ ixp2000_reg_write(IXP2000_GPIO_PDCR, (1 << line)); } - local_irq_restore(flags); + raw_local_irq_restore(flags); } @@ -331,6 +331,8 @@ static DEFINE_IRQ_CHAINED_TYPE(ixp2000_GPIO_irq_handler); +static DEFINE_IRQ_CHAINED_TYPE(ixp2000_GPIO_irq_handler); + void __init ixp2000_init_irq(void) { int irq; diff -urN linux-2.6.12-armirq/arch/arm/mach-ixp2000/pci.c linux-2.6.12-armirq-rt/arch/arm/mach-ixp2000/pci.c --- linux-2.6.12-armirq/arch/arm/mach-ixp2000/pci.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-ixp2000/pci.c 2005-07-16 16:41:52.000000000 +0200 @@ -146,7 +146,7 @@ pci_master_aborts = 1; - local_irq_save(flags); + raw_local_irq_save(flags); temp = *(IXP2000_PCI_CONTROL); if (temp & ((1 << 8) | (1 << 5))) { ixp2000_reg_write(IXP2000_PCI_CONTROL, temp); @@ -159,7 +159,7 @@ temp = *(IXP2000_PCI_CMDSTAT); } } - local_irq_restore(flags); + raw_local_irq_restore(flags); /* * If it was an imprecise abort, then we need to correct the @@ -177,7 +177,7 @@ volatile u32 temp; unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); temp = *(IXP2000_PCI_CONTROL); if (temp & ((1 << 8) | (1 << 5))) { ixp2000_reg_write(IXP2000_PCI_CONTROL, temp); @@ -190,7 +190,7 @@ temp = *(IXP2000_PCI_CMDSTAT); } } - local_irq_restore(flags); + raw_local_irq_restore(flags); return 0; } diff -urN linux-2.6.12-armirq/arch/arm/mach-ixp4xx/common.c linux-2.6.12-armirq-rt/arch/arm/mach-ixp4xx/common.c --- linux-2.6.12-armirq/arch/arm/mach-ixp4xx/common.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-ixp4xx/common.c 2005-07-16 16:41:52.000000000 +0200 @@ -290,7 +290,7 @@ static struct irqaction ixp4xx_timer_irq = { .name = "IXP4xx Timer Tick", - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_NODELAY, .handler = ixp4xx_timer_interrupt }; diff -urN linux-2.6.12-armirq/arch/arm/mach-lh7a40x/time.c linux-2.6.12-armirq-rt/arch/arm/mach-lh7a40x/time.c --- linux-2.6.12-armirq/arch/arm/mach-lh7a40x/time.c 2005-07-13 14:34:11.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-lh7a40x/time.c 2005-07-16 16:41:52.000000000 +0200 @@ -54,7 +54,7 @@ static struct irqaction lh7a40x_timer_irq = { .name = "LHA740x Timer Tick", - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_NODELAY, .handler = lh7a40x_timer_interrupt }; diff -urN linux-2.6.12-armirq/arch/arm/mach-omap/dma.c linux-2.6.12-armirq-rt/arch/arm/mach-omap/dma.c --- linux-2.6.12-armirq/arch/arm/mach-omap/dma.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-omap/dma.c 2005-07-16 16:41:52.000000000 +0200 @@ -937,11 +937,11 @@ unsigned long flags; int status; - local_irq_save(flags); + raw_local_irq_save(flags); omap_writew(omap_readw(OMAP_DMA_CCR(lch)) & ~OMAP_DMA_CCR_EN, OMAP_DMA_CCR(lch)); status = OMAP_DMA_CSR(lch); /* clear pending interrupts */ - local_irq_restore(flags); + raw_local_irq_restore(flags); } /* diff -urN linux-2.6.12-armirq/arch/arm/mach-omap/leds-h2p2-debug.c linux-2.6.12-armirq-rt/arch/arm/mach-omap/leds-h2p2-debug.c --- linux-2.6.12-armirq/arch/arm/mach-omap/leds-h2p2-debug.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-omap/leds-h2p2-debug.c 2005-07-16 16:41:52.000000000 +0200 @@ -45,7 +45,7 @@ static struct h2p2_dbg_fpga __iomem *fpga; static u16 led_state, hw_led_state; - local_irq_save(flags); + raw_local_irq_save(flags); if (!(led_state & LED_STATE_ENABLED) && evt != led_start) goto done; @@ -140,5 +140,5 @@ __raw_writew(~hw_led_state, &fpga->leds); done: - local_irq_restore(flags); + raw_local_irq_restore(flags); } diff -urN linux-2.6.12-armirq/arch/arm/mach-omap/leds-innovator.c linux-2.6.12-armirq-rt/arch/arm/mach-omap/leds-innovator.c --- linux-2.6.12-armirq/arch/arm/mach-omap/leds-innovator.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-omap/leds-innovator.c 2005-07-16 16:41:52.000000000 +0200 @@ -21,7 +21,7 @@ { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); switch (evt) { case led_start: @@ -99,5 +99,5 @@ if (led_state & LED_STATE_ENABLED) ; - local_irq_restore(flags); + raw_local_irq_restore(flags); } diff -urN linux-2.6.12-armirq/arch/arm/mach-omap/leds-osk.c linux-2.6.12-armirq-rt/arch/arm/mach-omap/leds-osk.c --- linux-2.6.12-armirq/arch/arm/mach-omap/leds-osk.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-omap/leds-osk.c 2005-07-16 16:41:52.000000000 +0200 @@ -96,7 +96,7 @@ unsigned long flags; u16 leds; - local_irq_save(flags); + raw_local_irq_save(flags); if (!(led_state & LED_STATE_ENABLED) && evt != led_start) goto done; @@ -190,9 +190,11 @@ leds &= TPS_LEDS; if (leds && (led_state & LED_STATE_CLAIMED)) { tps_leds_change |= leds; + raw_local_irq_restore(flags); schedule_work(&work); + return; } done: - local_irq_restore(flags); + raw_local_irq_restore(flags); } diff -urN linux-2.6.12-armirq/arch/arm/mach-omap/pm.c linux-2.6.12-armirq-rt/arch/arm/mach-omap/pm.c --- linux-2.6.12-armirq/arch/arm/mach-omap/pm.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-omap/pm.c 2005-07-16 16:41:52.000000000 +0200 @@ -165,7 +165,7 @@ * Step 1: turn off interrupts */ - local_irq_disable(); + raw_local_irq_disable(); local_fiq_disable(); /* @@ -366,7 +366,7 @@ * Reenable interrupts */ - local_irq_enable(); + raw_local_irq_enable(); local_fiq_enable(); printk("PM: OMAP%x is re-starting from deep sleep...\n", system_rev); diff -urN linux-2.6.12-armirq/arch/arm/mach-omap/time.c linux-2.6.12-armirq-rt/arch/arm/mach-omap/time.c --- linux-2.6.12-armirq/arch/arm/mach-omap/time.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-omap/time.c 2005-07-16 16:41:52.000000000 +0200 @@ -188,7 +188,7 @@ static struct irqaction omap_mpu_timer_irq = { .name = "mpu timer", - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_NODELAY, .handler = omap_mpu_timer_interrupt }; @@ -202,7 +202,7 @@ static struct irqaction omap_mpu_timer1_irq = { .name = "mpu timer1 overflow", - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_NODELAY, .handler = omap_mpu_timer1_interrupt }; @@ -349,7 +349,7 @@ static struct irqaction omap_32k_timer_irq = { .name = "32KHz timer", - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_NODELAY, .handler = omap_32k_timer_interrupt }; diff -urN linux-2.6.12-armirq/arch/arm/mach-pxa/corgi_ssp.c linux-2.6.12-armirq-rt/arch/arm/mach-pxa/corgi_ssp.c --- linux-2.6.12-armirq/arch/arm/mach-pxa/corgi_ssp.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-pxa/corgi_ssp.c 2005-07-16 16:41:52.000000000 +0200 @@ -22,7 +22,7 @@ #include #include -static spinlock_t corgi_ssp_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(corgi_ssp_lock); static struct ssp_dev corgi_ssp_dev; static struct ssp_state corgi_ssp_state; diff -urN linux-2.6.12-armirq/arch/arm/mach-pxa/dma.c linux-2.6.12-armirq-rt/arch/arm/mach-pxa/dma.c --- linux-2.6.12-armirq/arch/arm/mach-pxa/dma.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-pxa/dma.c 2005-07-16 16:41:52.000000000 +0200 @@ -43,7 +43,7 @@ if (!name || !irq_handler) return -EINVAL; - local_irq_save(flags); + raw_local_irq_save(flags); /* try grabbing a DMA channel with the requested priority */ for (i = prio; i < prio + PXA_DMA_NBCH(prio); i++) { @@ -73,7 +73,7 @@ i = -ENODEV; } - local_irq_restore(flags); + raw_local_irq_restore(flags); return i; } @@ -88,10 +88,10 @@ return; } - local_irq_save(flags); + raw_local_irq_save(flags); DCSR(dma_ch) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR; dma_channels[dma_ch].name = NULL; - local_irq_restore(flags); + raw_local_irq_restore(flags); } static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs) diff -urN linux-2.6.12-armirq/arch/arm/mach-pxa/generic.c linux-2.6.12-armirq-rt/arch/arm/mach-pxa/generic.c --- linux-2.6.12-armirq/arch/arm/mach-pxa/generic.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-pxa/generic.c 2005-07-16 16:41:52.000000000 +0200 @@ -48,7 +48,7 @@ int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8; int gafr; - local_irq_save(flags); + raw_local_irq_save(flags); if (gpio_mode & GPIO_DFLT_LOW) GPCR(gpio) = GPIO_bit(gpio); else if (gpio_mode & GPIO_DFLT_HIGH) @@ -59,7 +59,7 @@ GPDR(gpio) &= ~GPIO_bit(gpio); gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2)); GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2)); - local_irq_restore(flags); + raw_local_irq_restore(flags); } EXPORT_SYMBOL(pxa_gpio_mode); @@ -70,14 +70,14 @@ void pxa_set_cken(int clock, int enable) { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); if (enable) CKEN |= clock; else CKEN &= ~clock; - local_irq_restore(flags); + raw_local_irq_restore(flags); } EXPORT_SYMBOL(pxa_set_cken); diff -urN linux-2.6.12-armirq/arch/arm/mach-pxa/leds-idp.c linux-2.6.12-armirq-rt/arch/arm/mach-pxa/leds-idp.c --- linux-2.6.12-armirq/arch/arm/mach-pxa/leds-idp.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-pxa/leds-idp.c 2005-07-16 16:41:52.000000000 +0200 @@ -34,7 +34,7 @@ { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); switch (evt) { case led_start: @@ -113,5 +113,5 @@ else IDP_CPLD_LED_CONTROL |= IDP_LEDS_MASK; - local_irq_restore(flags); + raw_local_irq_restore(flags); } diff -urN linux-2.6.12-armirq/arch/arm/mach-pxa/leds-lubbock.c linux-2.6.12-armirq-rt/arch/arm/mach-pxa/leds-lubbock.c --- linux-2.6.12-armirq/arch/arm/mach-pxa/leds-lubbock.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-pxa/leds-lubbock.c 2005-07-16 16:41:52.000000000 +0200 @@ -48,7 +48,7 @@ { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); switch (evt) { case led_start: @@ -122,5 +122,5 @@ else LUB_DISC_BLNK_LED |= 0xff; - local_irq_restore(flags); + raw_local_irq_restore(flags); } diff -urN linux-2.6.12-armirq/arch/arm/mach-pxa/leds-mainstone.c linux-2.6.12-armirq-rt/arch/arm/mach-pxa/leds-mainstone.c --- linux-2.6.12-armirq/arch/arm/mach-pxa/leds-mainstone.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-pxa/leds-mainstone.c 2005-07-16 16:41:52.000000000 +0200 @@ -43,7 +43,7 @@ { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); switch (evt) { case led_start: @@ -117,5 +117,5 @@ else MST_LEDCTRL |= 0xff; - local_irq_restore(flags); + raw_local_irq_restore(flags); } diff -urN linux-2.6.12-armirq/arch/arm/mach-pxa/lubbock.c linux-2.6.12-armirq-rt/arch/arm/mach-pxa/lubbock.c --- linux-2.6.12-armirq/arch/arm/mach-pxa/lubbock.c 2005-07-13 14:34:11.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-pxa/lubbock.c 2005-07-16 16:41:52.000000000 +0200 @@ -47,9 +47,9 @@ { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); LUB_MISC_WR = (LUB_MISC_WR & ~mask) | (set & mask); - local_irq_restore(flags); + raw_local_irq_restore(flags); } EXPORT_SYMBOL(lubbock_set_misc_wr); diff -urN linux-2.6.12-armirq/arch/arm/mach-pxa/time.c linux-2.6.12-armirq-rt/arch/arm/mach-pxa/time.c --- linux-2.6.12-armirq/arch/arm/mach-pxa/time.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-pxa/time.c 2005-07-16 16:41:52.000000000 +0200 @@ -105,7 +105,7 @@ static struct irqaction pxa_timer_irq = { .name = "PXA Timer Tick", - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_NODELAY, .handler = pxa_timer_interrupt }; diff -urN linux-2.6.12-armirq/arch/arm/mach-rpc/dma.c linux-2.6.12-armirq-rt/arch/arm/mach-rpc/dma.c --- linux-2.6.12-armirq/arch/arm/mach-rpc/dma.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-rpc/dma.c 2005-07-16 16:41:52.000000000 +0200 @@ -171,11 +171,11 @@ unsigned long dma_base = dma->dma_base; unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); if (dma->state != ~DMA_ST_AB) disable_irq(dma->dma_irq); iomd_writeb(0, dma_base + CR); - local_irq_restore(flags); + raw_local_irq_restore(flags); } static int iomd_set_dma_speed(dmach_t channel, dma_t *dma, int cycle) diff -urN linux-2.6.12-armirq/arch/arm/mach-s3c2410/clock.c linux-2.6.12-armirq-rt/arch/arm/mach-s3c2410/clock.c --- linux-2.6.12-armirq/arch/arm/mach-s3c2410/clock.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-s3c2410/clock.c 2005-07-16 16:41:52.000000000 +0200 @@ -61,7 +61,7 @@ unsigned long clkcon; unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); clkcon = __raw_readl(S3C2410_CLKCON); clkcon &= ~clocks; @@ -74,7 +74,7 @@ __raw_writel(clkcon, S3C2410_CLKCON); - local_irq_restore(flags); + raw_local_irq_restore(flags); } /* enable and disable calls for use with the clk struct */ diff -urN linux-2.6.12-armirq/arch/arm/mach-s3c2410/dma.c linux-2.6.12-armirq-rt/arch/arm/mach-s3c2410/dma.c --- linux-2.6.12-armirq/arch/arm/mach-s3c2410/dma.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-s3c2410/dma.c 2005-07-16 16:41:52.000000000 +0200 @@ -329,11 +329,11 @@ pr_debug("s3c2410_start_dma: channel=%d\n", chan->number); - local_irq_save(flags); + raw_local_irq_save(flags); if (chan->state == S3C2410_DMA_RUNNING) { pr_debug("s3c2410_start_dma: already running (%d)\n", chan->state); - local_irq_restore(flags); + raw_local_irq_restore(flags); return 0; } @@ -348,7 +348,7 @@ printk(KERN_ERR "dma%d: channel has nothing loaded\n", chan->number); chan->state = S3C2410_DMA_IDLE; - local_irq_restore(flags); + raw_local_irq_restore(flags); return -EINVAL; } @@ -385,7 +385,7 @@ dbg_showchan(chan); - local_irq_restore(flags); + raw_local_irq_restore(flags); return 0; } @@ -451,7 +451,7 @@ buf->id = id; buf->magic = BUF_MAGIC; - local_irq_save(flags); + raw_local_irq_save(flags); if (chan->curr == NULL) { /* we've got nothing loaded... */ @@ -485,7 +485,7 @@ "timeout loading buffer\n", chan->number); dbg_showchan(chan); - local_irq_restore(flags); + raw_local_irq_restore(flags); return -EINVAL; } } @@ -499,7 +499,7 @@ } } - local_irq_restore(flags); + raw_local_irq_restore(flags); return 0; } @@ -661,9 +661,9 @@ return IRQ_HANDLED; } - local_irq_save(flags); + raw_local_irq_save(flags); s3c2410_dma_loadbuffer(chan, chan->next); - local_irq_restore(flags); + raw_local_irq_restore(flags); } else { s3c2410_dma_lastxfer(chan); @@ -698,14 +698,14 @@ check_channel(channel); - local_irq_save(flags); + raw_local_irq_save(flags); dbg_showchan(chan); if (chan->in_use) { if (client != chan->client) { printk(KERN_ERR "dma%d: already in use\n", channel); - local_irq_restore(flags); + raw_local_irq_restore(flags); return -EBUSY; } else { printk(KERN_ERR "dma%d: client already has channel\n", channel); @@ -724,7 +724,7 @@ if (err) { chan->in_use = 0; - local_irq_restore(flags); + raw_local_irq_restore(flags); printk(KERN_ERR "%s: cannot get IRQ %d for DMA %d\n", client->name, chan->irq, chan->number); @@ -735,7 +735,7 @@ chan->irq_enabled = 1; } - local_irq_restore(flags); + raw_local_irq_restore(flags); /* need to setup */ @@ -764,7 +764,7 @@ check_channel(channel); - local_irq_save(flags); + raw_local_irq_save(flags); if (chan->client != client) { @@ -789,7 +789,7 @@ free_irq(chan->irq, (void *)chan); chan->irq_claimed = 0; - local_irq_restore(flags); + raw_local_irq_restore(flags); return 0; } @@ -805,7 +805,7 @@ dbg_showchan(chan); - local_irq_save(flags); + raw_local_irq_save(flags); s3c2410_dma_call_op(chan, S3C2410_DMAOP_STOP); @@ -823,7 +823,7 @@ chan->state = S3C2410_DMA_IDLE; chan->load_state = S3C2410_DMALOAD_NONE; - local_irq_restore(flags); + raw_local_irq_restore(flags); return 0; } @@ -840,7 +840,7 @@ pr_debug("%s:\n", __FUNCTION__); - local_irq_save(flags); + raw_local_irq_save(flags); if (chan->state != S3C2410_DMA_IDLE) { pr_debug("%s: stopping channel...\n", __FUNCTION__ ); @@ -865,7 +865,7 @@ } } - local_irq_restore(flags); + raw_local_irq_restore(flags); return 0; } diff -urN linux-2.6.12-armirq/arch/arm/mach-s3c2410/gpio.c linux-2.6.12-armirq-rt/arch/arm/mach-s3c2410/gpio.c --- linux-2.6.12-armirq/arch/arm/mach-s3c2410/gpio.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-s3c2410/gpio.c 2005-07-16 16:41:52.000000000 +0200 @@ -58,7 +58,7 @@ mask = 3 << S3C2410_GPIO_OFFSET(pin)*2; } - local_irq_save(flags); + raw_local_irq_save(flags); con = __raw_readl(base + 0x00); con &= ~mask; @@ -66,7 +66,7 @@ __raw_writel(con, base + 0x00); - local_irq_restore(flags); + raw_local_irq_restore(flags); } EXPORT_SYMBOL(s3c2410_gpio_cfgpin); @@ -97,14 +97,14 @@ if (pin < S3C2410_GPIO_BANKB) return; - local_irq_save(flags); + raw_local_irq_save(flags); up = __raw_readl(base + 0x08); up &= ~(1L << offs); up |= to << offs; __raw_writel(up, base + 0x08); - local_irq_restore(flags); + raw_local_irq_restore(flags); } EXPORT_SYMBOL(s3c2410_gpio_pullup); @@ -116,14 +116,14 @@ unsigned long flags; unsigned long dat; - local_irq_save(flags); + raw_local_irq_save(flags); dat = __raw_readl(base + 0x04); dat &= ~(1 << offs); dat |= to << offs; __raw_writel(dat, base + 0x04); - local_irq_restore(flags); + raw_local_irq_restore(flags); } EXPORT_SYMBOL(s3c2410_gpio_setpin); @@ -143,12 +143,12 @@ unsigned long flags; unsigned long misccr; - local_irq_save(flags); + raw_local_irq_save(flags); misccr = __raw_readl(S3C2410_MISCCR); misccr &= ~clear; misccr ^= change; __raw_writel(misccr, S3C2410_MISCCR); - local_irq_restore(flags); + raw_local_irq_restore(flags); return misccr; } @@ -189,7 +189,7 @@ pin -= S3C2410_GPG8_EINT16; reg += pin & ~3; - local_irq_save(flags); + raw_local_irq_save(flags); /* update filter width and clock source */ @@ -205,7 +205,7 @@ val |= on << ((pin * 4) + 3); __raw_writel(val, S3C2410_EXTINT2); - local_irq_restore(flags); + raw_local_irq_restore(flags); return 0; } diff -urN linux-2.6.12-armirq/arch/arm/mach-s3c2410/s3c2440-dsc.c linux-2.6.12-armirq-rt/arch/arm/mach-s3c2410/s3c2440-dsc.c --- linux-2.6.12-armirq/arch/arm/mach-s3c2410/s3c2440-dsc.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-s3c2410/s3c2440-dsc.c 2005-07-16 16:41:52.000000000 +0200 @@ -45,14 +45,14 @@ base = (pin & S3C2440_SELECT_DSC1) ? S3C2440_DSC1 : S3C2440_DSC0; mask = 3 << S3C2440_DSC_GETSHIFT(pin); - local_irq_save(flags); + raw_local_irq_save(flags); val = __raw_readl(base); val &= ~mask; val |= value & mask; __raw_writel(val, base); - local_irq_restore(flags); + raw_local_irq_restore(flags); return 0; } diff -urN linux-2.6.12-armirq/arch/arm/mach-s3c2410/time.c linux-2.6.12-armirq-rt/arch/arm/mach-s3c2410/time.c --- linux-2.6.12-armirq/arch/arm/mach-s3c2410/time.c 2005-07-13 14:34:11.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-s3c2410/time.c 2005-07-16 16:41:52.000000000 +0200 @@ -138,7 +138,7 @@ static struct irqaction s3c2410_timer_irq = { .name = "S3C2410 Timer Tick", - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_NODELAY, .handler = s3c2410_timer_interrupt }; diff -urN linux-2.6.12-armirq/arch/arm/mach-sa1100/assabet.c linux-2.6.12-armirq-rt/arch/arm/mach-sa1100/assabet.c --- linux-2.6.12-armirq/arch/arm/mach-sa1100/assabet.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-sa1100/assabet.c 2005-07-16 16:41:52.000000000 +0200 @@ -60,10 +60,10 @@ { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); BCR_value = (BCR_value & ~mask) | val; ASSABET_BCR = BCR_value; - local_irq_restore(flags); + raw_local_irq_restore(flags); } EXPORT_SYMBOL(ASSABET_BCR_frob); diff -urN linux-2.6.12-armirq/arch/arm/mach-sa1100/badge4.c linux-2.6.12-armirq-rt/arch/arm/mach-sa1100/badge4.c --- linux-2.6.12-armirq/arch/arm/mach-sa1100/badge4.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-sa1100/badge4.c 2005-07-16 16:41:52.000000000 +0200 @@ -227,7 +227,7 @@ unsigned long flags; unsigned old_5V_bitmap; - local_irq_save(flags); + raw_local_irq_save(flags); old_5V_bitmap = badge4_5V_bitmap; @@ -240,15 +240,22 @@ /* detect on->off and off->on transitions */ if ((!old_5V_bitmap) && (badge4_5V_bitmap)) { /* was off, now on */ - printk(KERN_INFO "%s: enabling 5V supply rail\n", __FUNCTION__); GPSR = BADGE4_GPIO_PCMEN5V; } else if ((old_5V_bitmap) && (!badge4_5V_bitmap)) { /* was on, now off */ - printk(KERN_INFO "%s: disabling 5V supply rail\n", __FUNCTION__); GPCR = BADGE4_GPIO_PCMEN5V; } - local_irq_restore(flags); + raw_local_irq_restore(flags); + + /* detect on->off and off->on transitions */ + if ((!old_5V_bitmap) && (badge4_5V_bitmap)) { + /* was off, now on */ + printk(KERN_INFO "%s: enabling 5V supply rail\n", __FUNCTION__); + } else if ((old_5V_bitmap) && (!badge4_5V_bitmap)) { + /* was on, now off */ + printk(KERN_INFO "%s: disabling 5V supply rail\n", __FUNCTION__); + } } EXPORT_SYMBOL(badge4_set_5V); diff -urN linux-2.6.12-armirq/arch/arm/mach-sa1100/cpu-sa1110.c linux-2.6.12-armirq-rt/arch/arm/mach-sa1100/cpu-sa1110.c --- linux-2.6.12-armirq/arch/arm/mach-sa1100/cpu-sa1110.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-sa1100/cpu-sa1110.c 2005-07-16 16:41:52.000000000 +0200 @@ -283,7 +283,7 @@ * This means that we won't access SDRAM for the duration of * the programming. */ - local_irq_save(flags); + raw_local_irq_save(flags); asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0)); udelay(10); __asm__ __volatile__(" \n\ @@ -304,7 +304,7 @@ : "r" (&MDCNFG), "r" (&PPCR), "0" (sd.mdcnfg), "r" (sd.mdrefr), "r" (sd.mdcas[0]), "r" (sd.mdcas[1]), "r" (sd.mdcas[2]), "r" (ppcr)); - local_irq_restore(flags); + raw_local_irq_restore(flags); /* * Now, return the SDRAM refresh back to normal. diff -urN linux-2.6.12-armirq/arch/arm/mach-sa1100/dma.c linux-2.6.12-armirq-rt/arch/arm/mach-sa1100/dma.c --- linux-2.6.12-armirq/arch/arm/mach-sa1100/dma.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-sa1100/dma.c 2005-07-16 16:41:52.000000000 +0200 @@ -227,7 +227,7 @@ if (size > MAX_DMA_SIZE) return -EOVERFLOW; - local_irq_save(flags); + raw_local_irq_save(flags); status = regs->RdDCSR; /* If both DMA buffers are started, there's nothing else we can do. */ @@ -262,7 +262,7 @@ ret = 0; out: - local_irq_restore(flags); + raw_local_irq_restore(flags); return ret; } diff -urN linux-2.6.12-armirq/arch/arm/mach-sa1100/generic.c linux-2.6.12-armirq-rt/arch/arm/mach-sa1100/generic.c --- linux-2.6.12-armirq/arch/arm/mach-sa1100/generic.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-sa1100/generic.c 2005-07-16 16:41:52.000000000 +0200 @@ -135,7 +135,7 @@ static void sa1100_power_off(void) { mdelay(100); - local_irq_disable(); + raw_local_irq_disable(); /* disable internal oscillator, float CS lines */ PCFR = (PCFR_OPDE | PCFR_FP | PCFR_FS); /* enable wake-up on GPIO0 (Assabet...) */ @@ -386,7 +386,7 @@ { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); PGSR &= ~GPIO_MBGNT; GPCR = GPIO_MBGNT; @@ -394,7 +394,7 @@ GAFR &= ~(GPIO_MBGNT | GPIO_MBREQ); - local_irq_restore(flags); + raw_local_irq_restore(flags); } /* @@ -405,7 +405,7 @@ { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); PGSR &= ~GPIO_MBGNT; GPCR = GPIO_MBGNT; @@ -414,6 +414,6 @@ GAFR |= (GPIO_MBGNT | GPIO_MBREQ); TUCR |= TUCR_MR; - local_irq_restore(flags); + raw_local_irq_restore(flags); } diff -urN linux-2.6.12-armirq/arch/arm/mach-sa1100/h3600.c linux-2.6.12-armirq-rt/arch/arm/mach-sa1100/h3600.c --- linux-2.6.12-armirq/arch/arm/mach-sa1100/h3600.c 2005-07-13 14:34:11.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-sa1100/h3600.c 2005-07-16 16:41:52.000000000 +0200 @@ -319,7 +319,7 @@ } if (egpio || gpio) { - local_irq_save(flags); + raw_local_irq_save(flags); if (setp) { h3100_egpio |= egpio; GPSR = gpio; @@ -328,7 +328,7 @@ GPCR = gpio; } H3100_EGPIO = h3100_egpio; - local_irq_restore(flags); + raw_local_irq_restore(flags); } } @@ -449,13 +449,13 @@ } if (egpio) { - local_irq_save(flags); + raw_local_irq_save(flags); if (setp) h3600_egpio |= egpio; else h3600_egpio &= ~egpio; H3600_EGPIO = h3600_egpio; - local_irq_restore(flags); + raw_local_irq_restore(flags); } } @@ -727,7 +727,7 @@ static struct irqaction h3800_irq = { .name = "h3800_asic", .handler = h3800_IRQ_demux, - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_NODELAY, }; u32 kpio_int_shadow = 0; @@ -786,6 +786,8 @@ static DEFINE_IRQ_CHAINED_TYPE(h3800_IRQ_demux); +static DEFINE_IRQ_CHAINED_TYPE(h3800_IRQ_demux); + static void __init h3800_init_irq(void) { int i; diff -urN linux-2.6.12-armirq/arch/arm/mach-sa1100/leds-assabet.c linux-2.6.12-armirq-rt/arch/arm/mach-sa1100/leds-assabet.c --- linux-2.6.12-armirq/arch/arm/mach-sa1100/leds-assabet.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-sa1100/leds-assabet.c 2005-07-16 16:41:52.000000000 +0200 @@ -32,7 +32,7 @@ { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); switch (evt) { case led_start: @@ -111,5 +111,5 @@ if (led_state & LED_STATE_ENABLED) ASSABET_BCR_frob(ASSABET_BCR_LED_MASK, hw_led_state); - local_irq_restore(flags); + raw_local_irq_restore(flags); } diff -urN linux-2.6.12-armirq/arch/arm/mach-sa1100/leds-badge4.c linux-2.6.12-armirq-rt/arch/arm/mach-sa1100/leds-badge4.c --- linux-2.6.12-armirq/arch/arm/mach-sa1100/leds-badge4.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-sa1100/leds-badge4.c 2005-07-16 16:41:52.000000000 +0200 @@ -36,7 +36,7 @@ { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); switch (evt) { case led_start: @@ -108,5 +108,5 @@ GPCR = hw_led_state ^ LED_MASK; } - local_irq_restore(flags); + raw_local_irq_restore(flags); } diff -urN linux-2.6.12-armirq/arch/arm/mach-sa1100/leds-cerf.c linux-2.6.12-armirq-rt/arch/arm/mach-sa1100/leds-cerf.c --- linux-2.6.12-armirq/arch/arm/mach-sa1100/leds-cerf.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-sa1100/leds-cerf.c 2005-07-16 16:41:52.000000000 +0200 @@ -29,7 +29,7 @@ { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); switch (evt) { case led_start: @@ -107,5 +107,5 @@ GPCR = hw_led_state ^ LED_MASK; } - local_irq_restore(flags); + raw_local_irq_restore(flags); } diff -urN linux-2.6.12-armirq/arch/arm/mach-sa1100/leds-hackkit.c linux-2.6.12-armirq-rt/arch/arm/mach-sa1100/leds-hackkit.c --- linux-2.6.12-armirq/arch/arm/mach-sa1100/leds-hackkit.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-sa1100/leds-hackkit.c 2005-07-16 16:41:53.000000000 +0200 @@ -33,7 +33,7 @@ { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); switch(evt) { case led_start: @@ -109,5 +109,5 @@ GPCR = hw_led_state ^ LED_MASK; } - local_irq_restore(flags); + raw_local_irq_restore(flags); } diff -urN linux-2.6.12-armirq/arch/arm/mach-sa1100/leds-lart.c linux-2.6.12-armirq-rt/arch/arm/mach-sa1100/leds-lart.c --- linux-2.6.12-armirq/arch/arm/mach-sa1100/leds-lart.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-sa1100/leds-lart.c 2005-07-16 16:41:53.000000000 +0200 @@ -32,7 +32,7 @@ { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); switch(evt) { case led_start: @@ -98,5 +98,5 @@ GPCR = hw_led_state ^ LED_MASK; } - local_irq_restore(flags); + raw_local_irq_restore(flags); } diff -urN linux-2.6.12-armirq/arch/arm/mach-sa1100/simpad.c linux-2.6.12-armirq-rt/arch/arm/mach-sa1100/simpad.c --- linux-2.6.12-armirq/arch/arm/mach-sa1100/simpad.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-sa1100/simpad.c 2005-07-16 16:41:53.000000000 +0200 @@ -161,7 +161,7 @@ static void simpad_power_off(void) { - local_irq_disable(); // was cli + raw_local_irq_disable(); // was cli set_cs3(0x800); /* only SD_MEDIAQ */ /* disable internal oscillator, float CS lines */ @@ -178,7 +178,7 @@ PMCR = PMCR_SF; while(1); - local_irq_enable(); /* we won't ever call it */ + raw_local_irq_enable(); /* we won't ever call it */ } diff -urN linux-2.6.12-armirq/arch/arm/mach-sa1100/time.c linux-2.6.12-armirq-rt/arch/arm/mach-sa1100/time.c --- linux-2.6.12-armirq/arch/arm/mach-sa1100/time.c 2005-07-13 14:34:11.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-sa1100/time.c 2005-07-16 16:41:53.000000000 +0200 @@ -100,7 +100,7 @@ static struct irqaction sa1100_timer_irq = { .name = "SA11xx Timer Tick", - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_NODELAY, .handler = sa1100_timer_interrupt }; diff -urN linux-2.6.12-armirq/arch/arm/mach-shark/core.c linux-2.6.12-armirq-rt/arch/arm/mach-shark/core.c --- linux-2.6.12-armirq/arch/arm/mach-shark/core.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-shark/core.c 2005-07-16 16:41:53.000000000 +0200 @@ -84,7 +84,7 @@ static struct irqaction shark_timer_irq = { .name = "Shark Timer Tick", - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_NODELAY, .handler = shark_timer_interrupt }; diff -urN linux-2.6.12-armirq/arch/arm/mach-versatile/core.c linux-2.6.12-armirq-rt/arch/arm/mach-versatile/core.c --- linux-2.6.12-armirq/arch/arm/mach-versatile/core.c 2005-07-13 14:34:11.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mach-versatile/core.c 2005-07-16 16:41:53.000000000 +0200 @@ -724,7 +724,7 @@ unsigned long flags; u32 val; - local_irq_save(flags); + raw_local_irq_save(flags); val = readl(VA_LEDS_BASE); switch (ledevt) { @@ -749,7 +749,7 @@ } writel(val, VA_LEDS_BASE); - local_irq_restore(flags); + raw_local_irq_restore(flags); } #endif /* CONFIG_LEDS */ @@ -873,7 +873,7 @@ static struct irqaction versatile_timer_irq = { .name = "Versatile Timer Tick", - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_NODELAY, .handler = versatile_timer_interrupt }; diff -urN linux-2.6.12-armirq/arch/arm/mm/consistent.c linux-2.6.12-armirq-rt/arch/arm/mm/consistent.c --- linux-2.6.12-armirq/arch/arm/mm/consistent.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mm/consistent.c 2005-07-16 16:41:53.000000000 +0200 @@ -30,7 +30,7 @@ * This is the page table (2MB) covering uncached, DMA consistent allocations */ static pte_t *consistent_pte; -static DEFINE_SPINLOCK(consistent_lock); +static DEFINE_RAW_SPINLOCK(consistent_lock); /* * VM region handling support. diff -urN linux-2.6.12-armirq/arch/arm/mm/fault-armv.c linux-2.6.12-armirq-rt/arch/arm/mm/fault-armv.c --- linux-2.6.12-armirq/arch/arm/mm/fault-armv.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mm/fault-armv.c 2005-07-16 16:41:53.000000000 +0200 @@ -170,7 +170,7 @@ { register unsigned long zero = 0, one = 1, val; - local_irq_disable(); + raw_local_irq_disable(); mb(); *p1 = one; mb(); @@ -178,7 +178,7 @@ mb(); val = *p1; mb(); - local_irq_enable(); + raw_local_irq_enable(); return val != zero; } diff -urN linux-2.6.12-armirq/arch/arm/mm/init.c linux-2.6.12-armirq-rt/arch/arm/mm/init.c --- linux-2.6.12-armirq/arch/arm/mm/init.c 2005-07-13 14:30:06.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/arm/mm/init.c 2005-07-16 16:41:53.000000000 +0200 @@ -28,7 +28,7 @@ #define TABLE_SIZE (2 * PTRS_PER_PTE * sizeof(pte_t)) -DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); +DEFINE_PER_CPU_LOCKED(struct mmu_gather, mmu_gathers); extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; extern void _stext, _text, _etext, __data_start, _end, __init_begin, __init_end; diff -urN linux-2.6.12-armirq/arch/i386/Kconfig linux-2.6.12-armirq-rt/arch/i386/Kconfig --- linux-2.6.12-armirq/arch/i386/Kconfig 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/Kconfig 2005-07-16 16:41:53.000000000 +0200 @@ -369,16 +369,6 @@ default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODEGX1 default "6" if MK7 || MK8 || MPENTIUMM -config RWSEM_GENERIC_SPINLOCK - bool - depends on M386 - default y - -config RWSEM_XCHGADD_ALGORITHM - bool - depends on !M386 - default y - config GENERIC_CALIBRATE_DELAY bool default y @@ -435,7 +425,7 @@ config X86_USE_3DNOW bool - depends on MCYRIXIII || MK7 + depends on (MCYRIXIII || MK7) && !PREEMPT_RT default y config X86_OOSTORE @@ -511,28 +501,21 @@ cost of slightly increased overhead in some places. If unsure say N here. -config PREEMPT - bool "Preemptible Kernel" - help - This option reduces the latency of the kernel when reacting to - real-time or interactive events by allowing a low priority process to - be preempted even if it is in kernel mode executing a system call. - This allows applications to run more reliably even when the system is - under load. +source "kernel/Kconfig.preempt" - Say Y here if you are building a kernel for a desktop, embedded - or real-time system. Say N if you are unsure. +config RWSEM_GENERIC_SPINLOCK + bool + depends on M386 || PREEMPT_RT + default y -config PREEMPT_BKL - bool "Preempt The Big Kernel Lock" - depends on PREEMPT +config ASM_SEMAPHORES + bool default y - help - This option reduces the latency of the kernel by making the - big kernel lock preemptible. - Say Y here if you are building a kernel for a desktop system. - Say N if you are unsure. +config RWSEM_XCHGADD_ALGORITHM + bool + depends on !RWSEM_GENERIC_SPINLOCK && !PREEMPT_RT + default y config X86_UP_APIC bool "Local APIC support on uniprocessors" @@ -569,6 +552,16 @@ depends on X86_UP_IOAPIC || (SMP && !(X86_VISWS || X86_VOYAGER)) default y +config X86_IOAPIC_FAST + bool "enhanced IO-APIC support" + depends on X86_IO_APIC + default y + help + this option will activate further optimizations in the IO-APIC + code. NOTE: this is experimental code, and disabled by default. + Symptoms of non-working systems are boot-time lockups, stray or + screaming interrupts and other interrupt related weirdnesses. + config X86_VISWS_APIC bool depends on X86_VISWS @@ -911,7 +904,7 @@ config REGPARM bool "Use register arguments (EXPERIMENTAL)" - depends on EXPERIMENTAL + depends on EXPERIMENTAL && !MCOUNT default n help Compile the kernel with -mregparm=3. This uses a different ABI diff -urN linux-2.6.12-armirq/arch/i386/Kconfig.debug linux-2.6.12-armirq-rt/arch/i386/Kconfig.debug --- linux-2.6.12-armirq/arch/i386/Kconfig.debug 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/Kconfig.debug 2005-07-16 16:41:53.000000000 +0200 @@ -18,6 +18,7 @@ config DEBUG_STACKOVERFLOW bool "Check for stack overflows" depends on DEBUG_KERNEL + default y config KPROBES bool "Kprobes" @@ -32,6 +33,7 @@ config DEBUG_STACK_USAGE bool "Stack utilization instrumentation" depends on DEBUG_KERNEL + default y help Enables the display of the minimum amount of free stack which each task has ever had available in the sysrq-T and sysrq-P debug output. diff -urN linux-2.6.12-armirq/arch/i386/boot/compressed/misc.c linux-2.6.12-armirq-rt/arch/i386/boot/compressed/misc.c --- linux-2.6.12-armirq/arch/i386/boot/compressed/misc.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/boot/compressed/misc.c 2005-07-16 16:41:53.000000000 +0200 @@ -14,6 +14,12 @@ #include #include +#ifdef CONFIG_MCOUNT +void notrace mcount(void) +{ +} +#endif + /* * gzip declarations */ @@ -111,7 +117,7 @@ #define INPLACE_MOVE_ROUTINE 0x1000 #define LOW_BUFFER_START 0x2000 #define LOW_BUFFER_MAX 0x90000 -#define HEAP_SIZE 0x3000 +#define HEAP_SIZE 0x4000 static unsigned int low_buffer_end, low_buffer_size; static int high_loaded =0; static uch *high_buffer_start /* = (uch *)(((ulg)&end) + HEAP_SIZE)*/; diff -urN linux-2.6.12-armirq/arch/i386/kernel/Makefile linux-2.6.12-armirq-rt/arch/i386/kernel/Makefile --- linux-2.6.12-armirq/arch/i386/kernel/Makefile 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/Makefile 2005-07-16 16:41:53.000000000 +0200 @@ -4,11 +4,12 @@ extra-y := head.o init_task.o vmlinux.lds -obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \ +obj-y := process.o signal.o entry.o traps.o irq.o vm86.o \ ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \ pci-dma.o i386_ksyms.o i387.o dmi_scan.o bootflag.o \ doublefault.o quirks.o +obj-$(CONFIG_ASM_SEMAPHORES) += semaphore.o obj-y += cpu/ obj-y += timers/ obj-$(CONFIG_ACPI_BOOT) += acpi/ @@ -20,6 +21,7 @@ obj-$(CONFIG_APM) += apm.o obj-$(CONFIG_X86_SMP) += smp.o smpboot.o obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o +obj-$(CONFIG_MCOUNT) += mcount-wrapper.o obj-$(CONFIG_X86_MPPARSE) += mpparse.o obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o obj-$(CONFIG_X86_IO_APIC) += io_apic.o diff -urN linux-2.6.12-armirq/arch/i386/kernel/apic.c linux-2.6.12-armirq-rt/arch/i386/kernel/apic.c --- linux-2.6.12-armirq/arch/i386/kernel/apic.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/apic.c 2005-07-16 16:41:53.000000000 +0200 @@ -34,6 +34,7 @@ #include #include #include +#include #include @@ -523,9 +524,9 @@ if (!cpu_has_apic || !enabled_via_apicbase) return; - local_irq_disable(); + raw_local_irq_disable(); disable_local_APIC(); - local_irq_enable(); + raw_local_irq_enable(); } #ifdef CONFIG_PM @@ -569,9 +570,9 @@ apic_pm_state.apic_tdcr = apic_read(APIC_TDCR); apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR); - local_irq_save(flags); + raw_local_irq_save(flags); disable_local_APIC(); - local_irq_restore(flags); + raw_local_irq_restore(flags); return 0; } @@ -583,7 +584,7 @@ if (!apic_pm_state.active) return 0; - local_irq_save(flags); + raw_local_irq_save(flags); /* * Make sure the APICBASE points to the right address @@ -614,7 +615,7 @@ apic_write(APIC_LVTERR, apic_pm_state.apic_lvterr); apic_write(APIC_ESR, 0); apic_read(APIC_ESR); - local_irq_restore(flags); + raw_local_irq_restore(flags); return 0; } @@ -857,7 +858,6 @@ */ static unsigned int __init get_8254_timer_count(void) { - extern spinlock_t i8253_lock; unsigned long flags; unsigned int count; @@ -934,7 +934,7 @@ { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); /* * Wait for IRQ0's slice: @@ -943,7 +943,7 @@ __setup_APIC_LVTT(clocks); - local_irq_restore(flags); + raw_local_irq_restore(flags); } /* @@ -1032,7 +1032,7 @@ apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n"); using_apic_timer = 1; - local_irq_disable(); + raw_local_irq_disable(); calibration_result = calibrate_APIC_clock(); /* @@ -1040,7 +1040,7 @@ */ setup_APIC_timer(calibration_result); - local_irq_enable(); + raw_local_irq_enable(); } void __init setup_secondary_APIC_clock(void) @@ -1112,7 +1112,10 @@ { int cpu = smp_processor_id(); +#if 0 profile_tick(CPU_PROFILING, regs); +#endif + if (--per_cpu(prof_counter, cpu) <= 0) { /* * The multiplier may have changed since the last time we got @@ -1158,7 +1161,7 @@ * interrupt as well. Thus we cannot inline the local irq ... ] */ -fastcall void smp_apic_timer_interrupt(struct pt_regs *regs) +fastcall notrace void smp_apic_timer_interrupt(struct pt_regs *regs) { int cpu = smp_processor_id(); @@ -1167,6 +1170,8 @@ */ per_cpu(irq_stat, cpu).apic_timer_irqs++; + trace_special(regs->eip, 0, 0); + /* * NOTE! We'd better ACK the irq immediately, * because timer handling can be slow. diff -urN linux-2.6.12-armirq/arch/i386/kernel/apm.c linux-2.6.12-armirq-rt/arch/i386/kernel/apm.c --- linux-2.6.12-armirq/arch/i386/kernel/apm.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/apm.c 2005-07-16 16:41:53.000000000 +0200 @@ -228,10 +228,10 @@ #include #include #include +#include #include "io_ports.h" -extern spinlock_t i8253_lock; extern unsigned long get_cmos_time(void); extern void machine_real_restart(unsigned char *, int); @@ -552,9 +552,9 @@ */ #define APM_DO_CLI \ if (apm_info.allow_ints) \ - local_irq_enable(); \ + raw_local_irq_enable(); \ else \ - local_irq_disable(); + raw_local_irq_disable(); #ifdef APM_ZERO_SEGS # define APM_DECL_SEGS \ @@ -604,12 +604,12 @@ save_desc_40 = per_cpu(cpu_gdt_table, cpu)[0x40 / 8]; per_cpu(cpu_gdt_table, cpu)[0x40 / 8] = bad_bios_desc; - local_save_flags(flags); + raw_local_save_flags(flags); APM_DO_CLI; APM_DO_SAVE_SEGS; apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi); APM_DO_RESTORE_SEGS; - local_irq_restore(flags); + raw_local_irq_restore(flags); per_cpu(cpu_gdt_table, cpu)[0x40 / 8] = save_desc_40; put_cpu(); apm_restore_cpus(cpus); @@ -647,12 +647,12 @@ save_desc_40 = per_cpu(cpu_gdt_table, cpu)[0x40 / 8]; per_cpu(cpu_gdt_table, cpu)[0x40 / 8] = bad_bios_desc; - local_save_flags(flags); + raw_local_save_flags(flags); APM_DO_CLI; APM_DO_SAVE_SEGS; error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax); APM_DO_RESTORE_SEGS; - local_irq_restore(flags); + raw_local_irq_restore(flags); __get_cpu_var(cpu_gdt_table)[0x40 / 8] = save_desc_40; put_cpu(); apm_restore_cpus(cpus); @@ -1168,8 +1168,7 @@ static void reinit_timer(void) { #ifdef INIT_TIMER_AFTER_SUSPEND - unsigned long flags; - extern spinlock_t i8253_lock; + unsigned long flags; spin_lock_irqsave(&i8253_lock, flags); /* set the clock to 100 Hz */ @@ -1202,7 +1201,7 @@ } device_suspend(PMSG_SUSPEND); - local_irq_disable(); + raw_local_irq_disable(); device_power_down(PMSG_SUSPEND); /* serialize with the timer interrupt */ @@ -1218,14 +1217,14 @@ */ spin_unlock(&i8253_lock); write_sequnlock(&xtime_lock); - local_irq_enable(); + raw_local_irq_enable(); save_processor_state(); err = set_system_power_state(APM_STATE_SUSPEND); ignore_normal_resume = 1; restore_processor_state(); - local_irq_disable(); + raw_local_irq_disable(); write_seqlock(&xtime_lock); spin_lock(&i8253_lock); reinit_timer(); @@ -1240,7 +1239,7 @@ apm_error("suspend", err); err = (err == APM_SUCCESS) ? 0 : -EIO; device_power_up(); - local_irq_enable(); + raw_local_irq_enable(); device_resume(); pm_send_all(PM_RESUME, (void *)0); queue_event(APM_NORMAL_RESUME, NULL); @@ -1259,22 +1258,22 @@ { int err; - local_irq_disable(); + raw_local_irq_disable(); device_power_down(PMSG_SUSPEND); /* serialize with the timer interrupt */ write_seqlock(&xtime_lock); /* If needed, notify drivers here */ get_time_diff(); write_sequnlock(&xtime_lock); - local_irq_enable(); + raw_local_irq_enable(); err = set_system_power_state(APM_STATE_STANDBY); if ((err != APM_SUCCESS) && (err != APM_NO_ERROR)) apm_error("standby", err); - local_irq_disable(); + raw_local_irq_disable(); device_power_up(); - local_irq_enable(); + raw_local_irq_enable(); } static apm_event_t get_event(void) diff -urN linux-2.6.12-armirq/arch/i386/kernel/cpu/mtrr/cyrix.c linux-2.6.12-armirq-rt/arch/i386/kernel/cpu/mtrr/cyrix.c --- linux-2.6.12-armirq/arch/i386/kernel/cpu/mtrr/cyrix.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/cpu/mtrr/cyrix.c 2005-07-16 16:41:53.000000000 +0200 @@ -17,7 +17,7 @@ arr = CX86_ARR_BASE + (reg << 1) + reg; /* avoid multiplication by 3 */ /* Save flags and disable interrupts */ - local_irq_save(flags); + raw_local_irq_save(flags); ccr3 = getCx86(CX86_CCR3); setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */ @@ -28,7 +28,7 @@ setCx86(CX86_CCR3, ccr3); /* disable MAPEN */ /* Enable interrupts if it was enabled previously */ - local_irq_restore(flags); + raw_local_irq_restore(flags); shift = ((unsigned char *) base)[1] & 0x0f; *base >>= PAGE_SHIFT; diff -urN linux-2.6.12-armirq/arch/i386/kernel/cpu/mtrr/generic.c linux-2.6.12-armirq-rt/arch/i386/kernel/cpu/mtrr/generic.c --- linux-2.6.12-armirq/arch/i386/kernel/cpu/mtrr/generic.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/cpu/mtrr/generic.c 2005-07-16 16:41:53.000000000 +0200 @@ -242,7 +242,7 @@ static unsigned long cr4 = 0; static u32 deftype_lo, deftype_hi; -static DEFINE_SPINLOCK(set_atomicity_lock); +static DEFINE_RAW_SPINLOCK(set_atomicity_lock); /* * Since we are disabling the cache don't allow any interrupts - they @@ -304,14 +304,14 @@ unsigned long mask, count; unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); prepare_set(); /* Actually set the state */ mask = set_mtrr_state(deftype_lo,deftype_hi); post_set(); - local_irq_restore(flags); + raw_local_irq_restore(flags); /* Use the atomic bitops to update the global mask */ for (count = 0; count < sizeof mask * 8; ++count) { @@ -336,7 +336,7 @@ { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); prepare_set(); if (size == 0) { @@ -351,7 +351,7 @@ } post_set(); - local_irq_restore(flags); + raw_local_irq_restore(flags); } int generic_validate_add_page(unsigned long base, unsigned long size, unsigned int type) diff -urN linux-2.6.12-armirq/arch/i386/kernel/cpu/mtrr/main.c linux-2.6.12-armirq-rt/arch/i386/kernel/cpu/mtrr/main.c --- linux-2.6.12-armirq/arch/i386/kernel/cpu/mtrr/main.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/cpu/mtrr/main.c 2005-07-16 16:41:53.000000000 +0200 @@ -146,7 +146,7 @@ struct set_mtrr_data *data = info; unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); atomic_dec(&data->count); while(!atomic_read(&data->gate)) @@ -164,7 +164,7 @@ cpu_relax(); atomic_dec(&data->count); - local_irq_restore(flags); + raw_local_irq_restore(flags); } #endif @@ -225,7 +225,7 @@ if (smp_call_function(ipi_handler, &data, 1, 0) != 0) panic("mtrr: timed out waiting for other CPUs\n"); - local_irq_save(flags); + raw_local_irq_save(flags); while(atomic_read(&data.count)) cpu_relax(); @@ -259,7 +259,7 @@ while(atomic_read(&data.count)) cpu_relax(); - local_irq_restore(flags); + raw_local_irq_restore(flags); } /** diff -urN linux-2.6.12-armirq/arch/i386/kernel/cpu/mtrr/state.c linux-2.6.12-armirq-rt/arch/i386/kernel/cpu/mtrr/state.c --- linux-2.6.12-armirq/arch/i386/kernel/cpu/mtrr/state.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/cpu/mtrr/state.c 2005-07-16 16:41:53.000000000 +0200 @@ -12,7 +12,7 @@ unsigned int cr0; /* Disable interrupts locally */ - local_irq_save(ctxt->flags); + raw_local_irq_save(ctxt->flags); if (use_intel() || is_cpu(CYRIX)) { @@ -73,6 +73,6 @@ write_cr4(ctxt->cr4val); } /* Re-enable interrupts locally (if enabled previously) */ - local_irq_restore(ctxt->flags); + raw_local_irq_restore(ctxt->flags); } diff -urN linux-2.6.12-armirq/arch/i386/kernel/entry.S linux-2.6.12-armirq-rt/arch/i386/kernel/entry.S --- linux-2.6.12-armirq/arch/i386/kernel/entry.S 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/entry.S 2005-07-16 16:41:53.000000000 +0200 @@ -76,10 +76,10 @@ VM_MASK = 0x00020000 #ifdef CONFIG_PREEMPT -#define preempt_stop cli +# define preempt_stop cli #else -#define preempt_stop -#define resume_kernel restore_nocheck +# define preempt_stop +# define resume_kernel restore_nocheck #endif #define SAVE_ALL \ @@ -160,14 +160,17 @@ #ifdef CONFIG_PREEMPT ENTRY(resume_kernel) cli + cmpl $0, kernel_preemption + jz restore_nocheck cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ? jnz restore_nocheck need_resched: movl TI_flags(%ebp), %ecx # need_resched set ? testb $_TIF_NEED_RESCHED, %cl - jz restore_all + jz restore_nocheck testl $IF_MASK,EFLAGS(%esp) # interrupts off (exception path) ? - jz restore_all + jz restore_nocheck + cli call preempt_schedule_irq jmp need_resched #endif @@ -200,6 +203,11 @@ pushl %eax SAVE_ALL +#ifdef CONFIG_LATENCY_TRACE + pushl %edx; pushl %ecx; pushl %ebx; pushl %eax + call sys_call + popl %eax; popl %ebx; popl %ecx; popl %edx +#endif GET_THREAD_INFO(%ebp) /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */ @@ -213,6 +221,11 @@ movl TI_flags(%ebp), %ecx testw $_TIF_ALLWORK_MASK, %cx jne syscall_exit_work +#ifdef CONFIG_LATENCY_TRACE + pushl %eax + call sys_ret + popl %eax +#endif /* if something modifies registers it must also disable sysexit */ movl EIP(%esp), %edx movl OLDESP(%esp), %ecx @@ -225,6 +238,11 @@ ENTRY(system_call) pushl %eax # save orig_eax SAVE_ALL +#ifdef CONFIG_LATENCY_TRACE + pushl %edx; pushl %ecx; pushl %ebx; pushl %eax + call sys_call + popl %eax; popl %ebx; popl %ecx; popl %edx +#endif GET_THREAD_INFO(%ebp) # system call tracing in operation /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */ @@ -254,6 +272,17 @@ cmpl $((4 << 8) | 3), %eax je ldt_ss # returning to user-space with LDT SS restore_nocheck: +#if defined(CONFIG_CRITICAL_IRQSOFF_TIMING) || defined(CONFIG_LATENCY_TRACE) + pushl %eax +#ifdef CONFIG_CRITICAL_IRQSOFF_TIMING + call trace_irqs_on +#endif +#ifdef CONFIG_LATENCY_TRACE + call sys_ret +#endif + popl %eax +#endif +restore_nocheck_nmi: RESTORE_REGS addl $4, %esp 1: iret @@ -297,18 +326,22 @@ # perform work that needs to be done immediately before resumption ALIGN work_pending: - testb $_TIF_NEED_RESCHED, %cl + testb $(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED), %cl jz work_notifysig work_resched: - call schedule - cli # make sure we don't miss an interrupt + cli + call __schedule +#ifdef CONFIG_PREEMPT_RT + call local_irq_enable_noresched +#endif + # make sure we don't miss an interrupt # setting need_resched or sigpending # between sampling and the iret movl TI_flags(%ebp), %ecx andl $_TIF_WORK_MASK, %ecx # is there any work to be done other # than syscall tracing? jz restore_all - testb $_TIF_NEED_RESCHED, %cl + testb $(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED), %cl jnz work_resched work_notifysig: # deal with pending signals and @@ -348,6 +381,11 @@ syscall_exit_work: testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP), %cl jz work_pending +#ifdef CONFIG_CRITICAL_IRQSOFF_TIMING + pushl %eax + call trace_irqs_on + popl %eax +#endif sti # could let do_syscall_trace() call # schedule() instead movl %esp, %eax @@ -409,9 +447,16 @@ vector=vector+1 .endr +#ifdef CONFIG_CRITICAL_IRQSOFF_TIMING +# define TRACE_IRQS_OFF call trace_irqs_off_lowlevel; +#else +# define TRACE_IRQS_OFF +#endif + ALIGN common_interrupt: SAVE_ALL + TRACE_IRQS_OFF movl %esp,%eax call do_IRQ jmp ret_from_intr @@ -420,6 +465,7 @@ ENTRY(name) \ pushl $nr-256; \ SAVE_ALL \ + TRACE_IRQS_OFF \ movl %esp,%eax; \ call smp_/**/name; \ jmp ret_from_intr; @@ -549,7 +595,7 @@ xorl %edx,%edx # zero error code movl %esp,%eax # pt_regs pointer call do_nmi - jmp restore_all + jmp restore_nocheck_nmi nmi_stack_fixup: FIX_STACK(12,nmi_stack_correct, 1) diff -urN linux-2.6.12-armirq/arch/i386/kernel/i386_ksyms.c linux-2.6.12-armirq-rt/arch/i386/kernel/i386_ksyms.c --- linux-2.6.12-armirq/arch/i386/kernel/i386_ksyms.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/i386_ksyms.c 2005-07-16 16:41:53.000000000 +0200 @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -34,7 +35,6 @@ #include extern void dump_thread(struct pt_regs *, struct user *); -extern spinlock_t rtc_lock; /* This is definitely a GPL-only symbol */ EXPORT_SYMBOL_GPL(cpu_gdt_table); @@ -81,10 +81,12 @@ EXPORT_SYMBOL(cpu_khz); EXPORT_SYMBOL(apm_info); -EXPORT_SYMBOL(__down_failed); -EXPORT_SYMBOL(__down_failed_interruptible); -EXPORT_SYMBOL(__down_failed_trylock); -EXPORT_SYMBOL(__up_wakeup); +#ifdef CONFIG_ASM_SEMAPHORES +EXPORT_SYMBOL(__compat_down_failed); +EXPORT_SYMBOL(__compat_down_failed_interruptible); +EXPORT_SYMBOL(__compat_down_failed_trylock); +EXPORT_SYMBOL(__compat_up_wakeup); +#endif /* Networking helper routines. */ EXPORT_SYMBOL(csum_partial_copy_generic); /* Delay loops */ @@ -140,8 +142,10 @@ EXPORT_SYMBOL(cpu_data); EXPORT_SYMBOL(cpu_online_map); EXPORT_SYMBOL(cpu_callout_map); +#ifdef CONFIG_ASM_SEMAPHORES EXPORT_SYMBOL(__write_lock_failed); EXPORT_SYMBOL(__read_lock_failed); +#endif /* Global SMP stuff */ EXPORT_SYMBOL(smp_call_function); @@ -171,17 +175,19 @@ EXPORT_SYMBOL(register_die_notifier); #ifdef CONFIG_HAVE_DEC_LOCK -EXPORT_SYMBOL(_atomic_dec_and_lock); +EXPORT_SYMBOL(_atomic_dec_and_raw_spin_lock); #endif EXPORT_SYMBOL(__PAGE_KERNEL); #ifdef CONFIG_HIGHMEM EXPORT_SYMBOL(kmap); +EXPORT_SYMBOL(kmap_to_page); EXPORT_SYMBOL(kunmap); -EXPORT_SYMBOL(kmap_atomic); -EXPORT_SYMBOL(kunmap_atomic); -EXPORT_SYMBOL(kmap_atomic_to_page); +EXPORT_SYMBOL(__kmap_atomic); +EXPORT_SYMBOL(__kunmap_atomic); +EXPORT_SYMBOL(kunmap_virt); +EXPORT_SYMBOL(__kmap_atomic_to_page); #endif #if defined(CONFIG_X86_SPEEDSTEP_SMI) || defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE) diff -urN linux-2.6.12-armirq/arch/i386/kernel/i8259.c linux-2.6.12-armirq-rt/arch/i386/kernel/i8259.c --- linux-2.6.12-armirq/arch/i386/kernel/i8259.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/i8259.c 2005-07-16 16:41:53.000000000 +0200 @@ -38,7 +38,7 @@ * moves to arch independent land */ -DEFINE_SPINLOCK(i8259A_lock); +DEFINE_RAW_SPINLOCK(i8259A_lock); static void end_8259A_irq (unsigned int irq) { @@ -357,7 +357,7 @@ * New motherboards sometimes make IRQ 13 be a PCI interrupt, * so allow interrupt sharing. */ -static struct irqaction fpu_irq = { math_error_irq, 0, CPU_MASK_NONE, "fpu", NULL, NULL }; +static struct irqaction fpu_irq = { math_error_irq, SA_NODELAY, CPU_MASK_NONE, "fpu", NULL, NULL }; void __init init_ISA_irqs (void) { diff -urN linux-2.6.12-armirq/arch/i386/kernel/init_task.c linux-2.6.12-armirq-rt/arch/i386/kernel/init_task.c --- linux-2.6.12-armirq/arch/i386/kernel/init_task.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/init_task.c 2005-07-16 16:41:53.000000000 +0200 @@ -10,8 +10,8 @@ #include #include -static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; +static struct fs_struct init_fs = INIT_FS(init_fs); +static struct files_struct init_files = INIT_FILES(init_files); static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); diff -urN linux-2.6.12-armirq/arch/i386/kernel/io_apic.c linux-2.6.12-armirq-rt/arch/i386/kernel/io_apic.c --- linux-2.6.12-armirq/arch/i386/kernel/io_apic.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/io_apic.c 2005-07-16 16:41:53.000000000 +0200 @@ -37,6 +37,7 @@ #include #include #include +#include #include @@ -45,7 +46,7 @@ int (*ioapic_renumber_irq)(int ioapic, int irq); atomic_t irq_mis_count; -static DEFINE_SPINLOCK(ioapic_lock); +static DEFINE_RAW_SPINLOCK(ioapic_lock); /* * Is the SiS APIC rmw bug present ? @@ -127,19 +128,147 @@ } } +#ifdef CONFIG_X86_IOAPIC_FAST +# define IOAPIC_CACHE +#endif + +#ifdef IOAPIC_CACHE +# define MAX_IOAPIC_CACHE 512 + +/* + * Cache register values: + */ +static struct { + unsigned int reg; + unsigned int val[MAX_IOAPIC_CACHE]; +} io_apic_cache[MAX_IO_APICS] + ____cacheline_aligned_in_smp; +#endif + +volatile unsigned int *io_apic_base[MAX_IO_APICS]; + +static inline unsigned int __raw_io_apic_read(unsigned int apic, unsigned int reg) +{ + volatile unsigned int *io_apic; +#ifdef IOAPIC_CACHE + io_apic_cache[apic].reg = reg; +#endif + io_apic = io_apic_base[apic]; + io_apic[0] = reg; + return io_apic[4]; +} + +unsigned int raw_io_apic_read(unsigned int apic, unsigned int reg) +{ + unsigned int val = __raw_io_apic_read(apic, reg); + +#ifdef IOAPIC_CACHE + io_apic_cache[apic].val[reg] = val; +#endif + return val; +} + +unsigned int io_apic_read(unsigned int apic, unsigned int reg) +{ +#ifdef IOAPIC_CACHE + if (unlikely(reg >= MAX_IOAPIC_CACHE)) { + static int once = 1; + + if (once) { + once = 0; + printk("WARNING: ioapic register cache overflow: %d.\n", + reg); + dump_stack(); + } + return __raw_io_apic_read(apic, reg); + } + if (io_apic_cache[apic].val[reg] && !sis_apic_bug) { + io_apic_cache[apic].reg = -1; + return io_apic_cache[apic].val[reg]; + } +#endif + return raw_io_apic_read(apic, reg); +} + +void io_apic_write(unsigned int apic, unsigned int reg, unsigned int val) +{ + volatile unsigned int *io_apic; +#ifdef IOAPIC_CACHE + if (unlikely(reg >= MAX_IOAPIC_CACHE)) { + static int once = 1; + + if (once) { + once = 0; + printk("WARNING: ioapic register cache overflow: %d.\n", + reg); + dump_stack(); + } + } else + io_apic_cache[apic].val[reg] = val; +#endif + io_apic = io_apic_base[apic]; +#ifdef IOAPIC_CACHE + io_apic_cache[apic].reg = reg; +#endif + io_apic[0] = reg; + io_apic[4] = val; +} + +/* + * Some systems need a POST flush or else level-triggered interrupts + * generate lots of spurious interrupts due to the POST-ed write not + * reaching the IOAPIC before the IRQ is ACK-ed in the local APIC. + * + * It seems most systems need this - disable the optimization for now. + */ +//#ifndef CONFIG_X86_IOAPIC_FAST +# define IOAPIC_POSTFLUSH +//#endif + +/* + * Re-write a value: to be used for read-modify-write + * cycles where the read already set up the index register. + * + * Older SiS APIC requires we rewrite the index regiser + */ +void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int val) +{ + volatile unsigned int *io_apic; +#ifdef IOAPIC_CACHE + io_apic_cache[apic].val[reg] = val; +#endif + io_apic = io_apic_base[apic]; +#ifdef IOAPIC_CACHE + if (io_apic_cache[apic].reg != reg || sis_apic_bug) { + io_apic_cache[apic].reg = reg; +#else + if (unlikely(sis_apic_bug)) { +#endif + io_apic[0] = reg; + } + io_apic[4] = val; +#ifndef IOAPIC_POSTFLUSH + if (unlikely(sis_apic_bug)) +#endif + /* + * Force POST flush by reading: + */ + val = io_apic[4]; +} + static void __modify_IO_APIC_irq (unsigned int irq, unsigned long enable, unsigned long disable) { struct irq_pin_list *entry = irq_2_pin + irq; - unsigned int pin, reg; + unsigned int pin, val; for (;;) { pin = entry->pin; if (pin == -1) break; - reg = io_apic_read(entry->apic, 0x10 + pin*2); - reg &= ~disable; - reg |= enable; - io_apic_modify(entry->apic, 0x10 + pin*2, reg); + val = io_apic_read(entry->apic, 0x10 + pin*2); + val &= ~disable; + val |= enable; + io_apic_modify(entry->apic, 0x10 + pin*2, val); if (!entry->next) break; entry = irq_2_pin + entry->next; @@ -147,29 +276,17 @@ } /* mask = 1 */ -static void __mask_IO_APIC_irq (unsigned int irq) +static inline void __mask_IO_APIC_irq (unsigned int irq) { __modify_IO_APIC_irq(irq, 0x00010000, 0); } /* mask = 0 */ -static void __unmask_IO_APIC_irq (unsigned int irq) +static inline void __unmask_IO_APIC_irq (unsigned int irq) { __modify_IO_APIC_irq(irq, 0, 0x00010000); } -/* mask = 1, trigger = 0 */ -static void __mask_and_edge_IO_APIC_irq (unsigned int irq) -{ - __modify_IO_APIC_irq(irq, 0x00010000, 0x00008000); -} - -/* mask = 0, trigger = 1 */ -static void __unmask_and_level_IO_APIC_irq (unsigned int irq) -{ - __modify_IO_APIC_irq(irq, 0x00008000, 0x00010000); -} - static void mask_IO_APIC_irq (unsigned int irq) { unsigned long flags; @@ -216,9 +333,13 @@ { int apic, pin; - for (apic = 0; apic < nr_ioapics; apic++) + for (apic = 0; apic < nr_ioapics; apic++) { +#ifdef IOAPIC_CACHE + io_apic_cache[apic].reg = -1; +#endif for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) clear_IO_APIC_pin(apic, pin); + } } static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask) @@ -1303,7 +1424,7 @@ { } -void __init print_IO_APIC(void) +void /*__init*/ print_IO_APIC(void) { int apic, i; union IO_APIC_reg_00 reg_00; @@ -1405,8 +1526,8 @@ struct IO_APIC_route_entry entry; spin_lock_irqsave(&ioapic_lock, flags); - *(((int *)&entry)+0) = io_apic_read(apic, 0x10+i*2); - *(((int *)&entry)+1) = io_apic_read(apic, 0x11+i*2); + *(((int *)&entry)+0) = raw_io_apic_read(apic, 0x10+i*2); + *(((int *)&entry)+1) = raw_io_apic_read(apic, 0x11+i*2); spin_unlock_irqrestore(&ioapic_lock, flags); printk(KERN_DEBUG " %02x %03X %02X ", @@ -1452,7 +1573,7 @@ return; } -#if 0 +#if 1 static void print_APIC_bitfield (int base) { @@ -1565,7 +1686,6 @@ void /*__init*/ print_PIC(void) { - extern spinlock_t i8259A_lock; unsigned int v; unsigned long flags; @@ -1767,7 +1887,7 @@ { unsigned long t1 = jiffies; - local_irq_enable(); + raw_local_irq_enable(); /* Let ten ticks pass... */ mdelay((10 * 1000) / HZ); @@ -1831,9 +1951,11 @@ static void ack_edge_ioapic_irq(unsigned int irq) { move_irq(irq); +#if 0 if ((irq_desc[irq].status & (IRQ_PENDING | IRQ_DISABLED)) == (IRQ_PENDING | IRQ_DISABLED)) mask_IO_APIC_irq(irq); +#endif ack_APIC_irq(); } @@ -1858,6 +1980,30 @@ return 0; /* don't check for pending */ } +#ifdef CONFIG_PREEMPT_HARDIRQS + +/* + * in the PREEMPT_HARDIRQS case we dont want to keep the local + * APIC unacked, because the prevents further interrupts from + * being handled - and with IRQ threads being delayed arbitrarily, + * that's unacceptable. So we first mask the IRQ, then ack it. + * The hardirq thread will then unmask it. + */ +static void mask_and_ack_level_ioapic_irq(unsigned int irq) +{ + move_irq(irq); + mask_IO_APIC_irq(irq); + ack_APIC_irq(); +} + +#else + +static void mask_and_ack_level_ioapic_irq(unsigned int irq) +{ +} + +#endif + static void end_level_ioapic_irq (unsigned int irq) { unsigned long v; @@ -1892,8 +2038,10 @@ if (!(v & (1 << (i & 0x1f)))) { atomic_inc(&irq_mis_count); spin_lock(&ioapic_lock); - __mask_and_edge_IO_APIC_irq(irq); - __unmask_and_level_IO_APIC_irq(irq); + /* mask = 1, trigger = 0 */ + __modify_IO_APIC_irq(irq, 0x00010000, 0x00008000); + /* mask = 0, trigger = 1 */ + __modify_IO_APIC_irq(irq, 0x00008000, 0x00010000); spin_unlock(&ioapic_lock); } } @@ -1920,6 +2068,13 @@ return startup_level_ioapic_irq (irq); } +static void mask_and_ack_level_ioapic_vector (unsigned int vector) +{ + int irq = vector_to_irq(vector); + + mask_and_ack_level_ioapic_irq(irq); +} + static void end_level_ioapic_vector (unsigned int vector) { int irq = vector_to_irq(vector); @@ -2157,7 +2312,10 @@ */ apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); init_8259A(1); - timer_ack = 1; +#ifdef CONFIG_PREEMPT_RT + if (nmi_watchdog) +#endif + timer_ack = 1; enable_8259A_irq(0); pin1 = find_isa_irq_pin(0, mp_INT); diff -urN linux-2.6.12-armirq/arch/i386/kernel/irq.c linux-2.6.12-armirq-rt/arch/i386/kernel/irq.c --- linux-2.6.12-armirq/arch/i386/kernel/irq.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/irq.c 2005-07-16 16:41:53.000000000 +0200 @@ -48,7 +48,7 @@ * SMP cross-CPU interrupts have their own specific * handlers). */ -fastcall unsigned int do_IRQ(struct pt_regs *regs) +fastcall notrace unsigned int do_IRQ(struct pt_regs *regs) { /* high bits used in ret_from_ code */ int irq = regs->orig_eax & 0xff; @@ -56,8 +56,12 @@ union irq_ctx *curctx, *irqctx; u32 *isp; #endif - irq_enter(); +#ifdef CONFIG_LATENCY_TRACE + if (irq == trace_user_trigger_irq) + user_trace_start(); +#endif + trace_special(regs->eip, irq, 0); #ifdef CONFIG_DEBUG_STACKOVERFLOW /* Debugging check for stack overflow: is there less than 1KB free? */ { @@ -66,7 +70,7 @@ __asm__ __volatile__("andl %%esp,%0" : "=r" (esp) : "0" (THREAD_SIZE - 1)); if (unlikely(esp < (sizeof(struct thread_info) + STACK_WARN))) { - printk("do_IRQ: stack overflow: %ld\n", + printk("BUG: do_IRQ: stack overflow: %ld\n", esp - sizeof(struct thread_info)); dump_stack(); } @@ -165,7 +169,7 @@ if (in_interrupt()) return; - local_irq_save(flags); + raw_local_irq_save(flags); if (local_softirq_pending()) { curctx = current_thread_info(); @@ -186,7 +190,7 @@ ); } - local_irq_restore(flags); + raw_local_irq_restore(flags); } EXPORT_SYMBOL(do_softirq); @@ -217,8 +221,10 @@ } if (i < NR_IRQS) { - spin_lock_irqsave(&irq_desc[i].lock, flags); - action = irq_desc[i].action; + irq_desc_t *desc = irq_desc + i; + + spin_lock_irqsave(&desc->lock, flags); + action = desc->action; if (!action) goto skip; seq_printf(p, "%3d: ",i); @@ -229,15 +235,28 @@ if (cpu_online(j)) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif - seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %-14s", desc->handler->typename); +#define F(x,c) ((desc->status & x) ? c : '.') + seq_printf(p, " [%c%c%c%c%c%c%c%c%c%c/", + F(IRQ_INPROGRESS, 'I'), + F(IRQ_DISABLED, 'D'), + F(IRQ_PENDING, 'P'), + F(IRQ_REPLAY, 'R'), + F(IRQ_AUTODETECT, 'A'), + F(IRQ_WAITING, 'W'), + F(IRQ_LEVEL, 'L'), + F(IRQ_MASKED, 'M'), + F(IRQ_PER_CPU, 'C'), + F(IRQ_NODELAY, 'N')); +#undef F + seq_printf(p, "%3d]", desc->irqs_unhandled); seq_printf(p, " %s", action->name); - for (action=action->next; action; action = action->next) seq_printf(p, ", %s", action->name); seq_putc(p, '\n'); skip: - spin_unlock_irqrestore(&irq_desc[i].lock, flags); + spin_unlock_irqrestore(&desc->lock, flags); } else if (i == NR_IRQS) { seq_printf(p, "NMI: "); for (j = 0; j < NR_CPUS; j++) diff -urN linux-2.6.12-armirq/arch/i386/kernel/mcount-wrapper.S linux-2.6.12-armirq-rt/arch/i386/kernel/mcount-wrapper.S --- linux-2.6.12-armirq/arch/i386/kernel/mcount-wrapper.S 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/mcount-wrapper.S 2005-07-16 16:41:59.000000000 +0200 @@ -0,0 +1,27 @@ +/* + * linux/arch/i386/mcount-wrapper.S + * + * Copyright (C) 2004 Ingo Molnar + */ + +.globl mcount +mcount: + + cmpl $0, mcount_enabled + jz out + + push %ebp + mov %esp, %ebp + pushl %eax + pushl %ecx + pushl %edx + + call __mcount + + popl %edx + popl %ecx + popl %eax + popl %ebp +out: + ret + diff -urN linux-2.6.12-armirq/arch/i386/kernel/microcode.c linux-2.6.12-armirq-rt/arch/i386/kernel/microcode.c --- linux-2.6.12-armirq/arch/i386/kernel/microcode.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/microcode.c 2005-07-16 16:41:53.000000000 +0200 @@ -109,7 +109,7 @@ #define exttable_size(et) ((et)->count * EXT_SIGNATURE_SIZE + EXT_HEADER_SIZE) /* serialize access to the physical write to MSR 0x79 */ -static DEFINE_SPINLOCK(microcode_update_lock); +static DEFINE_RAW_SPINLOCK(microcode_update_lock); /* no concurrent ->write()s are allowed on /dev/cpu/microcode */ static DECLARE_MUTEX(microcode_sem); diff -urN linux-2.6.12-armirq/arch/i386/kernel/mpparse.c linux-2.6.12-armirq-rt/arch/i386/kernel/mpparse.c --- linux-2.6.12-armirq/arch/i386/kernel/mpparse.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/mpparse.c 2005-07-16 16:41:53.000000000 +0200 @@ -263,6 +263,7 @@ return; } mp_ioapics[nr_ioapics] = *m; + io_apic_base[nr_ioapics] = IO_APIC_BASE(nr_ioapics); nr_ioapics++; } @@ -914,6 +915,7 @@ mp_ioapics[idx].mpc_apicaddr = address; set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); + io_apic_base[idx] = IO_APIC_BASE(idx); mp_ioapics[idx].mpc_apicid = io_apic_get_unique_id(idx, id); mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx); diff -urN linux-2.6.12-armirq/arch/i386/kernel/nmi.c linux-2.6.12-armirq-rt/arch/i386/kernel/nmi.c --- linux-2.6.12-armirq/arch/i386/kernel/nmi.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/nmi.c 2005-07-16 16:41:53.000000000 +0200 @@ -36,7 +36,7 @@ unsigned int nmi_watchdog = NMI_NONE; extern int unknown_nmi_panic; -static unsigned int nmi_hz = HZ; +static unsigned int nmi_hz = 10000; static unsigned int nmi_perfctr_msr; /* the MSR to reset in NMI handler */ static unsigned int nmi_p4_cccr_val; extern void show_registers(struct pt_regs *regs); @@ -114,8 +114,8 @@ for (cpu = 0; cpu < NR_CPUS; cpu++) prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count; - local_irq_enable(); - mdelay((10*1000)/nmi_hz); // wait 10 ticks + raw_local_irq_enable(); + mdelay((100*1000)/nmi_hz); // wait 100 ticks for (cpu = 0; cpu < NR_CPUS; cpu++) { #ifdef CONFIG_SMP @@ -136,7 +136,7 @@ /* now that we know it works we can reduce NMI frequency to something more reasonable; makes a difference in some configs */ if (nmi_watchdog == NMI_LOCAL_APIC) - nmi_hz = 1; + nmi_hz = 10000; return 0; } @@ -339,8 +339,8 @@ | K7_NMI_EVENT; wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); - Dprintk("setting K7_PERFCTR0 to %08lx\n", -(cpu_khz/nmi_hz*1000)); - wrmsr(MSR_K7_PERFCTR0, -(cpu_khz/nmi_hz*1000), -1); + Dprintk("setting K7_PERFCTR0 to %08lx\n", -(cpu_khz*1000/nmi_hz)); + wrmsr(MSR_K7_PERFCTR0, -(cpu_khz*1000/nmi_hz), -1); apic_write(APIC_LVTPC, APIC_DM_NMI); evntsel |= K7_EVNTSEL_ENABLE; wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); @@ -361,8 +361,8 @@ | P6_NMI_EVENT; wrmsr(MSR_P6_EVNTSEL0, evntsel, 0); - Dprintk("setting P6_PERFCTR0 to %08lx\n", -(cpu_khz/nmi_hz*1000)); - wrmsr(MSR_P6_PERFCTR0, -(cpu_khz/nmi_hz*1000), 0); + Dprintk("setting P6_PERFCTR0 to %08lx\n", -(cpu_khz*1000/nmi_hz)); + wrmsr(MSR_P6_PERFCTR0, -(cpu_khz*1000/nmi_hz), 0); apic_write(APIC_LVTPC, APIC_DM_NMI); evntsel |= P6_EVNTSEL0_ENABLE; wrmsr(MSR_P6_EVNTSEL0, evntsel, 0); @@ -402,8 +402,8 @@ wrmsr(MSR_P4_CRU_ESCR0, P4_NMI_CRU_ESCR0, 0); wrmsr(MSR_P4_IQ_CCCR0, P4_NMI_IQ_CCCR0 & ~P4_CCCR_ENABLE, 0); - Dprintk("setting P4_IQ_COUNTER0 to 0x%08lx\n", -(cpu_khz/nmi_hz*1000)); - wrmsr(MSR_P4_IQ_COUNTER0, -(cpu_khz/nmi_hz*1000), -1); + Dprintk("setting P4_IQ_COUNTER0 to 0x%08lx\n", -(cpu_khz*1000/nmi_hz)); + wrmsr(MSR_P4_IQ_COUNTER0, -(cpu_khz*1000/nmi_hz), -1); apic_write(APIC_LVTPC, APIC_DM_NMI); wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0); return 1; @@ -472,13 +472,39 @@ */ for (i = 0; i < NR_CPUS; i++) alert_counter[i] = 0; + + /* + * Tickle the softlockup detector too: + */ + touch_softlockup_watchdog(); } extern void die_nmi(struct pt_regs *, const char *msg); -void nmi_watchdog_tick (struct pt_regs * regs) +int nmi_show_regs[NR_CPUS]; + +void nmi_show_all_regs(void) { + int i; + + if (nmi_watchdog == NMI_NONE) + return; + if (system_state != SYSTEM_RUNNING) { + printk("nmi_show_all_regs(): system state %d, not doing.\n", + system_state); + return; + } + + for_each_online_cpu(i) + nmi_show_regs[i] = 1; + for_each_online_cpu(i) + while (nmi_show_regs[i] == 1) + barrier(); +} +static DEFINE_RAW_SPINLOCK(nmi_print_lock); +void notrace nmi_watchdog_tick (struct pt_regs * regs) +{ /* * Since current_thread_info()-> is always on the stack, and we * always switch the stack NMI-atomically, it's safe to use @@ -488,14 +514,39 @@ sum = per_cpu(irq_stat, cpu).apic_timer_irqs; + profile_tick(CPU_PROFILING, regs); + if (nmi_show_regs[cpu]) { + nmi_show_regs[cpu] = 0; + spin_lock(&nmi_print_lock); + printk("NMI show regs on CPU#%d:\n", cpu); + show_regs(regs); + spin_unlock(&nmi_print_lock); + } + if (last_irq_sums[cpu] == sum) { /* * Ayiee, looks like this CPU is stuck ... * wait a few IRQs (5 seconds) before doing the oops ... */ alert_counter[cpu]++; - if (alert_counter[cpu] == 5*nmi_hz) + if (alert_counter[cpu] && !(alert_counter[cpu] % (5*nmi_hz))) { + int i; + + bust_spinlocks(1); + spin_lock(&nmi_print_lock); + printk("NMI watchdog detected lockup on CPU#%d (%d/%d)\n", cpu, alert_counter[cpu], 5*nmi_hz); + show_regs(regs); + spin_unlock(&nmi_print_lock); + + for_each_online_cpu(i) + if (i != cpu) + nmi_show_regs[i] = 1; + for_each_online_cpu(i) + while (nmi_show_regs[i] == 1) + barrier(); + die_nmi(regs, "NMI Watchdog detected LOCKUP"); + } } else { last_irq_sums[cpu] = sum; alert_counter[cpu] = 0; @@ -518,7 +569,7 @@ * other P6 variant */ apic_write(APIC_LVTPC, APIC_DM_NMI); } - wrmsr(nmi_perfctr_msr, -(cpu_khz/nmi_hz*1000), -1); + wrmsr(nmi_perfctr_msr, -(cpu_khz*1000/nmi_hz), -1); } } diff -urN linux-2.6.12-armirq/arch/i386/kernel/process.c linux-2.6.12-armirq-rt/arch/i386/kernel/process.c --- linux-2.6.12-armirq/arch/i386/kernel/process.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/process.c 2005-07-16 16:41:53.000000000 +0200 @@ -96,12 +96,13 @@ void default_idle(void) { if (!hlt_counter && boot_cpu_data.hlt_works_ok) { - local_irq_disable(); - if (!need_resched()) - safe_halt(); + raw_local_irq_disable(); + if (!need_resched() && !need_resched_delayed()) + raw_safe_halt(); else - local_irq_enable(); + raw_local_irq_enable(); } else { + raw_local_irq_enable(); cpu_relax(); } } @@ -115,7 +116,7 @@ { int oldval; - local_irq_enable(); + raw_local_irq_enable(); /* * Deal with another CPU just having chosen a thread to @@ -130,7 +131,7 @@ "testl %0, %1;" "rep; nop;" "je 2b;" - : : "i"(_TIF_NEED_RESCHED), "m" (current_thread_info()->flags)); + : : "i"(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED), "m" (current_thread_info()->flags)); clear_thread_flag(TIF_POLLING_NRFLAG); } else { @@ -148,7 +149,9 @@ { /* endless idle loop with no priority at all */ while (1) { - while (!need_resched()) { + BUG_ON(raw_irqs_disabled()); + + while (!need_resched() && !need_resched_delayed()) { void (*idle)(void); if (__get_cpu_var(cpu_idle_state)) @@ -161,9 +164,13 @@ idle = default_idle; __get_cpu_var(irq_stat).idle_timestamp = jiffies; + stop_critical_timing(); + propagate_preempt_locks_value(); idle(); } - schedule(); + raw_local_irq_disable(); + __schedule(); + raw_local_irq_enable(); } } @@ -204,16 +211,16 @@ */ static void mwait_idle(void) { - local_irq_enable(); + raw_local_irq_enable(); - if (!need_resched()) { + if (!need_resched() && !need_resched_delayed()) { set_thread_flag(TIF_POLLING_NRFLAG); do { __monitor((void *)¤t_thread_info()->flags, 0, 0); - if (need_resched()) + if (need_resched() || need_resched_delayed()) break; __mwait(0, 0); - } while (!need_resched()); + } while (!need_resched() && !need_resched_delayed()); clear_thread_flag(TIF_POLLING_NRFLAG); } } @@ -336,11 +343,16 @@ /* The process may have allocated an io port bitmap... nuke it. */ if (unlikely(NULL != t->io_bitmap_ptr)) { - int cpu = get_cpu(); - struct tss_struct *tss = &per_cpu(init_tss, cpu); + int cpu; + struct tss_struct *tss; + void *io_bitmap_ptr = t->io_bitmap_ptr; - kfree(t->io_bitmap_ptr); t->io_bitmap_ptr = NULL; + mb(); + kfree(io_bitmap_ptr); + + cpu = get_cpu(); + tss = &per_cpu(init_tss, cpu); /* * Careful, clear this in the TSS too: */ @@ -618,10 +630,10 @@ /* * Restore %fs and %gs if needed. */ - if (unlikely(prev->fs | prev->gs | next->fs | next->gs)) { + if (prev->fs | next->fs) loadsegment(fs, next->fs); + if (prev->gs | next->gs) loadsegment(gs, next->gs); - } /* * Now maybe reload the debug registers diff -urN linux-2.6.12-armirq/arch/i386/kernel/reboot.c linux-2.6.12-armirq-rt/arch/i386/kernel/reboot.c --- linux-2.6.12-armirq/arch/i386/kernel/reboot.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/reboot.c 2005-07-16 16:41:53.000000000 +0200 @@ -218,7 +218,7 @@ { unsigned long flags; - local_irq_disable(); + raw_local_irq_disable(); /* Write zero to CMOS register number 0x0f, which the BIOS POST routine will recognize as telling it to do a proper reboot. (Well diff -urN linux-2.6.12-armirq/arch/i386/kernel/semaphore.c linux-2.6.12-armirq-rt/arch/i386/kernel/semaphore.c --- linux-2.6.12-armirq/arch/i386/kernel/semaphore.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/semaphore.c 2005-07-16 16:41:53.000000000 +0200 @@ -16,6 +16,7 @@ #include #include #include +#include #include /* @@ -49,12 +50,12 @@ * we cannot lose wakeup events. */ -static fastcall void __attribute_used__ __up(struct semaphore *sem) +static fastcall void __attribute_used__ __compat_up(struct compat_semaphore *sem) { wake_up(&sem->wait); } -static fastcall void __attribute_used__ __sched __down(struct semaphore * sem) +static fastcall void __attribute_used__ __sched __compat_down(struct compat_semaphore * sem) { struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); @@ -91,7 +92,7 @@ tsk->state = TASK_RUNNING; } -static fastcall int __attribute_used__ __sched __down_interruptible(struct semaphore * sem) +static fastcall int __attribute_used__ __sched __compat_down_interruptible(struct compat_semaphore * sem) { int retval = 0; struct task_struct *tsk = current; @@ -154,7 +155,7 @@ * single "cmpxchg" without failure cases, * but then it wouldn't work on a 386. */ -static fastcall int __attribute_used__ __down_trylock(struct semaphore * sem) +static fastcall int __attribute_used__ __compat_down_trylock(struct compat_semaphore * sem) { int sleepers; unsigned long flags; @@ -190,15 +191,15 @@ asm( ".section .sched.text\n" ".align 4\n" -".globl __down_failed\n" -"__down_failed:\n\t" +".globl __compat_down_failed\n" +"__compat_down_failed:\n\t" #if defined(CONFIG_FRAME_POINTER) "pushl %ebp\n\t" "movl %esp,%ebp\n\t" #endif "pushl %edx\n\t" "pushl %ecx\n\t" - "call __down\n\t" + "call __compat_down\n\t" "popl %ecx\n\t" "popl %edx\n\t" #if defined(CONFIG_FRAME_POINTER) @@ -211,15 +212,15 @@ asm( ".section .sched.text\n" ".align 4\n" -".globl __down_failed_interruptible\n" -"__down_failed_interruptible:\n\t" +".globl __compat_down_failed_interruptible\n" +"__compat_down_failed_interruptible:\n\t" #if defined(CONFIG_FRAME_POINTER) "pushl %ebp\n\t" "movl %esp,%ebp\n\t" #endif "pushl %edx\n\t" "pushl %ecx\n\t" - "call __down_interruptible\n\t" + "call __compat_down_interruptible\n\t" "popl %ecx\n\t" "popl %edx\n\t" #if defined(CONFIG_FRAME_POINTER) @@ -232,15 +233,15 @@ asm( ".section .sched.text\n" ".align 4\n" -".globl __down_failed_trylock\n" -"__down_failed_trylock:\n\t" +".globl __compat_down_failed_trylock\n" +"__compat_down_failed_trylock:\n\t" #if defined(CONFIG_FRAME_POINTER) "pushl %ebp\n\t" "movl %esp,%ebp\n\t" #endif "pushl %edx\n\t" "pushl %ecx\n\t" - "call __down_trylock\n\t" + "call __compat_down_trylock\n\t" "popl %ecx\n\t" "popl %edx\n\t" #if defined(CONFIG_FRAME_POINTER) @@ -253,45 +254,20 @@ asm( ".section .sched.text\n" ".align 4\n" -".globl __up_wakeup\n" -"__up_wakeup:\n\t" +".globl __compat_up_wakeup\n" +"__compat_up_wakeup:\n\t" "pushl %edx\n\t" "pushl %ecx\n\t" - "call __up\n\t" + "call __compat_up\n\t" "popl %ecx\n\t" "popl %edx\n\t" "ret" ); -/* - * rw spinlock fallbacks - */ -#if defined(CONFIG_SMP) -asm( -".section .sched.text\n" -".align 4\n" -".globl __write_lock_failed\n" -"__write_lock_failed:\n\t" - LOCK "addl $" RW_LOCK_BIAS_STR ",(%eax)\n" -"1: rep; nop\n\t" - "cmpl $" RW_LOCK_BIAS_STR ",(%eax)\n\t" - "jne 1b\n\t" - LOCK "subl $" RW_LOCK_BIAS_STR ",(%eax)\n\t" - "jnz __write_lock_failed\n\t" - "ret" -); +int fastcall compat_sem_is_locked(struct compat_semaphore *sem) +{ + return (int) atomic_read(&sem->count) < 0; +} + +EXPORT_SYMBOL(compat_sem_is_locked); -asm( -".section .sched.text\n" -".align 4\n" -".globl __read_lock_failed\n" -"__read_lock_failed:\n\t" - LOCK "incl (%eax)\n" -"1: rep; nop\n\t" - "cmpl $1,(%eax)\n\t" - "js 1b\n\t" - LOCK "decl (%eax)\n\t" - "js __read_lock_failed\n\t" - "ret" -); -#endif diff -urN linux-2.6.12-armirq/arch/i386/kernel/signal.c linux-2.6.12-armirq-rt/arch/i386/kernel/signal.c --- linux-2.6.12-armirq/arch/i386/kernel/signal.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/signal.c 2005-07-16 16:41:53.000000000 +0200 @@ -593,6 +593,13 @@ int signr; struct k_sigaction ka; +#ifdef CONFIG_PREEMPT_RT + /* + * Fully-preemptible kernel does not need interrupts disabled: + */ + raw_local_irq_enable(); + preempt_check_resched(); +#endif /* * We want the common case to go fast, which * is why we may in certain cases get here from diff -urN linux-2.6.12-armirq/arch/i386/kernel/smp.c linux-2.6.12-armirq-rt/arch/i386/kernel/smp.c --- linux-2.6.12-armirq/arch/i386/kernel/smp.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/smp.c 2005-07-16 16:41:53.000000000 +0200 @@ -162,7 +162,7 @@ unsigned long cfg; unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); /* * Wait for idle. @@ -185,7 +185,7 @@ */ apic_write_around(APIC_ICR, cfg); - local_irq_restore(flags); + raw_local_irq_restore(flags); } void send_IPI_mask_sequence(cpumask_t mask, int vector) @@ -199,7 +199,7 @@ * should be modified to do 1 message per cluster ID - mbligh */ - local_irq_save(flags); + raw_local_irq_save(flags); for (query_cpu = 0; query_cpu < NR_CPUS; ++query_cpu) { if (cpu_isset(query_cpu, mask)) { @@ -226,7 +226,7 @@ apic_write_around(APIC_ICR, cfg); } } - local_irq_restore(flags); + raw_local_irq_restore(flags); } #include /* must come after the send_IPI functions above for inlining */ @@ -244,7 +244,7 @@ static cpumask_t flush_cpumask; static struct mm_struct * flush_mm; static unsigned long flush_va; -static DEFINE_SPINLOCK(tlbstate_lock); +static DEFINE_RAW_SPINLOCK(tlbstate_lock); #define FLUSH_ALL 0xffffffff /* @@ -389,7 +389,7 @@ while (!cpus_empty(flush_cpumask)) /* nothing. lockup detection does not belong here */ - mb(); + cpu_relax(); flush_mm = NULL; flush_va = 0; @@ -478,10 +478,20 @@ } /* + * this function sends a 'reschedule' IPI to all other CPUs. + * This is used when RT tasks are starving and other CPUs + * might be able to run them: + */ +void smp_send_reschedule_allbutself(void) +{ + send_IPI_allbutself(RESCHEDULE_VECTOR); +} + +/* * Structure and data for smp_call_function(). This is designed to minimise * static memory requirements. It also looks cleaner. */ -static DEFINE_SPINLOCK(call_lock); +static DEFINE_RAW_SPINLOCK(call_lock); struct call_data_struct { void (*func) (void *info); @@ -520,7 +530,7 @@ return 0; /* Can deadlock when called with interrupts disabled */ - WARN_ON(irqs_disabled()); + WARN_ON(raw_irqs_disabled()); data.func = func; data.info = info; @@ -554,7 +564,7 @@ * Remove this CPU: */ cpu_clear(smp_processor_id(), cpu_online_map); - local_irq_disable(); + raw_local_irq_disable(); disable_local_APIC(); if (cpu_data[smp_processor_id()].hlt_works_ok) for(;;) __asm__("hlt"); @@ -569,19 +579,20 @@ { smp_call_function(stop_this_cpu, NULL, 1, 0); - local_irq_disable(); + raw_local_irq_disable(); disable_local_APIC(); - local_irq_enable(); + raw_local_irq_enable(); } /* - * Reschedule call back. Nothing to do, - * all the work is done automatically when - * we return from the interrupt. + * Reschedule call back. Trigger a reschedule pass so that + * RT-overload balancing can pass tasks around. */ -fastcall void smp_reschedule_interrupt(struct pt_regs *regs) +fastcall notrace void smp_reschedule_interrupt(struct pt_regs *regs) { + trace_special(regs->eip, 0, 0); ack_APIC_irq(); + set_tsk_need_resched(current); } fastcall void smp_call_function_interrupt(struct pt_regs *regs) diff -urN linux-2.6.12-armirq/arch/i386/kernel/smpboot.c linux-2.6.12-armirq-rt/arch/i386/kernel/smpboot.c --- linux-2.6.12-armirq/arch/i386/kernel/smpboot.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/smpboot.c 2005-07-16 16:41:53.000000000 +0200 @@ -440,7 +440,7 @@ cpu_set(smp_processor_id(), cpu_online_map); /* We can take interrupts now: we're officially "up". */ - local_irq_enable(); + raw_local_irq_enable(); wmb(); cpu_idle(); @@ -1120,17 +1120,17 @@ { /* This only works at boot for x86. See "rewrite" above. */ if (cpu_isset(cpu, smp_commenced_mask)) { - local_irq_enable(); + raw_local_irq_enable(); return -ENOSYS; } /* In case one didn't come up */ if (!cpu_isset(cpu, cpu_callin_map)) { - local_irq_enable(); + raw_local_irq_enable(); return -EIO; } - local_irq_enable(); + raw_local_irq_enable(); /* Unleash the CPU! */ cpu_set(cpu, smp_commenced_mask); while (!cpu_isset(cpu, cpu_online_map)) diff -urN linux-2.6.12-armirq/arch/i386/kernel/time.c linux-2.6.12-armirq-rt/arch/i386/kernel/time.c --- linux-2.6.12-armirq/arch/i386/kernel/time.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/time.c 2005-07-16 16:41:53.000000000 +0200 @@ -68,7 +68,8 @@ #include "io_ports.h" -extern spinlock_t i8259A_lock; +#include + int pit_latch_buggy; /* extern */ #include "do_timer.h" @@ -81,9 +82,11 @@ extern unsigned long wall_jiffies; -DEFINE_SPINLOCK(rtc_lock); +DEFINE_RAW_SPINLOCK(rtc_lock); + +#include -DEFINE_SPINLOCK(i8253_lock); +DEFINE_RAW_SPINLOCK(i8253_lock); EXPORT_SYMBOL(i8253_lock); struct timer_opts *cur_timer = &timer_none; @@ -231,7 +234,7 @@ EXPORT_SYMBOL(monotonic_clock); #if defined(CONFIG_SMP) && defined(CONFIG_FRAME_POINTER) -unsigned long profile_pc(struct pt_regs *regs) +unsigned long notrace profile_pc(struct pt_regs *regs) { unsigned long pc = instruction_pointer(regs); @@ -252,17 +255,18 @@ { #ifdef CONFIG_X86_IO_APIC if (timer_ack) { + unsigned long flags; /* * Subtle, when I/O APICs are used we have to ack timer IRQ * manually to reset the IRR bit for do_slow_gettimeoffset(). * This will also deassert NMI lines for the watchdog if run * on an 82489DX-based system. */ - spin_lock(&i8259A_lock); + spin_lock_irqsave(&i8259A_lock, flags); outb(0x0c, PIC_MASTER_OCW3); /* Ack the IRQ; AEOI will end it automatically. */ inb(PIC_MASTER_POLL); - spin_unlock(&i8259A_lock); + spin_unlock_irqrestore(&i8259A_lock, flags); } #endif @@ -326,8 +330,7 @@ } static void sync_cmos_clock(unsigned long dummy); -static struct timer_list sync_cmos_timer = - TIMER_INITIALIZER(sync_cmos_clock, 0, 0); +static DEFINE_TIMER(sync_cmos_timer, sync_cmos_clock, 0, 0); static void sync_cmos_clock(unsigned long dummy) { @@ -405,6 +408,7 @@ write_sequnlock_irqrestore(&xtime_lock, flags); jiffies += sleep_length; wall_jiffies += sleep_length; + touch_softlockup_watchdog(); return 0; } diff -urN linux-2.6.12-armirq/arch/i386/kernel/timers/timer_cyclone.c linux-2.6.12-armirq-rt/arch/i386/kernel/timers/timer_cyclone.c --- linux-2.6.12-armirq/arch/i386/kernel/timers/timer_cyclone.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/timers/timer_cyclone.c 2005-07-16 16:41:53.000000000 +0200 @@ -17,9 +17,9 @@ #include #include #include -#include "io_ports.h" +#include -extern spinlock_t i8253_lock; +#include "io_ports.h" /* Number of usecs that the last interrupt was delayed */ static int delay_at_last_interrupt; @@ -36,7 +36,7 @@ static u32 last_cyclone_low; static u32 last_cyclone_high; static unsigned long long monotonic_base; -static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED; +static DECLARE_RAW_SEQLOCK(monotonic_lock); /* helper macro to atomically read both cyclone counter registers */ #define read_cyclone_counter(low,high) \ diff -urN linux-2.6.12-armirq/arch/i386/kernel/timers/timer_hpet.c linux-2.6.12-armirq-rt/arch/i386/kernel/timers/timer_hpet.c --- linux-2.6.12-armirq/arch/i386/kernel/timers/timer_hpet.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/timers/timer_hpet.c 2005-07-16 16:41:53.000000000 +0200 @@ -24,7 +24,7 @@ static unsigned long last_tsc_low; /* lsb 32 bits of Time Stamp Counter */ static unsigned long last_tsc_high; /* msb 32 bits of Time Stamp Counter */ static unsigned long long monotonic_base; -static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED; +static DECLARE_RAW_SEQLOCK(monotonic_lock); /* convert from cycles(64bits) => nanoseconds (64bits) * basic equation: diff -urN linux-2.6.12-armirq/arch/i386/kernel/timers/timer_pit.c linux-2.6.12-armirq-rt/arch/i386/kernel/timers/timer_pit.c --- linux-2.6.12-armirq/arch/i386/kernel/timers/timer_pit.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/timers/timer_pit.c 2005-07-16 16:41:53.000000000 +0200 @@ -15,9 +15,8 @@ #include #include #include +#include -extern spinlock_t i8259A_lock; -extern spinlock_t i8253_lock; #include "do_timer.h" #include "io_ports.h" @@ -166,7 +165,6 @@ void setup_pit_timer(void) { - extern spinlock_t i8253_lock; unsigned long flags; spin_lock_irqsave(&i8253_lock, flags); diff -urN linux-2.6.12-armirq/arch/i386/kernel/timers/timer_pm.c linux-2.6.12-armirq-rt/arch/i386/kernel/timers/timer_pm.c --- linux-2.6.12-armirq/arch/i386/kernel/timers/timer_pm.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/timers/timer_pm.c 2005-07-16 16:41:53.000000000 +0200 @@ -41,7 +41,7 @@ static u32 offset_delay; static unsigned long long monotonic_base; -static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED; +static DECLARE_RAW_SEQLOCK(monotonic_lock); #define ACPI_PM_MASK 0xFFFFFF /* limit it to 24 bits */ diff -urN linux-2.6.12-armirq/arch/i386/kernel/timers/timer_tsc.c linux-2.6.12-armirq-rt/arch/i386/kernel/timers/timer_tsc.c --- linux-2.6.12-armirq/arch/i386/kernel/timers/timer_tsc.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/timers/timer_tsc.c 2005-07-16 16:41:53.000000000 +0200 @@ -24,6 +24,7 @@ #include "mach_timer.h" #include +#include #ifdef CONFIG_HPET_TIMER static unsigned long hpet_usec_quotient; @@ -35,8 +36,6 @@ int tsc_disable __initdata = 0; -extern spinlock_t i8253_lock; - static int use_tsc; /* Number of usecs that the last interrupt was delayed */ static int delay_at_last_interrupt; @@ -44,7 +43,7 @@ static unsigned long last_tsc_low; /* lsb 32 bits of Time Stamp Counter */ static unsigned long last_tsc_high; /* msb 32 bits of Time Stamp Counter */ static unsigned long long monotonic_base; -static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED; +static DECLARE_RAW_SEQLOCK(monotonic_lock); /* convert from cycles(64bits) => nanoseconds (64bits) * basic equation: @@ -143,7 +142,7 @@ * synchronized across all CPUs. */ #ifndef CONFIG_NUMA - if (!use_tsc) + if (unlikely(!use_tsc)) #endif /* no locking but a rare wrong value is not a big deal */ return jiffies_64 * (1000000000 / HZ); @@ -171,9 +170,9 @@ static void mark_offset_tsc_hpet(void) { unsigned long long this_offset, last_offset; - unsigned long offset, temp, hpet_current; + unsigned long offset, temp, hpet_current, flags; - write_seqlock(&monotonic_lock); + write_seqlock_irqsave(&monotonic_lock, flags); last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; /* * It is important that these two operations happen almost at @@ -201,7 +200,7 @@ /* update the monotonic base value */ this_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; monotonic_base += cycles_2_ns(this_offset - last_offset); - write_sequnlock(&monotonic_lock); + write_sequnlock_irqrestore(&monotonic_lock, flags); /* calculate delay_at_last_interrupt */ /* @@ -342,7 +341,10 @@ static void mark_offset_tsc(void) { - unsigned long lost,delay; + unsigned long lost,delay, flags; +#ifndef CONFIG_PREEMPT_RT + unsigned long flags2; +#endif unsigned long delta = last_tsc_low; int count; int countmp; @@ -350,7 +352,7 @@ unsigned long long this_offset, last_offset; static int lost_count = 0; - write_seqlock(&monotonic_lock); + write_seqlock_irqsave(&monotonic_lock, flags); last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; /* * It is important that these two operations happen almost at @@ -368,24 +370,34 @@ rdtsc(last_tsc_low, last_tsc_high); - spin_lock(&i8253_lock); - outb_p(0x00, PIT_MODE); /* latch the count ASAP */ - - count = inb_p(PIT_CH0); /* read the latched count */ +#ifdef CONFIG_PREEMPT_RT + /* + * On PREEMPT_RT the timer IRQ never gets delayed by + * other interrupts, so we dont have to read the + * count: + */ + count = LATCH - 2; +#else + spin_lock_irqsave(&i8253_lock, flags2); + outb(0x00, PIT_MODE); /* latch the count ASAP */ + count = inb(PIT_CH0); /* read the latched count */ count |= inb(PIT_CH0) << 8; +# undef VIA686A_WORKAROUND /* * VIA686a test code... reset the latch if count > max + 1 * from timer_pit.c - cjb */ +# ifdef VIA686A_WORKAROUND if (count > LATCH) { outb_p(0x34, PIT_MODE); outb_p(LATCH & 0xff, PIT_CH0); outb(LATCH >> 8, PIT_CH0); count = LATCH - 1; } - - spin_unlock(&i8253_lock); +# endif + spin_unlock_irqrestore(&i8253_lock, flags2); +#endif /* PREEMPT_RT */ if (pit_latch_buggy) { /* get center value of last 3 time lutch */ @@ -438,7 +450,7 @@ /* update the monotonic base value */ this_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; monotonic_base += cycles_2_ns(this_offset - last_offset); - write_sequnlock(&monotonic_lock); + write_sequnlock_irqrestore(&monotonic_lock, flags); /* calculate delay_at_last_interrupt */ count = ((LATCH-1) - count) * TICK_SIZE; diff -urN linux-2.6.12-armirq/arch/i386/kernel/traps.c linux-2.6.12-armirq-rt/arch/i386/kernel/traps.c --- linux-2.6.12-armirq/arch/i386/kernel/traps.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/traps.c 2005-07-16 16:41:53.000000000 +0200 @@ -93,7 +93,7 @@ static int kstack_depth_to_print = 24; struct notifier_block *i386die_chain; -static DEFINE_SPINLOCK(die_notifier_lock); +static DEFINE_RAW_SPINLOCK(die_notifier_lock); int register_die_notifier(struct notifier_block *nb) { @@ -115,22 +115,27 @@ unsigned long *stack, unsigned long ebp) { unsigned long addr; +#ifndef CONFIG_FRAME_POINTER + unsigned long prev_frame; +#endif -#ifdef CONFIG_FRAME_POINTER +#ifdef CONFIG_FRAME_POINTER while (valid_stack_ptr(tinfo, (void *)ebp)) { addr = *(unsigned long *)(ebp + 4); printk(" [<%08lx>] ", addr); print_symbol("%s", addr); - printk("\n"); + printk(" (%ld)\n", *(unsigned long *)ebp - ebp); ebp = *(unsigned long *)ebp; } #else + prev_frame = (unsigned long)stack; while (valid_stack_ptr(tinfo, stack)) { addr = *stack++; if (__kernel_text_address(addr)) { printk(" [<%08lx>]", addr); print_symbol(" %s", addr); - printk("\n"); + printk(" (%ld)\n", (unsigned long)stack - prev_frame); + prev_frame = (unsigned long)stack; } } #endif @@ -162,6 +167,8 @@ break; printk(" =======================\n"); } + print_traces(task); + show_held_locks(task); } void show_stack(struct task_struct *task, unsigned long *esp) @@ -200,6 +207,12 @@ EXPORT_SYMBOL(dump_stack); +#if defined(CONFIG_DEBUG_STACKOVERFLOW) && defined(CONFIG_LATENCY_TRACE) +extern unsigned long worst_stack_left; +#else +# define worst_stack_left -1L +#endif + void show_registers(struct pt_regs *regs) { int i; @@ -224,10 +237,17 @@ regs->eax, regs->ebx, regs->ecx, regs->edx); printk("esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n", regs->esi, regs->edi, regs->ebp, esp); - printk("ds: %04x es: %04x ss: %04x\n", - regs->xds & 0xffff, regs->xes & 0xffff, ss); - printk("Process %s (pid: %d, threadinfo=%p task=%p)", + printk("ds: %04x es: %04x ss: %04x preempt: %08x\n", + regs->xds & 0xffff, regs->xes & 0xffff, ss, preempt_count()); + printk("Process %s (pid: %d, threadinfo=%p task=%p", current->comm, current->pid, current_thread_info(), current); + + if (in_kernel) + printk(" stack_left=%ld worst_left=%ld)", + (esp & (THREAD_SIZE-1))-sizeof(struct thread_info), + worst_stack_left); + else + printk(")"); /* * When in-kernel, we also print out the stack and code at the * time of the fault.. @@ -296,11 +316,11 @@ void die(const char * str, struct pt_regs * regs, long err) { static struct { - spinlock_t lock; + raw_spinlock_t lock; u32 lock_owner; int lock_owner_depth; } die = { - .lock = SPIN_LOCK_UNLOCKED, + .lock = RAW_SPIN_LOCK_UNLOCKED, .lock_owner = -1, .lock_owner_depth = 0 }; @@ -369,6 +389,11 @@ if (!(regs->xcs & 3)) goto kernel_trap; +#ifdef CONFIG_PREEMPT_RT + raw_local_irq_enable(); + preempt_check_resched(); +#endif + trap_signal: { struct task_struct *tsk = current; tsk->thread.error_code = error_code; @@ -497,7 +522,7 @@ return; gp_in_vm86: - local_irq_enable(); + raw_local_irq_enable(); handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code); return; @@ -551,10 +576,11 @@ printk("Do you have a strange power saving mode enabled?\n"); } -static DEFINE_SPINLOCK(nmi_print_lock); +static DEFINE_RAW_SPINLOCK(nmi_print_lock); void die_nmi (struct pt_regs *regs, const char *msg) { + deadlock_trace_off(); spin_lock(&nmi_print_lock); /* * We are in trouble anyway, lets at least try @@ -569,17 +595,19 @@ console_silent(); spin_unlock(&nmi_print_lock); bust_spinlocks(0); + nmi_exit(); do_exit(SIGSEGV); } -static void default_do_nmi(struct pt_regs * regs) +static void notrace default_do_nmi(struct pt_regs * regs) { unsigned char reason = 0; /* Only the BSP gets external NMIs from the system. */ if (!smp_processor_id()) reason = get_nmi_reason(); - + +// trace_special(6, 0, 0); if (!(reason & 0xc0)) { if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT) == NOTIFY_STOP) @@ -591,6 +619,7 @@ */ if (nmi_watchdog) { nmi_watchdog_tick(regs); +// trace_special(6, 1, 0); return; } #endif @@ -610,18 +639,19 @@ reassert_nmi(); } -static int dummy_nmi_callback(struct pt_regs * regs, int cpu) +static notrace int dummy_nmi_callback(struct pt_regs * regs, int cpu) { return 0; } static nmi_callback_t nmi_callback = dummy_nmi_callback; -fastcall void do_nmi(struct pt_regs * regs, long error_code) +fastcall notrace void do_nmi(struct pt_regs * regs, long error_code) { int cpu; nmi_enter(); + nmi_trace((unsigned long)do_nmi, regs->eip, regs->eflags); cpu = smp_processor_id(); ++nmi_count(cpu); @@ -689,7 +719,7 @@ return; /* It's safe to allow irq's after DR6 has been saved */ if (regs->eflags & X86_EFLAGS_IF) - local_irq_enable(); + raw_local_irq_enable(); /* Mask out spurious debug traps due to lazy DR7 setting */ if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) { diff -urN linux-2.6.12-armirq/arch/i386/kernel/vm86.c linux-2.6.12-armirq-rt/arch/i386/kernel/vm86.c --- linux-2.6.12-armirq/arch/i386/kernel/vm86.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/kernel/vm86.c 2005-07-16 16:41:53.000000000 +0200 @@ -105,9 +105,10 @@ * from process context. Enable interrupts here, before trying * to access user space. */ - local_irq_enable(); + raw_local_irq_enable(); if (!current->thread.vm86_info) { + raw_local_irq_disable(); printk("no vm86_info: BAD\n"); do_exit(SIGSEGV); } diff -urN linux-2.6.12-armirq/arch/i386/lib/bitops.c linux-2.6.12-armirq-rt/arch/i386/lib/bitops.c --- linux-2.6.12-armirq/arch/i386/lib/bitops.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/lib/bitops.c 2005-07-16 16:41:53.000000000 +0200 @@ -68,3 +68,37 @@ return (offset + set + res); } EXPORT_SYMBOL(find_next_zero_bit); + + +/* + * rw spinlock fallbacks + */ +#if defined(CONFIG_SMP) +asm( +".section .sched.text\n" +".align 4\n" +".globl __write_lock_failed\n" +"__write_lock_failed:\n\t" + LOCK "addl $" RW_LOCK_BIAS_STR ",(%eax)\n" +"1: rep; nop\n\t" + "cmpl $" RW_LOCK_BIAS_STR ",(%eax)\n\t" + "jne 1b\n\t" + LOCK "subl $" RW_LOCK_BIAS_STR ",(%eax)\n\t" + "jnz __write_lock_failed\n\t" + "ret" +); + +asm( +".section .sched.text\n" +".align 4\n" +".globl __read_lock_failed\n" +"__read_lock_failed:\n\t" + LOCK "incl (%eax)\n" +"1: rep; nop\n\t" + "cmpl $1,(%eax)\n\t" + "js 1b\n\t" + LOCK "decl (%eax)\n\t" + "js __read_lock_failed\n\t" + "ret" +); +#endif diff -urN linux-2.6.12-armirq/arch/i386/lib/dec_and_lock.c linux-2.6.12-armirq-rt/arch/i386/lib/dec_and_lock.c --- linux-2.6.12-armirq/arch/i386/lib/dec_and_lock.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/lib/dec_and_lock.c 2005-07-16 16:41:53.000000000 +0200 @@ -10,7 +10,7 @@ #include #include -int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) +int _atomic_dec_and_raw_spin_lock(atomic_t *atomic, raw_spinlock_t *lock) { int counter; int newcount; @@ -32,9 +32,9 @@ return 0; slow_path: - spin_lock(lock); + _raw_spin_lock(lock); if (atomic_dec_and_test(atomic)) return 1; - spin_unlock(lock); + _raw_spin_unlock(lock); return 0; } diff -urN linux-2.6.12-armirq/arch/i386/mach-default/setup.c linux-2.6.12-armirq-rt/arch/i386/mach-default/setup.c --- linux-2.6.12-armirq/arch/i386/mach-default/setup.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/mach-default/setup.c 2005-07-16 16:41:53.000000000 +0200 @@ -27,7 +27,7 @@ /* * IRQ2 is cascade interrupt to second interrupt controller */ -static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL}; +static struct irqaction irq2 = { no_action, SA_NODELAY, CPU_MASK_NONE, "cascade", NULL, NULL}; /** * intr_init_hook - post gate setup interrupt initialisation @@ -71,7 +71,7 @@ { } -static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL}; +static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT | SA_NODELAY, CPU_MASK_NONE, "timer", NULL, NULL}; /** * time_init_hook - do any specific initialisations for the system timer. diff -urN linux-2.6.12-armirq/arch/i386/mach-visws/setup.c linux-2.6.12-armirq-rt/arch/i386/mach-visws/setup.c --- linux-2.6.12-armirq/arch/i386/mach-visws/setup.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/mach-visws/setup.c 2005-07-16 16:41:53.000000000 +0200 @@ -112,7 +112,7 @@ static struct irqaction irq0 = { .handler = timer_interrupt, - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_NODELAY, .name = "timer", }; diff -urN linux-2.6.12-armirq/arch/i386/mach-visws/visws_apic.c linux-2.6.12-armirq-rt/arch/i386/mach-visws/visws_apic.c --- linux-2.6.12-armirq/arch/i386/mach-visws/visws_apic.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/mach-visws/visws_apic.c 2005-07-16 16:41:53.000000000 +0200 @@ -261,11 +261,13 @@ static struct irqaction master_action = { .handler = piix4_master_intr, .name = "PIIX4-8259", + .flags = SA_NODELAY, }; static struct irqaction cascade_action = { .handler = no_action, .name = "cascade", + .flags = SA_NODELAY, }; diff -urN linux-2.6.12-armirq/arch/i386/mach-voyager/setup.c linux-2.6.12-armirq-rt/arch/i386/mach-voyager/setup.c --- linux-2.6.12-armirq/arch/i386/mach-voyager/setup.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/mach-voyager/setup.c 2005-07-16 16:41:53.000000000 +0200 @@ -17,7 +17,7 @@ /* * IRQ2 is cascade interrupt to second interrupt controller */ -static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL}; +static struct irqaction irq2 = { no_action, SA_NODELAY, CPU_MASK_NONE, "cascade", NULL, NULL}; void __init intr_init_hook(void) { @@ -40,7 +40,7 @@ { } -static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL}; +static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT | SA_NODELAY, CPU_MASK_NONE, "timer", NULL, NULL}; void __init time_init_hook(void) { diff -urN linux-2.6.12-armirq/arch/i386/mach-voyager/voyager_basic.c linux-2.6.12-armirq-rt/arch/i386/mach-voyager/voyager_basic.c --- linux-2.6.12-armirq/arch/i386/mach-voyager/voyager_basic.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/mach-voyager/voyager_basic.c 2005-07-16 16:41:53.000000000 +0200 @@ -30,6 +30,7 @@ #include #include #include +#include /* * Power off function, if any @@ -182,7 +183,6 @@ * and swiftly introduce it to something sharp and * pointy. */ __u16 val; - extern spinlock_t i8253_lock; spin_lock(&i8253_lock); diff -urN linux-2.6.12-armirq/arch/i386/mm/fault.c linux-2.6.12-armirq-rt/arch/i386/mm/fault.c --- linux-2.6.12-armirq/arch/i386/mm/fault.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/mm/fault.c 2005-07-16 16:41:53.000000000 +0200 @@ -38,6 +38,8 @@ int loglevel_save = console_loglevel; if (yes) { + stop_trace(); + zap_rt_locks(); oops_in_progress = 1; return; } @@ -199,6 +201,18 @@ return 0; } +static void force_sig_info_fault(int si_signo, int si_code, + unsigned long address, struct task_struct *tsk) +{ + siginfo_t info; + + info.si_signo = si_signo; + info.si_errno = 0; + info.si_code = si_code; + info.si_addr = (void __user *)address; + force_sig_info(si_signo, &info, tsk); +} + fastcall void do_invalid_op(struct pt_regs *, unsigned long); /* @@ -211,29 +225,29 @@ * bit 1 == 0 means read, 1 means write * bit 2 == 0 means kernel, 1 means user-mode */ -fastcall void do_page_fault(struct pt_regs *regs, unsigned long error_code) +fastcall notrace void do_page_fault(struct pt_regs *regs, unsigned long error_code) { struct task_struct *tsk; struct mm_struct *mm; struct vm_area_struct * vma; unsigned long address; unsigned long page; - int write; - siginfo_t info; - + int write, si_code; + /* get the address */ __asm__("movl %%cr2,%0":"=r" (address)); + trace_special(regs->eip, error_code, address); if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14, SIGSEGV) == NOTIFY_STOP) return; /* It's safe to allow irq's after cr2 has been saved */ if (regs->eflags & (X86_EFLAGS_IF|VM_MASK)) - local_irq_enable(); + raw_local_irq_enable(); tsk = current; - info.si_code = SEGV_MAPERR; + si_code = SEGV_MAPERR; /* * We fault-in kernel-space virtual memory on-demand. The @@ -313,7 +327,7 @@ * we can handle it.. */ good_area: - info.si_code = SEGV_ACCERR; + si_code = SEGV_ACCERR; write = 0; switch (error_code & 3) { default: /* 3: write, present */ @@ -387,11 +401,7 @@ /* Kernel addresses are always protection faults */ tsk->thread.error_code = error_code | (address >= TASK_SIZE); tsk->thread.trap_no = 14; - info.si_signo = SIGSEGV; - info.si_errno = 0; - /* info.si_code has been set above */ - info.si_addr = (void __user *)address; - force_sig_info(SIGSEGV, &info, tsk); + force_sig_info_fault(SIGSEGV, si_code, address, tsk); return; } @@ -440,9 +450,9 @@ } #endif if (address < PAGE_SIZE) - printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference"); + printk(KERN_ALERT "BUG: Unable to handle kernel NULL pointer dereference"); else - printk(KERN_ALERT "Unable to handle kernel paging request"); + printk(KERN_ALERT "BUG: Unable to handle kernel paging request"); printk(" at virtual address %08lx\n",address); printk(KERN_ALERT " printing eip:\n"); printk("%08lx\n", regs->eip); @@ -497,11 +507,7 @@ tsk->thread.cr2 = address; tsk->thread.error_code = error_code; tsk->thread.trap_no = 14; - info.si_signo = SIGBUS; - info.si_errno = 0; - info.si_code = BUS_ADRERR; - info.si_addr = (void __user *)address; - force_sig_info(SIGBUS, &info, tsk); + force_sig_info_fault(SIGBUS, BUS_ADRERR, address, tsk); return; vmalloc_fault: diff -urN linux-2.6.12-armirq/arch/i386/mm/highmem.c linux-2.6.12-armirq-rt/arch/i386/mm/highmem.c --- linux-2.6.12-armirq/arch/i386/mm/highmem.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/mm/highmem.c 2005-07-16 16:41:53.000000000 +0200 @@ -17,6 +17,27 @@ kunmap_high(page); } +void kunmap_virt(void *ptr) +{ + struct page *page; + + if ((unsigned long)ptr < PKMAP_ADDR(0)) + return; + page = pte_page(pkmap_page_table[PKMAP_NR((unsigned long)ptr)]); + kunmap(page); +} + +struct page *kmap_to_page(void *ptr) +{ + struct page *page; + + if ((unsigned long)ptr < PKMAP_ADDR(0)) + return virt_to_page(ptr); + page = pte_page(pkmap_page_table[PKMAP_NR((unsigned long)ptr)]); + return page; +} + + /* * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because * no global lock is needed and because the kmap code must perform a global TLB @@ -25,7 +46,7 @@ * However when holding an atomic kmap is is not legal to sleep, so atomic * kmaps are appropriate for short, tight code paths only. */ -void *kmap_atomic(struct page *page, enum km_type type) +void *__kmap_atomic(struct page *page, enum km_type type) { enum fixed_addresses idx; unsigned long vaddr; @@ -47,7 +68,7 @@ return (void*) vaddr; } -void kunmap_atomic(void *kvaddr, enum km_type type) +void __kunmap_atomic(void *kvaddr, enum km_type type) { #ifdef CONFIG_DEBUG_HIGHMEM unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; @@ -74,7 +95,7 @@ preempt_check_resched(); } -struct page *kmap_atomic_to_page(void *ptr) +struct page *__kmap_atomic_to_page(void *ptr) { unsigned long idx, vaddr = (unsigned long)ptr; pte_t *pte; diff -urN linux-2.6.12-armirq/arch/i386/mm/init.c linux-2.6.12-armirq-rt/arch/i386/mm/init.c --- linux-2.6.12-armirq/arch/i386/mm/init.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/mm/init.c 2005-07-16 16:41:53.000000000 +0200 @@ -42,7 +42,7 @@ unsigned int __VMALLOC_RESERVE = 128 << 20; -DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); +DEFINE_PER_CPU_LOCKED(struct mmu_gather, mmu_gathers); unsigned long highstart_pfn, highend_pfn; static int noinline do_test_wp_bit(void); diff -urN linux-2.6.12-armirq/arch/i386/mm/pageattr.c linux-2.6.12-armirq-rt/arch/i386/mm/pageattr.c --- linux-2.6.12-armirq/arch/i386/mm/pageattr.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/mm/pageattr.c 2005-07-16 16:41:53.000000000 +0200 @@ -206,6 +206,9 @@ { if (PageHighMem(page)) return; + if (!enable) + check_no_locks_freed(page_address(page), page_address(page+numpages)); + /* the return value is ignored - the calls cannot fail, * large pages are disabled at boot time. */ diff -urN linux-2.6.12-armirq/arch/i386/mm/pgtable.c linux-2.6.12-armirq-rt/arch/i386/mm/pgtable.c --- linux-2.6.12-armirq/arch/i386/mm/pgtable.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/i386/mm/pgtable.c 2005-07-16 16:41:53.000000000 +0200 @@ -172,7 +172,7 @@ * recommendations and having no core impact whatsoever. * -- wli */ -DEFINE_SPINLOCK(pgd_lock); +DEFINE_RAW_SPINLOCK(pgd_lock); struct page *pgd_list; static inline void pgd_list_add(pgd_t *pgd) diff -urN linux-2.6.12-armirq/arch/ia64/kernel/perfmon.c linux-2.6.12-armirq-rt/arch/ia64/kernel/perfmon.c --- linux-2.6.12-armirq/arch/ia64/kernel/perfmon.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ia64/kernel/perfmon.c 2005-07-16 16:41:53.000000000 +0200 @@ -497,7 +497,7 @@ static pfm_stats_t pfm_stats[NR_CPUS]; static pfm_session_t pfm_sessions; /* global sessions information */ -static spinlock_t pfm_alt_install_check = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(pfm_alt_install_check); static pfm_intr_handler_desc_t *pfm_alt_intr_handler; static struct proc_dir_entry *perfmon_dir; diff -urN linux-2.6.12-armirq/arch/ia64/sn/kernel/xpnet.c linux-2.6.12-armirq-rt/arch/ia64/sn/kernel/xpnet.c --- linux-2.6.12-armirq/arch/ia64/sn/kernel/xpnet.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ia64/sn/kernel/xpnet.c 2005-07-16 16:41:53.000000000 +0200 @@ -130,7 +130,7 @@ */ static u64 xpnet_broadcast_partitions; /* protect above */ -static spinlock_t xpnet_broadcast_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(xpnet_broadcast_lock); /* * Since the Block Transfer Engine (BTE) is being used for the transfer diff -urN linux-2.6.12-armirq/arch/m68k/amiga/amisound.c linux-2.6.12-armirq-rt/arch/m68k/amiga/amisound.c --- linux-2.6.12-armirq/arch/m68k/amiga/amisound.c 2005-07-13 14:30:07.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/m68k/amiga/amisound.c 2005-07-16 16:41:53.000000000 +0200 @@ -63,7 +63,7 @@ } static void nosound( unsigned long ignored ); -static struct timer_list sound_timer = TIMER_INITIALIZER(nosound, 0, 0); +static DEFINE_TIMER(sound_timer, nosound, 0, 0); void amiga_mksound( unsigned int hz, unsigned int ticks ) { diff -urN linux-2.6.12-armirq/arch/m68k/mac/macboing.c linux-2.6.12-armirq-rt/arch/m68k/mac/macboing.c --- linux-2.6.12-armirq/arch/m68k/mac/macboing.c 2005-07-13 14:30:08.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/m68k/mac/macboing.c 2005-07-16 16:41:53.000000000 +0200 @@ -56,8 +56,7 @@ /* * our timer to start/continue/stop the bell */ -static struct timer_list mac_sound_timer = - TIMER_INITIALIZER(mac_nosound, 0, 0); +static DEFINE_TIMER(mac_sound_timer, mac_nosound, 0, 0); /* * Sort of initialize the sound chip (called from mac_mksound on the first diff -urN linux-2.6.12-armirq/arch/mips/Kconfig linux-2.6.12-armirq-rt/arch/mips/Kconfig --- linux-2.6.12-armirq/arch/mips/Kconfig 2005-07-13 14:30:08.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/mips/Kconfig 2005-07-16 16:41:53.000000000 +0200 @@ -308,6 +308,7 @@ config MOMENCO_OCELOT bool "Support for Momentum Ocelot board" select DMA_NONCOHERENT + select NO_SPINLOCK select HW_HAS_PCI select IRQ_CPU select IRQ_CPU_RM7K @@ -660,6 +661,7 @@ depends on EXPERIMENTAL select BOOT_ELF32 select DMA_COHERENT + select NO_SPINLOCK select SWAP_IO_SPACE choice @@ -903,12 +905,21 @@ bool "FPCIB0 Backplane Support" depends on TOSHIBA_RBTX4927 +source "lib/Kconfig.RT" + config RWSEM_GENERIC_SPINLOCK bool + depends on !PREEMPT_RT default y config RWSEM_XCHGADD_ALGORITHM bool + depends on !PREEMPT_RT + +config ASM_SEMAPHORES + bool + depends on !PREEMPT_RT + default y config GENERIC_CALIBRATE_DELAY bool @@ -929,6 +940,9 @@ config DMA_COHERENT bool +config NO_SPINLOCK + bool + config DMA_IP27 bool @@ -1453,15 +1467,6 @@ This is purely to save memory - each supported CPU adds approximately eight kilobytes to the kernel image. -config PREEMPT - bool "Preemptible Kernel" - help - This option reduces the latency of the kernel when reacting to - real-time or interactive events by allowing a low priority process to - be preempted even if it is in kernel mode executing a system call. - This allows applications to run more reliably even when the system is - under load. - config RTC_DS1742 bool "DS1742 BRAM/RTC support" depends on TOSHIBA_JMR3927 || TOSHIBA_RBTX4927 @@ -1476,10 +1481,6 @@ This will result in additional memory usage, so it is not recommended for normal users. -config RWSEM_GENERIC_SPINLOCK - bool - default y - endmenu menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)" diff -urN linux-2.6.12-armirq/arch/mips/kernel/Makefile linux-2.6.12-armirq-rt/arch/mips/kernel/Makefile --- linux-2.6.12-armirq/arch/mips/kernel/Makefile 2005-07-13 14:30:08.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/mips/kernel/Makefile 2005-07-16 16:41:53.000000000 +0200 @@ -5,7 +5,7 @@ extra-y := head.o init_task.o vmlinux.lds obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ - ptrace.o reset.o semaphore.o setup.o signal.o syscall.o \ + ptrace.o reset.o setup.o signal.o syscall.o \ time.o traps.o unaligned.o binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \ @@ -17,6 +17,8 @@ obj-$(CONFIG_MIPS64) += module-elf64.o endif +obj-$(CONFIG_ASM_SEMAPHORES) += semaphore.o + obj-$(CONFIG_CPU_R3000) += r2300_fpu.o r2300_switch.o obj-$(CONFIG_CPU_TX39XX) += r2300_fpu.o r2300_switch.o obj-$(CONFIG_CPU_TX49XX) += r4k_fpu.o r4k_switch.o diff -urN linux-2.6.12-armirq/arch/mips/kernel/entry.S linux-2.6.12-armirq-rt/arch/mips/kernel/entry.S --- linux-2.6.12-armirq/arch/mips/kernel/entry.S 2005-07-13 14:30:08.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/mips/kernel/entry.S 2005-07-16 16:41:53.000000000 +0200 @@ -48,6 +48,8 @@ #ifdef CONFIG_PREEMPT ENTRY(resume_kernel) + lw t0, kernel_preemption + beqz t0, restore_all lw t0, TI_PRE_COUNT($28) bnez t0, restore_all need_resched: @@ -57,12 +59,9 @@ LONG_L t0, PT_STATUS(sp) # Interrupts off? andi t0, 1 beqz t0, restore_all - li t0, PREEMPT_ACTIVE - sw t0, TI_PRE_COUNT($28) - local_irq_enable t0 - jal schedule - sw zero, TI_PRE_COUNT($28) local_irq_disable t0 + jal preempt_schedule_irq + sw zero, TI_PRE_COUNT($28) b need_resched #endif @@ -92,6 +91,7 @@ andi t0, a2, _TIF_NEED_RESCHED beqz t0, work_notifysig work_resched: + local_irq_enable t0 jal schedule local_irq_disable t0 # make sure need_resched and diff -urN linux-2.6.12-armirq/arch/mips/kernel/gdb-stub.c linux-2.6.12-armirq-rt/arch/mips/kernel/gdb-stub.c --- linux-2.6.12-armirq/arch/mips/kernel/gdb-stub.c 2005-07-13 14:30:08.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/mips/kernel/gdb-stub.c 2005-07-16 16:41:53.000000000 +0200 @@ -176,7 +176,7 @@ /* * spin locks for smp case */ -static spinlock_t kgdb_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(kgdb_lock); static spinlock_t kgdb_cpulock[NR_CPUS] = { [0 ... NR_CPUS-1] = SPIN_LOCK_UNLOCKED}; /* diff -urN linux-2.6.12-armirq/arch/mips/kernel/genrtc.c linux-2.6.12-armirq-rt/arch/mips/kernel/genrtc.c --- linux-2.6.12-armirq/arch/mips/kernel/genrtc.c 2005-07-13 14:30:08.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/mips/kernel/genrtc.c 2005-07-16 16:41:53.000000000 +0200 @@ -14,7 +14,7 @@ #include #include -static spinlock_t mips_rtc_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(mips_rtc_lock); unsigned int get_rtc_time(struct rtc_time *time) { diff -urN linux-2.6.12-armirq/arch/mips/kernel/i8259.c linux-2.6.12-armirq-rt/arch/mips/kernel/i8259.c --- linux-2.6.12-armirq/arch/mips/kernel/i8259.c 2005-07-13 14:34:11.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/mips/kernel/i8259.c 2005-07-16 16:41:53.000000000 +0200 @@ -31,7 +31,7 @@ * moves to arch independent land */ -spinlock_t i8259A_lock = SPIN_LOCK_UNLOCKED; +spinlock_t DEFINE_RAW_SPINLOCK(i8259A_lock); static void end_8259A_irq (unsigned int irq) { diff -urN linux-2.6.12-armirq/arch/mips/kernel/irq.c linux-2.6.12-armirq-rt/arch/mips/kernel/irq.c --- linux-2.6.12-armirq/arch/mips/kernel/irq.c 2005-07-13 14:30:08.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/mips/kernel/irq.c 2005-07-16 16:41:53.000000000 +0200 @@ -125,7 +125,10 @@ irq_desc[i].action = NULL; irq_desc[i].depth = 1; irq_desc[i].handler = &no_irq_type; - spin_lock_init(&irq_desc[i].lock); + raw_spin_lock_init(&irq_desc[i].lock); +#ifdef CONFIG_PREEMPT_HARDIRQS + irq_desc[i].thread = NULL; +#endif } arch_init_irq(); diff -urN linux-2.6.12-armirq/arch/mips/kernel/module.c linux-2.6.12-armirq-rt/arch/mips/kernel/module.c --- linux-2.6.12-armirq/arch/mips/kernel/module.c 2005-07-13 14:30:08.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/mips/kernel/module.c 2005-07-16 16:41:53.000000000 +0200 @@ -2,7 +2,7 @@ #include static LIST_HEAD(dbe_list); -static DEFINE_SPINLOCK(dbe_lock); +static DEFINE_RAW_SPINLOCK(dbe_lock); /* Given an address, look for it in the module exception tables. */ const struct exception_table_entry *search_module_dbetables(unsigned long addr) diff -urN linux-2.6.12-armirq/arch/mips/kernel/process.c linux-2.6.12-armirq-rt/arch/mips/kernel/process.c --- linux-2.6.12-armirq/arch/mips/kernel/process.c 2005-07-13 14:30:08.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/mips/kernel/process.c 2005-07-16 16:41:53.000000000 +0200 @@ -58,6 +58,7 @@ while (!need_resched()) if (cpu_wait) (*cpu_wait)(); + local_irq_enable(); schedule(); } } diff -urN linux-2.6.12-armirq/arch/mips/kernel/semaphore.c linux-2.6.12-armirq-rt/arch/mips/kernel/semaphore.c --- linux-2.6.12-armirq/arch/mips/kernel/semaphore.c 2005-07-13 14:30:08.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/mips/kernel/semaphore.c 2005-07-16 16:41:53.000000000 +0200 @@ -63,7 +63,7 @@ : "=&r" (old_count), "=&r" (tmp), "=m" (sem->count) : "r" (incr), "m" (sem->count)); } else { - static DEFINE_SPINLOCK(semaphore_lock); + static DEFINE_RAW_SPINLOCK(semaphore_lock); unsigned long flags; spin_lock_irqsave(&semaphore_lock, flags); diff -urN linux-2.6.12-armirq/arch/mips/kernel/signal.c linux-2.6.12-armirq-rt/arch/mips/kernel/signal.c --- linux-2.6.12-armirq/arch/mips/kernel/signal.c 2005-07-13 14:30:08.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/mips/kernel/signal.c 2005-07-16 16:41:53.000000000 +0200 @@ -449,6 +449,10 @@ } #endif +#ifdef CONFIG_PREEMPT_RT + local_irq_enable(); + preempt_check_resched(); +#endif /* * We want the common case to go fast, which is why we may in certain * cases get here from kernel mode. Just return without doing anything diff -urN linux-2.6.12-armirq/arch/mips/kernel/signal32.c linux-2.6.12-armirq-rt/arch/mips/kernel/signal32.c --- linux-2.6.12-armirq/arch/mips/kernel/signal32.c 2005-07-13 14:30:08.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/mips/kernel/signal32.c 2005-07-16 16:41:53.000000000 +0200 @@ -766,6 +766,10 @@ siginfo_t info; int signr; +#ifdef CONFIG_PREEMPT_RT + local_irq_enable(); + preempt_check_resched(); +#endif /* * We want the common case to go fast, which is why we may in certain * cases get here from kernel mode. Just return without doing anything diff -urN linux-2.6.12-armirq/arch/mips/kernel/smp.c linux-2.6.12-armirq-rt/arch/mips/kernel/smp.c --- linux-2.6.12-armirq/arch/mips/kernel/smp.c 2005-07-13 14:30:08.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/mips/kernel/smp.c 2005-07-16 16:41:53.000000000 +0200 @@ -105,7 +105,22 @@ cpu_idle(); } -DEFINE_SPINLOCK(smp_call_lock); +DEFINE_RAW_SPINLOCK(smp_call_lock); + +/* + * this function sends a 'reschedule' IPI to all other CPUs. + * This is used when RT tasks are starving and other CPUs + * might be able to run them. + */ +void smp_send_reschedule_allbutself(void) +{ + int cpu = smp_processor_id(); + int i; + + for (i = 0; i < NR_CPUS; i++) + if (cpu_online(i) && i != cpu) + core_send_ipi(i, SMP_RESCHEDULE_YOURSELF); +} struct call_data_struct *call_data; @@ -284,6 +299,8 @@ return 0; } +static DEFINE_RAW_SPINLOCK(tlbstate_lock); + static void flush_tlb_all_ipi(void *info) { local_flush_tlb_all(); @@ -315,6 +332,7 @@ void flush_tlb_mm(struct mm_struct *mm) { preempt_disable(); + spin_lock(&tlbstate_lock); if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) { smp_call_function(flush_tlb_mm_ipi, (void *)mm, 1, 1); @@ -324,6 +342,7 @@ if (smp_processor_id() != i) cpu_context(i, mm) = 0; } + spin_unlock(&tlbstate_lock); local_flush_tlb_mm(mm); preempt_enable(); @@ -347,6 +366,8 @@ struct mm_struct *mm = vma->vm_mm; preempt_disable(); + spin_lock(&tlbstate_lock); + if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) { struct flush_tlb_data fd; @@ -360,6 +381,7 @@ if (smp_processor_id() != i) cpu_context(i, mm) = 0; } + spin_unlock(&tlbstate_lock); local_flush_tlb_range(vma, start, end); preempt_enable(); } @@ -390,6 +412,8 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) { preempt_disable(); + spin_lock(&tlbstate_lock); + if ((atomic_read(&vma->vm_mm->mm_users) != 1) || (current->mm != vma->vm_mm)) { struct flush_tlb_data fd; @@ -402,6 +426,7 @@ if (smp_processor_id() != i) cpu_context(i, vma->vm_mm) = 0; } + spin_unlock(&tlbstate_lock); local_flush_tlb_page(vma, page); preempt_enable(); } diff -urN linux-2.6.12-armirq/arch/mips/kernel/time.c linux-2.6.12-armirq-rt/arch/mips/kernel/time.c --- linux-2.6.12-armirq/arch/mips/kernel/time.c 2005-07-13 14:30:08.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/mips/kernel/time.c 2005-07-16 16:41:53.000000000 +0200 @@ -52,7 +52,7 @@ */ extern volatile unsigned long wall_jiffies; -DEFINE_SPINLOCK(rtc_lock); +DEFINE_RAW_SPINLOCK(rtc_lock); /* * By default we provide the null RTC ops @@ -555,7 +555,7 @@ static struct irqaction timer_irqaction = { .handler = timer_interrupt, - .flags = SA_INTERRUPT, + .flags = SA_NODELAY | SA_INTERRUPT, .name = "timer", }; diff -urN linux-2.6.12-armirq/arch/mips/kernel/traps.c linux-2.6.12-armirq-rt/arch/mips/kernel/traps.c --- linux-2.6.12-armirq/arch/mips/kernel/traps.c 2005-07-13 14:30:08.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/mips/kernel/traps.c 2005-07-16 16:41:53.000000000 +0200 @@ -250,7 +250,7 @@ printk("\n"); } -static DEFINE_SPINLOCK(die_lock); +static DEFINE_RAW_SPINLOCK(die_lock); NORET_TYPE void __die(const char * str, struct pt_regs * regs, const char * file, const char * func, unsigned long line) diff -urN linux-2.6.12-armirq/arch/mips/lib/dec_and_lock.c linux-2.6.12-armirq-rt/arch/mips/lib/dec_and_lock.c --- linux-2.6.12-armirq/arch/mips/lib/dec_and_lock.c 2005-07-13 14:30:08.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/mips/lib/dec_and_lock.c 2005-07-16 16:41:53.000000000 +0200 @@ -28,7 +28,7 @@ */ #ifndef ATOMIC_DEC_AND_LOCK -int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) +int _atomic_dec_and_raw_spin_lock(atomic_t *atomic, raw_spinlock_t *lock) { int counter; int newcount; @@ -44,12 +44,12 @@ return 0; } - spin_lock(lock); + _raw_spin_lock(lock); if (atomic_dec_and_test(atomic)) return 1; - spin_unlock(lock); + _raw_spin_unlock(lock); return 0; } -EXPORT_SYMBOL(_atomic_dec_and_lock); +EXPORT_SYMBOL(_atomic_dec_and_raw_spin_lock); #endif /* ATOMIC_DEC_AND_LOCK */ diff -urN linux-2.6.12-armirq/arch/mips/math-emu/cp1emu.c linux-2.6.12-armirq-rt/arch/mips/math-emu/cp1emu.c --- linux-2.6.12-armirq/arch/mips/math-emu/cp1emu.c 2005-07-13 14:30:08.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/mips/math-emu/cp1emu.c 2005-07-16 16:41:53.000000000 +0200 @@ -1310,7 +1310,9 @@ if (sig) break; + preempt_enable(); cond_resched(); + preempt_disable(); } while (xcp->cp0_epc > prevepc); /* SIGILL indicates a non-fpu instruction */ diff -urN linux-2.6.12-armirq/arch/mips/sibyte/sb1250/irq.c linux-2.6.12-armirq-rt/arch/mips/sibyte/sb1250/irq.c --- linux-2.6.12-armirq/arch/mips/sibyte/sb1250/irq.c 2005-07-13 14:34:11.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/mips/sibyte/sb1250/irq.c 2005-07-16 16:41:53.000000000 +0200 @@ -86,7 +86,7 @@ /* Store the CPU id (not the logical number) */ int sb1250_irq_owner[SB1250_NR_IRQS]; -DEFINE_SPINLOCK(sb1250_imr_lock); +DEFINE_RAW_SPINLOCK(sb1250_imr_lock); void sb1250_mask_irq(int cpu, int irq) { @@ -274,7 +274,7 @@ static struct irqaction sb1250_dummy_action = { .handler = sb1250_dummy_handler, - .flags = 0, + .flags = SA_NODELAY, .mask = CPU_MASK_NONE, .name = "sb1250-private", .next = NULL, diff -urN linux-2.6.12-armirq/arch/mips/sibyte/sb1250/time.c linux-2.6.12-armirq-rt/arch/mips/sibyte/sb1250/time.c --- linux-2.6.12-armirq/arch/mips/sibyte/sb1250/time.c 2005-07-13 14:30:08.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/mips/sibyte/sb1250/time.c 2005-07-16 16:41:53.000000000 +0200 @@ -115,10 +115,12 @@ ll_timer_interrupt(irq, regs); } - /* - * every CPU should do profiling and process accouting - */ - ll_local_timer_interrupt(irq, regs); + if (cpu != 0) { + /* + * every CPU should do profiling and process accouting + */ + ll_local_timer_interrupt(irq, regs); + } } /* diff -urN linux-2.6.12-armirq/arch/ppc/8260_io/enet.c linux-2.6.12-armirq-rt/arch/ppc/8260_io/enet.c --- linux-2.6.12-armirq/arch/ppc/8260_io/enet.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/8260_io/enet.c 2005-07-16 16:41:53.000000000 +0200 @@ -116,7 +116,7 @@ scc_t *sccp; struct net_device_stats stats; uint tx_full; - spinlock_t lock; + raw_spinlock_t lock; }; static int scc_enet_open(struct net_device *dev); diff -urN linux-2.6.12-armirq/arch/ppc/8260_io/fcc_enet.c linux-2.6.12-armirq-rt/arch/ppc/8260_io/fcc_enet.c --- linux-2.6.12-armirq/arch/ppc/8260_io/fcc_enet.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/8260_io/fcc_enet.c 2005-07-16 16:41:53.000000000 +0200 @@ -377,7 +377,7 @@ volatile fcc_enet_t *ep; struct net_device_stats stats; uint tx_free; - spinlock_t lock; + raw_spinlock_t lock; #ifdef CONFIG_USE_MDIO uint phy_id; diff -urN linux-2.6.12-armirq/arch/ppc/8xx_io/commproc.c linux-2.6.12-armirq-rt/arch/ppc/8xx_io/commproc.c --- linux-2.6.12-armirq/arch/ppc/8xx_io/commproc.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/8xx_io/commproc.c 2005-07-16 16:41:53.000000000 +0200 @@ -372,7 +372,7 @@ /* * dpalloc / dpfree bits. */ -static spinlock_t cpm_dpmem_lock; +static raw_spinlock_t cpm_dpmem_lock; /* * 16 blocks should be enough to satisfy all requests * until the memory subsystem goes up... diff -urN linux-2.6.12-armirq/arch/ppc/8xx_io/cs4218_tdm.c linux-2.6.12-armirq-rt/arch/ppc/8xx_io/cs4218_tdm.c --- linux-2.6.12-armirq/arch/ppc/8xx_io/cs4218_tdm.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/8xx_io/cs4218_tdm.c 2005-07-16 16:41:53.000000000 +0200 @@ -1380,7 +1380,7 @@ spin_unlock_irqrestore(&cs4218_lock, flags); } -static struct timer_list beep_timer = TIMER_INITIALIZER(cs_nosound, 0, 0); +static DEFINE_TIMER(beep_timer, cs_nosound, 0, 0); }; static void cs_mksound(unsigned int hz, unsigned int ticks) diff -urN linux-2.6.12-armirq/arch/ppc/8xx_io/enet.c linux-2.6.12-armirq-rt/arch/ppc/8xx_io/enet.c --- linux-2.6.12-armirq/arch/ppc/8xx_io/enet.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/8xx_io/enet.c 2005-07-16 16:41:53.000000000 +0200 @@ -144,7 +144,7 @@ unsigned char *rx_vaddr[RX_RING_SIZE]; struct net_device_stats stats; uint tx_full; - spinlock_t lock; + raw_spinlock_t lock; }; static int scc_enet_open(struct net_device *dev); diff -urN linux-2.6.12-armirq/arch/ppc/8xx_io/fec.c linux-2.6.12-armirq-rt/arch/ppc/8xx_io/fec.c --- linux-2.6.12-armirq/arch/ppc/8xx_io/fec.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/8xx_io/fec.c 2005-07-16 16:41:53.000000000 +0200 @@ -165,7 +165,7 @@ struct net_device_stats stats; uint tx_full; - spinlock_t lock; + raw_spinlock_t lock; #ifdef CONFIG_USE_MDIO uint phy_id; diff -urN linux-2.6.12-armirq/arch/ppc/Kconfig linux-2.6.12-armirq-rt/arch/ppc/Kconfig --- linux-2.6.12-armirq/arch/ppc/Kconfig 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/Kconfig 2005-07-16 16:41:53.000000000 +0200 @@ -17,9 +17,16 @@ config RWSEM_GENERIC_SPINLOCK bool + depends on !PREEMPT_RT + +config ASM_SEMAPHORES + bool + depends on !PREEMPT_RT + default y config RWSEM_XCHGADD_ALGORITHM bool + depends on !RWSEM_GENERIC_SPINLOCK && !PREEMPT_RT default y config GENERIC_CALIBRATE_DELAY @@ -897,15 +904,7 @@ depends on SMP default "4" -config PREEMPT - bool "Preemptible Kernel" - help - This option reduces the latency of the kernel when reacting to - real-time or interactive events by allowing a low priority process to - be preempted even if it is in kernel mode executing a system call. - - Say Y here if you are building a kernel for a desktop, embedded - or real-time system. Say N if you are unsure. +source "lib/Kconfig.RT" config HIGHMEM bool "High memory support" diff -urN linux-2.6.12-armirq/arch/ppc/boot/Makefile linux-2.6.12-armirq-rt/arch/ppc/boot/Makefile --- linux-2.6.12-armirq/arch/ppc/boot/Makefile 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/boot/Makefile 2005-07-16 16:41:53.000000000 +0200 @@ -11,6 +11,15 @@ # CFLAGS += -fno-builtin -D__BOOTER__ -Iarch/$(ARCH)/boot/include + +ifdef CONFIG_MCOUNT +# do not trace the boot loader +nullstring := +space := $(nullstring) # end of the line +pg_flag = $(nullstring) -pg # end of the line +CFLAGS := $(subst ${pg_flag},${space},${CFLAGS}) +endif + HOSTCFLAGS += -Iarch/$(ARCH)/boot/include BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd diff -urN linux-2.6.12-armirq/arch/ppc/kernel/Makefile linux-2.6.12-armirq-rt/arch/ppc/kernel/Makefile --- linux-2.6.12-armirq/arch/ppc/kernel/Makefile 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/kernel/Makefile 2005-07-16 16:41:53.000000000 +0200 @@ -14,8 +14,9 @@ obj-y := entry.o traps.o irq.o idle.o time.o misc.o \ process.o signal.o ptrace.o align.o \ - semaphore.o syscalls.o setup.o \ + syscalls.o setup.o \ cputable.o ppc_htab.o perfmon.o +obj-$(CONFIG_ASM_SEMAPHORES) += semaphore.o obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o obj-$(CONFIG_POWER4) += cpu_setup_power4.o diff -urN linux-2.6.12-armirq/arch/ppc/kernel/dma-mapping.c linux-2.6.12-armirq-rt/arch/ppc/kernel/dma-mapping.c --- linux-2.6.12-armirq/arch/ppc/kernel/dma-mapping.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/kernel/dma-mapping.c 2005-07-16 16:41:53.000000000 +0200 @@ -71,7 +71,7 @@ * This is the page table (2MB) covering uncached, DMA consistent allocations */ static pte_t *consistent_pte; -static DEFINE_SPINLOCK(consistent_lock); +static DEFINE_RAW_SPINLOCK(consistent_lock); /* * VM region handling support. diff -urN linux-2.6.12-armirq/arch/ppc/kernel/entry.S linux-2.6.12-armirq-rt/arch/ppc/kernel/entry.S --- linux-2.6.12-armirq/arch/ppc/kernel/entry.S 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/kernel/entry.S 2005-07-16 16:41:53.000000000 +0200 @@ -1026,3 +1026,85 @@ /* XXX load up BATs and panic */ #endif /* CONFIG_PPC_OF */ + +#ifdef CONFIG_MCOUNT + +/* + * mcount() is not the same as _mcount(). The callers of mcount() have a + * normal context. The callers of _mcount() do not have a stack frame and + * have not saved the "caller saves" registers. + */ +_GLOBAL(mcount) + stwu r1,-16(r1) + mflr r3 + lis r5,mcount_enabled@ha + lwz r5,mcount_enabled@l(r5) + stw r3,20(r1) + cmpwi r5,0 + beq 1f + /* r3 contains lr (eip), put parent lr (parent_eip) in r4 */ + lwz r4,16(r1) + lwz r4,4(r4) + bl __trace +1: + lwz r0,20(r1) + mtlr r0 + addi r1,r1,16 + blr + +/* + * The -pg flag, which is specified in the case of CONFIG_MCOUNT, causes the + * C compiler to add a call to _mcount() at the start of each function preamble, + * before the stack frame is created. An example of this preamble code is: + * + * mflr r0 + * lis r12,-16354 + * stw r0,4(r1) + * addi r0,r12,-19652 + * bl 0xc00034c8 <_mcount> + * mflr r0 + * stwu r1,-16(r1) + */ +_GLOBAL(_mcount) +#define M_STK_SIZE 48 + /* Would not expect to need to save cr, but glibc version of */ + /* _mcount() does, so cautiously saving it here too. */ + stwu r1,-M_STK_SIZE(r1) + stw r3, 12(r1) + stw r4, 16(r1) + stw r5, 20(r1) + stw r6, 24(r1) + mflr r3 /* will use as first arg to __trace() */ + mfcr r4 + lis r5,mcount_enabled@ha + lwz r5,mcount_enabled@l(r5) + cmpwi r5,0 + stw r3, 44(r1) /* lr */ + stw r4, 8(r1) /* cr */ + stw r7, 28(r1) + stw r8, 32(r1) + stw r9, 36(r1) + stw r10,40(r1) + beq 1f + /* r3 contains lr (eip), put parent lr (parent_eip) in r4 */ + lwz r4,M_STK_SIZE+4(r1) + bl __trace +1: + lwz r8, 8(r1) /* cr */ + lwz r9, 44(r1) /* lr */ + lwz r3, 12(r1) + lwz r4, 16(r1) + lwz r5, 20(r1) + mtcrf 0xff,r8 + mtctr r9 + lwz r0, 52(r1) + lwz r6, 24(r1) + lwz r7, 28(r1) + lwz r8, 32(r1) + lwz r9, 36(r1) + lwz r10,40(r1) + addi r1,r1,M_STK_SIZE + mtlr r0 + bctr + +#endif /* CONFIG_MCOUNT */ diff -urN linux-2.6.12-armirq/arch/ppc/kernel/ppc_ksyms.c linux-2.6.12-armirq-rt/arch/ppc/kernel/ppc_ksyms.c --- linux-2.6.12-armirq/arch/ppc/kernel/ppc_ksyms.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/kernel/ppc_ksyms.c 2005-07-16 16:41:53.000000000 +0200 @@ -295,9 +295,11 @@ EXPORT_SYMBOL(xmon); EXPORT_SYMBOL(xmon_printf); #endif -EXPORT_SYMBOL(__up); -EXPORT_SYMBOL(__down); -EXPORT_SYMBOL(__down_interruptible); +#ifdef CONFIG_ASM_SEMAPHORES +EXPORT_SYMBOL(__compat_up); +EXPORT_SYMBOL(__compat_down); +EXPORT_SYMBOL(__compat_down_interruptible); +#endif #if defined(CONFIG_KGDB) || defined(CONFIG_XMON) extern void (*debugger)(struct pt_regs *regs); diff -urN linux-2.6.12-armirq/arch/ppc/kernel/semaphore.c linux-2.6.12-armirq-rt/arch/ppc/kernel/semaphore.c --- linux-2.6.12-armirq/arch/ppc/kernel/semaphore.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/kernel/semaphore.c 2005-07-16 16:41:53.000000000 +0200 @@ -29,7 +29,7 @@ * sem->count = tmp; * return old_count; */ -static inline int __sem_update_count(struct semaphore *sem, int incr) +static inline int __sem_update_count(struct compat_semaphore *sem, int incr) { int old_count, tmp; @@ -48,7 +48,7 @@ return old_count; } -void __up(struct semaphore *sem) +void __compat_up(struct compat_semaphore *sem) { /* * Note that we incremented count in up() before we came here, @@ -70,7 +70,7 @@ * Thus it is only when we decrement count from some value > 0 * that we have actually got the semaphore. */ -void __sched __down(struct semaphore *sem) +void __sched __compat_down(struct compat_semaphore *sem) { struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); @@ -100,7 +100,7 @@ wake_up(&sem->wait); } -int __sched __down_interruptible(struct semaphore * sem) +int __sched __compat_down_interruptible(struct compat_semaphore * sem) { int retval = 0; struct task_struct *tsk = current; @@ -129,3 +129,8 @@ wake_up(&sem->wait); return retval; } + +int compat_sem_is_locked(struct compat_semaphore *sem) +{ + return (int) atomic_read(&sem->count) < 0; +} diff -urN linux-2.6.12-armirq/arch/ppc/kernel/smp.c linux-2.6.12-armirq-rt/arch/ppc/kernel/smp.c --- linux-2.6.12-armirq/arch/ppc/kernel/smp.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/kernel/smp.c 2005-07-16 16:41:53.000000000 +0200 @@ -137,6 +137,11 @@ smp_message_pass(cpu, PPC_MSG_RESCHEDULE, 0, 0); } +void smp_send_reschedule_allbutself(void) +{ + smp_message_pass(MSG_ALL_BUT_SELF, PPC_MSG_RESCHEDULE, 0, 0); +} + #ifdef CONFIG_XMON void smp_send_xmon_break(int cpu) { @@ -161,7 +166,7 @@ * static memory requirements. It also looks cleaner. * Stolen from the i386 version. */ -static DEFINE_SPINLOCK(call_lock); +static DEFINE_RAW_SPINLOCK(call_lock); static struct call_data_struct { void (*func) (void *info); diff -urN linux-2.6.12-armirq/arch/ppc/kernel/time.c linux-2.6.12-armirq-rt/arch/ppc/kernel/time.c --- linux-2.6.12-armirq/arch/ppc/kernel/time.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/kernel/time.c 2005-07-16 16:41:53.000000000 +0200 @@ -86,10 +86,11 @@ unsigned tb_to_us; unsigned tb_last_stamp; unsigned long tb_to_ns_scale; +unsigned long cpu_khz; extern unsigned long wall_jiffies; -DEFINE_SPINLOCK(rtc_lock); +DEFINE_RAW_SPINLOCK(rtc_lock); EXPORT_SYMBOL(rtc_lock); @@ -293,6 +294,7 @@ tb_ticks_per_jiffy = DECREMENTER_COUNT_601; /* mulhwu_scale_factor(1000000000, 1000000) is 0x418937 */ tb_to_us = 0x418937; + cpu_khz = 1000000000 / 1000; } else { ppc_md.calibrate_decr(); tb_to_ns_scale = mulhwu(tb_to_us, 1000 << 10); diff -urN linux-2.6.12-armirq/arch/ppc/kernel/traps.c linux-2.6.12-armirq-rt/arch/ppc/kernel/traps.c --- linux-2.6.12-armirq/arch/ppc/kernel/traps.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/kernel/traps.c 2005-07-16 16:41:53.000000000 +0200 @@ -72,7 +72,7 @@ * Trap & Exception support */ -DEFINE_SPINLOCK(die_lock); +DEFINE_RAW_SPINLOCK(die_lock); void die(const char * str, struct pt_regs * fp, long err) { diff -urN linux-2.6.12-armirq/arch/ppc/lib/dec_and_lock.c linux-2.6.12-armirq-rt/arch/ppc/lib/dec_and_lock.c --- linux-2.6.12-armirq/arch/ppc/lib/dec_and_lock.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/lib/dec_and_lock.c 2005-07-16 16:41:53.000000000 +0200 @@ -19,7 +19,7 @@ */ #ifndef ATOMIC_DEC_AND_LOCK -int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) +int _atomic_dec_and_raw_spin_lock(atomic_t *atomic, raw_spinlock_t *lock) { int counter; int newcount; @@ -35,12 +35,12 @@ return 0; } - spin_lock(lock); + _raw_spin_lock(lock); if (atomic_dec_and_test(atomic)) return 1; - spin_unlock(lock); + _raw_spin_unlock(lock); return 0; } -EXPORT_SYMBOL(_atomic_dec_and_lock); +EXPORT_SYMBOL(_atomic_dec_and_raw_spin_lock); #endif /* ATOMIC_DEC_AND_LOCK */ diff -urN linux-2.6.12-armirq/arch/ppc/lib/locks.c linux-2.6.12-armirq-rt/arch/ppc/lib/locks.c --- linux-2.6.12-armirq/arch/ppc/lib/locks.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/lib/locks.c 2005-07-16 16:41:53.000000000 +0200 @@ -43,7 +43,7 @@ return ret; } -void _raw_spin_lock(spinlock_t *lock) +void __raw_spin_lock(raw_spinlock_t *lock) { int cpu = smp_processor_id(); unsigned int stuck = INIT_STUCK; @@ -63,9 +63,9 @@ lock->owner_pc = (unsigned long)__builtin_return_address(0); lock->owner_cpu = cpu; } -EXPORT_SYMBOL(_raw_spin_lock); +EXPORT_SYMBOL(__raw_spin_lock); -int _raw_spin_trylock(spinlock_t *lock) +int __raw_spin_trylock(raw_spinlock_t *lock) { if (__spin_trylock(&lock->lock)) return 0; @@ -73,9 +73,9 @@ lock->owner_pc = (unsigned long)__builtin_return_address(0); return 1; } -EXPORT_SYMBOL(_raw_spin_trylock); +EXPORT_SYMBOL(__raw_spin_trylock); -void _raw_spin_unlock(spinlock_t *lp) +void __raw_spin_unlock(raw_spinlock_t *lp) { if ( !lp->lock ) printk("_spin_unlock(%p): no lock cpu %d curr PC %p %s/%d\n", @@ -89,13 +89,13 @@ wmb(); lp->lock = 0; } -EXPORT_SYMBOL(_raw_spin_unlock); +EXPORT_SYMBOL(__raw_spin_unlock); /* * For rwlocks, zero is unlocked, -1 is write-locked, * positive is read-locked. */ -static __inline__ int __read_trylock(rwlock_t *rw) +static __inline__ int __read_trylock(raw_rwlock_t *rw) { signed int tmp; @@ -115,13 +115,13 @@ return tmp; } -int _raw_read_trylock(rwlock_t *rw) +int __raw_read_trylock(raw_rwlock_t *rw) { return __read_trylock(rw) > 0; } -EXPORT_SYMBOL(_raw_read_trylock); +EXPORT_SYMBOL(__raw_read_trylock); -void _raw_read_lock(rwlock_t *rw) +void __raw_read_lock(rwlock_t *rw) { unsigned int stuck; @@ -136,9 +136,9 @@ } } } -EXPORT_SYMBOL(_raw_read_lock); +EXPORT_SYMBOL(__raw_read_lock); -void _raw_read_unlock(rwlock_t *rw) +void __raw_read_unlock(raw_rwlock_t *rw) { if ( rw->lock == 0 ) printk("_read_unlock(): %s/%d (nip %08lX) lock %d\n", @@ -147,9 +147,9 @@ wmb(); atomic_dec((atomic_t *) &(rw)->lock); } -EXPORT_SYMBOL(_raw_read_unlock); +EXPORT_SYMBOL(__raw_read_unlock); -void _raw_write_lock(rwlock_t *rw) +void __raw_write_lock(raw_rwlock_t *rw) { unsigned int stuck; @@ -165,18 +165,18 @@ } wmb(); } -EXPORT_SYMBOL(_raw_write_lock); +EXPORT_SYMBOL(__raw_write_lock); -int _raw_write_trylock(rwlock_t *rw) +int __raw_write_trylock(raw_rwlock_t *rw) { if (cmpxchg(&rw->lock, 0, -1) != 0) return 0; wmb(); return 1; } -EXPORT_SYMBOL(_raw_write_trylock); +EXPORT_SYMBOL(__raw_write_trylock); -void _raw_write_unlock(rwlock_t *rw) +void __raw_write_unlock(raw_rwlock_t *rw) { if (rw->lock >= 0) printk("_write_lock(): %s/%d (nip %08lX) lock %d\n", @@ -185,6 +185,6 @@ wmb(); rw->lock = 0; } -EXPORT_SYMBOL(_raw_write_unlock); +EXPORT_SYMBOL(__raw_write_unlock); #endif diff -urN linux-2.6.12-armirq/arch/ppc/platforms/adir_setup.c linux-2.6.12-armirq-rt/arch/ppc/platforms/adir_setup.c --- linux-2.6.12-armirq/arch/ppc/platforms/adir_setup.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/platforms/adir_setup.c 2005-07-16 16:41:53.000000000 +0200 @@ -77,6 +77,7 @@ freq = adir_get_bus_speed(); tb_ticks_per_jiffy = freq / HZ / divisor; tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000); + cpu_khz = (freq / divisor) / 1000; } static int diff -urN linux-2.6.12-armirq/arch/ppc/platforms/apus_setup.c linux-2.6.12-armirq-rt/arch/ppc/platforms/apus_setup.c --- linux-2.6.12-armirq/arch/ppc/platforms/apus_setup.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/platforms/apus_setup.c 2005-07-16 16:41:53.000000000 +0200 @@ -282,6 +282,7 @@ freq/1000000, freq%1000000); tb_ticks_per_jiffy = freq / HZ; tb_to_us = mulhwu_scale_factor(freq, 1000000); + cpu_khz = freq / 1000; __bus_speed = bus_speed; __speed_test_failed = speed_test_failed; diff -urN linux-2.6.12-armirq/arch/ppc/platforms/chrp_smp.c linux-2.6.12-armirq-rt/arch/ppc/platforms/chrp_smp.c --- linux-2.6.12-armirq/arch/ppc/platforms/chrp_smp.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/platforms/chrp_smp.c 2005-07-16 16:41:53.000000000 +0200 @@ -57,7 +57,7 @@ do_openpic_setup_cpu(); } -static DEFINE_SPINLOCK(timebase_lock); +static DEFINE_RAW_SPINLOCK(timebase_lock); static unsigned int timebase_upper = 0, timebase_lower = 0; void __devinit diff -urN linux-2.6.12-armirq/arch/ppc/platforms/chrp_time.c linux-2.6.12-armirq-rt/arch/ppc/platforms/chrp_time.c --- linux-2.6.12-armirq/arch/ppc/platforms/chrp_time.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/platforms/chrp_time.c 2005-07-16 16:41:53.000000000 +0200 @@ -189,4 +189,5 @@ freq/1000000, freq%1000000); tb_ticks_per_jiffy = freq / HZ; tb_to_us = mulhwu_scale_factor(freq, 1000000); + cpu_khz = freq / 1000; } diff -urN linux-2.6.12-armirq/arch/ppc/platforms/ev64260.c linux-2.6.12-armirq-rt/arch/ppc/platforms/ev64260.c --- linux-2.6.12-armirq/arch/ppc/platforms/ev64260.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/platforms/ev64260.c 2005-07-16 16:41:53.000000000 +0200 @@ -552,6 +552,7 @@ tb_ticks_per_jiffy = freq / HZ; tb_to_us = mulhwu_scale_factor(freq, 1000000); + cpu_khz = freq / 1000; return; } diff -urN linux-2.6.12-armirq/arch/ppc/platforms/gemini_setup.c linux-2.6.12-armirq-rt/arch/ppc/platforms/gemini_setup.c --- linux-2.6.12-armirq/arch/ppc/platforms/gemini_setup.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/platforms/gemini_setup.c 2005-07-16 16:41:53.000000000 +0200 @@ -462,6 +462,7 @@ divisor = 4; tb_ticks_per_jiffy = freq / HZ / divisor; tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000); + cpu_khz = (freq / divisor) / 1000; } unsigned long __init gemini_find_end_of_memory(void) diff -urN linux-2.6.12-armirq/arch/ppc/platforms/hdpu.c linux-2.6.12-armirq-rt/arch/ppc/platforms/hdpu.c --- linux-2.6.12-armirq/arch/ppc/platforms/hdpu.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/platforms/hdpu.c 2005-07-16 16:41:53.000000000 +0200 @@ -58,7 +58,7 @@ static void hdpu_set_l1pe(void); static void hdpu_cpustate_set(unsigned char new_state); #ifdef CONFIG_SMP -static spinlock_t timebase_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(timebase_lock); static unsigned int timebase_upper = 0, timebase_lower = 0; extern int smp_tb_synchronized; diff -urN linux-2.6.12-armirq/arch/ppc/platforms/k2.c linux-2.6.12-armirq-rt/arch/ppc/platforms/k2.c --- linux-2.6.12-armirq/arch/ppc/platforms/k2.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/platforms/k2.c 2005-07-16 16:41:53.000000000 +0200 @@ -411,6 +411,7 @@ freq = k2_get_bus_speed(); tb_ticks_per_jiffy = freq / HZ / divisor; tb_to_us = mulhwu_scale_factor(freq / divisor, 1000000); + cpu_khz = (freq / divisor) / 1000; } static int k2_show_cpuinfo(struct seq_file *m) diff -urN linux-2.6.12-armirq/arch/ppc/platforms/pmac_feature.c linux-2.6.12-armirq-rt/arch/ppc/platforms/pmac_feature.c --- linux-2.6.12-armirq/arch/ppc/platforms/pmac_feature.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/platforms/pmac_feature.c 2005-07-16 16:41:53.000000000 +0200 @@ -63,7 +63,7 @@ * We use a single global lock to protect accesses. Each driver has * to take care of its own locking */ -static DEFINE_SPINLOCK(feature_lock __pmacdata); +static DEFINE_RAW_SPINLOCK(feature_lock __pmacdata); #define LOCK(flags) spin_lock_irqsave(&feature_lock, flags); #define UNLOCK(flags) spin_unlock_irqrestore(&feature_lock, flags); diff -urN linux-2.6.12-armirq/arch/ppc/platforms/pmac_nvram.c linux-2.6.12-armirq-rt/arch/ppc/platforms/pmac_nvram.c --- linux-2.6.12-armirq/arch/ppc/platforms/pmac_nvram.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/platforms/pmac_nvram.c 2005-07-16 16:41:54.000000000 +0200 @@ -80,7 +80,7 @@ static int nvram_mult, is_core_99; static int core99_bank = 0; static int nvram_partitions[3]; -static DEFINE_SPINLOCK(nv_lock); +static DEFINE_RAW_SPINLOCK(nv_lock); extern int pmac_newworld; extern int system_running; diff -urN linux-2.6.12-armirq/arch/ppc/platforms/pmac_pic.c linux-2.6.12-armirq-rt/arch/ppc/platforms/pmac_pic.c --- linux-2.6.12-armirq/arch/ppc/platforms/pmac_pic.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/platforms/pmac_pic.c 2005-07-16 16:41:54.000000000 +0200 @@ -68,7 +68,7 @@ static int max_real_irqs __pmacdata; static u32 level_mask[4] __pmacdata; -static DEFINE_SPINLOCK(pmac_pic_lock __pmacdata); +static DEFINE_RAW_SPINLOCK(pmac_pic_lock __pmacdata); #define GATWICK_IRQ_POOL_SIZE 10 diff -urN linux-2.6.12-armirq/arch/ppc/platforms/pmac_time.c linux-2.6.12-armirq-rt/arch/ppc/platforms/pmac_time.c --- linux-2.6.12-armirq/arch/ppc/platforms/pmac_time.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/platforms/pmac_time.c 2005-07-16 16:41:54.000000000 +0200 @@ -197,6 +197,7 @@ tb_ticks_per_jiffy = (dstart - dend) / (6 * (HZ/100)); tb_to_us = mulhwu_scale_factor(dstart - dend, 60000); + cpu_khz = (dstart - dend) / 60; printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %u (%u ticks)\n", tb_ticks_per_jiffy, dstart - dend); @@ -288,4 +289,5 @@ freq/1000000, freq%1000000); tb_ticks_per_jiffy = freq / HZ; tb_to_us = mulhwu_scale_factor(freq, 1000000); + cpu_khz = freq / 1000; } diff -urN linux-2.6.12-armirq/arch/ppc/platforms/powerpmc250.c linux-2.6.12-armirq-rt/arch/ppc/platforms/powerpmc250.c --- linux-2.6.12-armirq/arch/ppc/platforms/powerpmc250.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/platforms/powerpmc250.c 2005-07-16 16:41:54.000000000 +0200 @@ -167,6 +167,7 @@ tb_ticks_per_jiffy = freq / (HZ * divisor); tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000); + cpu_khz = (freq / divisor) / 1000; } static void diff -urN linux-2.6.12-armirq/arch/ppc/platforms/prep_setup.c linux-2.6.12-armirq-rt/arch/ppc/platforms/prep_setup.c --- linux-2.6.12-armirq/arch/ppc/platforms/prep_setup.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/platforms/prep_setup.c 2005-07-16 16:41:54.000000000 +0200 @@ -938,6 +938,7 @@ (freq/divisor)/1000000, (freq/divisor)%1000000); tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000); + cpu_khz = (freq / divisor) / 1000; tb_ticks_per_jiffy = freq / HZ / divisor; } } diff -urN linux-2.6.12-armirq/arch/ppc/platforms/prpmc750.c linux-2.6.12-armirq-rt/arch/ppc/platforms/prpmc750.c --- linux-2.6.12-armirq/arch/ppc/platforms/prpmc750.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/platforms/prpmc750.c 2005-07-16 16:41:54.000000000 +0200 @@ -271,6 +271,7 @@ tb_ticks_per_jiffy = freq / (HZ * divisor); tb_to_us = mulhwu_scale_factor(freq / divisor, 1000000); + cpu_khz = (freq / divisor) / 1000; } static void prpmc750_restart(char *cmd) diff -urN linux-2.6.12-armirq/arch/ppc/platforms/prpmc800.c linux-2.6.12-armirq-rt/arch/ppc/platforms/prpmc800.c --- linux-2.6.12-armirq/arch/ppc/platforms/prpmc800.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/platforms/prpmc800.c 2005-07-16 16:41:54.000000000 +0200 @@ -331,6 +331,7 @@ tb_ticks_per_second = 100000000 / 4; tb_ticks_per_jiffy = tb_ticks_per_second / HZ; tb_to_us = mulhwu_scale_factor(tb_ticks_per_second, 1000000); + cpu_khz = tb_ticks_per_second / 1000; return; } @@ -371,6 +372,7 @@ tb_ticks_per_second = (tbl_end - tbl_start) * 2; tb_ticks_per_jiffy = tb_ticks_per_second / HZ; tb_to_us = mulhwu_scale_factor(tb_ticks_per_second, 1000000); + cpu_khz = tb_ticks_per_second / 1000; } static void prpmc800_restart(char *cmd) diff -urN linux-2.6.12-armirq/arch/ppc/platforms/sbc82xx.c linux-2.6.12-armirq-rt/arch/ppc/platforms/sbc82xx.c --- linux-2.6.12-armirq/arch/ppc/platforms/sbc82xx.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/platforms/sbc82xx.c 2005-07-16 16:41:54.000000000 +0200 @@ -68,7 +68,7 @@ static volatile char *sbc82xx_i8259_map; static char sbc82xx_i8259_mask = 0xff; -static DEFINE_SPINLOCK(sbc82xx_i8259_lock); +static DEFINE_RAW_SPINLOCK(sbc82xx_i8259_lock); static void sbc82xx_i8259_mask_and_ack_irq(unsigned int irq_nr) { diff -urN linux-2.6.12-armirq/arch/ppc/platforms/spruce.c linux-2.6.12-armirq-rt/arch/ppc/platforms/spruce.c --- linux-2.6.12-armirq/arch/ppc/platforms/spruce.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/platforms/spruce.c 2005-07-16 16:41:54.000000000 +0200 @@ -150,6 +150,7 @@ freq = SPRUCE_BUS_SPEED; tb_ticks_per_jiffy = freq / HZ / divisor; tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000); + cpu_khz = (freq / divisor) / 1000; } static int diff -urN linux-2.6.12-armirq/arch/ppc/syslib/cpm2_common.c linux-2.6.12-armirq-rt/arch/ppc/syslib/cpm2_common.c --- linux-2.6.12-armirq/arch/ppc/syslib/cpm2_common.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/syslib/cpm2_common.c 2005-07-16 16:41:54.000000000 +0200 @@ -115,7 +115,7 @@ /* * dpalloc / dpfree bits. */ -static spinlock_t cpm_dpmem_lock; +static raw_spinlock_t cpm_dpmem_lock; /* 16 blocks should be enough to satisfy all requests * until the memory subsystem goes up... */ static rh_block_t cpm_boot_dpmem_rh_block[16]; diff -urN linux-2.6.12-armirq/arch/ppc/syslib/ibm44x_common.c linux-2.6.12-armirq-rt/arch/ppc/syslib/ibm44x_common.c --- linux-2.6.12-armirq/arch/ppc/syslib/ibm44x_common.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/syslib/ibm44x_common.c 2005-07-16 16:41:54.000000000 +0200 @@ -60,6 +60,7 @@ { tb_ticks_per_jiffy = freq / HZ; tb_to_us = mulhwu_scale_factor(freq, 1000000); + cpu_khz = freq / 1000; /* Set the time base to zero */ mtspr(SPRN_TBWL, 0); diff -urN linux-2.6.12-armirq/arch/ppc/syslib/m8260_setup.c linux-2.6.12-armirq-rt/arch/ppc/syslib/m8260_setup.c --- linux-2.6.12-armirq/arch/ppc/syslib/m8260_setup.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/syslib/m8260_setup.c 2005-07-16 16:41:54.000000000 +0200 @@ -79,6 +79,7 @@ divisor = 4; tb_ticks_per_jiffy = freq / HZ / divisor; tb_to_us = mulhwu_scale_factor(freq / divisor, 1000000); + cpu_khz = (freq / divisor) / 1000; } /* The 8260 has an internal 1-second timer update register that diff -urN linux-2.6.12-armirq/arch/ppc/syslib/m8xx_setup.c linux-2.6.12-armirq-rt/arch/ppc/syslib/m8xx_setup.c --- linux-2.6.12-armirq/arch/ppc/syslib/m8xx_setup.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/syslib/m8xx_setup.c 2005-07-16 16:41:54.000000000 +0200 @@ -163,6 +163,7 @@ printk("Decrementer Frequency = %d/%d\n", freq, divisor); tb_ticks_per_jiffy = freq / HZ / divisor; tb_to_us = mulhwu_scale_factor(freq / divisor, 1000000); + cpu_khz = (freq / divisor) / 1000; /* Perform some more timer/timebase initialization. This used * to be done elsewhere, but other changes caused it to get diff -urN linux-2.6.12-armirq/arch/ppc/syslib/mpc52xx_setup.c linux-2.6.12-armirq-rt/arch/ppc/syslib/mpc52xx_setup.c --- linux-2.6.12-armirq/arch/ppc/syslib/mpc52xx_setup.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/syslib/mpc52xx_setup.c 2005-07-16 16:41:54.000000000 +0200 @@ -214,6 +214,7 @@ tb_ticks_per_jiffy = xlbfreq / HZ / divisor; tb_to_us = mulhwu_scale_factor(xlbfreq / divisor, 1000000); + cpu_khz = (xlbfreq / divisor) / 1000; } int mpc52xx_match_psc_function(int psc_idx, const char *func) diff -urN linux-2.6.12-armirq/arch/ppc/syslib/mv64x60.c linux-2.6.12-armirq-rt/arch/ppc/syslib/mv64x60.c --- linux-2.6.12-armirq/arch/ppc/syslib/mv64x60.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/syslib/mv64x60.c 2005-07-16 16:41:54.000000000 +0200 @@ -32,7 +32,7 @@ u8 mv64x60_pci_exclude_bridge = 1; -spinlock_t mv64x60_lock = SPIN_LOCK_UNLOCKED; +DEFINE_SPINLOCK(mv64x60_lock); static phys_addr_t mv64x60_bridge_pbase = 0; static void *mv64x60_bridge_vbase = 0; diff -urN linux-2.6.12-armirq/arch/ppc/syslib/ocp.c linux-2.6.12-armirq-rt/arch/ppc/syslib/ocp.c --- linux-2.6.12-armirq/arch/ppc/syslib/ocp.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/syslib/ocp.c 2005-07-16 16:41:54.000000000 +0200 @@ -45,11 +45,11 @@ #include #include #include +#include #include #include #include -#include #include //#define DBG(x) printk x diff -urN linux-2.6.12-armirq/arch/ppc/syslib/open_pic.c linux-2.6.12-armirq-rt/arch/ppc/syslib/open_pic.c --- linux-2.6.12-armirq/arch/ppc/syslib/open_pic.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/syslib/open_pic.c 2005-07-16 16:41:54.000000000 +0200 @@ -528,7 +528,7 @@ } #if defined(CONFIG_SMP) || defined(CONFIG_PM) -static DEFINE_SPINLOCK(openpic_setup_lock); +static DEFINE_RAW_SPINLOCK(openpic_setup_lock); #endif #ifdef CONFIG_SMP diff -urN linux-2.6.12-armirq/arch/ppc/syslib/open_pic2.c linux-2.6.12-armirq-rt/arch/ppc/syslib/open_pic2.c --- linux-2.6.12-armirq/arch/ppc/syslib/open_pic2.c 2005-07-13 14:34:11.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/syslib/open_pic2.c 2005-07-16 16:41:54.000000000 +0200 @@ -384,7 +384,7 @@ vec); } -static DEFINE_SPINLOCK(openpic2_setup_lock); +static DEFINE_RAW_SPINLOCK(openpic2_setup_lock); /* * Initialize a timer interrupt (and disable it) diff -urN linux-2.6.12-armirq/arch/ppc/syslib/ppc4xx_setup.c linux-2.6.12-armirq-rt/arch/ppc/syslib/ppc4xx_setup.c --- linux-2.6.12-armirq/arch/ppc/syslib/ppc4xx_setup.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/syslib/ppc4xx_setup.c 2005-07-16 16:41:54.000000000 +0200 @@ -178,6 +178,7 @@ freq = bip->bi_tbfreq; tb_ticks_per_jiffy = freq / HZ; tb_to_us = mulhwu_scale_factor(freq, 1000000); + cpu_khz = freq / 1000; /* Set the time base to zero. ** At 200 Mhz, time base will rollover in ~2925 years. diff -urN linux-2.6.12-armirq/arch/ppc/syslib/ppc85xx_setup.c linux-2.6.12-armirq-rt/arch/ppc/syslib/ppc85xx_setup.c --- linux-2.6.12-armirq/arch/ppc/syslib/ppc85xx_setup.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/syslib/ppc85xx_setup.c 2005-07-16 16:41:54.000000000 +0200 @@ -58,6 +58,7 @@ divisor = 8; tb_ticks_per_jiffy = freq / divisor / HZ; tb_to_us = mulhwu_scale_factor(freq / divisor, 1000000); + cpu_khz = (freq / divisor) / 1000; /* Set the time base to zero */ mtspr(SPRN_TBWL, 0); diff -urN linux-2.6.12-armirq/arch/ppc/syslib/prom.c linux-2.6.12-armirq-rt/arch/ppc/syslib/prom.c --- linux-2.6.12-armirq/arch/ppc/syslib/prom.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/syslib/prom.c 2005-07-16 16:41:54.000000000 +0200 @@ -1397,7 +1397,7 @@ } #endif -static DEFINE_SPINLOCK(rtas_lock); +static DEFINE_RAW_SPINLOCK(rtas_lock); /* this can be called after setup -- Cort */ int __openfirmware diff -urN linux-2.6.12-armirq/arch/ppc/syslib/qspan_pci.c linux-2.6.12-armirq-rt/arch/ppc/syslib/qspan_pci.c --- linux-2.6.12-armirq/arch/ppc/syslib/qspan_pci.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/syslib/qspan_pci.c 2005-07-16 16:41:54.000000000 +0200 @@ -94,7 +94,7 @@ #define mk_config_type1(bus, dev, offset) \ mk_config_addr(bus, dev, offset) | 1; -static spinlock_t pcibios_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(pcibios_lock); int qspan_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, unsigned char offset, unsigned char *val) diff -urN linux-2.6.12-armirq/arch/ppc/syslib/todc_time.c linux-2.6.12-armirq-rt/arch/ppc/syslib/todc_time.c --- linux-2.6.12-armirq/arch/ppc/syslib/todc_time.c 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc/syslib/todc_time.c 2005-07-16 16:41:54.000000000 +0200 @@ -508,6 +508,7 @@ tb_ticks_per_jiffy = freq / HZ; tb_to_us = mulhwu_scale_factor(freq, 1000000); + cpu_khz = freq / 1000; return; } diff -urN linux-2.6.12-armirq/arch/ppc64/Kconfig linux-2.6.12-armirq-rt/arch/ppc64/Kconfig --- linux-2.6.12-armirq/arch/ppc64/Kconfig 2005-07-13 14:30:09.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc64/Kconfig 2005-07-16 16:41:54.000000000 +0200 @@ -215,26 +215,7 @@ when dealing with POWER5 cpus at a cost of slightly increased overhead in some places. If unsure say N here. -config PREEMPT - bool "Preemptible Kernel" - help - This option reduces the latency of the kernel when reacting to - real-time or interactive events by allowing a low priority process to - be preempted even if it is in kernel mode executing a system call. - - Say Y here if you are building a kernel for a desktop, embedded - or real-time system. Say N if you are unsure. - -config PREEMPT_BKL - bool "Preempt The Big Kernel Lock" - depends on PREEMPT - default y - help - This option reduces the latency of the kernel by making the - big kernel lock preemptible. - - Say Y here if you are building a kernel for a desktop system. - Say N if you are unsure. +source "kernel/Kconfig.preempt" config EEH bool "PCI Extended Error Handling (EEH)" if EMBEDDED diff -urN linux-2.6.12-armirq/arch/ppc64/kernel/pmc.c linux-2.6.12-armirq-rt/arch/ppc64/kernel/pmc.c --- linux-2.6.12-armirq/arch/ppc64/kernel/pmc.c 2005-07-13 14:30:10.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/ppc64/kernel/pmc.c 2005-07-16 16:41:54.000000000 +0200 @@ -26,7 +26,7 @@ mtspr(SPRN_MMCR0, mmcr0); } -static spinlock_t pmc_owner_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(pmc_owner_lock); static void *pmc_owner_caller; /* mostly for debugging */ perf_irq_t perf_irq = dummy_perf; diff -urN linux-2.6.12-armirq/arch/sparc/lib/atomic32.c linux-2.6.12-armirq-rt/arch/sparc/lib/atomic32.c --- linux-2.6.12-armirq/arch/sparc/lib/atomic32.c 2005-07-13 14:30:12.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/sparc/lib/atomic32.c 2005-07-16 16:41:54.000000000 +0200 @@ -20,7 +20,7 @@ #else /* SMP */ -static spinlock_t dummy = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(dummy); #define ATOMIC_HASH_SIZE 1 #define ATOMIC_HASH(a) (&dummy) diff -urN linux-2.6.12-armirq/arch/x86_64/Kconfig linux-2.6.12-armirq-rt/arch/x86_64/Kconfig --- linux-2.6.12-armirq/arch/x86_64/Kconfig 2005-07-13 14:30:13.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/x86_64/Kconfig 2005-07-16 16:41:54.000000000 +0200 @@ -34,13 +34,6 @@ config SBUS bool -config RWSEM_GENERIC_SPINLOCK - bool - default y - -config RWSEM_XCHGADD_ALGORITHM - bool - config GENERIC_CALIBRATE_DELAY bool default y @@ -207,33 +200,6 @@ If you don't know what to do here, say N. -config PREEMPT - bool "Preemptible Kernel" - ---help--- - This option reduces the latency of the kernel when reacting to - real-time or interactive events by allowing a low priority process to - be preempted even if it is in kernel mode executing a system call. - This allows applications to run more reliably even when the system is - under load. On contrary it may also break your drivers and add - priority inheritance problems to your system. Don't select it if - you rely on a stable system or have slightly obscure hardware. - It's also not very well tested on x86-64 currently. - You have been warned. - - Say Y here if you are feeling brave and building a kernel for a - desktop, embedded or real-time system. Say N if you are unsure. - -config PREEMPT_BKL - bool "Preempt The Big Kernel Lock" - depends on PREEMPT - default y - help - This option reduces the latency of the kernel by making the - big kernel lock preemptible. - - Say Y here if you are building a kernel for a desktop system. - Say N if you are unsure. - config SCHED_SMT bool "SMT (Hyperthreading) scheduler support" depends on SMP @@ -244,6 +210,16 @@ cost of slightly increased overhead in some places. If unsure say N here. +source "kernel/Kconfig.preempt" + +config RWSEM_GENERIC_SPINLOCK + bool + depends on PREEMPT_RT + default y + +config RWSEM_XCHGADD_ALGORITHM + bool + config K8_NUMA bool "K8 NUMA support" select NUMA diff -urN linux-2.6.12-armirq/arch/x86_64/ia32/sys_ia32.c linux-2.6.12-armirq-rt/arch/x86_64/ia32/sys_ia32.c --- linux-2.6.12-armirq/arch/x86_64/ia32/sys_ia32.c 2005-07-13 14:30:13.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/x86_64/ia32/sys_ia32.c 2005-07-16 16:41:54.000000000 +0200 @@ -455,6 +455,10 @@ struct timespec kts; struct timezone ktz; + int ret = timeofday_API_hacks(tv, tz); + if (ret != 1) + return ret; + if (tv) { if (get_tv32(&ktv, tv)) return -EFAULT; diff -urN linux-2.6.12-armirq/arch/x86_64/kernel/Makefile linux-2.6.12-armirq-rt/arch/x86_64/kernel/Makefile --- linux-2.6.12-armirq/arch/x86_64/kernel/Makefile 2005-07-13 14:30:13.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/x86_64/kernel/Makefile 2005-07-16 16:41:54.000000000 +0200 @@ -4,11 +4,12 @@ extra-y := head.o head64.o init_task.o vmlinux.lds EXTRA_AFLAGS := -traditional -obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \ +obj-y := process.o signal.o entry.o traps.o irq.o \ ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_x86_64.o \ x8664_ksyms.o i387.o syscall.o vsyscall.o \ setup64.o bootflag.o e820.o reboot.o quirks.o +obj-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += semaphore.o obj-$(CONFIG_X86_MCE) += mce.o obj-$(CONFIG_X86_MCE_INTEL) += mce_intel.o obj-$(CONFIG_MTRR) += ../../i386/kernel/cpu/mtrr/ diff -urN linux-2.6.12-armirq/arch/x86_64/kernel/apic.c linux-2.6.12-armirq-rt/arch/x86_64/kernel/apic.c --- linux-2.6.12-armirq/arch/x86_64/kernel/apic.c 2005-07-13 14:30:13.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/x86_64/kernel/apic.c 2005-07-16 16:41:54.000000000 +0200 @@ -478,10 +478,9 @@ apic_pm_state.apic_tmict = apic_read(APIC_TMICT); apic_pm_state.apic_tdcr = apic_read(APIC_TDCR); apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR); - local_save_flags(flags); - local_irq_disable(); + raw_local_irq_save(flags); disable_local_APIC(); - local_irq_restore(flags); + raw_local_irq_restore(flags); return 0; } @@ -496,7 +495,7 @@ /* XXX: Pavel needs this for S3 resume, but can't explain why */ set_fixmap_nocache(FIX_APIC_BASE, APIC_DEFAULT_PHYS_BASE); - local_irq_save(flags); + raw_local_irq_save(flags); rdmsr(MSR_IA32_APICBASE, l, h); l &= ~MSR_IA32_APICBASE_BASE; l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE; @@ -519,7 +518,7 @@ apic_write(APIC_LVTERR, apic_pm_state.apic_lvterr); apic_write(APIC_ESR, 0); apic_read(APIC_ESR); - local_irq_restore(flags); + raw_local_irq_restore(flags); return 0; } @@ -676,7 +675,7 @@ { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); /* For some reasons this doesn't work on Simics, so fake it for now */ if (!strstr(boot_cpu_data.x86_model_id, "Screwdriver")) { @@ -706,7 +705,7 @@ __setup_APIC_LVTT(clocks); - local_irq_restore(flags); + raw_local_irq_restore(flags); } /* @@ -763,7 +762,7 @@ printk(KERN_INFO "Using local APIC timer interrupts.\n"); using_apic_timer = 1; - local_irq_disable(); + raw_local_irq_disable(); calibration_result = calibrate_APIC_clock(); /* @@ -771,14 +770,14 @@ */ setup_APIC_timer(calibration_result); - local_irq_enable(); + raw_local_irq_enable(); } void __init setup_secondary_APIC_clock(void) { - local_irq_disable(); /* FIXME: Do we need this? --RR */ + raw_local_irq_disable(); /* FIXME: Do we need this? --RR */ setup_APIC_timer(calibration_result); - local_irq_enable(); + raw_local_irq_enable(); } void __init disable_APIC_timer(void) diff -urN linux-2.6.12-armirq/arch/x86_64/kernel/early_printk.c linux-2.6.12-armirq-rt/arch/x86_64/kernel/early_printk.c --- linux-2.6.12-armirq/arch/x86_64/kernel/early_printk.c 2005-07-13 14:30:13.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/x86_64/kernel/early_printk.c 2005-07-16 16:41:54.000000000 +0200 @@ -160,7 +160,7 @@ void early_printk(const char *fmt, ...) { - char buf[512]; + static char buf[512]; int n; va_list ap; diff -urN linux-2.6.12-armirq/arch/x86_64/kernel/entry.S linux-2.6.12-armirq-rt/arch/x86_64/kernel/entry.S --- linux-2.6.12-armirq/arch/x86_64/kernel/entry.S 2005-07-13 14:30:13.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/x86_64/kernel/entry.S 2005-07-16 16:41:54.000000000 +0200 @@ -211,8 +211,8 @@ /* Handle reschedules */ /* edx: work, edi: workmask */ sysret_careful: - bt $TIF_NEED_RESCHED,%edx - jnc sysret_signal + testl $(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED),%edx + jz sysret_signal sti pushq %rdi call schedule @@ -231,7 +231,7 @@ leaq -ARGOFFSET(%rsp),%rdi # &pt_regs -> arg1 xorl %esi,%esi # oldset -> arg2 call ptregscall_common -1: movl $_TIF_NEED_RESCHED,%edi +1: movl $(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED),%edi jmp sysret_check /* Do syscall tracing */ @@ -280,8 +280,8 @@ /* First do a reschedule test. */ /* edx: work, edi: workmask */ int_careful: - bt $TIF_NEED_RESCHED,%edx - jnc int_very_careful + testl $(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED),%edx + jz int_very_careful sti pushq %rdi call schedule @@ -310,7 +310,7 @@ movq %rsp,%rdi # &ptregs -> arg1 xorl %esi,%esi # oldset -> arg2 call do_notify_resume -1: movl $_TIF_NEED_RESCHED,%edi +1: movl $(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED),%edi int_restore_rest: RESTORE_REST cli @@ -478,8 +478,8 @@ /* edi: workmask, edx: work */ retint_careful: - bt $TIF_NEED_RESCHED,%edx - jnc retint_signal + testl $(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED),%edx + jz retint_signal sti pushq %rdi call schedule @@ -499,7 +499,7 @@ call do_notify_resume RESTORE_REST cli - movl $_TIF_NEED_RESCHED,%edi + movl $(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED),%edi GET_THREAD_INFO(%rcx) jmp retint_check @@ -918,3 +918,40 @@ ENTRY(call_debug) zeroentry do_call_debug +#ifdef CONFIG_LATENCY_TRACE + +ENTRY(mcount) + cmpq $0, trace_enabled + jz out + + push %rbp + mov %rsp,%rbp + + push %r9 + push %r8 + push %rdi + push %rsi + push %rdx + push %rcx + push %rax + + mov 0x0(%rbp),%rax + mov 0x8(%rbp),%rdi + mov 0x8(%rax),%rsi + + call __trace + + pop %rax + pop %rcx + pop %rdx + pop %rsi + pop %rdi + pop %r8 + pop %r9 + + leaveq +out: + ret + +#endif + diff -urN linux-2.6.12-armirq/arch/x86_64/kernel/i8259.c linux-2.6.12-armirq-rt/arch/x86_64/kernel/i8259.c --- linux-2.6.12-armirq/arch/x86_64/kernel/i8259.c 2005-07-13 14:34:11.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/x86_64/kernel/i8259.c 2005-07-16 16:41:54.000000000 +0200 @@ -130,7 +130,7 @@ * moves to arch independent land */ -DEFINE_SPINLOCK(i8259A_lock); +DEFINE_RAW_SPINLOCK(i8259A_lock); static void end_8259A_irq (unsigned int irq) { @@ -439,7 +439,7 @@ * IRQ2 is cascade interrupt to second interrupt controller */ -static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL}; +static struct irqaction irq2 = { no_action, SA_NODELAY, CPU_MASK_NONE, "cascade", NULL, NULL}; void __init init_ISA_irqs (void) { diff -urN linux-2.6.12-armirq/arch/x86_64/kernel/init_task.c linux-2.6.12-armirq-rt/arch/x86_64/kernel/init_task.c --- linux-2.6.12-armirq/arch/x86_64/kernel/init_task.c 2005-07-13 14:30:13.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/x86_64/kernel/init_task.c 2005-07-16 16:41:54.000000000 +0200 @@ -10,8 +10,8 @@ #include #include -static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; +static struct fs_struct init_fs = INIT_FS(init_fs); +static struct files_struct init_files = INIT_FILES(init_files); static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); diff -urN linux-2.6.12-armirq/arch/x86_64/kernel/io_apic.c linux-2.6.12-armirq-rt/arch/x86_64/kernel/io_apic.c --- linux-2.6.12-armirq/arch/x86_64/kernel/io_apic.c 2005-07-13 14:30:13.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/x86_64/kernel/io_apic.c 2005-07-16 16:41:54.000000000 +0200 @@ -45,7 +45,7 @@ static int no_timer_check; -static DEFINE_SPINLOCK(ioapic_lock); +static DEFINE_RAW_SPINLOCK(ioapic_lock); /* * # of IRQ routing registers @@ -115,6 +115,9 @@ reg = io_apic_read(entry->apic, 0x10 + R + pin*2); \ reg ACTION; \ io_apic_modify(entry->apic, reg); \ + /* Force POST flush by reading: */ \ + reg = io_apic_read(entry->apic, 0x10 + R + pin*2); \ + \ if (!entry->next) \ break; \ entry = irq_2_pin + entry->next; \ @@ -127,10 +130,8 @@ static void name##_IO_APIC_irq (unsigned int irq) \ __DO_ACTION(R, ACTION, FINAL) -DO_ACTION( __mask, 0, |= 0x00010000, io_apic_sync(entry->apic) ) - /* mask = 1 */ -DO_ACTION( __unmask, 0, &= 0xfffeffff, ) - /* mask = 0 */ +DO_ACTION( __mask, 0, |= 0x00010000, ) /* mask = 1 */ +DO_ACTION( __unmask, 0, &= 0xfffeffff, ) /* mask = 0 */ static void mask_IO_APIC_irq (unsigned int irq) { @@ -1064,7 +1065,6 @@ void __apicdebuginit print_PIC(void) { - extern spinlock_t i8259A_lock; unsigned int v; unsigned long flags; @@ -1218,7 +1218,7 @@ { unsigned long t1 = jiffies; - local_irq_enable(); + raw_local_irq_enable(); /* Let ten ticks pass... */ mdelay((10 * 1000) / HZ); @@ -1310,11 +1310,48 @@ return 0; /* don't check for pending */ } +/* + * In the preemptible case mask the IRQ first then handle it and ack it. + * + * (In the non-preemptible case we keep the IRQ unacked in the local APIC + * and dont need to do the masking, because the code executes atomically.) + */ +#ifdef CONFIG_PREEMPT_HARDIRQS + +static void mask_and_ack_level_ioapic_irq(unsigned int irq) +{ + mask_IO_APIC_irq(irq); + ack_APIC_irq(); +} + +static void end_level_ioapic_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & IRQ_INPROGRESS)) + unmask_IO_APIC_irq(irq); +} + +static void enable_level_ioapic_irq(unsigned int irq) +{ + unmask_IO_APIC_irq(irq); +} + +#else /* !CONFIG_PREEMPT_HARDIRQS */ + +static void mask_and_ack_level_ioapic_irq(unsigned int irq) +{ +} + static void end_level_ioapic_irq (unsigned int irq) { ack_APIC_irq(); } +static void enable_level_ioapic_irq(unsigned int irq) +{ + unmask_IO_APIC_irq(irq); +} +#endif /* !CONFIG_PREEMPT_HARDIRQS */ + static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask) { unsigned long flags; @@ -1354,6 +1391,13 @@ return startup_level_ioapic_irq (irq); } +static void mask_and_ack_level_ioapic_vector (unsigned int vector) +{ + int irq = vector_to_irq(vector); + + mask_and_ack_level_ioapic_irq(irq); +} + static void end_level_ioapic_vector (unsigned int vector) { int irq = vector_to_irq(vector); @@ -1361,6 +1405,11 @@ end_level_ioapic_irq(irq); } +static void enable_level_ioapic_vector(unsigned int vector) +{ + enable_level_ioapic_irq(vector_to_irq(vector)); +} + static void mask_IO_APIC_vector (unsigned int vector) { int irq = vector_to_irq(vector); diff -urN linux-2.6.12-armirq/arch/x86_64/kernel/irq.c linux-2.6.12-armirq-rt/arch/x86_64/kernel/irq.c --- linux-2.6.12-armirq/arch/x86_64/kernel/irq.c 2005-07-13 14:30:13.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/x86_64/kernel/irq.c 2005-07-16 16:41:54.000000000 +0200 @@ -43,7 +43,8 @@ } if (i < NR_IRQS) { - spin_lock_irqsave(&irq_desc[i].lock, flags); + raw_local_irq_save(flags); + spin_lock(&irq_desc[i].lock); action = irq_desc[i].action; if (!action) goto skip; @@ -63,7 +64,8 @@ seq_printf(p, ", %s", action->name); seq_putc(p, '\n'); skip: - spin_unlock_irqrestore(&irq_desc[i].lock, flags); + spin_unlock(&irq_desc[i].lock); + raw_local_irq_restore(flags); } else if (i == NR_IRQS) { seq_printf(p, "NMI: "); for (j = 0; j < NR_CPUS; j++) diff -urN linux-2.6.12-armirq/arch/x86_64/kernel/nmi.c linux-2.6.12-armirq-rt/arch/x86_64/kernel/nmi.c --- linux-2.6.12-armirq/arch/x86_64/kernel/nmi.c 2005-07-13 14:30:13.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/x86_64/kernel/nmi.c 2005-07-16 16:41:54.000000000 +0200 @@ -44,7 +44,7 @@ * This is maintained separately from nmi_active because the NMI * watchdog may also be driven from the I/O APIC timer. */ -static DEFINE_SPINLOCK(lapic_nmi_owner_lock); +static DEFINE_RAW_SPINLOCK(lapic_nmi_owner_lock); static unsigned int lapic_nmi_owner; #define LAPIC_NMI_WATCHDOG (1<<0) #define LAPIC_NMI_RESERVED (1<<1) @@ -128,7 +128,7 @@ static __init void nmi_cpu_busy(void *data) { volatile int *endflag = data; - local_irq_enable(); + raw_local_irq_enable(); /* Intentionally don't use cpu_relax here. This is to make sure that the performance counter really ticks, even if there is a simulator or similar that catches the @@ -157,7 +157,7 @@ for (cpu = 0; cpu < NR_CPUS; cpu++) counts[cpu] = cpu_pda[cpu].__nmi_count; - local_irq_enable(); + raw_local_irq_enable(); mdelay((10*1000)/nmi_hz); // wait 10 ticks for (cpu = 0; cpu < NR_CPUS; cpu++) { @@ -463,14 +463,46 @@ */ for (i = 0; i < NR_CPUS; i++) per_cpu(nmi_touch, i) = 1; + + touch_softlockup_watchdog(); +} + +int nmi_show_regs[NR_CPUS]; + +void nmi_show_all_regs(void) +{ + int i; + + if (nmi_watchdog == NMI_NONE) + return; + if (system_state != SYSTEM_RUNNING) { + printk("nmi_show_all_regs(): system state %d, not doing.\n", + system_state); + return; + } + + for_each_online_cpu(i) + nmi_show_regs[i] = 1; + for_each_online_cpu(i) + while (nmi_show_regs[i] == 1) + barrier(); } +static DEFINE_RAW_SPINLOCK(nmi_print_lock); + void nmi_watchdog_tick (struct pt_regs * regs, unsigned reason) { int sum; int touched = 0; + int cpu = safe_smp_processor_id(); sum = read_pda(apic_timer_irqs); + if (nmi_show_regs[cpu]) { + nmi_show_regs[cpu] = 0; + spin_lock(&nmi_print_lock); + show_regs(regs); + spin_unlock(&nmi_print_lock); + } if (__get_cpu_var(nmi_touch)) { __get_cpu_var(nmi_touch) = 0; touched = 1; @@ -482,6 +514,11 @@ */ local_inc(&__get_cpu_var(alert_counter)); if (local_read(&__get_cpu_var(alert_counter)) == 5*nmi_hz) { + int i; + + for (i = 0; i < NR_CPUS; i++) + nmi_show_regs[i] = 1; + if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) { local_set(&__get_cpu_var(alert_counter), 0); diff -urN linux-2.6.12-armirq/arch/x86_64/kernel/process.c linux-2.6.12-armirq-rt/arch/x86_64/kernel/process.c --- linux-2.6.12-armirq/arch/x86_64/kernel/process.c 2005-07-13 14:30:13.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/x86_64/kernel/process.c 2005-07-16 16:41:54.000000000 +0200 @@ -85,12 +85,13 @@ void default_idle(void) { if (!atomic_read(&hlt_counter)) { - local_irq_disable(); - if (!need_resched()) - safe_halt(); + raw_local_irq_disable(); + if (!need_resched() && !need_resched_delayed()) + raw_safe_halt(); else - local_irq_enable(); - } + raw_local_irq_enable(); + } else + raw_local_irq_enable(); } /* @@ -102,7 +103,7 @@ { int oldval; - local_irq_enable(); + raw_local_irq_enable(); /* * Deal with another CPU just having chosen a thread to @@ -118,7 +119,7 @@ "rep; nop;" "je 2b;" : : - "i" (_TIF_NEED_RESCHED), + "i" (_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_DELAYED), "m" (current_thread_info()->flags)); } else { set_need_resched(); @@ -163,7 +164,9 @@ { /* endless idle loop with no priority at all */ while (1) { - while (!need_resched()) { + BUG_ON(raw_irqs_disabled()); + + while (!need_resched() && !need_resched_delayed()) { void (*idle)(void); if (__get_cpu_var(cpu_idle_state)) @@ -173,10 +176,13 @@ idle = pm_idle; if (!idle) idle = default_idle; + stop_critical_timing(); + propagate_preempt_locks_value(); idle(); } - - schedule(); + raw_local_irq_disable(); + __schedule(); + raw_local_irq_enable(); } } @@ -189,16 +195,16 @@ */ static void mwait_idle(void) { - local_irq_enable(); + raw_local_irq_enable(); - if (!need_resched()) { + if (!need_resched() && !need_resched_delayed()) { set_thread_flag(TIF_POLLING_NRFLAG); do { __monitor((void *)¤t_thread_info()->flags, 0, 0); - if (need_resched()) + if (need_resched() || need_resched_delayed()) break; __mwait(0, 0); - } while (!need_resched()); + } while (!need_resched() && !need_resched_delayed()); clear_thread_flag(TIF_POLLING_NRFLAG); } } @@ -283,7 +289,7 @@ void show_regs(struct pt_regs *regs) { __show_regs(regs); - show_trace(®s->rsp); + show_trace(current, ®s->rsp); } /* @@ -294,13 +300,14 @@ struct task_struct *me = current; struct thread_struct *t = &me->thread; if (me->thread.io_bitmap_ptr) { - struct tss_struct *tss = &per_cpu(init_tss, get_cpu()); + struct tss_struct *tss; kfree(t->io_bitmap_ptr); t->io_bitmap_ptr = NULL; /* * Careful, clear this in the TSS too: */ + tss = &per_cpu(init_tss, get_cpu()); memset(tss->io_bitmap, 0xff, t->io_bitmap_max); t->io_bitmap_max = 0; put_cpu(); diff -urN linux-2.6.12-armirq/arch/x86_64/kernel/reboot.c linux-2.6.12-armirq-rt/arch/x86_64/kernel/reboot.c --- linux-2.6.12-armirq/arch/x86_64/kernel/reboot.c 2005-07-13 14:30:13.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/x86_64/kernel/reboot.c 2005-07-16 16:41:54.000000000 +0200 @@ -114,12 +114,12 @@ #endif if (!reboot_force) { - local_irq_disable(); + raw_local_irq_disable(); #ifndef CONFIG_SMP disable_local_APIC(); #endif disable_IO_APIC(); - local_irq_enable(); + raw_local_irq_enable(); } /* Tell the BIOS if we want cold or warm reboot */ diff -urN linux-2.6.12-armirq/arch/x86_64/kernel/semaphore.c linux-2.6.12-armirq-rt/arch/x86_64/kernel/semaphore.c --- linux-2.6.12-armirq/arch/x86_64/kernel/semaphore.c 2005-07-13 14:30:13.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/x86_64/kernel/semaphore.c 2005-07-16 16:41:54.000000000 +0200 @@ -50,12 +50,12 @@ * we cannot lose wakeup events. */ -void __up(struct semaphore *sem) +void __compat_up(struct compat_semaphore *sem) { wake_up(&sem->wait); } -void __sched __down(struct semaphore * sem) +void __sched __compat_down(struct compat_semaphore * sem) { struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); @@ -92,7 +92,7 @@ tsk->state = TASK_RUNNING; } -int __sched __down_interruptible(struct semaphore * sem) +int __sched __compat_down_interruptible(struct compat_semaphore * sem) { int retval = 0; struct task_struct *tsk = current; @@ -155,7 +155,7 @@ * single "cmpxchg" without failure cases, * but then it wouldn't work on a 386. */ -int __down_trylock(struct semaphore * sem) +int __compat_down_trylock(struct compat_semaphore * sem) { int sleepers; unsigned long flags; diff -urN linux-2.6.12-armirq/arch/x86_64/kernel/signal.c linux-2.6.12-armirq-rt/arch/x86_64/kernel/signal.c --- linux-2.6.12-armirq/arch/x86_64/kernel/signal.c 2005-07-13 14:30:13.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/x86_64/kernel/signal.c 2005-07-16 16:41:54.000000000 +0200 @@ -411,6 +411,13 @@ siginfo_t info; int signr; +#ifdef CONFIG_PREEMPT_RT + /* + * Fully-preemptible kernel does not need interrupts disabled: + */ + raw_local_irq_enable(); + preempt_check_resched(); +#endif /* * We want the common case to go fast, which * is why we may in certain cases get here from diff -urN linux-2.6.12-armirq/arch/x86_64/kernel/smp.c linux-2.6.12-armirq-rt/arch/x86_64/kernel/smp.c --- linux-2.6.12-armirq/arch/x86_64/kernel/smp.c 2005-07-13 14:30:13.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/x86_64/kernel/smp.c 2005-07-16 16:41:54.000000000 +0200 @@ -42,7 +42,7 @@ static cpumask_t flush_cpumask; static struct mm_struct * flush_mm; static unsigned long flush_va; -static DEFINE_SPINLOCK(tlbstate_lock); +static DEFINE_RAW_SPINLOCK(tlbstate_lock); #define FLUSH_ALL -1ULL /* @@ -268,10 +268,20 @@ } /* + * this function sends a 'reschedule' IPI to all other CPUs. + * This is used when RT tasks are starving and other CPUs + * might be able to run them: + */ +void smp_send_reschedule_allbutself(void) +{ + send_IPI_allbutself(RESCHEDULE_VECTOR); +} + +/* * Structure and data for smp_call_function(). This is designed to minimise * static memory requirements. It also looks cleaner. */ -static DEFINE_SPINLOCK(call_lock); +static DEFINE_RAW_SPINLOCK(call_lock); struct call_data_struct { void (*func) (void *info); @@ -349,9 +359,9 @@ * Remove this CPU: */ cpu_clear(smp_processor_id(), cpu_online_map); - local_irq_disable(); + raw_local_irq_disable(); disable_local_APIC(); - local_irq_enable(); + raw_local_irq_enable(); } static void smp_really_stop_cpu(void *dummy) @@ -375,9 +385,9 @@ if (!nolock) spin_unlock(&call_lock); - local_irq_disable(); + raw_local_irq_disable(); disable_local_APIC(); - local_irq_enable(); + raw_local_irq_enable(); } /* diff -urN linux-2.6.12-armirq/arch/x86_64/kernel/smpboot.c linux-2.6.12-armirq-rt/arch/x86_64/kernel/smpboot.c --- linux-2.6.12-armirq/arch/x86_64/kernel/smpboot.c 2005-07-13 14:30:13.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/x86_64/kernel/smpboot.c 2005-07-16 16:41:54.000000000 +0200 @@ -188,7 +188,7 @@ latency and low latency is the primary objective here. -AK */ #define no_cpu_relax() barrier() -static __cpuinitdata DEFINE_SPINLOCK(tsc_sync_lock); +static __cpuinitdata DEFINE_RAW_SPINLOCK(tsc_sync_lock); static volatile __cpuinitdata unsigned long go[SLAVE + 1]; static int notscsync __cpuinitdata; @@ -207,7 +207,7 @@ go[MASTER] = 0; - local_irq_save(flags); + raw_local_irq_save(flags); { for (i = 0; i < NUM_ROUNDS*NUM_ITERS; ++i) { while (!go[MASTER]) @@ -216,7 +216,7 @@ rdtscll(go[SLAVE]); } } - local_irq_restore(flags); + raw_local_irq_restore(flags); } /* diff -urN linux-2.6.12-armirq/arch/x86_64/kernel/time.c linux-2.6.12-armirq-rt/arch/x86_64/kernel/time.c --- linux-2.6.12-armirq/arch/x86_64/kernel/time.c 2005-07-13 14:30:13.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/x86_64/kernel/time.c 2005-07-16 16:41:54.000000000 +0200 @@ -53,8 +53,8 @@ extern void i8254_timer_resume(void); extern int using_apic_timer; -DEFINE_SPINLOCK(rtc_lock); -DEFINE_SPINLOCK(i8253_lock); +DEFINE_RAW_SPINLOCK(rtc_lock); +DEFINE_RAW_SPINLOCK(i8253_lock); static int nohpet __initdata = 0; static int notsc __initdata = 0; @@ -871,7 +871,7 @@ } static struct irqaction irq0 = { - timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL + timer_interrupt, SA_INTERRUPT | SA_NODELAY, CPU_MASK_NONE, "timer", NULL, NULL }; extern void __init config_acpi_tables(void); @@ -1027,6 +1027,7 @@ write_sequnlock_irqrestore(&xtime_lock,flags); jiffies += sleep_length; wall_jiffies += sleep_length; + touch_softlockup_watchdog(); return 0; } diff -urN linux-2.6.12-armirq/arch/x86_64/kernel/traps.c linux-2.6.12-armirq-rt/arch/x86_64/kernel/traps.c --- linux-2.6.12-armirq/arch/x86_64/kernel/traps.c 2005-07-13 14:30:13.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/x86_64/kernel/traps.c 2005-07-16 16:41:54.000000000 +0200 @@ -90,7 +90,7 @@ static inline void conditional_sti(struct pt_regs *regs) { if (regs->eflags & X86_EFLAGS_IF) - local_irq_enable(); + raw_local_irq_enable(); } static int kstack_depth_to_print = 10; @@ -156,7 +156,7 @@ * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack */ -void show_trace(unsigned long *stack) +void show_trace(struct task_struct *task, unsigned long *stack) { unsigned long addr; const unsigned cpu = safe_smp_processor_id(); @@ -221,6 +221,7 @@ HANDLE_STACK (((long) stack & (THREAD_SIZE-1)) != 0); #undef HANDLE_STACK printk("\n"); + print_traces(task); } void show_stack(struct task_struct *tsk, unsigned long * rsp) @@ -257,7 +258,7 @@ printk("%016lx ", *stack++); touch_nmi_watchdog(); } - show_trace((unsigned long *)rsp); + show_trace(tsk, (unsigned long *)rsp); } /* @@ -266,7 +267,7 @@ void dump_stack(void) { unsigned long dummy; - show_trace(&dummy); + show_trace(current, &dummy); } EXPORT_SYMBOL(dump_stack); @@ -339,14 +340,14 @@ } #endif -static DEFINE_SPINLOCK(die_lock); +static DEFINE_RAW_SPINLOCK(die_lock); static int die_owner = -1; void oops_begin(void) { int cpu = safe_smp_processor_id(); /* racy, but better than risking deadlock. */ - local_irq_disable(); + raw_local_irq_disable(); if (!spin_trylock(&die_lock)) { if (cpu == die_owner) /* nested oops. should stop eventually */; diff -urN linux-2.6.12-armirq/arch/x86_64/kernel/vsyscall.c linux-2.6.12-armirq-rt/arch/x86_64/kernel/vsyscall.c --- linux-2.6.12-armirq/arch/x86_64/kernel/vsyscall.c 2005-07-13 14:30:13.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/x86_64/kernel/vsyscall.c 2005-07-16 16:41:54.000000000 +0200 @@ -38,7 +38,7 @@ #define force_inline __attribute__((always_inline)) inline int __sysctl_vsyscall __section_sysctl_vsyscall = 1; -seqlock_t __xtime_lock __section_xtime_lock = SEQLOCK_UNLOCKED; +raw_seqlock_t __xtime_lock __section_xtime_lock = RAW_SEQLOCK_UNLOCKED; #include diff -urN linux-2.6.12-armirq/arch/x86_64/kernel/x8664_ksyms.c linux-2.6.12-armirq-rt/arch/x86_64/kernel/x8664_ksyms.c --- linux-2.6.12-armirq/arch/x86_64/kernel/x8664_ksyms.c 2005-07-13 14:30:13.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/x86_64/kernel/x8664_ksyms.c 2005-07-16 16:41:54.000000000 +0200 @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -33,8 +34,6 @@ #include #include -extern spinlock_t rtc_lock; - #ifdef CONFIG_SMP extern void __write_lock_failed(rwlock_t *rw); extern void __read_lock_failed(rwlock_t *rw); @@ -62,10 +61,12 @@ EXPORT_SYMBOL(pm_power_off); EXPORT_SYMBOL(get_cmos_time); -EXPORT_SYMBOL(__down_failed); -EXPORT_SYMBOL(__down_failed_interruptible); -EXPORT_SYMBOL(__down_failed_trylock); -EXPORT_SYMBOL(__up_wakeup); +#ifdef CONFIG_RWSEM_GENERIC_SPINLOCK +EXPORT_SYMBOL(__compat_down_failed); +EXPORT_SYMBOL(__compat_down_failed_interruptible); +EXPORT_SYMBOL(__compat_down_failed_trylock); +EXPORT_SYMBOL(__compat_up_wakeup); +#endif /* Networking helper routines. */ EXPORT_SYMBOL(csum_partial_copy_nocheck); EXPORT_SYMBOL(ip_compute_csum); @@ -179,7 +180,7 @@ EXPORT_SYMBOL(empty_zero_page); #ifdef CONFIG_HAVE_DEC_LOCK -EXPORT_SYMBOL(_atomic_dec_and_lock); +EXPORT_SYMBOL(_atomic_dec_and_raw_spin_lock); #endif EXPORT_SYMBOL(die_chain); diff -urN linux-2.6.12-armirq/arch/x86_64/lib/dec_and_lock.c linux-2.6.12-armirq-rt/arch/x86_64/lib/dec_and_lock.c --- linux-2.6.12-armirq/arch/x86_64/lib/dec_and_lock.c 2005-07-13 14:30:13.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/x86_64/lib/dec_and_lock.c 2005-07-16 16:41:54.000000000 +0200 @@ -10,7 +10,7 @@ #include #include -int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) +int _atomic_dec_and_raw_spin_lock(atomic_t *atomic, raw_spinlock_t *lock) { int counter; int newcount; diff -urN linux-2.6.12-armirq/arch/x86_64/lib/thunk.S linux-2.6.12-armirq-rt/arch/x86_64/lib/thunk.S --- linux-2.6.12-armirq/arch/x86_64/lib/thunk.S 2005-07-13 14:30:13.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/x86_64/lib/thunk.S 2005-07-16 16:41:54.000000000 +0200 @@ -43,11 +43,13 @@ thunk rwsem_downgrade_thunk,rwsem_downgrade_wake #endif thunk do_softirq_thunk,do_softirq - - thunk __down_failed,__down - thunk_retrax __down_failed_interruptible,__down_interruptible - thunk_retrax __down_failed_trylock,__down_trylock - thunk __up_wakeup,__up + +#ifdef CONFIG_RWSEM_GENERIC_SPINLOCK + thunk __compat_down_failed,__compat_down + thunk_retrax __compat_down_failed_interruptible,__compat_down_interruptible + thunk_retrax __compat_down_failed_trylock,__compat_down_trylock + thunk __compat_up_wakeup,__compat_up +#endif /* SAVE_ARGS below is used only for the .cfi directives it contains. */ CFI_STARTPROC diff -urN linux-2.6.12-armirq/arch/x86_64/mm/fault.c linux-2.6.12-armirq-rt/arch/x86_64/mm/fault.c --- linux-2.6.12-armirq/arch/x86_64/mm/fault.c 2005-07-13 14:30:13.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/x86_64/mm/fault.c 2005-07-16 16:41:54.000000000 +0200 @@ -39,6 +39,7 @@ { int loglevel_save = console_loglevel; if (yes) { + stop_trace(); oops_in_progress = 1; } else { #ifdef CONFIG_VT @@ -326,7 +327,7 @@ return; if (likely(regs->eflags & X86_EFLAGS_IF)) - local_irq_enable(); + raw_local_irq_enable(); if (unlikely(page_fault_trace)) printk("pagefault rip:%lx rsp:%lx cs:%lu ss:%lu address %lx error %lx\n", diff -urN linux-2.6.12-armirq/arch/x86_64/mm/init.c linux-2.6.12-armirq-rt/arch/x86_64/mm/init.c --- linux-2.6.12-armirq/arch/x86_64/mm/init.c 2005-07-13 14:30:13.000000000 +0200 +++ linux-2.6.12-armirq-rt/arch/x86_64/mm/init.c 2005-07-16 16:41:54.000000000 +0200 @@ -47,7 +47,7 @@ extern char _stext[]; -DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); +DEFINE_PER_CPU_LOCKED(struct mmu_gather, mmu_gathers); /* * NOTE: pagetable_init alloc all the fixmap pagetables contiguous on the diff -urN linux-2.6.12-armirq/drivers/acorn/block/fd1772.c linux-2.6.12-armirq-rt/drivers/acorn/block/fd1772.c --- linux-2.6.12-armirq/drivers/acorn/block/fd1772.c 2005-07-13 14:30:14.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/acorn/block/fd1772.c 2005-07-16 16:41:54.000000000 +0200 @@ -376,19 +376,15 @@ /************************* End of Prototypes **************************/ -static struct timer_list motor_off_timer = - TIMER_INITIALIZER(fd_motor_off_timer, 0, 0); +static DEFINE_TIMER(motor_off_timer, fd_motor_off_timer, 0, 0); #ifdef TRACKBUFFER -static struct timer_list readtrack_timer = - TIMER_INITIALIZER(fd_readtrack_check, 0, 0); +static DEFINE_TIMER(readtrack_timer, fd_readtrack_check, 0, 0); #endif -static struct timer_list timeout_timer = - TIMER_INITIALIZER(fd_times_out, 0, 0); +static DEFINE_TIMER(timeout_timer, fd_times_out, 0, 0); -static struct timer_list fd_timer = - TIMER_INITIALIZER(check_change, 0, 0); +static DEFINE_TIMER(fd_timer, check_change, 0, 0); /* DAG: Haven't got a clue what this is? */ int stdma_islocked(void) diff -urN linux-2.6.12-armirq/drivers/acpi/osl.c linux-2.6.12-armirq-rt/drivers/acpi/osl.c --- linux-2.6.12-armirq/drivers/acpi/osl.c 2005-07-13 14:30:14.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/acpi/osl.c 2005-07-16 16:41:54.000000000 +0200 @@ -829,14 +829,14 @@ u32 initial_units, acpi_handle *handle) { - struct semaphore *sem = NULL; + struct compat_semaphore *sem = NULL; ACPI_FUNCTION_TRACE ("os_create_semaphore"); - sem = acpi_os_allocate(sizeof(struct semaphore)); + sem = acpi_os_allocate(sizeof(struct compat_semaphore)); if (!sem) return_ACPI_STATUS (AE_NO_MEMORY); - memset(sem, 0, sizeof(struct semaphore)); + memset(sem, 0, sizeof(struct compat_semaphore)); sema_init(sem, initial_units); @@ -860,7 +860,7 @@ acpi_os_delete_semaphore( acpi_handle handle) { - struct semaphore *sem = (struct semaphore*) handle; + struct compat_semaphore *sem = (struct compat_semaphore*) handle; ACPI_FUNCTION_TRACE ("os_delete_semaphore"); @@ -892,7 +892,7 @@ u16 timeout) { acpi_status status = AE_OK; - struct semaphore *sem = (struct semaphore*)handle; + struct compat_semaphore *sem = (struct compat_semaphore*)handle; int ret = 0; ACPI_FUNCTION_TRACE ("os_wait_semaphore"); @@ -974,7 +974,7 @@ acpi_handle handle, u32 units) { - struct semaphore *sem = (struct semaphore *) handle; + struct compat_semaphore *sem = (struct compat_semaphore *) handle; ACPI_FUNCTION_TRACE ("os_signal_semaphore"); diff -urN linux-2.6.12-armirq/drivers/acpi/processor_idle.c linux-2.6.12-armirq-rt/drivers/acpi/processor_idle.c --- linux-2.6.12-armirq/drivers/acpi/processor_idle.c 2005-07-13 14:30:14.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/acpi/processor_idle.c 2005-07-16 16:41:54.000000000 +0200 @@ -179,14 +179,14 @@ * Interrupts must be disabled during bus mastering calculations and * for C2/C3 transitions. */ - local_irq_disable(); + raw_local_irq_disable(); /* * Check whether we truly need to go idle, or should * reschedule: */ if (unlikely(need_resched())) { - local_irq_enable(); + raw_local_irq_enable(); return; } @@ -248,7 +248,7 @@ * issues (e.g. floppy DMA transfer overrun/underrun). */ if (pr->power.bm_activity & cx->demotion.threshold.bm) { - local_irq_enable(); + raw_local_irq_enable(); next_state = cx->demotion.state; goto end; } @@ -272,7 +272,7 @@ if (pm_idle_save) pm_idle_save(); else - safe_halt(); + raw_safe_halt(); /* * TBD: Can't get time duration while in C1, as resumes * go to an ISR rather than here. Need to instrument @@ -291,7 +291,7 @@ /* Get end time (ticks) */ t2 = inl(acpi_fadt.xpm_tmr_blk.address); /* Re-enable interrupts */ - local_irq_enable(); + raw_local_irq_enable(); /* Compute time (ticks) that we were actually asleep */ sleep_ticks = ticks_elapsed(t1, t2) - cx->latency_ticks - C2_OVERHEAD; break; @@ -310,13 +310,13 @@ /* Enable bus master arbitration */ acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_DO_NOT_LOCK); /* Re-enable interrupts */ - local_irq_enable(); + raw_local_irq_enable(); /* Compute time (ticks) that we were actually asleep */ sleep_ticks = ticks_elapsed(t1, t2) - cx->latency_ticks - C3_OVERHEAD; break; default: - local_irq_enable(); + raw_local_irq_enable(); return; } @@ -392,7 +392,7 @@ if (pm_idle_save) pm_idle_save(); else - safe_halt(); + raw_safe_halt(); return; } diff -urN linux-2.6.12-armirq/drivers/atm/atmtcp.c linux-2.6.12-armirq-rt/drivers/atm/atmtcp.c --- linux-2.6.12-armirq/drivers/atm/atmtcp.c 2005-07-13 14:30:14.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/atm/atmtcp.c 2005-07-16 16:41:54.000000000 +0200 @@ -368,7 +368,7 @@ .ops = &atmtcp_c_dev_ops, .type = "atmtcp", .number = 999, - .lock = SPIN_LOCK_UNLOCKED + .lock = SPIN_LOCK_UNLOCKED(atmtcp_control_dev.lock) }; diff -urN linux-2.6.12-armirq/drivers/atm/idt77105.c linux-2.6.12-armirq-rt/drivers/atm/idt77105.c --- linux-2.6.12-armirq/drivers/atm/idt77105.c 2005-07-13 14:30:15.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/atm/idt77105.c 2005-07-16 16:41:54.000000000 +0200 @@ -50,10 +50,8 @@ static void idt77105_restart_timer_func(unsigned long); -static struct timer_list stats_timer = - TIMER_INITIALIZER(idt77105_stats_timer_func, 0, 0); -static struct timer_list restart_timer = - TIMER_INITIALIZER(idt77105_restart_timer_func, 0, 0); +static DEFINE_TIMER(stats_timer, idt77105_stats_timer_func, 0, 0); +static DEFINE_TIMER(restart_timer, idt77105_restart_timer_func, 0, 0); static int start_timer = 1; static struct idt77105_priv *idt77105_all = NULL; diff -urN linux-2.6.12-armirq/drivers/atm/iphase.c linux-2.6.12-armirq-rt/drivers/atm/iphase.c --- linux-2.6.12-armirq/drivers/atm/iphase.c 2005-07-13 14:30:15.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/atm/iphase.c 2005-07-16 16:41:54.000000000 +0200 @@ -79,7 +79,7 @@ static struct atm_dev *_ia_dev[8]; static int iadev_count; static void ia_led_timer(unsigned long arg); -static struct timer_list ia_timer = TIMER_INITIALIZER(ia_led_timer, 0, 0); +static DEFINE_TIMER(ia_timer, ia_led_timer, 0, 0); static int IA_TX_BUF = DFL_TX_BUFFERS, IA_TX_BUF_SZ = DFL_TX_BUF_SZ; static int IA_RX_BUF = DFL_RX_BUFFERS, IA_RX_BUF_SZ = DFL_RX_BUF_SZ; static uint IADebugFlag = /* IF_IADBG_ERR | IF_IADBG_CBR| IF_IADBG_INIT_ADAPTER diff -urN linux-2.6.12-armirq/drivers/block/acsi.c linux-2.6.12-armirq-rt/drivers/block/acsi.c --- linux-2.6.12-armirq/drivers/block/acsi.c 2005-07-13 14:30:15.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/block/acsi.c 2005-07-16 16:41:54.000000000 +0200 @@ -371,7 +371,7 @@ /************************* End of Prototypes **************************/ -struct timer_list acsi_timer = TIMER_INITIALIZER(acsi_times_out, 0, 0); +DEFINE_TIMER(acsi_timer, acsi_times_out, 0, 0); #ifdef CONFIG_ATARI_SLM diff -urN linux-2.6.12-armirq/drivers/block/acsi_slm.c linux-2.6.12-armirq-rt/drivers/block/acsi_slm.c --- linux-2.6.12-armirq/drivers/block/acsi_slm.c 2005-07-13 14:30:15.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/block/acsi_slm.c 2005-07-16 16:41:54.000000000 +0200 @@ -268,7 +268,7 @@ /************************* End of Prototypes **************************/ -static struct timer_list slm_timer = TIMER_INITIALIZER(slm_test_ready, 0, 0); +static DEFINE_TIMER(slm_timer, slm_test_ready, 0, 0); static struct file_operations slm_fops = { .owner = THIS_MODULE, diff -urN linux-2.6.12-armirq/drivers/block/ataflop.c linux-2.6.12-armirq-rt/drivers/block/ataflop.c --- linux-2.6.12-armirq/drivers/block/ataflop.c 2005-07-13 14:30:15.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/block/ataflop.c 2005-07-16 16:41:54.000000000 +0200 @@ -371,16 +371,10 @@ /************************* End of Prototypes **************************/ -static struct timer_list motor_off_timer = - TIMER_INITIALIZER(fd_motor_off_timer, 0, 0); -static struct timer_list readtrack_timer = - TIMER_INITIALIZER(fd_readtrack_check, 0, 0); - -static struct timer_list timeout_timer = - TIMER_INITIALIZER(fd_times_out, 0, 0); - -static struct timer_list fd_timer = - TIMER_INITIALIZER(check_change, 0, 0); +static DEFINE_TIMER(motor_off_timer, fd_motor_off_timer, 0, 0); +static DEFINE_TIMER(readtrack_timer, fd_readtrack_check, 0, 0); +static DEFINE_TIMER(timeout_timer, fd_times_out, 0, 0); +static DEFINE_TIMER(fd_timer, check_change, 0, 0); static inline void start_motor_off_timer(void) { diff -urN linux-2.6.12-armirq/drivers/block/floppy.c linux-2.6.12-armirq-rt/drivers/block/floppy.c --- linux-2.6.12-armirq/drivers/block/floppy.c 2005-07-13 14:30:15.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/block/floppy.c 2005-07-16 16:41:54.000000000 +0200 @@ -626,7 +626,7 @@ #endif /* DEBUGT */ typedef void (*timeout_fn) (unsigned long); -static struct timer_list fd_timeout = TIMER_INITIALIZER(floppy_shutdown, 0, 0); +static DEFINE_TIMER(fd_timeout, floppy_shutdown, 0, 0); static const char *timeout_message; @@ -1010,7 +1010,7 @@ schedule_work(&floppy_work); } -static struct timer_list fd_timer = TIMER_INITIALIZER(NULL, 0, 0); +static DEFINE_TIMER(fd_timer, NULL, 0, 0); static void cancel_activity(void) { diff -urN linux-2.6.12-armirq/drivers/block/ll_rw_blk.c linux-2.6.12-armirq-rt/drivers/block/ll_rw_blk.c --- linux-2.6.12-armirq/drivers/block/ll_rw_blk.c 2005-07-13 14:30:15.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/block/ll_rw_blk.c 2005-07-16 16:41:54.000000000 +0200 @@ -1413,7 +1413,7 @@ */ void blk_plug_device(request_queue_t *q) { - WARN_ON(!irqs_disabled()); + WARN_ON_NONRT(!irqs_disabled()); /* * don't plug a stopped queue, it must be paired with blk_start_queue() @@ -1434,7 +1434,7 @@ */ int blk_remove_plug(request_queue_t *q) { - WARN_ON(!irqs_disabled()); + WARN_ON_NONRT(!irqs_disabled()); if (!test_and_clear_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags)) return 0; diff -urN linux-2.6.12-armirq/drivers/block/loop.c linux-2.6.12-armirq-rt/drivers/block/loop.c --- linux-2.6.12-armirq/drivers/block/loop.c 2005-07-13 14:30:15.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/block/loop.c 2005-07-16 16:41:54.000000000 +0200 @@ -482,7 +482,7 @@ lo->lo_bio = lo->lo_biotail = bio; spin_unlock_irqrestore(&lo->lo_lock, flags); - up(&lo->lo_bh_mutex); + complete(&lo->lo_bh_done); } /* @@ -531,7 +531,7 @@ return 0; err: if (atomic_dec_and_test(&lo->lo_pending)) - up(&lo->lo_bh_mutex); + complete(&lo->lo_bh_done); out: bio_io_error(old_bio, old_bio->bi_size); return 0; @@ -599,12 +599,12 @@ /* * up sem, we are running */ - up(&lo->lo_sem); + complete(&lo->lo_done); for (;;) { - down_interruptible(&lo->lo_bh_mutex); + wait_for_completion_interruptible(&lo->lo_bh_done); /* - * could be upped because of tear-down, not because of + * could be completed because of tear-down, not because of * pending work */ if (!atomic_read(&lo->lo_pending)) @@ -625,7 +625,7 @@ break; } - up(&lo->lo_sem); + complete(&lo->lo_done); return 0; } @@ -836,7 +836,7 @@ set_blocksize(bdev, lo_blocksize); kernel_thread(loop_thread, lo, CLONE_KERNEL); - down(&lo->lo_sem); + wait_for_completion(&lo->lo_done); return 0; out_putf: @@ -901,10 +901,10 @@ spin_lock_irq(&lo->lo_lock); lo->lo_state = Lo_rundown; if (atomic_dec_and_test(&lo->lo_pending)) - up(&lo->lo_bh_mutex); + complete(&lo->lo_bh_done); spin_unlock_irq(&lo->lo_lock); - down(&lo->lo_sem); + wait_for_completion(&lo->lo_done); lo->lo_backing_file = NULL; @@ -1281,8 +1281,8 @@ if (!lo->lo_queue) goto out_mem4; init_MUTEX(&lo->lo_ctl_mutex); - init_MUTEX_LOCKED(&lo->lo_sem); - init_MUTEX_LOCKED(&lo->lo_bh_mutex); + init_completion(&lo->lo_done); + init_completion(&lo->lo_bh_done); lo->lo_number = i; spin_lock_init(&lo->lo_lock); disk->major = LOOP_MAJOR; diff -urN linux-2.6.12-armirq/drivers/block/ps2esdi.c linux-2.6.12-armirq-rt/drivers/block/ps2esdi.c --- linux-2.6.12-armirq/drivers/block/ps2esdi.c 2005-07-13 14:30:15.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/block/ps2esdi.c 2005-07-16 16:41:54.000000000 +0200 @@ -99,8 +99,7 @@ static int no_int_yet; static int ps2esdi_drives; static u_short io_base; -static struct timer_list esdi_timer = - TIMER_INITIALIZER(ps2esdi_reset_timer, 0, 0); +static DEFINE_TIMER(esdi_timer, ps2esdi_reset_timer, 0, 0); static int reset_status; static int ps2esdi_slot = -1; static int tp720esdi = 0; /* Is it Integrated ESDI of ThinkPad-720? */ diff -urN linux-2.6.12-armirq/drivers/cdrom/aztcd.c linux-2.6.12-armirq-rt/drivers/cdrom/aztcd.c --- linux-2.6.12-armirq/drivers/cdrom/aztcd.c 2005-07-13 14:30:15.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/cdrom/aztcd.c 2005-07-16 16:41:54.000000000 +0200 @@ -297,7 +297,7 @@ static int AztTimeout, AztTries; static DECLARE_WAIT_QUEUE_HEAD(azt_waitq); -static struct timer_list delay_timer = TIMER_INITIALIZER(NULL, 0, 0); +static DEFINE_TIMER(delay_timer, NULL, 0, 0); static struct azt_DiskInfo DiskInfo; static struct azt_Toc Toc[MAX_TRACKS]; diff -urN linux-2.6.12-armirq/drivers/cdrom/gscd.c linux-2.6.12-armirq-rt/drivers/cdrom/gscd.c --- linux-2.6.12-armirq/drivers/cdrom/gscd.c 2005-07-13 14:30:15.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/cdrom/gscd.c 2005-07-16 16:41:54.000000000 +0200 @@ -146,7 +146,7 @@ static int AudioEnd_m; static int AudioEnd_f; -static struct timer_list gscd_timer = TIMER_INITIALIZER(NULL, 0, 0); +static DEFINE_TIMER(gscd_timer, NULL, 0, 0); static DEFINE_SPINLOCK(gscd_lock); static struct request_queue *gscd_queue; diff -urN linux-2.6.12-armirq/drivers/cdrom/optcd.c linux-2.6.12-armirq-rt/drivers/cdrom/optcd.c --- linux-2.6.12-armirq/drivers/cdrom/optcd.c 2005-07-13 14:30:15.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/cdrom/optcd.c 2005-07-16 16:41:54.000000000 +0200 @@ -264,7 +264,7 @@ static int sleep_timeout; /* max # of ticks to sleep */ static DECLARE_WAIT_QUEUE_HEAD(waitq); static void sleep_timer(unsigned long data); -static struct timer_list delay_timer = TIMER_INITIALIZER(sleep_timer, 0, 0); +static DEFINE_TIMER(delay_timer, sleep_timer, 0, 0); static DEFINE_SPINLOCK(optcd_lock); static struct request_queue *opt_queue; diff -urN linux-2.6.12-armirq/drivers/cdrom/sbpcd.c linux-2.6.12-armirq-rt/drivers/cdrom/sbpcd.c --- linux-2.6.12-armirq/drivers/cdrom/sbpcd.c 2005-07-13 14:30:15.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/cdrom/sbpcd.c 2005-07-16 16:41:54.000000000 +0200 @@ -742,13 +742,10 @@ unsigned long cli_sti; /* for saving the processor flags */ #endif /*==========================================================================*/ -static struct timer_list delay_timer = - TIMER_INITIALIZER(mark_timeout_delay, 0, 0); -static struct timer_list data_timer = - TIMER_INITIALIZER(mark_timeout_data, 0, 0); +static DEFINE_TIMER(delay_timer, mark_timeout_delay, 0, 0); +static DEFINE_TIMER(data_timer, mark_timeout_data, 0, 0); #if 0 -static struct timer_list audio_timer = - TIMER_INITIALIZER(mark_timeout_audio, 0, 0); +static DEFINE_TIMER(audio_timer, mark_timeout_audio, 0, 0); #endif /*==========================================================================*/ /* diff -urN linux-2.6.12-armirq/drivers/cdrom/sjcd.c linux-2.6.12-armirq-rt/drivers/cdrom/sjcd.c --- linux-2.6.12-armirq/drivers/cdrom/sjcd.c 2005-07-13 14:30:15.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/cdrom/sjcd.c 2005-07-16 16:41:54.000000000 +0200 @@ -151,7 +151,7 @@ /* * Timer. */ -static struct timer_list sjcd_delay_timer = TIMER_INITIALIZER(NULL, 0, 0); +static DEFINE_TIMER(sjcd_delay_timer, NULL, 0, 0); #define SJCD_SET_TIMER( func, tmout ) \ ( sjcd_delay_timer.expires = jiffies+tmout, \ diff -urN linux-2.6.12-armirq/drivers/char/Kconfig linux-2.6.12-armirq-rt/drivers/char/Kconfig --- linux-2.6.12-armirq/drivers/char/Kconfig 2005-07-13 14:30:15.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/char/Kconfig 2005-07-16 16:41:54.000000000 +0200 @@ -711,6 +711,45 @@ To compile this driver as a module, choose M here: the module will be called rtc. +config RTC_HISTOGRAM + tristate "Real Time Clock Histogram Support" + default y + depends on RTC + ---help--- + If you say Y here then the kernel will track the delivery and + wakeup latency of /dev/rtc using tasks and will report a + histogram to the kernel log when the application closes /dev/rtc. + +config BLOCKER + tristate "Priority Inheritance Debugging (Blocker) Device Support" + default y + ---help--- + If you say Y here then a device will be created that the userspace + pi_test suite uses to test and measure kernel locking primitives. + +config LPPTEST + tristate "Parallel Port Based Latency Measurement Device" + depends on !PARPORT + default y + ---help--- + If you say Y here then a device will be created that the userspace + testlpp utility uses to measure IRQ latencies of a target system + from an independent measurement system. + + NOTE: this code assumes x86 PCs and that the parallel port is + bidirectional and is on IRQ 7. + + to use the device, both the target and the source system needs to + run a kernel with CONFIG_LPPTEST enabled. To measure latencies, + use the scripts/testlpp utility in your kernel source directory, + and run it (as root) on the source system - it will start printing + out the latencies it took to get a response from the target system: + + Latency of response: 12.2 usecs (121265 cycles) + + then generate various workloads on the target system to see how + (worst-case-) latencies are impacted. + config SGI_DS1286 tristate "SGI DS1286 RTC support" depends on SGI_IP22 diff -urN linux-2.6.12-armirq/drivers/char/Makefile linux-2.6.12-armirq-rt/drivers/char/Makefile --- linux-2.6.12-armirq/drivers/char/Makefile 2005-07-13 14:30:15.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/char/Makefile 2005-07-16 16:41:54.000000000 +0200 @@ -57,6 +57,8 @@ obj-$(CONFIG_APPLICOM) += applicom.o obj-$(CONFIG_SONYPI) += sonypi.o obj-$(CONFIG_RTC) += rtc.o +obj-$(CONFIG_BLOCKER) += blocker.o +obj-$(CONFIG_LPPTEST) += lpptest.o obj-$(CONFIG_HPET) += hpet.o obj-$(CONFIG_GEN_RTC) += genrtc.o obj-$(CONFIG_EFI_RTC) += efirtc.o diff -urN linux-2.6.12-armirq/drivers/char/blocker.c linux-2.6.12-armirq-rt/drivers/char/blocker.c --- linux-2.6.12-armirq/drivers/char/blocker.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.12-armirq-rt/drivers/char/blocker.c 2005-07-16 16:41:59.000000000 +0200 @@ -0,0 +1,118 @@ +/* + * priority inheritance testing device + */ + +#include +#include + +#define BLOCKER_MINOR 221 + +#define BLOCK_IOCTL 4245 +#define BLOCK_SET_DEPTH 4246 + +#define MAX_LOCK_DEPTH 10 + +u64 notrace get_cpu_tick(void) +{ + u64 tsc; +#ifdef ARCHARM + tsc = *oscr; +#else + __asm__ __volatile__("rdtsc" : "=A" (tsc)); +#endif + return tsc; +} + +void loop(int loops) +{ + int i; + + for (i = 0; i < loops; i++) + get_cpu_tick(); +} + +static spinlock_t blocker_lock[MAX_LOCK_DEPTH]; + +static unsigned int lock_depth = 1; + +void do_the_lock_and_loop(unsigned int args) +{ + int i, max; + + if (rt_task(current)) + max = lock_depth; + else if (lock_depth > 1) + max = (current->pid % lock_depth) + 1; + else + max = 1; + + /* Always lock from the top down */ + for (i = max-1; i >= 0; i--) + spin_lock(&blocker_lock[i]); + loop(args); + for (i = 0; i < max; i++) + spin_unlock(&blocker_lock[i]); +} + +static int blocker_open(struct inode *in, struct file *file) +{ + printk(KERN_INFO "blocker_open called\n"); + + return 0; +} + +static long blocker_ioctl(struct file *file, + unsigned int cmd, unsigned long args) +{ + switch(cmd) { + case BLOCK_IOCTL: + do_the_lock_and_loop(args); + return 0; + case BLOCK_SET_DEPTH: + if (args >= MAX_LOCK_DEPTH) + return -EINVAL; + lock_depth = args; + return 0; + default: + return -EINVAL; + } +} + +static struct file_operations blocker_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .unlocked_ioctl = blocker_ioctl, + .open = blocker_open, +}; + +static struct miscdevice blocker_dev = +{ + BLOCKER_MINOR, + "blocker", + &blocker_fops +}; + +static int __init blocker_init(void) +{ + int i; + + if (misc_register(&blocker_dev)) + return -ENODEV; + + for (i = 0; i < MAX_LOCK_DEPTH; i++) + spin_lock_init(blocker_lock + i); + + return 0; +} + +void __exit blocker_exit(void) +{ + printk(KERN_INFO "blocker device uninstalled\n"); + misc_deregister(&blocker_dev); +} + +module_init(blocker_init); +module_exit(blocker_exit); + +MODULE_LICENSE("GPL"); + diff -urN linux-2.6.12-armirq/drivers/char/cyclades.c linux-2.6.12-armirq-rt/drivers/char/cyclades.c --- linux-2.6.12-armirq/drivers/char/cyclades.c 2005-07-13 14:30:15.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/char/cyclades.c 2005-07-16 16:41:54.000000000 +0200 @@ -865,7 +865,7 @@ static long cyz_polling_cycle = CZ_DEF_POLL; static int cyz_timeron = 0; -static struct timer_list cyz_timerlist = TIMER_INITIALIZER(cyz_poll, 0, 0); +static DEFINE_TIMER(cyz_timerlist, cyz_poll, 0, 0); #else /* CONFIG_CYZ_INTR */ static void cyz_rx_restart(unsigned long); diff -urN linux-2.6.12-armirq/drivers/char/hangcheck-timer.c linux-2.6.12-armirq-rt/drivers/char/hangcheck-timer.c --- linux-2.6.12-armirq/drivers/char/hangcheck-timer.c 2005-07-13 14:30:16.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/char/hangcheck-timer.c 2005-07-16 16:41:54.000000000 +0200 @@ -149,8 +149,7 @@ static void hangcheck_fire(unsigned long); -static struct timer_list hangcheck_ticktock = - TIMER_INITIALIZER(hangcheck_fire, 0, 0); +static DEFINE_TIMER(hangcheck_ticktock, hangcheck_fire, 0, 0); static void hangcheck_fire(unsigned long data) diff -urN linux-2.6.12-armirq/drivers/char/ip2main.c linux-2.6.12-armirq-rt/drivers/char/ip2main.c --- linux-2.6.12-armirq/drivers/char/ip2main.c 2005-07-13 14:30:16.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/char/ip2main.c 2005-07-16 16:41:54.000000000 +0200 @@ -255,7 +255,7 @@ * selected, the board is serviced periodically to see if anything needs doing. */ #define POLL_TIMEOUT (jiffies + 1) -static struct timer_list PollTimer = TIMER_INITIALIZER(ip2_poll, 0, 0); +static DEFINE_TIMER(PollTimer, ip2_poll, 0, 0); static char TimerOn; #ifdef IP2DEBUG_TRACE diff -urN linux-2.6.12-armirq/drivers/char/istallion.c linux-2.6.12-armirq-rt/drivers/char/istallion.c --- linux-2.6.12-armirq/drivers/char/istallion.c 2005-07-13 14:30:16.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/char/istallion.c 2005-07-16 16:41:54.000000000 +0200 @@ -781,7 +781,7 @@ * much cheaper on host cpu than using interrupts. It turns out to * not increase character latency by much either... */ -static struct timer_list stli_timerlist = TIMER_INITIALIZER(stli_poll, 0, 0); +static DEFINE_TIMER(stli_timerlist, stli_poll, 0, 0); static int stli_timeron; diff -urN linux-2.6.12-armirq/drivers/char/keyboard.c linux-2.6.12-armirq-rt/drivers/char/keyboard.c --- linux-2.6.12-armirq/drivers/char/keyboard.c 2005-07-13 14:30:16.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/char/keyboard.c 2005-07-16 16:41:54.000000000 +0200 @@ -233,8 +233,7 @@ } } -static struct timer_list kd_mksound_timer = - TIMER_INITIALIZER(kd_nosound, 0, 0); +static DEFINE_TIMER(kd_mksound_timer, kd_nosound, 0, 0); void kd_mksound(unsigned int hz, unsigned int ticks) { diff -urN linux-2.6.12-armirq/drivers/char/lpptest.c linux-2.6.12-armirq-rt/drivers/char/lpptest.c --- linux-2.6.12-armirq/drivers/char/lpptest.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.12-armirq-rt/drivers/char/lpptest.c 2005-07-16 16:41:59.000000000 +0200 @@ -0,0 +1,162 @@ +/* + * /dev/lpptest device: test IRQ handling latencies over parallel port + * + * Copyright (C) 2005 Thomas Gleixner, Ingo Molnar + * + * licensed under the GPL + * + * You need to have CONFIG_PARPORT disabled for this device, it is a + * completely self-contained device that assumes sole ownership of the + * parallel port. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LPPTEST_CHAR_MAJOR 245 +#define LPPTEST_DEVICE_NAME "lpptest" + +#define LPPTEST_IRQ 7 + +#define LPPTEST_TEST _IOR (LPPTEST_CHAR_MAJOR, 1, unsigned long long) +#define LPPTEST_DISABLE _IOR (LPPTEST_CHAR_MAJOR, 2, unsigned long long) +#define LPPTEST_ENABLE _IOR (LPPTEST_CHAR_MAJOR, 3, unsigned long long) + +static char dev_id[] = "lpptest"; + +#define INIT_PORT() outb(0x04, 0x37a) +#define ENABLE_IRQ() outb(0x10, 0x37a) +#define DISABLE_IRQ() outb(0, 0x37a) + +static unsigned char out = 0x5a; + +/** + * Interrupt handler. Flip a bit in the reply. + */ +static int lpptest_irq (int irq, void *dev_id, struct pt_regs *regs) +{ + out ^= 0xff; + outb(out, 0x378); + + return IRQ_HANDLED; +} + +static cycles_t test_response(void) +{ + cycles_t now, end; + unsigned char in; + int timeout = 0; + + local_irq_disable(); + in = inb(0x379); + inb(0x378); + outb(0x08, 0x378); + rdtscll(now); + while(1) { + if (inb(0x379) != in) + break; + if (timeout++ > 1000000) { + outb(0x00, 0x378); + local_irq_enable(); + + return 0; + } + } + rdtscll(end); + outb(0x00, 0x378); + local_irq_enable(); + + return end - now; +} + +static int lpptest_open(struct inode *inode, struct file *file) +{ + return 0; +} + +static int lpptest_close(struct inode *inode, struct file *file) +{ + return 0; +} + +int lpptest_ioctl(struct inode *inode, struct file *file, unsigned int ioctl_num, unsigned long ioctl_param) +{ + int retval = 0; + + switch (ioctl_num) { + + case LPPTEST_DISABLE: + DISABLE_IRQ(); + break; + + case LPPTEST_ENABLE: + ENABLE_IRQ(); + break; + + case LPPTEST_TEST: { + + cycles_t diff = test_response(); + if (copy_to_user((void *)ioctl_param, (void*) &diff, sizeof(diff))) + goto errcpy; + break; + } + default: retval = -EINVAL; + } + + return retval; + + errcpy: + return -EFAULT; +} + +static struct file_operations lpptest_dev_fops = { + .ioctl = lpptest_ioctl, + .open = lpptest_open, + .release = lpptest_close, +}; + +static int __init lpptest_init (void) +{ + if (register_chrdev(LPPTEST_CHAR_MAJOR, LPPTEST_DEVICE_NAME, &lpptest_dev_fops)) + { + printk(KERN_NOTICE "Can't allocate major number %d for lpptest.\n", + LPPTEST_CHAR_MAJOR); + return -EAGAIN; + } + + if (request_irq (LPPTEST_IRQ, lpptest_irq, 0, "lpptest", dev_id)) { + printk (KERN_WARNING "lpptest: irq %d in use. Unload parport module!\n", LPPTEST_IRQ); + unregister_chrdev(LPPTEST_CHAR_MAJOR, LPPTEST_DEVICE_NAME); + return -EAGAIN; + } + irq_desc[LPPTEST_IRQ].status |= IRQ_NODELAY; + irq_desc[LPPTEST_IRQ].action->flags |= SA_NODELAY | SA_INTERRUPT; + + INIT_PORT(); + ENABLE_IRQ(); + + return 0; +} +module_init (lpptest_init); + +static void __exit lpptest_exit (void) +{ + DISABLE_IRQ(); + + free_irq(LPPTEST_IRQ, dev_id); + unregister_chrdev(LPPTEST_CHAR_MAJOR, LPPTEST_DEVICE_NAME); +} +module_exit (lpptest_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("lpp test module"); + diff -urN linux-2.6.12-armirq/drivers/char/random.c linux-2.6.12-armirq-rt/drivers/char/random.c --- linux-2.6.12-armirq/drivers/char/random.c 2005-07-13 14:30:16.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/char/random.c 2005-07-16 16:41:54.000000000 +0200 @@ -417,7 +417,7 @@ .poolinfo = &poolinfo_table[0], .name = "input", .limit = 1, - .lock = SPIN_LOCK_UNLOCKED, + .lock = SPIN_LOCK_UNLOCKED(input_pool.lock), .pool = input_pool_data }; @@ -426,7 +426,7 @@ .name = "blocking", .limit = 1, .pull = &input_pool, - .lock = SPIN_LOCK_UNLOCKED, + .lock = SPIN_LOCK_UNLOCKED(blocking_pool.lock), .pool = blocking_pool_data }; @@ -434,7 +434,7 @@ .poolinfo = &poolinfo_table[1], .name = "nonblocking", .pull = &input_pool, - .lock = SPIN_LOCK_UNLOCKED, + .lock = SPIN_LOCK_UNLOCKED(nonblocking_pool.lock), .pool = nonblocking_pool_data }; @@ -581,8 +581,11 @@ preempt_disable(); /* if over the trickle threshold, use only 1 in 4096 samples */ if (input_pool.entropy_count > trickle_thresh && - (__get_cpu_var(trickle_count)++ & 0xfff)) - goto out; + (__get_cpu_var(trickle_count)++ & 0xfff)) { + preempt_enable(); + return; + } + preempt_enable(); sample.jiffies = jiffies; sample.cycles = get_cycles(); @@ -627,9 +630,6 @@ if(input_pool.entropy_count >= random_read_wakeup_thresh) wake_up_interruptible(&random_read_wait); - -out: - preempt_enable(); } extern void add_input_randomness(unsigned int type, unsigned int code, diff -urN linux-2.6.12-armirq/drivers/char/rtc.c linux-2.6.12-armirq-rt/drivers/char/rtc.c --- linux-2.6.12-armirq/drivers/char/rtc.c 2005-07-13 14:30:16.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/char/rtc.c 2005-07-16 16:41:54.000000000 +0200 @@ -78,6 +78,7 @@ #include #include #include +#include #include #include @@ -87,6 +88,28 @@ #include #endif +#ifdef CONFIG_RTC_HISTOGRAM + +static cycles_t last_interrupt_time; + +#include + +#define CPU_MHZ (cpu_khz / 1000) + +#define HISTSIZE 10000 +static int histogram[HISTSIZE]; + +static int rtc_state; + +enum rtc_states { + S_STARTUP, /* First round - let the application start */ + S_IDLE, /* Waiting for an interrupt */ + S_WAITING_FOR_READ, /* Signal delivered. waiting for rtc_read() */ + S_READ_MISSED, /* Signal delivered, read() deadline missed */ +}; + +#endif + #ifdef __sparc__ #include #include @@ -204,7 +227,147 @@ return uip; } +#ifndef RTC_IRQ +# undef CONFIG_RTC_HISTOGRAM +#endif + +static inline void rtc_open_event(void) +{ +#ifdef CONFIG_RTC_HISTOGRAM + int i; + + last_interrupt_time = 0; + rtc_state = S_STARTUP; + rtc_irq_data = 0; + + for (i = 0; i < HISTSIZE; i++) + histogram[i] = 0; +#endif +} + +static inline void rtc_wake_event(void) +{ +#ifndef CONFIG_RTC_HISTOGRAM + kill_fasync (&rtc_async_queue, SIGIO, POLL_IN); +#else + if (!(rtc_status & RTC_IS_OPEN)) + return; + + switch (rtc_state) { + /* Startup */ + case S_STARTUP: + kill_fasync (&rtc_async_queue, SIGIO, POLL_IN); + break; + /* Waiting for an interrupt */ + case S_IDLE: + kill_fasync (&rtc_async_queue, SIGIO, POLL_IN); + last_interrupt_time = get_cycles(); + rtc_state = S_WAITING_FOR_READ; + break; + + /* Signal has been delivered. waiting for rtc_read() */ + case S_WAITING_FOR_READ: + /* + * Well foo. The usermode application didn't + * schedule and read in time. + */ + rtc_state = S_READ_MISSED; + printk("`%s'[%d] is being piggy. need_resched=%d, cpu=%d\n", + current->comm, current->pid, + need_resched(), smp_processor_id()); + printk("Read missed before next interrupt\n"); + break; + /* Signal has been delivered, read() deadline was missed */ + case S_READ_MISSED: + /* + * Not much we can do here. We're waiting for the usermode + * application to read the rtc + */ + break; + } +#endif +} + +static inline void rtc_read_event(void) +{ +#ifdef CONFIG_RTC_HISTOGRAM + cycles_t now = get_cycles(); + + switch (rtc_state) { + /* Startup */ + case S_STARTUP: + rtc_state = S_IDLE; + break; + + /* Waiting for an interrupt */ + case S_IDLE: + printk("bug in rtc_read(): called in state S_IDLE!\n"); + break; + case S_WAITING_FOR_READ: /* + * Signal has been delivered. + * waiting for rtc_read() + */ + /* + * Well done + */ + case S_READ_MISSED: /* + * Signal has been delivered, read() + * deadline was missed + */ + /* + * So, you finally got here. + */ + if (!last_interrupt_time) + printk("bug in rtc_read(): last_interrupt_time = 0\n"); + rtc_state = S_IDLE; + { + cycles_t latency = now - last_interrupt_time; + unsigned long delta; /* Microseconds */ + + delta = latency; + delta /= CPU_MHZ; + + if (delta > 1000 * 1000) { + printk("rtc: eek\n"); + } else { + unsigned long slot = delta; + if (slot >= HISTSIZE) + slot = HISTSIZE - 1; + histogram[slot]++; + if (delta > 2000) + printk("wow! That was a " + "%ld millisec bump\n", + delta / 1000); + } + } + rtc_state = S_IDLE; + break; + } +#endif +} + +static inline void rtc_close_event(void) +{ +#ifdef CONFIG_RTC_HISTOGRAM + int i = 0; + unsigned long total = 0; + + for (i = 0; i < HISTSIZE; i++) + total += histogram[i]; + if (!total) + return; + + printk("\nrtc latency histogram of {%s/%d, %lu samples}:\n", + current->comm, current->pid, total); + for (i = 0; i < HISTSIZE; i++) { + if (histogram[i]) + printk("%d %d\n", i, histogram[i]); + } +#endif +} + #ifdef RTC_IRQ + /* * A very tiny interrupt handler. It runs with SA_INTERRUPT set, * but there is possibility of conflicting with the set_rtc_mmss() @@ -217,6 +380,8 @@ irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { + int mod; + /* * Can be an alarm interrupt, update complete interrupt, * or a periodic interrupt. We store the status in the @@ -238,19 +403,22 @@ rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) & 0xF0); } + mod = 0; if (rtc_status & RTC_TIMER_ON) - mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100); + mod = 1; spin_unlock (&rtc_lock); + if (mod) + mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100); /* Now do the rest of the actions */ spin_lock(&rtc_task_lock); if (rtc_callback) rtc_callback->func(rtc_callback->private_data); spin_unlock(&rtc_task_lock); - wake_up_interruptible(&rtc_wait); - kill_fasync (&rtc_async_queue, SIGIO, POLL_IN); + rtc_wake_event(); + wake_up_interruptible(&rtc_wait); return IRQ_HANDLED; } @@ -354,6 +522,8 @@ schedule(); } while (1); + rtc_read_event(); + if (count < sizeof(unsigned long)) retval = put_user(data, (unsigned int __user *)buf) ?: sizeof(int); else @@ -404,8 +574,8 @@ if (rtc_status & RTC_TIMER_ON) { spin_lock_irq (&rtc_lock); rtc_status &= ~RTC_TIMER_ON; - del_timer(&rtc_irq_timer); spin_unlock_irq (&rtc_lock); + del_timer(&rtc_irq_timer); } return 0; } @@ -423,9 +593,9 @@ if (!(rtc_status & RTC_TIMER_ON)) { spin_lock_irq (&rtc_lock); rtc_irq_timer.expires = jiffies + HZ/rtc_freq + 2*HZ/100; - add_timer(&rtc_irq_timer); rtc_status |= RTC_TIMER_ON; spin_unlock_irq (&rtc_lock); + add_timer(&rtc_irq_timer); } set_rtc_irq_bit(RTC_PIE); return 0; @@ -583,6 +753,11 @@ save_freq_select = CMOS_READ(RTC_FREQ_SELECT); CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); + /* + * Make CMOS date writes nonpreemptible even on PREEMPT_RT. + * There's a limit to everything! =B-) + */ + preempt_disable(); #ifdef CONFIG_MACH_DECSTATION CMOS_WRITE(real_yrs, RTC_DEC_YEAR); #endif @@ -592,6 +767,7 @@ CMOS_WRITE(hrs, RTC_HOURS); CMOS_WRITE(min, RTC_MINUTES); CMOS_WRITE(sec, RTC_SECONDS); + preempt_enable(); CMOS_WRITE(save_control, RTC_CONTROL); CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); @@ -689,6 +865,7 @@ if(rtc_status & RTC_IS_OPEN) goto out_busy; + rtc_open_event(); rtc_status |= RTC_IS_OPEN; rtc_irq_data = 0; @@ -710,6 +887,7 @@ { #ifdef RTC_IRQ unsigned char tmp; + int del; if (rtc_has_irq == 0) goto no_irq; @@ -728,11 +906,14 @@ CMOS_WRITE(tmp, RTC_CONTROL); CMOS_READ(RTC_INTR_FLAGS); } + del = 0; if (rtc_status & RTC_TIMER_ON) { rtc_status &= ~RTC_TIMER_ON; - del_timer(&rtc_irq_timer); + del = 1; } spin_unlock_irq(&rtc_lock); + if (del) + del_timer(&rtc_irq_timer); if (file->f_flags & FASYNC) { rtc_fasync (-1, file, 0); @@ -744,6 +925,7 @@ rtc_irq_data = 0; rtc_status &= ~RTC_IS_OPEN; spin_unlock_irq (&rtc_lock); + rtc_close_event(); return 0; } @@ -808,6 +990,7 @@ return -EIO; #else unsigned char tmp; + int del; spin_lock_irq(&rtc_lock); spin_lock(&rtc_task_lock); @@ -827,12 +1010,15 @@ CMOS_WRITE(tmp, RTC_CONTROL); CMOS_READ(RTC_INTR_FLAGS); } + del = 0; if (rtc_status & RTC_TIMER_ON) { rtc_status &= ~RTC_TIMER_ON; - del_timer(&rtc_irq_timer); + del = 1; } rtc_status &= ~RTC_IS_OPEN; spin_unlock(&rtc_task_lock); + if (del) + del_timer(&rtc_irq_timer); spin_unlock_irq(&rtc_lock); return 0; #endif @@ -894,7 +1080,6 @@ struct proc_dir_entry *ent; #if defined(__alpha__) || defined(__mips__) unsigned int year, ctrl; - unsigned long uip_watchdog; char *guess = NULL; #endif #ifdef __sparc__ @@ -1000,12 +1185,8 @@ /* Each operating system on an Alpha uses its own epoch. Let's try to guess which one we are using now. */ - uip_watchdog = jiffies; if (rtc_is_updating() != 0) - while (jiffies - uip_watchdog < 2*HZ/100) { - barrier(); - cpu_relax(); - } + msleep(2*HZ/100); spin_lock_irq(&rtc_lock); year = CMOS_READ(RTC_YEAR); @@ -1097,6 +1278,7 @@ static void rtc_dropped_irq(unsigned long data) { unsigned long freq; + int mod; spin_lock_irq (&rtc_lock); @@ -1106,8 +1288,9 @@ } /* Just in case someone disabled the timer from behind our back... */ + mod = 0; if (rtc_status & RTC_TIMER_ON) - mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100); + mod = 1; rtc_irq_data += ((rtc_freq/HZ)<<8); rtc_irq_data &= ~0xff; @@ -1116,6 +1299,8 @@ freq = rtc_freq; spin_unlock_irq(&rtc_lock); + if (mod) + mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100); printk(KERN_WARNING "rtc: lost some interrupts at %ldHz.\n", freq); @@ -1213,7 +1398,6 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm) { - unsigned long uip_watchdog = jiffies; unsigned char ctrl; #ifdef CONFIG_MACH_DECSTATION unsigned int real_year; @@ -1221,19 +1405,15 @@ /* * read RTC once any update in progress is done. The update - * can take just over 2ms. We wait 10 to 20ms. There is no need to + * can take just over 2ms. We wait 20ms. There is no need to * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP. * If you need to know *exactly* when a second has started, enable * periodic update complete interrupts, (via ioctl) and then * immediately read /dev/rtc which will block until you get the IRQ. * Once the read clears, read the RTC time (again via ioctl). Easy. */ - if (rtc_is_updating() != 0) - while (jiffies - uip_watchdog < 2*HZ/100) { - barrier(); - cpu_relax(); - } + msleep(2*HZ/100); /* * Only the values that we read from the RTC are set. We leave diff -urN linux-2.6.12-armirq/drivers/char/specialix.c linux-2.6.12-armirq-rt/drivers/char/specialix.c --- linux-2.6.12-armirq/drivers/char/specialix.c 2005-07-13 14:30:16.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/char/specialix.c 2005-07-16 16:41:55.000000000 +0200 @@ -2491,7 +2491,7 @@ #endif for (i = 0; i < SX_NBOARD; i++) - sx_board[i].lock = SPIN_LOCK_UNLOCKED; + spin_lock_init(&sx_board[i].lock); if (sx_init_drivers()) { func_exit(); diff -urN linux-2.6.12-armirq/drivers/char/sx.c linux-2.6.12-armirq-rt/drivers/char/sx.c --- linux-2.6.12-armirq/drivers/char/sx.c 2005-07-13 14:30:16.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/char/sx.c 2005-07-16 16:41:55.000000000 +0200 @@ -2321,7 +2321,7 @@ #ifdef NEW_WRITE_LOCKING port->gs.port_write_sem = MUTEX; #endif - port->gs.driver_lock = SPIN_LOCK_UNLOCKED; + spin_lock_init(&port->gs.driver_lock); /* * Initializing wait queue */ diff -urN linux-2.6.12-armirq/drivers/char/sysrq.c linux-2.6.12-armirq-rt/drivers/char/sysrq.c --- linux-2.6.12-armirq/drivers/char/sysrq.c 2005-07-13 14:30:16.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/char/sysrq.c 2005-07-16 16:41:55.000000000 +0200 @@ -153,6 +153,38 @@ .enable_mask = SYSRQ_ENABLE_DUMP, }; +#ifdef CONFIG_RT_DEADLOCK_DETECT + +static void sysrq_handle_showlocks(int key, struct pt_regs *pt_regs, + struct tty_struct *tty) +{ + show_all_locks(); +} + +static struct sysrq_key_op sysrq_showlocks_op = { + .handler = sysrq_handle_showlocks, + .help_msg = "show-all-locks(D)", + .action_msg = "Show Locks Held", +}; + +#endif + +#if defined(__i386__) + +static void sysrq_handle_showallregs(int key, struct pt_regs *pt_regs, + struct tty_struct *tty) +{ + nmi_show_all_regs(); +} + +static struct sysrq_key_op sysrq_showallregs_op = { + .handler = sysrq_handle_showallregs, + .help_msg = "showalLcpupc", + .action_msg = "Show Regs On All CPUs", +}; + +#endif + static void sysrq_handle_showstate(int key, struct pt_regs *pt_regs, struct tty_struct *tty) @@ -274,7 +306,11 @@ and will never arrive */ /* b */ &sysrq_reboot_op, /* c */ NULL, +#ifdef CONFIG_RT_DEADLOCK_DETECT +/* d */ &sysrq_showlocks_op, +#else /* d */ NULL, +#endif /* e */ &sysrq_term_op, /* f */ &sysrq_moom_op, /* g */ NULL, @@ -286,7 +322,11 @@ #else /* k */ NULL, #endif +#if defined(__i386__) +/* l */ &sysrq_showallregs_op, +#else /* l */ NULL, +#endif /* m */ &sysrq_showmem_op, /* n */ &sysrq_unrt_op, /* o */ NULL, /* This will often be registered diff -urN linux-2.6.12-armirq/drivers/char/tpm/tpm_nsc.c linux-2.6.12-armirq-rt/drivers/char/tpm/tpm_nsc.c --- linux-2.6.12-armirq/drivers/char/tpm/tpm_nsc.c 2005-07-13 14:30:16.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/char/tpm/tpm_nsc.c 2005-07-16 16:41:55.000000000 +0200 @@ -56,8 +56,7 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data) { int expired = 0; - struct timer_list status_timer = - TIMER_INITIALIZER(tpm_time_expired, jiffies + 10 * HZ, + DEFINE_TIMER(status_timer, tpm_time_expired, jiffies + 10 * HZ, (unsigned long) &expired); /* status immediately available check */ @@ -85,8 +84,7 @@ { int status; int expired = 0; - struct timer_list status_timer = - TIMER_INITIALIZER(tpm_time_expired, jiffies + 100, + DEFINE_TIMER(status_timer, tpm_time_expired, jiffies + 100, (unsigned long) &expired); /* status immediately available check */ diff -urN linux-2.6.12-armirq/drivers/char/tty_io.c linux-2.6.12-armirq-rt/drivers/char/tty_io.c --- linux-2.6.12-armirq/drivers/char/tty_io.c 2005-07-13 14:30:16.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/char/tty_io.c 2005-07-16 16:41:55.000000000 +0200 @@ -224,6 +224,7 @@ printk(KERN_WARNING "Warning: dev (%s) tty->count(%d) " "!= #fd's(%d) in %s\n", tty->name, tty->count, count, routine); + dump_stack(); return count; } #endif @@ -827,8 +828,8 @@ p->signal->tty = NULL; if (!p->signal->leader) continue; - send_group_sig_info(SIGHUP, SEND_SIG_PRIV, p); - send_group_sig_info(SIGCONT, SEND_SIG_PRIV, p); + group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p); + group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p); if (tty->pgrp > 0) p->signal->tty_old_pgrp = tty->pgrp; } while_each_task_pid(tty->session, PIDTYPE_SID, p); diff -urN linux-2.6.12-armirq/drivers/char/vt.c linux-2.6.12-armirq-rt/drivers/char/vt.c --- linux-2.6.12-armirq/drivers/char/vt.c 2005-07-13 14:30:16.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/char/vt.c 2005-07-16 16:41:55.000000000 +0200 @@ -2159,6 +2159,13 @@ if (vc->vc_mode != KD_TEXT) goto quit; + /* + * Skip kernel message from within a critical section going + * to a preemptible console (such as fbcon). + */ + if (in_atomic_rt() && vc->vc_sw->con_preemptible) + goto quit; + /* undraw cursor first */ if (IS_FG(vc)) hide_cursor(vc); @@ -2782,8 +2789,8 @@ } hide_cursor(vc); - del_timer_sync(&console_timer); - blank_timer_expired = 0; +// del_timer_sync(&console_timer); +// blank_timer_expired = 0; save_screen(vc); /* In case we need to reset origin, blanking hook returns 1 */ @@ -2796,8 +2803,8 @@ return; if (vesa_off_interval) { - blank_state = blank_vesa_wait, - mod_timer(&console_timer, jiffies + vesa_off_interval); + blank_state = blank_vesa_wait; +// mod_timer(&console_timer, jiffies + vesa_off_interval); } if (vesa_blank_mode) @@ -2834,8 +2841,11 @@ return; /* but leave console_blanked != 0 */ if (blankinterval) { - mod_timer(&console_timer, jiffies + blankinterval); - blank_state = blank_normal_wait; +#ifdef CONFIG_PREEMPT_RT + local_irq_enable(); +#endif +// mod_timer(&console_timer, jiffies + blankinterval); +// blank_state = blank_normal_wait; } console_blanked = 0; @@ -2886,16 +2896,16 @@ /* This isn't perfectly race free, but a race here would be mostly harmless, * at worse, we'll do a spurrious blank and it's unlikely */ - del_timer(&console_timer); - blank_timer_expired = 0; +// del_timer(&console_timer); +// blank_timer_expired = 0; if (ignore_poke || !vc_cons[fg_console].d || vc_cons[fg_console].d->vc_mode == KD_GRAPHICS) return; if (console_blanked) unblank_screen(); else if (blankinterval) { - mod_timer(&console_timer, jiffies + blankinterval); - blank_state = blank_normal_wait; +// mod_timer(&console_timer, jiffies + blankinterval); +// blank_state = blank_normal_wait; } } diff -urN linux-2.6.12-armirq/drivers/char/watchdog/mixcomwd.c linux-2.6.12-armirq-rt/drivers/char/watchdog/mixcomwd.c --- linux-2.6.12-armirq/drivers/char/watchdog/mixcomwd.c 2005-07-13 14:30:16.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/char/watchdog/mixcomwd.c 2005-07-16 16:41:55.000000000 +0200 @@ -59,7 +59,7 @@ static int watchdog_port; static int mixcomwd_timer_alive; -static struct timer_list mixcomwd_timer = TIMER_INITIALIZER(NULL, 0, 0); +static DEFINE_TIMER(mixcomwd_timer, NULL, 0, 0); static char expect_close; #ifdef CONFIG_WATCHDOG_NOWAYOUT diff -urN linux-2.6.12-armirq/drivers/char/watchdog/softdog.c linux-2.6.12-armirq-rt/drivers/char/watchdog/softdog.c --- linux-2.6.12-armirq/drivers/char/watchdog/softdog.c 2005-07-13 14:30:16.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/char/watchdog/softdog.c 2005-07-16 16:41:55.000000000 +0200 @@ -80,8 +80,7 @@ static void watchdog_fire(unsigned long); -static struct timer_list watchdog_ticktock = - TIMER_INITIALIZER(watchdog_fire, 0, 0); +static DEFINE_TIMER(watchdog_ticktock, watchdog_fire, 0, 0); static unsigned long timer_alive; static char expect_close; diff -urN linux-2.6.12-armirq/drivers/cpufreq/cpufreq.c linux-2.6.12-armirq-rt/drivers/cpufreq/cpufreq.c --- linux-2.6.12-armirq/drivers/cpufreq/cpufreq.c 2005-07-13 14:30:16.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/cpufreq/cpufreq.c 2005-07-16 16:41:55.000000000 +0200 @@ -605,7 +605,8 @@ policy->cpu = cpu; policy->cpus = cpumask_of_cpu(cpu); - init_MUTEX_LOCKED(&policy->lock); + init_MUTEX(&policy->lock); + down(&policy->lock); init_completion(&policy->kobj_unregister); INIT_WORK(&policy->update, handle_update, (void *)(long)cpu); @@ -614,6 +615,7 @@ */ ret = cpufreq_driver->init(policy); if (ret) { + up(&policy->lock); dprintk("initialization failed\n"); goto err_out; } @@ -626,8 +628,10 @@ strlcpy(policy->kobj.name, "cpufreq", KOBJ_NAME_LEN); ret = kobject_register(&policy->kobj); - if (ret) + if (ret) { + up(&policy->lock); goto err_out; + } /* set up files for this cpu device */ drv_attr = cpufreq_driver->attr; diff -urN linux-2.6.12-armirq/drivers/i2c/busses/i2c-s3c2410.c linux-2.6.12-armirq-rt/drivers/i2c/busses/i2c-s3c2410.c --- linux-2.6.12-armirq/drivers/i2c/busses/i2c-s3c2410.c 2005-07-13 14:30:16.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/i2c/busses/i2c-s3c2410.c 2005-07-16 16:41:55.000000000 +0200 @@ -573,7 +573,7 @@ }; static struct s3c24xx_i2c s3c24xx_i2c = { - .lock = SPIN_LOCK_UNLOCKED, + .lock = SPIN_LOCK_UNLOCKED(s3c24xx_i2c.lock), .wait = __WAIT_QUEUE_HEAD_INITIALIZER(s3c24xx_i2c.wait), .adap = { .name = "s3c2410-i2c", diff -urN linux-2.6.12-armirq/drivers/ide/ide-io.c linux-2.6.12-armirq-rt/drivers/ide/ide-io.c --- linux-2.6.12-armirq/drivers/ide/ide-io.c 2005-07-13 14:30:16.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/ide/ide-io.c 2005-07-16 16:41:55.000000000 +0200 @@ -1106,7 +1106,7 @@ ide_get_lock(ide_intr, hwgroup); /* caller must own ide_lock */ - BUG_ON(!irqs_disabled()); + BUG_ON_NONRT(!irqs_disabled()); while (!hwgroup->busy) { hwgroup->busy = 1; @@ -1360,7 +1360,7 @@ #endif /* DISABLE_IRQ_NOSYNC */ /* local CPU only, * as if we were handling an interrupt */ - local_irq_disable(); + local_irq_disable_nort(); if (hwgroup->polling) { startstop = handler(drive); } else if (drive_is_ready(drive)) { @@ -1556,8 +1556,10 @@ del_timer(&hwgroup->timer); spin_unlock(&ide_lock); +#ifndef CONFIG_PREEMPT_RT if (drive->unmask) local_irq_enable(); +#endif /* service this interrupt, may set handler for next interrupt */ startstop = handler(drive); spin_lock_irq(&ide_lock); diff -urN linux-2.6.12-armirq/drivers/ide/ide-iops.c linux-2.6.12-armirq-rt/drivers/ide/ide-iops.c --- linux-2.6.12-armirq/drivers/ide/ide-iops.c 2005-07-13 14:30:16.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/ide/ide-iops.c 2005-07-16 16:41:55.000000000 +0200 @@ -762,13 +762,11 @@ printk("%s: CHECK for good STATUS\n", drive->name); return 0; } - local_irq_save(flags); - SELECT_MASK(drive, 0); id = kmalloc(SECTOR_WORDS*4, GFP_ATOMIC); - if (!id) { - local_irq_restore(flags); + if (!id) return 0; - } + local_irq_save(flags); + SELECT_MASK(drive, 0); ata_input_data(drive, id, SECTOR_WORDS); (void) hwif->INB(IDE_STATUS_REG); /* clear drive IRQ */ local_irq_enable(); diff -urN linux-2.6.12-armirq/drivers/ide/ide-taskfile.c linux-2.6.12-armirq-rt/drivers/ide/ide-taskfile.c --- linux-2.6.12-armirq/drivers/ide/ide-taskfile.c 2005-07-13 14:30:17.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/ide/ide-taskfile.c 2005-07-16 16:41:55.000000000 +0200 @@ -265,7 +265,7 @@ ide_hwif_t *hwif = drive->hwif; struct scatterlist *sg = hwif->sg_table; struct page *page; -#ifdef CONFIG_HIGHMEM +#if defined(CONFIG_HIGHMEM) && !defined(CONFIG_PREEMPT_RT) unsigned long flags; #endif unsigned int offset; @@ -278,7 +278,7 @@ page = nth_page(page, (offset >> PAGE_SHIFT)); offset %= PAGE_SIZE; -#ifdef CONFIG_HIGHMEM +#if defined(CONFIG_HIGHMEM) && !defined(CONFIG_PREEMPT_RT) local_irq_save(flags); #endif buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset; @@ -298,7 +298,7 @@ taskfile_input_data(drive, buf, SECTOR_WORDS); kunmap_atomic(buf, KM_BIO_SRC_IRQ); -#ifdef CONFIG_HIGHMEM +#if defined(CONFIG_HIGHMEM) && !defined(CONFIG_PREEMPT_RT) local_irq_restore(flags); #endif } @@ -456,8 +456,10 @@ return startstop; } +#ifndef CONFIG_PREEMPT_RT if (!drive->unmask) local_irq_disable(); +#endif ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL); ide_pio_datablock(drive, rq, 1); diff -urN linux-2.6.12-armirq/drivers/ide/legacy/hd.c linux-2.6.12-armirq-rt/drivers/ide/legacy/hd.c --- linux-2.6.12-armirq/drivers/ide/legacy/hd.c 2005-07-13 14:30:17.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/ide/legacy/hd.c 2005-07-16 16:41:55.000000000 +0200 @@ -156,11 +156,13 @@ #if (HD_DELAY > 0) + +#include + unsigned long last_req; unsigned long read_timer(void) { - extern spinlock_t i8253_lock; unsigned long t, flags; int i; diff -urN linux-2.6.12-armirq/drivers/ieee1394/ieee1394_types.h linux-2.6.12-armirq-rt/drivers/ieee1394/ieee1394_types.h --- linux-2.6.12-armirq/drivers/ieee1394/ieee1394_types.h 2005-07-13 14:30:17.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/ieee1394/ieee1394_types.h 2005-07-16 16:41:55.000000000 +0200 @@ -19,7 +19,7 @@ spinlock_t lock; u8 next; u32 allocations; - struct semaphore count; + struct compat_semaphore count; }; #define HPSB_TPOOL_INIT(_tp) \ @@ -28,7 +28,7 @@ spin_lock_init(&(_tp)->lock); \ (_tp)->next = 0; \ (_tp)->allocations = 0; \ - sema_init(&(_tp)->count, 63); \ + sema_init(&(_tp)->count, 63); \ } while (0) diff -urN linux-2.6.12-armirq/drivers/ieee1394/nodemgr.c linux-2.6.12-armirq-rt/drivers/ieee1394/nodemgr.c --- linux-2.6.12-armirq/drivers/ieee1394/nodemgr.c 2005-07-13 14:30:17.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/ieee1394/nodemgr.c 2005-07-16 16:41:55.000000000 +0200 @@ -114,7 +114,7 @@ struct hpsb_host *host; struct list_head list; struct completion exited; - struct semaphore reset_sem; + struct compat_semaphore reset_sem; int pid; char daemon_name[15]; int kill_me; diff -urN linux-2.6.12-armirq/drivers/ieee1394/raw1394-private.h linux-2.6.12-armirq-rt/drivers/ieee1394/raw1394-private.h --- linux-2.6.12-armirq/drivers/ieee1394/raw1394-private.h 2005-07-13 14:30:17.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/ieee1394/raw1394-private.h 2005-07-16 16:41:55.000000000 +0200 @@ -29,7 +29,7 @@ struct list_head req_pending; struct list_head req_complete; - struct semaphore complete_sem; + struct compat_semaphore complete_sem; spinlock_t reqlists_lock; wait_queue_head_t poll_wait_complete; diff -urN linux-2.6.12-armirq/drivers/input/gameport/gameport.c linux-2.6.12-armirq-rt/drivers/input/gameport/gameport.c --- linux-2.6.12-armirq/drivers/input/gameport/gameport.c 2005-07-13 14:30:17.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/input/gameport/gameport.c 2005-07-16 16:41:55.000000000 +0200 @@ -61,12 +61,13 @@ #if defined(__i386__) +#include + #define DELTA(x,y) ((y)-(x)+((y)<(x)?1193182/HZ:0)) #define GET_TIME(x) do { x = get_time_pit(); } while (0) static unsigned int get_time_pit(void) { - extern spinlock_t i8253_lock; unsigned long flags; unsigned int count; diff -urN linux-2.6.12-armirq/drivers/input/joystick/analog.c linux-2.6.12-armirq-rt/drivers/input/joystick/analog.c --- linux-2.6.12-armirq/drivers/input/joystick/analog.c 2005-07-13 14:30:17.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/input/joystick/analog.c 2005-07-16 16:41:55.000000000 +0200 @@ -140,12 +140,14 @@ */ #ifdef __i386__ + +#include + #define GET_TIME(x) do { if (cpu_has_tsc) rdtscl(x); else x = get_time_pit(); } while (0) #define DELTA(x,y) (cpu_has_tsc ? ((y) - (x)) : ((x) - (y) + ((x) < (y) ? CLOCK_TICK_RATE / HZ : 0))) #define TIME_NAME (cpu_has_tsc?"TSC":"PIT") static unsigned int get_time_pit(void) { - extern spinlock_t i8253_lock; unsigned long flags; unsigned int count; diff -urN linux-2.6.12-armirq/drivers/media/dvb/dvb-core/dvb_frontend.c linux-2.6.12-armirq-rt/drivers/media/dvb/dvb-core/dvb_frontend.c --- linux-2.6.12-armirq/drivers/media/dvb/dvb-core/dvb_frontend.c 2005-07-13 14:30:18.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/media/dvb/dvb-core/dvb_frontend.c 2005-07-16 16:41:55.000000000 +0200 @@ -94,7 +94,7 @@ struct dvb_device *dvbdev; struct dvb_frontend_parameters parameters; struct dvb_fe_events events; - struct semaphore sem; + struct compat_semaphore sem; struct list_head list_head; wait_queue_head_t wait_queue; pid_t thread_pid; @@ -535,7 +535,7 @@ printk("dvb_frontend_stop: thread PID %d already died\n", fepriv->thread_pid); /* make sure the mutex was not held by the thread */ - init_MUTEX (&fepriv->sem); + sema_init (&fepriv->sem, 1); return; } @@ -876,10 +876,10 @@ fepriv = fe->frontend_priv; memset(fe->frontend_priv, 0, sizeof(struct dvb_frontend_private)); - init_MUTEX (&fepriv->sem); + sema_init (&fepriv->sem, 1); init_waitqueue_head (&fepriv->wait_queue); init_waitqueue_head (&fepriv->events.wait_queue); - init_MUTEX (&fepriv->events.sem); + sema_init (&fepriv->events.sem, 1); fe->dvb = dvb; fepriv->inversion = INVERSION_OFF; diff -urN linux-2.6.12-armirq/drivers/media/dvb/dvb-core/dvb_frontend.h linux-2.6.12-armirq-rt/drivers/media/dvb/dvb-core/dvb_frontend.h --- linux-2.6.12-armirq/drivers/media/dvb/dvb-core/dvb_frontend.h 2005-07-13 14:30:18.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/media/dvb/dvb-core/dvb_frontend.h 2005-07-16 16:41:55.000000000 +0200 @@ -108,7 +108,7 @@ int eventr; int overflow; wait_queue_head_t wait_queue; - struct semaphore sem; + struct compat_semaphore sem; }; struct dvb_frontend { diff -urN linux-2.6.12-armirq/drivers/media/video/cx88/cx88-video.c linux-2.6.12-armirq-rt/drivers/media/video/cx88/cx88-video.c --- linux-2.6.12-armirq/drivers/media/video/cx88/cx88-video.c 2005-07-13 14:30:18.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/media/video/cx88/cx88-video.c 2005-07-16 16:41:55.000000000 +0200 @@ -261,7 +261,7 @@ .default_value = 0, .type = V4L2_CTRL_TYPE_INTEGER, }, - .off = 0, + .off = 128, .reg = MO_HUE, .mask = 0x00ff, .shift = 0, diff -urN linux-2.6.12-armirq/drivers/media/video/zr36120_i2c.c linux-2.6.12-armirq-rt/drivers/media/video/zr36120_i2c.c --- linux-2.6.12-armirq/drivers/media/video/zr36120_i2c.c 2005-07-13 14:30:18.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/media/video/zr36120_i2c.c 2005-07-16 16:41:55.000000000 +0200 @@ -120,7 +120,7 @@ I2C_BUSID_ZORAN, NULL, - SPIN_LOCK_UNLOCKED, + SPIN_LOCK_UNLOCKED(zoran_i2c_bus_template.lock), attach_inform, detach_inform, diff -urN linux-2.6.12-armirq/drivers/net/3c59x.c linux-2.6.12-armirq-rt/drivers/net/3c59x.c --- linux-2.6.12-armirq/drivers/net/3c59x.c 2005-07-13 14:30:20.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/net/3c59x.c 2005-07-16 16:41:55.000000000 +0200 @@ -956,9 +956,9 @@ struct vortex_private *vp = netdev_priv(dev); unsigned long flags; local_save_flags(flags); - local_irq_disable(); + local_irq_disable_nort(); (vp->full_bus_master_rx ? boomerang_interrupt:vortex_interrupt)(dev->irq,dev,NULL); - local_irq_restore(flags); + local_irq_restore_nort(flags); } #endif @@ -1987,13 +1987,17 @@ /* * Block interrupts because vortex_interrupt does a bare spin_lock() */ +#ifndef CONFIG_PREEMPT_RT unsigned long flags; local_irq_save(flags); +#endif if (vp->full_bus_master_tx) boomerang_interrupt(dev->irq, dev, NULL); else vortex_interrupt(dev->irq, dev, NULL); +#ifndef CONFIG_PREEMPT_RT local_irq_restore(flags); +#endif } } diff -urN linux-2.6.12-armirq/drivers/net/atari_bionet.c linux-2.6.12-armirq-rt/drivers/net/atari_bionet.c --- linux-2.6.12-armirq/drivers/net/atari_bionet.c 2005-07-13 14:30:20.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/net/atari_bionet.c 2005-07-16 16:41:55.000000000 +0200 @@ -155,7 +155,7 @@ static struct net_device_stats *net_get_stats(struct net_device *dev); static void bionet_tick(unsigned long); -static struct timer_list bionet_timer = TIMER_INITIALIZER(bionet_tick, 0, 0); +static DEFINE_TIMER(bionet_timer, bionet_tick, 0, 0); #define STRAM_ADDR(a) (((a) & 0xff000000) == 0) diff -urN linux-2.6.12-armirq/drivers/net/atari_pamsnet.c linux-2.6.12-armirq-rt/drivers/net/atari_pamsnet.c --- linux-2.6.12-armirq/drivers/net/atari_pamsnet.c 2005-07-13 14:30:20.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/net/atari_pamsnet.c 2005-07-16 16:41:55.000000000 +0200 @@ -165,7 +165,7 @@ static irqreturn_t pamsnet_intr(int irq, void *data, struct pt_regs *fp); -static struct timer_list pamsnet_timer = TIMER_INITIALIZER(pamsnet_tick, 0, 0); +static DEFINE_TIMER(pamsnet_timer, pamsnet_tick, 0, 0); #define STRAM_ADDR(a) (((a) & 0xff000000) == 0) diff -urN linux-2.6.12-armirq/drivers/net/cris/eth_v10.c linux-2.6.12-armirq-rt/drivers/net/cris/eth_v10.c --- linux-2.6.12-armirq/drivers/net/cris/eth_v10.c 2005-07-13 14:30:20.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/net/cris/eth_v10.c 2005-07-16 16:41:55.000000000 +0200 @@ -384,8 +384,8 @@ static unsigned int network_tr_ctrl_shadow = 0; /* Network speed indication. */ -static struct timer_list speed_timer = TIMER_INITIALIZER(NULL, 0, 0); -static struct timer_list clear_led_timer = TIMER_INITIALIZER(NULL, 0, 0); +static DEFINE_TIMER(speed_timer, NULL, 0, 0); +static DEFINE_TIMER(clear_led_timer, NULL, 0, 0); static int current_speed; /* Speed read from transceiver */ static int current_speed_selection; /* Speed selected by user */ static unsigned long led_next_time; @@ -393,7 +393,7 @@ static int rx_queue_len; /* Duplex */ -static struct timer_list duplex_timer = TIMER_INITIALIZER(NULL, 0, 0); +static DEFINE_TIMER(duplex_timer, NULL, 0, 0); static int full_duplex; static enum duplex current_duplex; diff -urN linux-2.6.12-armirq/drivers/net/e1000/e1000_main.c linux-2.6.12-armirq-rt/drivers/net/e1000/e1000_main.c --- linux-2.6.12-armirq/drivers/net/e1000/e1000_main.c 2005-07-13 14:30:20.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/net/e1000/e1000_main.c 2005-07-16 16:41:55.000000000 +0200 @@ -2270,10 +2270,10 @@ if(adapter->pcix_82544) count += nr_frags; - local_irq_save(flags); + local_irq_save_nort(flags); if (!spin_trylock(&adapter->tx_lock)) { /* Collision - tell upper layer to requeue */ - local_irq_restore(flags); + local_irq_restore_nort(flags); return NETDEV_TX_LOCKED; } if(adapter->hw.tx_pkt_filtering && (adapter->hw.mac_type == e1000_82573) ) diff -urN linux-2.6.12-armirq/drivers/net/hamradio/yam.c linux-2.6.12-armirq-rt/drivers/net/hamradio/yam.c --- linux-2.6.12-armirq/drivers/net/hamradio/yam.c 2005-07-13 14:30:20.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/net/hamradio/yam.c 2005-07-16 16:41:55.000000000 +0200 @@ -170,7 +170,7 @@ static char ax25_test[7] = {'L' << 1, 'I' << 1, 'N' << 1, 'U' << 1, 'X' << 1, ' ' << 1, '1' << 1}; -static struct timer_list yam_timer = TIMER_INITIALIZER(NULL, 0, 0); +static DEFINE_TIMER(yam_timer, NULL, 0, 0); /* --------------------------------------------------------------------- */ diff -urN linux-2.6.12-armirq/drivers/net/mv643xx_eth.c linux-2.6.12-armirq-rt/drivers/net/mv643xx_eth.c --- linux-2.6.12-armirq/drivers/net/mv643xx_eth.c 2005-07-13 14:30:20.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/net/mv643xx_eth.c 2005-07-16 16:41:55.000000000 +0200 @@ -95,7 +95,7 @@ static void __iomem *mv643xx_eth_shared_base; /* used to protect MV643XX_ETH_SMI_REG, which is shared across ports */ -static spinlock_t mv643xx_eth_phy_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(mv643xx_eth_phy_lock); static inline u32 mv_read(int offset) { diff -urN linux-2.6.12-armirq/drivers/net/netconsole.c linux-2.6.12-armirq-rt/drivers/net/netconsole.c --- linux-2.6.12-armirq/drivers/net/netconsole.c 2005-07-13 14:30:20.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/net/netconsole.c 2005-07-16 16:41:55.000000000 +0200 @@ -75,10 +75,19 @@ return; local_irq_save(flags); +#ifdef CONFIG_PREEMPT_RT + /* + * A bit hairy. Netconsole uses mutexes (indirectly) and + * thus must have interrupts enabled: + */ + local_irq_enable(); +#endif for(left = len; left; ) { frag = min(left, MAX_PRINT_CHUNK); + WARN_ON_RT(irqs_disabled()); netpoll_send_udp(&np, msg, frag); + WARN_ON_RT(irqs_disabled()); msg += frag; left -= frag; } diff -urN linux-2.6.12-armirq/drivers/net/ns83820.c linux-2.6.12-armirq-rt/drivers/net/ns83820.c --- linux-2.6.12-armirq/drivers/net/ns83820.c 2005-07-13 14:30:20.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/net/ns83820.c 2005-07-16 16:41:55.000000000 +0200 @@ -1013,8 +1013,6 @@ struct ns83820 *dev = PRIV(ndev); u32 cmdsts, tx_done_idx, *desc; - spin_lock_irq(&dev->tx_lock); - dprintk("do_tx_done(%p)\n", ndev); tx_done_idx = dev->tx_done_idx; desc = dev->tx_descs + (tx_done_idx * DESC_SIZE); @@ -1070,7 +1068,6 @@ netif_start_queue(ndev); netif_wake_queue(ndev); } - spin_unlock_irq(&dev->tx_lock); } static void ns83820_cleanup_tx(struct ns83820 *dev) @@ -1371,7 +1368,9 @@ * work has accumulated */ if ((ISR_TXDESC | ISR_TXIDLE | ISR_TXOK | ISR_TXERR) & isr) { + spin_lock_irq(&dev->tx_lock); do_tx_done(ndev); + spin_unlock_irq(&dev->tx_lock); /* Disable TxOk if there are no outstanding tx packets. */ @@ -1456,7 +1455,7 @@ u32 tx_done_idx, *desc; unsigned long flags; - local_irq_save(flags); + spin_lock_irqsave(&dev->tx_lock, flags); tx_done_idx = dev->tx_done_idx; desc = dev->tx_descs + (tx_done_idx * DESC_SIZE); @@ -1483,7 +1482,7 @@ ndev->name, tx_done_idx, dev->tx_free_idx, le32_to_cpu(desc[DESC_CMDSTS])); - local_irq_restore(flags); + spin_unlock_irqrestore(&dev->tx_lock, flags); } static void ns83820_tx_watch(unsigned long data) diff -urN linux-2.6.12-armirq/drivers/net/ppp_async.c linux-2.6.12-armirq-rt/drivers/net/ppp_async.c --- linux-2.6.12-armirq/drivers/net/ppp_async.c 2005-07-13 14:30:20.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/net/ppp_async.c 2005-07-16 16:41:55.000000000 +0200 @@ -65,7 +65,7 @@ struct tasklet_struct tsk; atomic_t refcnt; - struct semaphore dead_sem; + struct compat_semaphore dead_sem; struct ppp_channel chan; /* interface to generic ppp layer */ unsigned char obuf[OBUFSIZE]; }; diff -urN linux-2.6.12-armirq/drivers/net/ppp_synctty.c linux-2.6.12-armirq-rt/drivers/net/ppp_synctty.c --- linux-2.6.12-armirq/drivers/net/ppp_synctty.c 2005-07-13 14:30:20.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/net/ppp_synctty.c 2005-07-16 16:41:55.000000000 +0200 @@ -70,7 +70,7 @@ struct tasklet_struct tsk; atomic_t refcnt; - struct semaphore dead_sem; + struct compat_semaphore dead_sem; struct ppp_channel chan; /* interface to generic ppp layer */ }; diff -urN linux-2.6.12-armirq/drivers/net/tg3.c linux-2.6.12-armirq-rt/drivers/net/tg3.c --- linux-2.6.12-armirq/drivers/net/tg3.c 2005-07-13 14:30:20.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/net/tg3.c 2005-07-16 16:41:55.000000000 +0200 @@ -3247,11 +3247,8 @@ * So we really do need to disable interrupts when taking * tx_lock here. */ - local_irq_save(flags); - if (!spin_trylock(&tp->tx_lock)) { - local_irq_restore(flags); + if (!spin_trylock_irqsave(&tp->tx_lock, flags)) return NETDEV_TX_LOCKED; - } /* This is a hard error, log it. */ if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->nr_frags + 1))) { diff -urN linux-2.6.12-armirq/drivers/net/tulip/tulip_core.c linux-2.6.12-armirq-rt/drivers/net/tulip/tulip_core.c --- linux-2.6.12-armirq/drivers/net/tulip/tulip_core.c 2005-07-13 14:30:21.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/net/tulip/tulip_core.c 2005-07-16 16:41:55.000000000 +0200 @@ -1802,6 +1802,7 @@ pci_iounmap(pdev, tp->base_addr); free_netdev (dev); pci_release_regions (pdev); + pci_disable_device (pdev); pci_set_drvdata (pdev, NULL); /* pci_power_off (pdev, -1); */ diff -urN linux-2.6.12-armirq/drivers/oprofile/oprofilefs.c linux-2.6.12-armirq-rt/drivers/oprofile/oprofilefs.c --- linux-2.6.12-armirq/drivers/oprofile/oprofilefs.c 2005-07-13 14:30:21.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/oprofile/oprofilefs.c 2005-07-16 16:41:55.000000000 +0200 @@ -21,7 +21,7 @@ #define OPROFILEFS_MAGIC 0x6f70726f -DEFINE_SPINLOCK(oprofilefs_lock); +DEFINE_RAW_SPINLOCK(oprofilefs_lock); static struct inode * oprofilefs_get_inode(struct super_block * sb, int mode) { diff -urN linux-2.6.12-armirq/drivers/parisc/iosapic.c linux-2.6.12-armirq-rt/drivers/parisc/iosapic.c --- linux-2.6.12-armirq/drivers/parisc/iosapic.c 2005-07-13 14:30:21.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/parisc/iosapic.c 2005-07-16 16:41:55.000000000 +0200 @@ -215,7 +215,7 @@ #define IOSAPIC_IRDT_ID_EID_SHIFT 0x10 -static spinlock_t iosapic_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(iosapic_lock); static inline void iosapic_eoi(void __iomem *addr, unsigned int data) { diff -urN linux-2.6.12-armirq/drivers/pci/hotplug/cpci_hotplug_core.c linux-2.6.12-armirq-rt/drivers/pci/hotplug/cpci_hotplug_core.c --- linux-2.6.12-armirq/drivers/pci/hotplug/cpci_hotplug_core.c 2005-07-13 14:30:21.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/pci/hotplug/cpci_hotplug_core.c 2005-07-16 16:41:55.000000000 +0200 @@ -60,8 +60,8 @@ static atomic_t extracting; int cpci_debug; static struct cpci_hp_controller *controller; -static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */ -static struct semaphore thread_exit; /* guard ensure thread has exited before calling it quits */ +static struct compat_semaphore event_semaphore; /* mutex for process loop (up if something to process) */ +static struct compat_semaphore thread_exit; /* guard ensure thread has exited before calling it quits */ static int thread_finished = 1; static int enable_slot(struct hotplug_slot *slot); diff -urN linux-2.6.12-armirq/drivers/pci/hotplug/cpqphp_ctrl.c linux-2.6.12-armirq-rt/drivers/pci/hotplug/cpqphp_ctrl.c --- linux-2.6.12-armirq/drivers/pci/hotplug/cpqphp_ctrl.c 2005-07-13 14:30:21.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/pci/hotplug/cpqphp_ctrl.c 2005-07-16 16:41:55.000000000 +0200 @@ -45,8 +45,8 @@ u8 behind_bridge, struct resource_lists *resources); static void interrupt_event_handler(struct controller *ctrl); -static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */ -static struct semaphore event_exit; /* guard ensure thread has exited before calling it quits */ +static struct compat_semaphore event_semaphore; /* mutex for process loop (up if something to process) */ +static struct compat_semaphore event_exit; /* guard ensure thread has exited before calling it quits */ static int event_finished; static unsigned long pushbutton_pending; /* = 0 */ diff -urN linux-2.6.12-armirq/drivers/pci/hotplug/ibmphp_hpc.c linux-2.6.12-armirq-rt/drivers/pci/hotplug/ibmphp_hpc.c --- linux-2.6.12-armirq/drivers/pci/hotplug/ibmphp_hpc.c 2005-07-13 14:30:21.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/pci/hotplug/ibmphp_hpc.c 2005-07-16 16:41:55.000000000 +0200 @@ -104,7 +104,7 @@ static struct semaphore sem_hpcaccess; // lock access to HPC static struct semaphore semOperations; // lock all operations and // access to data structures -static struct semaphore sem_exit; // make sure polling thread goes away +static struct compat_semaphore sem_exit; // make sure polling thread goes away //---------------------------------------------------------------------------- // local function prototypes //---------------------------------------------------------------------------- diff -urN linux-2.6.12-armirq/drivers/pci/hotplug/pciehp_ctrl.c linux-2.6.12-armirq-rt/drivers/pci/hotplug/pciehp_ctrl.c --- linux-2.6.12-armirq/drivers/pci/hotplug/pciehp_ctrl.c 2005-07-13 14:30:21.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/pci/hotplug/pciehp_ctrl.c 2005-07-16 16:41:55.000000000 +0200 @@ -48,8 +48,8 @@ u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev); static void interrupt_event_handler(struct controller *ctrl); -static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */ -static struct semaphore event_exit; /* guard ensure thread has exited before calling it quits */ +static struct compat_semaphore event_semaphore; /* mutex for process loop (up if something to process) */ +static struct compat_semaphore event_exit; /* guard ensure thread has exited before calling it quits */ static int event_finished; static unsigned long pushbutton_pending; /* = 0 */ static unsigned long surprise_rm_pending; /* = 0 */ diff -urN linux-2.6.12-armirq/drivers/pci/hotplug/shpchp_ctrl.c linux-2.6.12-armirq-rt/drivers/pci/hotplug/shpchp_ctrl.c --- linux-2.6.12-armirq/drivers/pci/hotplug/shpchp_ctrl.c 2005-07-13 14:30:21.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/pci/hotplug/shpchp_ctrl.c 2005-07-16 16:41:55.000000000 +0200 @@ -47,8 +47,8 @@ u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev); static void interrupt_event_handler(struct controller *ctrl); -static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */ -static struct semaphore event_exit; /* guard ensure thread has exited before calling it quits */ +static struct compat_semaphore event_semaphore; /* mutex for process loop (up if something to process) */ +static struct compat_semaphore event_exit; /* guard ensure thread has exited before calling it quits */ static int event_finished; static unsigned long pushbutton_pending; /* = 0 */ diff -urN linux-2.6.12-armirq/drivers/pcmcia/ds.c linux-2.6.12-armirq-rt/drivers/pcmcia/ds.c --- linux-2.6.12-armirq/drivers/pcmcia/ds.c 2005-07-13 14:30:21.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/pcmcia/ds.c 2005-07-16 16:41:55.000000000 +0200 @@ -436,9 +436,13 @@ { cistpl_manfid_t manf_id; cistpl_funcid_t func_id; - cistpl_vers_1_t vers1; + cistpl_vers_1_t *vers1; unsigned int i; + vers1 = kmalloc(sizeof(*vers1), GFP_KERNEL); + if (!vers1) + return -ENOMEM; + if (!pccard_read_tuple(p_dev->socket, p_dev->func, CISTPL_MANFID, &manf_id)) { p_dev->manf_id = manf_id.manf; @@ -455,23 +459,30 @@ /* rule of thumb: cards with no FUNCID, but with * common memory device geometry information, are * probably memory cards (from pcmcia-cs) */ - cistpl_device_geo_t devgeo; + cistpl_device_geo_t *devgeo; + + devgeo = kmalloc(sizeof(*devgeo), GFP_KERNEL); + if (!devgeo) { + kfree(vers1); + return -ENOMEM; + } if (!pccard_read_tuple(p_dev->socket, p_dev->func, - CISTPL_DEVICE_GEO, &devgeo)) { + CISTPL_DEVICE_GEO, devgeo)) { ds_dbg(0, "mem device geometry probably means " "FUNCID_MEMORY\n"); p_dev->func_id = CISTPL_FUNCID_MEMORY; p_dev->has_func_id = 1; } + kfree(devgeo); } if (!pccard_read_tuple(p_dev->socket, p_dev->func, CISTPL_VERS_1, - &vers1)) { - for (i=0; i < vers1.ns; i++) { + vers1)) { + for (i=0; i < vers1->ns; i++) { char *tmp; unsigned int length; - tmp = vers1.str + vers1.ofs[i]; + tmp = vers1->str + vers1->ofs[i]; length = strlen(tmp) + 1; if ((length < 3) || (length > 255)) @@ -487,6 +498,7 @@ } } + kfree(vers1); return 0; } @@ -856,7 +868,9 @@ rescan: p_dev->cardmgr = p_drv; - pcmcia_device_query(p_dev); + ret = pcmcia_device_query(p_dev); + if (ret) + goto err_put_module; /* * Prevent this racing with a card insertion. diff -urN linux-2.6.12-armirq/drivers/s390/char/vmlogrdr.c linux-2.6.12-armirq-rt/drivers/s390/char/vmlogrdr.c --- linux-2.6.12-armirq/drivers/s390/char/vmlogrdr.c 2005-07-13 14:30:21.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/s390/char/vmlogrdr.c 2005-07-16 16:41:55.000000000 +0200 @@ -145,7 +145,7 @@ .recording_name = "EREP", .minor_num = 0, .buffer_free = 1, - .priv_lock = SPIN_LOCK_UNLOCKED, + .priv_lock = SPIN_LOCK_UNLOCKED(sys_ser[0].priv_lock), .autorecording = 1, .autopurge = 1, }, @@ -154,7 +154,7 @@ .recording_name = "ACCOUNT", .minor_num = 1, .buffer_free = 1, - .priv_lock = SPIN_LOCK_UNLOCKED, + .priv_lock = SPIN_LOCK_UNLOCKED(sys_ser[1].priv_lock), .autorecording = 1, .autopurge = 1, }, @@ -163,7 +163,7 @@ .recording_name = "SYMPTOM", .minor_num = 2, .buffer_free = 1, - .priv_lock = SPIN_LOCK_UNLOCKED, + .priv_lock = SPIN_LOCK_UNLOCKED(sys_ser[2].priv_lock), .autorecording = 1, .autopurge = 1, } diff -urN linux-2.6.12-armirq/drivers/s390/cio/cmf.c linux-2.6.12-armirq-rt/drivers/s390/cio/cmf.c --- linux-2.6.12-armirq/drivers/s390/cio/cmf.c 2005-07-13 14:30:21.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/s390/cio/cmf.c 2005-07-16 16:41:55.000000000 +0200 @@ -297,7 +297,7 @@ }; static struct cmb_area cmb_area = { - .lock = SPIN_LOCK_UNLOCKED, + .lock = SPIN_LOCK_UNLOCKED(cmb_area.lock), .list = LIST_HEAD_INIT(cmb_area.list), .num_channels = 1024, }; diff -urN linux-2.6.12-armirq/drivers/sbus/char/aurora.c linux-2.6.12-armirq-rt/drivers/sbus/char/aurora.c --- linux-2.6.12-armirq/drivers/sbus/char/aurora.c 2005-07-13 14:30:22.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/sbus/char/aurora.c 2005-07-16 16:41:55.000000000 +0200 @@ -871,8 +871,7 @@ #ifdef AURORA_INT_DEBUG static void aurora_timer (unsigned long ignored); -static struct timer_list aurora_poll_timer = - TIMER_INITIALIZER(aurora_timer, 0, 0); +static DEFINE_TIMER(aurora_poll_timer, aurora_timer, 0, 0); static void aurora_timer (unsigned long ignored) diff -urN linux-2.6.12-armirq/drivers/sbus/char/cpwatchdog.c linux-2.6.12-armirq-rt/drivers/sbus/char/cpwatchdog.c --- linux-2.6.12-armirq/drivers/sbus/char/cpwatchdog.c 2005-07-13 14:30:22.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/sbus/char/cpwatchdog.c 2005-07-16 16:41:55.000000000 +0200 @@ -155,7 +155,7 @@ }; static struct wd_device wd_dev = { - 0, SPIN_LOCK_UNLOCKED, 0, 0, 0, 0, + 0, SPIN_LOCK_UNLOCKED(wd_dev.lock), 0, 0, 0, 0, }; static struct timer_list wd_timer; diff -urN linux-2.6.12-armirq/drivers/scsi/aacraid/aacraid.h linux-2.6.12-armirq-rt/drivers/scsi/aacraid/aacraid.h --- linux-2.6.12-armirq/drivers/scsi/aacraid/aacraid.h 2005-07-13 14:30:22.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/scsi/aacraid/aacraid.h 2005-07-16 16:41:55.000000000 +0200 @@ -666,7 +666,7 @@ u32 unique; // unique value representing this context ulong jiffies; // used for cleanup - dmb changed to ulong struct list_head next; // used to link context's into a linked list - struct semaphore wait_sem; // this is used to wait for the next fib to arrive. + struct compat_semaphore wait_sem; // this is used to wait for the next fib to arrive. int wait; // Set to true when thread is in WaitForSingleObject unsigned long count; // total number of FIBs on FibList struct list_head fib_list; // this holds fibs and their attachd hw_fibs @@ -733,7 +733,7 @@ * This is the event the sendfib routine will wait on if the * caller did not pass one and this is synch io. */ - struct semaphore event_wait; + struct compat_semaphore event_wait; spinlock_t event_lock; u32 done; /* gets set to 1 when fib is complete */ diff -urN linux-2.6.12-armirq/drivers/scsi/aic7xxx/aic79xx_osm.h linux-2.6.12-armirq-rt/drivers/scsi/aic7xxx/aic79xx_osm.h --- linux-2.6.12-armirq/drivers/scsi/aic7xxx/aic79xx_osm.h 2005-07-13 14:30:22.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/scsi/aic7xxx/aic79xx_osm.h 2005-07-16 16:41:55.000000000 +0200 @@ -529,9 +529,9 @@ struct timer_list completeq_timer; struct timer_list reset_timer; struct timer_list stats_timer; - struct semaphore eh_sem; - struct semaphore dv_sem; - struct semaphore dv_cmd_sem; /* XXX This needs to be in + struct compat_semaphore eh_sem; + struct compat_semaphore dv_sem; + struct compat_semaphore dv_cmd_sem; /* XXX This needs to be in * the target struct */ struct scsi_device *dv_scsi_dev; diff -urN linux-2.6.12-armirq/drivers/scsi/aic7xxx/aic7xxx_osm.h linux-2.6.12-armirq-rt/drivers/scsi/aic7xxx/aic7xxx_osm.h --- linux-2.6.12-armirq/drivers/scsi/aic7xxx/aic7xxx_osm.h 2005-07-13 14:30:22.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/scsi/aic7xxx/aic7xxx_osm.h 2005-07-16 16:41:55.000000000 +0200 @@ -450,7 +450,7 @@ spinlock_t spin_lock; u_int qfrozen; struct timer_list reset_timer; - struct semaphore eh_sem; + struct compat_semaphore eh_sem; struct Scsi_Host *host; /* pointer to scsi host */ #define AHC_LINUX_NOIRQ ((uint32_t)~0) uint32_t irq; /* IRQ for this adapter */ diff -urN linux-2.6.12-armirq/drivers/scsi/pluto.c linux-2.6.12-armirq-rt/drivers/scsi/pluto.c --- linux-2.6.12-armirq/drivers/scsi/pluto.c 2005-07-13 14:30:23.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/scsi/pluto.c 2005-07-16 16:41:55.000000000 +0200 @@ -95,8 +95,7 @@ int i, retry, nplutos; fc_channel *fc; Scsi_Device dev; - struct timer_list fc_timer = - TIMER_INITIALIZER(pluto_detect_timeout, 0, 0); + struct DEFINE_TIMER(fc_timer, pluto_detect_timeout, 0, 0); tpnt->proc_name = "pluto"; fcscount = 0; diff -urN linux-2.6.12-armirq/drivers/scsi/qla2xxx/qla_def.h linux-2.6.12-armirq-rt/drivers/scsi/qla2xxx/qla_def.h --- linux-2.6.12-armirq/drivers/scsi/qla2xxx/qla_def.h 2005-07-13 14:30:24.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/scsi/qla2xxx/qla_def.h 2005-07-16 16:41:55.000000000 +0200 @@ -2217,7 +2217,7 @@ spinlock_t mbx_reg_lock; /* Mbx Cmd Register Lock */ struct semaphore mbx_cmd_sem; /* Serialialize mbx access */ - struct semaphore mbx_intr_sem; /* Used for completion notification */ + struct compat_semaphore mbx_intr_sem; /* Used for completion notification */ uint32_t mbx_flags; #define MBX_IN_PROGRESS BIT_0 diff -urN linux-2.6.12-armirq/drivers/scsi/qla2xxx/qla_os.c linux-2.6.12-armirq-rt/drivers/scsi/qla2xxx/qla_os.c --- linux-2.6.12-armirq/drivers/scsi/qla2xxx/qla_os.c 2005-07-13 14:30:24.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/scsi/qla2xxx/qla_os.c 2005-07-16 16:41:55.000000000 +0200 @@ -1920,12 +1920,13 @@ static int qla2x00_do_dpc(void *data) { - DECLARE_MUTEX_LOCKED(sem); + DECLARE_MUTEX(sem); scsi_qla_host_t *ha; fc_port_t *fcport; uint8_t status; uint16_t next_loopid; + down(&sem); ha = (scsi_qla_host_t *)data; lock_kernel(); diff -urN linux-2.6.12-armirq/drivers/serial/cpm_uart/cpm_uart_core.c linux-2.6.12-armirq-rt/drivers/serial/cpm_uart/cpm_uart_core.c --- linux-2.6.12-armirq/drivers/serial/cpm_uart/cpm_uart_core.c 2005-07-13 14:30:25.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/serial/cpm_uart/cpm_uart_core.c 2005-07-16 16:41:55.000000000 +0200 @@ -864,7 +864,7 @@ .irq = SMC1_IRQ, .ops = &cpm_uart_pops, .iotype = SERIAL_IO_MEM, - .lock = SPIN_LOCK_UNLOCKED, + .lock = SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SMC1].port.lock), }, .flags = FLAG_SMC, .tx_nrfifos = TX_NUM_FIFO, @@ -878,7 +878,7 @@ .irq = SMC2_IRQ, .ops = &cpm_uart_pops, .iotype = SERIAL_IO_MEM, - .lock = SPIN_LOCK_UNLOCKED, + .lock = SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SMC2].port.lock), }, .flags = FLAG_SMC, .tx_nrfifos = TX_NUM_FIFO, @@ -895,7 +895,7 @@ .irq = SCC1_IRQ, .ops = &cpm_uart_pops, .iotype = SERIAL_IO_MEM, - .lock = SPIN_LOCK_UNLOCKED, + .lock = SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC1].port.lock), }, .tx_nrfifos = TX_NUM_FIFO, .tx_fifosize = TX_BUF_SIZE, @@ -908,7 +908,7 @@ .irq = SCC2_IRQ, .ops = &cpm_uart_pops, .iotype = SERIAL_IO_MEM, - .lock = SPIN_LOCK_UNLOCKED, + .lock = SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC2].port.lock), }, .tx_nrfifos = TX_NUM_FIFO, .tx_fifosize = TX_BUF_SIZE, @@ -921,7 +921,7 @@ .irq = SCC3_IRQ, .ops = &cpm_uart_pops, .iotype = SERIAL_IO_MEM, - .lock = SPIN_LOCK_UNLOCKED, + .lock = SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC3].port.lock), }, .tx_nrfifos = TX_NUM_FIFO, .tx_fifosize = TX_BUF_SIZE, @@ -934,7 +934,7 @@ .irq = SCC4_IRQ, .ops = &cpm_uart_pops, .iotype = SERIAL_IO_MEM, - .lock = SPIN_LOCK_UNLOCKED, + .lock = SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC4].port.lock), }, .tx_nrfifos = TX_NUM_FIFO, .tx_fifosize = TX_BUF_SIZE, diff -urN linux-2.6.12-armirq/drivers/serial/s3c2410.c linux-2.6.12-armirq-rt/drivers/serial/s3c2410.c --- linux-2.6.12-armirq/drivers/serial/s3c2410.c 2005-07-13 14:30:25.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/serial/s3c2410.c 2005-07-16 16:41:56.000000000 +0200 @@ -975,7 +975,7 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[NR_PORTS] = { [0] = { .port = { - .lock = SPIN_LOCK_UNLOCKED, + .lock = SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[0].port.lock), .iotype = UPIO_MEM, .irq = IRQ_S3CUART_RX0, .uartclk = 0, @@ -987,7 +987,7 @@ }, [1] = { .port = { - .lock = SPIN_LOCK_UNLOCKED, + .lock = SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[1].port.lock), .iotype = UPIO_MEM, .irq = IRQ_S3CUART_RX1, .uartclk = 0, @@ -1001,7 +1001,7 @@ [2] = { .port = { - .lock = SPIN_LOCK_UNLOCKED, + .lock = SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[2].port.lock), .iotype = UPIO_MEM, .irq = IRQ_S3CUART_RX2, .uartclk = 0, diff -urN linux-2.6.12-armirq/drivers/usb/core/hcd.c linux-2.6.12-armirq-rt/drivers/usb/core/hcd.c --- linux-2.6.12-armirq/drivers/usb/core/hcd.c 2005-07-13 14:30:25.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/usb/core/hcd.c 2005-07-16 16:41:56.000000000 +0200 @@ -353,7 +353,9 @@ const u8 *bufp = tbuf; int len = 0; int patch_wakeup = 0; +#ifndef CONFIG_PREEMPT_RT unsigned long flags; +#endif int status = 0; int n; @@ -506,13 +508,17 @@ } /* any errors get returned through the urb completion */ +#ifndef CONFIG_PREEMPT_RT local_irq_save (flags); +#endif spin_lock (&urb->lock); if (urb->status == -EINPROGRESS) urb->status = status; spin_unlock (&urb->lock); usb_hcd_giveback_urb (hcd, urb, NULL); +#ifndef CONFIG_PREEMPT_RT local_irq_restore (flags); +#endif return 0; } @@ -562,15 +568,13 @@ unsigned long flags; urb = (struct urb *) ptr; - local_irq_save (flags); - spin_lock (&urb->lock); + spin_lock_irqsave (&urb->lock, flags); /* do nothing if the urb's been unlinked */ if (!urb->dev || urb->status != -EINPROGRESS || (hcd = urb->dev->bus->hcpriv) == NULL) { - spin_unlock (&urb->lock); - local_irq_restore (flags); + spin_unlock_irqrestore (&urb->lock, flags); return; } @@ -588,12 +592,12 @@ mod_timer (&hcd->rh_timer, jiffies + HZ/4); } spin_unlock (&hcd_data_lock); - spin_unlock (&urb->lock); /* local irqs are always blocked in completions */ if (length > 0) usb_hcd_giveback_urb (hcd, urb, NULL); - local_irq_restore (flags); + + spin_unlock_irqrestore (&urb->lock, flags); } /*-------------------------------------------------------------------------*/ @@ -619,17 +623,23 @@ static int usb_rh_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) { +#ifndef CONFIG_PREEMPT_RT unsigned long flags; +#endif /* note: always a synchronous unlink */ if ((unsigned long) urb == hcd->rh_timer.data) { del_timer_sync (&hcd->rh_timer); hcd->rh_timer.data = 0; +#ifndef CONFIG_PREEMPT_RT local_irq_save (flags); +#endif urb->hcpriv = NULL; usb_hcd_giveback_urb (hcd, urb, NULL); +#ifndef CONFIG_PREEMPT_RT local_irq_restore (flags); +#endif } else if (usb_pipeendpoint(urb->pipe) == 0) { spin_lock_irq(&urb->lock); /* from usb_kill_urb */ @@ -1357,15 +1367,13 @@ WARN_ON (!HC_IS_RUNNING (hcd->state) && hcd->state != HC_STATE_HALT); - local_irq_disable (); - /* FIXME move most of this into message.c as part of its * endpoint disable logic */ /* ep is already gone from udev->ep_{in,out}[]; no more submits */ rescan: - spin_lock (&hcd_data_lock); + spin_lock_irq (&hcd_data_lock); list_for_each_entry (urb, &ep->urb_list, urb_list) { int tmp; @@ -1378,13 +1386,13 @@ if (urb->status != -EINPROGRESS) continue; usb_get_urb (urb); - spin_unlock (&hcd_data_lock); + spin_unlock_irq (&hcd_data_lock); - spin_lock (&urb->lock); + spin_lock_irq (&urb->lock); tmp = urb->status; if (tmp == -EINPROGRESS) urb->status = -ESHUTDOWN; - spin_unlock (&urb->lock); + spin_unlock_irq (&urb->lock); /* kick hcd unless it's already returning this */ if (tmp == -EINPROGRESS) { @@ -1407,8 +1415,7 @@ /* list contents may have changed */ goto rescan; } - spin_unlock (&hcd_data_lock); - local_irq_enable (); + spin_unlock_irq (&hcd_data_lock); /* synchronize with the hardware, so old configuration state * clears out immediately (and will be freed). diff -urN linux-2.6.12-armirq/drivers/usb/host/hc_crisv10.c linux-2.6.12-armirq-rt/drivers/usb/host/hc_crisv10.c --- linux-2.6.12-armirq/drivers/usb/host/hc_crisv10.c 2005-07-13 14:30:25.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/usb/host/hc_crisv10.c 2005-07-16 16:41:56.000000000 +0200 @@ -178,8 +178,8 @@ 0xff /* __u8 PortPwrCtrlMask; *** 7 ports max *** */ }; -static struct timer_list bulk_start_timer = TIMER_INITIALIZER(NULL, 0, 0); -static struct timer_list bulk_eot_timer = TIMER_INITIALIZER(NULL, 0, 0); +static DEFINE_TIMER(bulk_start_timer, NULL, 0, 0); +static DEFINE_TIMER(bulk_eot_timer, NULL, 0, 0); /* We want the start timer to expire before the eot timer, because the former might start traffic, thus making it unnecessary for the latter to time out. */ diff -urN linux-2.6.12-armirq/drivers/usb/net/usbnet.c linux-2.6.12-armirq-rt/drivers/usb/net/usbnet.c --- linux-2.6.12-armirq/drivers/usb/net/usbnet.c 2005-07-13 14:30:26.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/usb/net/usbnet.c 2005-07-16 16:41:56.000000000 +0200 @@ -3490,6 +3490,8 @@ urb->dev = NULL; entry->state = tx_done; + spin_lock_rt(&dev->txq.lock); + spin_unlock_rt(&dev->txq.lock); defer_bh (dev, skb); } diff -urN linux-2.6.12-armirq/drivers/usb/storage/usb.c linux-2.6.12-armirq-rt/drivers/usb/storage/usb.c --- linux-2.6.12-armirq/drivers/usb/storage/usb.c 2005-07-13 14:30:26.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/usb/storage/usb.c 2005-07-16 16:41:56.000000000 +0200 @@ -317,6 +317,7 @@ if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) { US_DEBUGP("-- exiting\n"); up(&(us->dev_semaphore)); + up(&us->sema); break; } diff -urN linux-2.6.12-armirq/drivers/usb/storage/usb.h linux-2.6.12-armirq-rt/drivers/usb/storage/usb.h --- linux-2.6.12-armirq/drivers/usb/storage/usb.h 2005-07-13 14:30:26.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/usb/storage/usb.h 2005-07-16 16:41:56.000000000 +0200 @@ -171,7 +171,7 @@ dma_addr_t iobuf_dma; /* mutual exclusion and synchronization structures */ - struct semaphore sema; /* to sleep thread on */ + struct compat_semaphore sema; /* to sleep thread on */ struct completion notify; /* thread begin/end */ wait_queue_head_t delay_wait; /* wait during scan, reset */ diff -urN linux-2.6.12-armirq/drivers/video/backlight/corgi_bl.c linux-2.6.12-armirq-rt/drivers/video/backlight/corgi_bl.c --- linux-2.6.12-armirq/drivers/video/backlight/corgi_bl.c 2005-07-13 14:30:26.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/video/backlight/corgi_bl.c 2005-07-16 16:41:56.000000000 +0200 @@ -29,7 +29,7 @@ static int corgibl_powermode = FB_BLANK_UNBLANK; static int current_intensity = 0; static int corgibl_limit = 0; -static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(bl_lock); static void corgibl_send_intensity(int intensity) { diff -urN linux-2.6.12-armirq/drivers/video/console/fbcon.c linux-2.6.12-armirq-rt/drivers/video/console/fbcon.c --- linux-2.6.12-armirq/drivers/video/console/fbcon.c 2005-07-13 14:30:26.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/video/console/fbcon.c 2005-07-16 16:41:56.000000000 +0200 @@ -1052,7 +1052,6 @@ { struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; struct fbcon_ops *ops = info->fbcon_par; - struct display *p = &fb_display[vc->vc_num]; u_int y_break; @@ -1081,10 +1080,11 @@ struct display *p = &fb_display[vc->vc_num]; struct fbcon_ops *ops = info->fbcon_par; - if (!fbcon_is_inactive(vc, info)) + if (!fbcon_is_inactive(vc, info)) { ops->putcs(vc, info, s, count, real_y(p, ypos), xpos, get_color(vc, info, scr_readw(s), 1), get_color(vc, info, scr_readw(s), 0)); + } } static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos) @@ -2768,6 +2768,7 @@ .con_screen_pos = fbcon_screen_pos, .con_getxy = fbcon_getxy, .con_resize = fbcon_resize, + .con_preemptible = 1, }; static struct notifier_block fbcon_event_notifier = { diff -urN linux-2.6.12-armirq/drivers/video/console/vgacon.c linux-2.6.12-armirq-rt/drivers/video/console/vgacon.c --- linux-2.6.12-armirq/drivers/video/console/vgacon.c 2005-07-13 14:30:26.000000000 +0200 +++ linux-2.6.12-armirq-rt/drivers/video/console/vgacon.c 2005-07-16 16:41:56.000000000 +0200 @@ -53,7 +53,7 @@ #include