| Message ID | 444ef6c4bbb47d55c700452d8cd23229@localhost |
|---|---|
| State | Accepted |
| Delegated to: | Ralf Baechle |
| Headers | show |
On Tue, Nov 23, 2010 at 10:26:44AM -0800, Kevin Cernekee wrote: > write_c0_compare(read_c0_count()); > > Even if the counter doesn't increment during execution, this might not > generate an interrupt until the counter wraps around. The CPU may > perform the comparison each time CP0 COUNT increments, not when CP0 > COMPARE is written. > > If mips_next_event() is called with a very small delta, and CP0 COUNT > increments during the calculation of "cnt += delta", it is possible > that CP0 COMPARE will be written with the current value of CP0 COUNT. > If this is detected, the function should return -ETIME, to indicate > that the interrupt might not have actually gotten scheduled. Good catch - though on real hardware it should be theoretical as the minimum timer interval is 300ns. So it should only be trigerable on a very slow system like a hardware emulator or maybe if a software emulator like qemu gets rescheduled between the update and the read-back. Applied, Ralf
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c index 2f4d7a9..98c5a97 100644 --- a/arch/mips/kernel/cevt-r4k.c +++ b/arch/mips/kernel/cevt-r4k.c @@ -32,7 +32,7 @@ static int mips_next_event(unsigned long delta, cnt = read_c0_count(); cnt += delta; write_c0_compare(cnt); - res = ((int)(read_c0_count() - cnt) > 0) ? -ETIME : 0; + res = ((int)(read_c0_count() - cnt) >= 0) ? -ETIME : 0; return res; }
Consider the following test case: write_c0_compare(read_c0_count()); Even if the counter doesn't increment during execution, this might not generate an interrupt until the counter wraps around. The CPU may perform the comparison each time CP0 COUNT increments, not when CP0 COMPARE is written. If mips_next_event() is called with a very small delta, and CP0 COUNT increments during the calculation of "cnt += delta", it is possible that CP0 COMPARE will be written with the current value of CP0 COUNT. If this is detected, the function should return -ETIME, to indicate that the interrupt might not have actually gotten scheduled. Signed-off-by: Kevin Cernekee <cernekee@gmail.com> --- arch/mips/kernel/cevt-r4k.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)