Skip to content

Commit

Permalink
MN10300: Prevent cnt32_to_63() from being preempted in sched_clock()
Browse files Browse the repository at this point in the history
Prevent cnt32_to_63() from being preempted in sched_clock() because it may
read its internal counter, get preempted, get delayed for more than the half
period of the 'TSC' and then write the internal counter, thus corrupting it.

Whilst some callers of sched_clock() have interrupts disabled or hold
spinlocks, not all do, and so preemption must be held here.

Note that sched_clock() is called from lockdep, but that shouldn't be a problem
because although preempt_disable() calls into lockdep, lockdep has a recursion
counter to deal with this.

Signed-off-by: David Howells <dhowells@redhat.com>
  • Loading branch information
David Howells committed Oct 27, 2010
1 parent dcd42ed commit 3b950de
Showing 1 changed file with 5 additions and 0 deletions.
5 changes: 5 additions & 0 deletions arch/mn10300/kernel/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ unsigned long long sched_clock(void)
unsigned long tsc, tmp;
unsigned product[3]; /* 96-bit intermediate value */

/* cnt32_to_63() is not safe with preemption */
preempt_disable();

/* read the TSC value
*/
tsc = 0 - get_cycles(); /* get_cycles() counts down */
Expand All @@ -64,6 +67,8 @@ unsigned long long sched_clock(void)
*/
tsc64.ll = cnt32_to_63(tsc) & 0x7fffffffffffffffULL;

preempt_enable();

/* scale the 64-bit TSC value to a nanosecond value via a 96-bit
* intermediate
*/
Expand Down

0 comments on commit 3b950de

Please sign in to comment.