--- linux-2.6-npiggin/include/linux/sched.h | 1 + linux-2.6-npiggin/kernel/futex.c | 15 +++++++++++++-- linux-2.6-npiggin/kernel/sched.c | 8 ++++++++ linux-2.6-npiggin/kernel/timer.c | 12 +++++++++++- 4 files changed, 33 insertions(+), 3 deletions(-) diff -puN kernel/futex.c~futex-debug kernel/futex.c --- linux-2.6/kernel/futex.c~futex-debug 2004-10-26 21:59:06.000000000 +1000 +++ linux-2.6-npiggin/kernel/futex.c 2004-10-26 21:59:55.000000000 +1000 @@ -271,7 +271,11 @@ static void wake_futex(struct futex_q *q * The lock in wake_up_all() is a crucial memory barrier after the * list_del_init() and also before assigning to q->lock_ptr. */ + + current->flags |= PF_FUTEX_DEBUG; wake_up_all(&q->waiters); + current->flags &= ~PF_FUTEX_DEBUG; + /* * The waiting task can free the futex_q as soon as this is written, * without taking any locks. This must come last. @@ -524,8 +528,11 @@ static int futex_wait(unsigned long uadd * !list_empty() is safe here without any lock. * q.lock_ptr != 0 is not safe, because of ordering against wakeup. */ - if (likely(!list_empty(&q.list))) + if (likely(!list_empty(&q.list))) { + current->flags |= PF_FUTEX_DEBUG; time = schedule_timeout(time); + current->flags &= ~PF_FUTEX_DEBUG; + } __set_current_state(TASK_RUNNING); /* @@ -539,7 +546,11 @@ static int futex_wait(unsigned long uadd if (time == 0) return -ETIMEDOUT; /* A spurious wakeup should never happen. */ - WARN_ON(!signal_pending(current)); + if (!signal_pending(current)) { + printk("futex_wait woken: %lu %i %lu\n", + uaddr, val, time); + WARN_ON(1); + } return -EINTR; out_unqueue: diff -puN include/linux/sched.h~futex-debug include/linux/sched.h --- linux-2.6/include/linux/sched.h~futex-debug 2004-10-26 21:59:06.000000000 +1000 +++ linux-2.6-npiggin/include/linux/sched.h 2004-10-26 22:01:01.000000000 +1000 @@ -701,6 +701,7 @@ do { if (atomic_dec_and_test(&(tsk)->usa #define PF_LESS_THROTTLE 0x00100000 /* Throttle me less: I clean memory */ #define PF_SYNCWRITE 0x00200000 /* I am doing a sync write */ #define PF_BORROWED_MM 0x00400000 /* I am a kthread doing use_mm */ +#define PF_FUTEX_DEBUG 0x00800000 #ifdef CONFIG_SMP extern int set_cpus_allowed(task_t *p, cpumask_t new_mask); diff -puN kernel/sched.c~futex-debug kernel/sched.c --- linux-2.6/kernel/sched.c~futex-debug 2004-10-26 21:59:06.000000000 +1000 +++ linux-2.6-npiggin/kernel/sched.c 2004-10-26 22:02:51.000000000 +1000 @@ -993,6 +993,14 @@ static int try_to_wake_up(task_t * p, un old_state = p->state; if (!(old_state & state)) goto out; + + if ((p->flags & PF_FUTEX_DEBUG) + && !(current->flags & PF_FUTEX_DEBUG)) { + printk("%s %i waking %s: %i %i\n", + current->comm, (int)in_interrupt(), + p->comm, p->tgid, p->pid); + WARN_ON(1); + } if (p->array) goto out_running; diff -puN kernel/timer.c~futex-debug kernel/timer.c --- linux-2.6/kernel/timer.c~futex-debug 2004-10-26 21:59:17.000000000 +1000 +++ linux-2.6-npiggin/kernel/timer.c 2004-10-26 21:59:55.000000000 +1000 @@ -1083,6 +1083,13 @@ static void process_timeout(unsigned lon wake_up_process((task_t *)__data); } +static void futex_timeout(unsigned long __data) +{ + current->flags |= PF_FUTEX_DEBUG; + wake_up_process((task_t *)__data); + current->flags &= ~PF_FUTEX_DEBUG; +} + /** * schedule_timeout - sleep until timeout * @timeout: timeout value in jiffies @@ -1149,7 +1156,10 @@ fastcall signed long __sched schedule_ti init_timer(&timer); timer.expires = expire; timer.data = (unsigned long) current; - timer.function = process_timeout; + if (current->flags & PF_FUTEX_DEBUG) + timer.function = futex_timeout; + else + timer.function = process_timeout; add_timer(&timer); schedule(); _