From: Ingo Molnar timer_interrupt does write_seqlock(&xtime_lock), and sched_clock() is called inside timer_interrupt(). So sched_clock() cannot call get_jiffies_64(), because that does read_seqretry(&xtime_lock). The easy fix is below. Since this only affects 1) non-TSC-sync 32-bit systems, and since a once-every-400 days overflow will get the interactivity of 1-2 tasks wrong, this is not a big thing. To get cleanly out of the recursion we'd have to add a separate callback from the TIMER_SOFTIRQ context, that updates rq->timestamp_last_tick and does nothing else. We dont want to move the rest of scheduler_tick() to softirq context because the timer-IRQ is much more precise - softirqs can get delayed. So we've got to live with this small grossness. Yet another solution would be to define a separate sched_clock_timer() function, which an arch could separately fill in if it needs to. (the default would be to make sched_clock == sched_clock_timer) This way x86 could use the jiffies_64 value directly in sched_clock_timer(), and could do the get_jiffies_64() thing in sched_clock(). arch/i386/kernel/timers/timer_tsc.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) diff -puN arch/i386/kernel/timers/timer_tsc.c~sched_clock-2.6.0-A1-deadlock-fix arch/i386/kernel/timers/timer_tsc.c --- 25/arch/i386/kernel/timers/timer_tsc.c~sched_clock-2.6.0-A1-deadlock-fix 2003-12-30 00:45:09.000000000 -0800 +++ 25-akpm/arch/i386/kernel/timers/timer_tsc.c 2003-12-30 00:45:09.000000000 -0800 @@ -140,7 +140,8 @@ unsigned long long sched_clock(void) #ifndef CONFIG_NUMA if (!use_tsc) #endif - return (unsigned long long)get_jiffies_64() * (1000000000 / HZ); + /* jiffies might overflow but this is not a big deal here */ + return (unsigned long long)jiffies * (1000000000 / HZ); /* Read the Time Stamp Counter */ rdtscll(this_offset); _