diff -urpN -X /home/fletch/.diff.exclude 718-fs_aio_8_down_wq-ppc64/arch/x86_64/kernel/semaphore.c 719-fs_aio_9_down_wq-x86_64/arch/x86_64/kernel/semaphore.c --- 718-fs_aio_8_down_wq-ppc64/arch/x86_64/kernel/semaphore.c Sun Nov 17 20:29:59 2002 +++ 719-fs_aio_9_down_wq-x86_64/arch/x86_64/kernel/semaphore.c Sat Jun 14 20:44:31 2003 @@ -54,15 +54,20 @@ void __up(struct semaphore *sem) wake_up(&sem->wait); } -void __down(struct semaphore * sem) +int __down_wq(struct semaphore * sem, wait_queue_t *wait) { struct task_struct *tsk = current; - DECLARE_WAITQUEUE(wait, tsk); + DECLARE_WAITQUEUE(local_wait, tsk); unsigned long flags; - tsk->state = TASK_UNINTERRUPTIBLE; + if (is_sync_wait(wait)) + tsk->state = TASK_UNINTERRUPTIBLE; + if (!wait) { + wait = &local_wait; + } + spin_lock_irqsave(&sem->wait.lock, flags); - add_wait_queue_exclusive_locked(&sem->wait, &wait); + add_wait_queue_exclusive_locked(&sem->wait, wait); sem->sleepers++; for (;;) { @@ -80,16 +85,22 @@ void __down(struct semaphore * sem) sem->sleepers = 1; /* us - see -1 above */ spin_unlock_irqrestore(&sem->wait.lock, flags); + if (!is_sync_wait(wait)) + return -EIOCBRETRY; + schedule(); spin_lock_irqsave(&sem->wait.lock, flags); tsk->state = TASK_UNINTERRUPTIBLE; } - remove_wait_queue_locked(&sem->wait, &wait); + if (is_sync_wait(wait) || !list_empty(&wait->task_list)) + remove_wait_queue_locked(&sem->wait, wait); wake_up_locked(&sem->wait); spin_unlock_irqrestore(&sem->wait.lock, flags); tsk->state = TASK_RUNNING; + return 0; } + int __down_interruptible(struct semaphore * sem) { diff -urpN -X /home/fletch/.diff.exclude 718-fs_aio_8_down_wq-ppc64/arch/x86_64/kernel/x8664_ksyms.c 719-fs_aio_9_down_wq-x86_64/arch/x86_64/kernel/x8664_ksyms.c --- 718-fs_aio_8_down_wq-ppc64/arch/x86_64/kernel/x8664_ksyms.c Sat Jun 14 18:37:26 2003 +++ 719-fs_aio_9_down_wq-x86_64/arch/x86_64/kernel/x8664_ksyms.c Sat Jun 14 20:44:31 2003 @@ -64,7 +64,7 @@ EXPORT_SYMBOL(get_cmos_time); EXPORT_SYMBOL(__io_virt_debug); #endif -EXPORT_SYMBOL_NOVERS(__down_failed); +EXPORT_SYMBOL_NOVERS(__down_failed_wq); EXPORT_SYMBOL_NOVERS(__down_failed_interruptible); EXPORT_SYMBOL_NOVERS(__down_failed_trylock); EXPORT_SYMBOL_NOVERS(__up_wakeup); diff -urpN -X /home/fletch/.diff.exclude 718-fs_aio_8_down_wq-ppc64/arch/x86_64/lib/thunk.S 719-fs_aio_9_down_wq-x86_64/arch/x86_64/lib/thunk.S --- 718-fs_aio_8_down_wq-ppc64/arch/x86_64/lib/thunk.S Sun Nov 17 20:29:44 2002 +++ 719-fs_aio_9_down_wq-x86_64/arch/x86_64/lib/thunk.S Sat Jun 14 20:44:31 2003 @@ -38,7 +38,7 @@ #endif thunk do_softirq_thunk,do_softirq - thunk __down_failed,__down + thunk __down_failed_wq,__down_wq thunk_retrax __down_failed_interruptible,__down_interruptible thunk_retrax __down_failed_trylock,__down_trylock thunk __up_wakeup,__up diff -urpN -X /home/fletch/.diff.exclude 718-fs_aio_8_down_wq-ppc64/include/asm-x86_64/semaphore.h 719-fs_aio_9_down_wq-x86_64/include/asm-x86_64/semaphore.h --- 718-fs_aio_8_down_wq-ppc64/include/asm-x86_64/semaphore.h Wed Mar 5 07:37:07 2003 +++ 719-fs_aio_9_down_wq-x86_64/include/asm-x86_64/semaphore.h Sat Jun 14 20:44:31 2003 @@ -98,39 +98,48 @@ static inline void init_MUTEX_LOCKED (st sema_init(sem, 0); } -asmlinkage void __down_failed(void /* special register calling convention */); +asmlinkage int __down_failed_wq(void /* special register calling convention */); asmlinkage int __down_failed_interruptible(void /* params in registers */); asmlinkage int __down_failed_trylock(void /* params in registers */); asmlinkage void __up_wakeup(void /* special register calling convention */); -asmlinkage void __down(struct semaphore * sem); +asmlinkage int __down_wq(struct semaphore * sem, wait_queue_t *wait); asmlinkage int __down_interruptible(struct semaphore * sem); asmlinkage int __down_trylock(struct semaphore * sem); asmlinkage void __up(struct semaphore * sem); /* * This is ugly, but we want the default case to fall through. - * "__down_failed" is a special asm handler that calls the C + * "__down_failed_wq" is a special asm handler that calls the C * routine that actually waits. See arch/x86_64/kernel/semaphore.c */ -static inline void down(struct semaphore * sem) +static inline int down_wq(struct semaphore * sem, wait_queue_t *wait) { + int result; + #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif __asm__ __volatile__( "# atomic down operation\n\t" - LOCK "decl %0\n\t" /* --sem->count */ - "js 2f\n" + LOCK "decl %1\n\t" /* --sem->count */ + "js 2f\n\t" + "xorl %0,%0\n" "1:\n" LOCK_SECTION_START("") - "2:\tcall __down_failed\n\t" + "2:\tcall __down_failed_wq\n\t" "jmp 1b\n" LOCK_SECTION_END - :"=m" (sem->count) - :"D" (sem) + :"=a" (result), "=m" (sem->count) + :"D" (sem), "S" (wait) :"memory"); + return result; +} + +static inline void down(struct semaphore * sem) +{ + down_wq(sem, NULL); } /*