Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 12 May 2014 13:05:04 +0000 (UTC)
From:      Ian Lepore <ian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r265913 - head/sys/arm/arm
Message-ID:  <201405121305.s4CD54GW026630@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ian
Date: Mon May 12 13:05:03 2014
New Revision: 265913
URL: http://svnweb.freebsd.org/changeset/base/265913

Log:
  Interrupts need to be disabled on entry to cpu_sleep() for ARM.  Given
  that and the need to be in a critical section when switching to idleclock
  mode for event timers, use spinlock_enter()/exit() to achieve both needs.
  
  The ARM WFI (wait for interrupt) instruction blocks until an interrupt is
  asserted, and it will unblock even if interrupts are masked, and it will
  unblock immediately if an interrupt is already pending.  It is necessary
  to execute it with interrupts disabled, otherwise the interrupt that
  should unblock it may occur and be serviced just prior to executing the
  instruction.  At that point the system is inappropriately asleep until
  the next timer tick or some other random interrupt happens.
  
  In general, interrupts need to be disabled continuously from the time the
  decision is made that there is no work to be done and sleeping is needed
  until actually going to sleep, to avoid a race where handling a new
  interrupt changes the basis for deciding there is no work to be done.
  
  Submitted by:	hps@ (in slightly different form)

Modified:
  head/sys/arm/arm/machdep.c

Modified: head/sys/arm/arm/machdep.c
==============================================================================
--- head/sys/arm/arm/machdep.c	Mon May 12 12:04:44 2014	(r265912)
+++ head/sys/arm/arm/machdep.c	Mon May 12 13:05:03 2014	(r265913)
@@ -426,9 +426,9 @@ cpu_idle(int busy)
 	
 	CTR2(KTR_SPARE2, "cpu_idle(%d) at %d",
 	    busy, curcpu);
+	spinlock_enter();
 #ifndef NO_EVENTTIMERS
 	if (!busy) {
-		critical_enter();
 		cpu_idleclock();
 	}
 #endif
@@ -437,9 +437,9 @@ cpu_idle(int busy)
 #ifndef NO_EVENTTIMERS
 	if (!busy) {
 		cpu_activeclock();
-		critical_exit();
 	}
 #endif
+	spinlock_exit();
 	CTR2(KTR_SPARE2, "cpu_idle(%d) at %d done",
 	    busy, curcpu);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201405121305.s4CD54GW026630>