From owner-svn-src-all@FreeBSD.ORG Mon May 12 13:05:04 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 3FABDD45; Mon, 12 May 2014 13:05:04 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 2D1F923CC; Mon, 12 May 2014 13:05:04 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s4CD54Zn026632; Mon, 12 May 2014 13:05:04 GMT (envelope-from ian@svn.freebsd.org) Received: (from ian@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s4CD54GW026630; Mon, 12 May 2014 13:05:04 GMT (envelope-from ian@svn.freebsd.org) Message-Id: <201405121305.s4CD54GW026630@svn.freebsd.org> From: Ian Lepore Date: Mon, 12 May 2014 13:05:04 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r265913 - head/sys/arm/arm X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 12 May 2014 13:05:04 -0000 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); }