Messages in this thread Patch in this message | | | Subject | [PATCH] Re: cond_resched() fix | From | Jim Houston <> | Date | Mon, 17 Jul 2006 23:25:43 -0400 |
| |
Hi Andrew,
I found an off by one error in your recent cond_resched fix. In cond_resched_lock() it calls __resched_legal() before dropping the spin lock. __resched_legal() will always finds the preempt_count non-zero and will prevent the call to __cond_resched().
The attached patch adds a parameter to __resched_legal() with the expected preempt_count value. The patch was made against a Linus's git tree. It will apply cleanly to linux-2.6.18-rc2.
Jim Houston - Concurrent Computer Corp.
-- --- linux-2.6/kernel/sched.c.orig 2006-07-17 09:30:05.000000000 -0400 +++ linux-2.6/kernel/sched.c 2006-07-17 23:00:50.000000000 -0400 @@ -4456,9 +4456,9 @@ return 0; } -static inline int __resched_legal(void) +static inline int __resched_legal(int expected_preempt_count) { - if (unlikely(preempt_count())) + if (unlikely(preempt_count() != expected_preempt_count)) return 0; if (unlikely(system_state != SYSTEM_RUNNING)) return 0; @@ -4484,7 +4484,7 @@ int __sched cond_resched(void) { - if (need_resched() && __resched_legal()) { + if (need_resched() && __resched_legal(0)) { __cond_resched(); return 1; } @@ -4510,7 +4510,7 @@ ret = 1; spin_lock(lock); } - if (need_resched() && __resched_legal()) { + if (need_resched() && __resched_legal(1)) { spin_release(&lock->dep_map, 1, _THIS_IP_); _raw_spin_unlock(lock); preempt_enable_no_resched(); @@ -4526,7 +4526,7 @@ { BUG_ON(!in_softirq()); - if (need_resched() && __resched_legal()) { + if (need_resched() && __resched_legal(0)) { raw_local_irq_disable(); _local_bh_enable(); raw_local_irq_enable();
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |