From owner-freebsd-current@FreeBSD.ORG Tue Sep 27 13:51:09 2011 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 99EBF106566B; Tue, 27 Sep 2011 13:51:09 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from cyrus.watson.org (cyrus.watson.org [65.122.17.42]) by mx1.freebsd.org (Postfix) with ESMTP id 6F6B18FC16; Tue, 27 Sep 2011 13:51:09 +0000 (UTC) Received: from bigwig.baldwin.cx (66.111.2.69.static.nyinternet.net [66.111.2.69]) by cyrus.watson.org (Postfix) with ESMTPSA id 0CABB46B58; Tue, 27 Sep 2011 09:51:09 -0400 (EDT) Received: from jhbbsd.localnet (unknown [209.249.190.124]) by bigwig.baldwin.cx (Postfix) with ESMTPSA id 91B2B8A02F; Tue, 27 Sep 2011 09:51:08 -0400 (EDT) From: John Baldwin To: Adrian Chadd Date: Tue, 27 Sep 2011 09:51:07 -0400 User-Agent: KMail/1.13.5 (FreeBSD/8.2-CBSD-20110617; KDE/4.5.5; amd64; ; ) References: In-Reply-To: MIME-Version: 1.0 Content-Type: Text/Plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Message-Id: <201109270951.07839.jhb@freebsd.org> X-Greylist: Sender succeeded SMTP AUTH, not delayed by milter-greylist-4.2.6 (bigwig.baldwin.cx); Tue, 27 Sep 2011 09:51:08 -0400 (EDT) Cc: attilio@freebsd.org, freebsd-current@freebsd.org, freebsd-mips@freebsd.org Subject: Re: ath / 802.11n performance issues and timer code X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 27 Sep 2011 13:51:09 -0000 On Monday, September 26, 2011 11:36:26 pm Adrian Chadd wrote: > .. and as a follow up (and cc'ing attillo and freebsd-mips, in case > it's relevant to other platforms and there's a MIPS specific thing to > fix): > > * 2128: mi_switch to idle > * 2129: kern_clocksource.c:762 - ie, cpu_idleclock() has been called > * 2130: the ath interrupt comes in > * 2134: it's skipped for now as the idle thread is in a critical section > * 2136: kern_clocksource.c:266 - ie, getnextcpuevent(), inside cpu_idleclock(). > > What I bet is happening is this race between the critical section + > cpu_idleclock() and the ath0 interrupt: > > * idle gets scheduled > * critical_enter() is called in the mips cpu_idle() routine > * the ath interrupt comes in here and gets handled, but since we're in > a critical section, it won't preempt things > * the cpu_idleclock() code completes without releasing the preemption, > and the only thing that wakes up from that wait is the next interrupt > (clock, arge0, etc.) I think this is a mips-specific bug, though it may be well to audit all the cpu_idle() implementations. On x86 the idle hooks all check sched_runnable() with interrupts disabled and then atomically re-enable interrupts and sleep only if that is false, e.g.: static void cpu_idle_hlt(int busy) { int *state; state = (int *)PCPU_PTR(monitorbuf); *state = STATE_SLEEPING; /* * We must absolutely guarentee that hlt is the next instruction * after sti or we introduce a timing window. */ disable_intr(); if (sched_runnable()) enable_intr(); else __asm __volatile("sti; hlt"); *state = STATE_RUNNING; } I don't know if it is possible to do the same thing with the mips "wait" instruction. -- John Baldwin