From owner-freebsd-mips@FreeBSD.ORG Wed Sep 28 14:44:18 2011 Return-Path: Delivered-To: freebsd-mips@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 134381065673 for ; Wed, 28 Sep 2011 14:44:18 +0000 (UTC) (envelope-from adrian.chadd@gmail.com) Received: from mail-yx0-f182.google.com (mail-yx0-f182.google.com [209.85.213.182]) by mx1.freebsd.org (Postfix) with ESMTP id CB0818FC0C for ; Wed, 28 Sep 2011 14:44:17 +0000 (UTC) Received: by yxk36 with SMTP id 36so8125130yxk.13 for ; Wed, 28 Sep 2011 07:44:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:sender:date:x-google-sender-auth:message-id:subject :from:to:content-type; bh=i7QYe2eM/BihUFteKBHIanadOO/n7X2Ijxs+W2OENfM=; b=ddiKiKsjEJxd+GmNKYhvkqvEpB+Esw7hk/5iSSLV5LaY15ofupFGUQ13JHwaetuU+h IYeW+d5OJb+ioCpnAmK2OQM1Vn9sSp9FX6/LQEmPARaWQLR3J6gUtQ/hbPZp9eSDbpYn bgTvEkLF0PLV+zszBrXVF3TGjtp7WdGv+lpLU= MIME-Version: 1.0 Received: by 10.236.75.227 with SMTP id z63mr56186904yhd.55.1317221057024; Wed, 28 Sep 2011 07:44:17 -0700 (PDT) Sender: adrian.chadd@gmail.com Received: by 10.236.111.42 with HTTP; Wed, 28 Sep 2011 07:44:13 -0700 (PDT) Date: Wed, 28 Sep 2011 22:44:13 +0800 X-Google-Sender-Auth: nnUkKRjr9nYokpVVIqRU-M5ITEQ Message-ID: From: Adrian Chadd To: freebsd-mips@freebsd.org Content-Type: text/plain; charset=ISO-8859-1 Subject: eventtimer issue on mips: temporary workaround X-BeenThere: freebsd-mips@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Porting FreeBSD to MIPS List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Sep 2011 14:44:18 -0000 Hi all, I've found that there's an issue with how mav@ shoehorned in event timer handling to mips. Basically, if a non-fast interrupt comes in after the critical_enter() call in cpu_idle() but before the wait instruction, it won't interrupt wait and it won't be serviced until the next interrupt ends the wait. For ath, since it's a netisr, this means the netisr won't be run until the next interrupt fires. Here's my temporary, not-quite-correct workaround. ray@ pointed out this from Linux: http://lxr.free-electrons.com/source/arch/mips/kernel/cpu-probe.c?a=sh .. which indicates that they're calling wait with interrupts masked. This apparently doesn't stop it breaking wait, it merely stops it from flipping to the interrupt handler. There are also a number of MIPS platform specific workarounds to implement idle. I'd really appreciate some feedback on this and hopefully a correct solution. :) Adrian Index: mips/machdep.c =================================================================== --- mips/machdep.c (revision 225610) +++ mips/machdep.c (working copy) @@ -497,7 +497,16 @@ critical_enter(); cpu_idleclock(); } - __asm __volatile ("wait"); + + intr_disable(); + if (sched_runnable()) { + intr_enable(); + } else { + /* XXX this isn't atomic! */ + intr_enable(); + __asm __volatile ("wait"); + } + if (!busy) { cpu_activeclock(); critical_exit();