From owner-freebsd-hackers@FreeBSD.ORG Thu Aug 3 02:24:23 2006 Return-Path: X-Original-To: freebsd-hackers@freebsd.org Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id D317F16A505 for ; Thu, 3 Aug 2006 02:24:23 +0000 (UTC) (envelope-from pyunyh@gmail.com) Received: from ug-out-1314.google.com (ug-out-1314.google.com [66.249.92.174]) by mx1.FreeBSD.org (Postfix) with ESMTP id 1DA2A43D4C for ; Thu, 3 Aug 2006 02:24:22 +0000 (GMT) (envelope-from pyunyh@gmail.com) Received: by ug-out-1314.google.com with SMTP id m2so2274972uge for ; Wed, 02 Aug 2006 19:24:22 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:date:from:to:cc:subject:message-id:reply-to:references:mime-version:content-type:content-disposition:in-reply-to:user-agent; b=KrTtpKcSOZTcg2eV5qZcvLF+IdweUD0osOPja6o8nUUnCWS+AL6sAK1OXdjoCevsxHW/ZrX4qC3gNk8Dw5RfOTpD70FriKeyk4jtG9OiFp/UrKMNoYtlKbz5yP/WNJpjfZ3cauS4v57FzlZn0TIN0ctwb4H95PLO/9DCzXw1wAM= Received: by 10.65.114.16 with SMTP id r16mr2320928qbm; Wed, 02 Aug 2006 19:24:21 -0700 (PDT) Received: from michelle.cdnetworks.co.kr ( [211.53.35.84]) by mx.gmail.com with ESMTP id c12sm4276219nzc.2006.08.02.19.24.19; Wed, 02 Aug 2006 19:24:21 -0700 (PDT) Received: from michelle.cdnetworks.co.kr (localhost.cdnetworks.co.kr [127.0.0.1]) by michelle.cdnetworks.co.kr (8.13.5/8.13.5) with ESMTP id k732PU0h049833 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 3 Aug 2006 11:25:30 +0900 (KST) (envelope-from pyunyh@gmail.com) Received: (from yongari@localhost) by michelle.cdnetworks.co.kr (8.13.5/8.13.5/Submit) id k732PQBQ049832; Thu, 3 Aug 2006 11:25:26 +0900 (KST) (envelope-from pyunyh@gmail.com) Date: Thu, 3 Aug 2006 11:25:26 +0900 From: Pyun YongHyeon To: Hans Petter Selasky Message-ID: <20060803022526.GB49195@cdnetworks.co.kr> References: <200608021437.55500.hselasky@c2i.net> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <200608021437.55500.hselasky@c2i.net> User-Agent: Mutt/1.4.2.1i Cc: freebsd-hackers@freebsd.org Subject: Re: miibus + USB = problem X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: pyunyh@gmail.com List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 03 Aug 2006 02:24:24 -0000 On Wed, Aug 02, 2006 at 02:37:55PM +0200, Hans Petter Selasky wrote: > Hi, > > I am currently in the progress of porting "if_aue.c" to my new USB API, and > have hit a problem that needs to be solved. The problem is that the USB > system sleeps under "miibus_xxx". Questions are: > > Is this allowed? > > What locks are held when these functions are called ? > > Reference: > > /* MII interface */ > DEVMETHOD(miibus_readreg, aue_miibus_readreg), > DEVMETHOD(miibus_writereg, aue_miibus_writereg), > DEVMETHOD(miibus_statchg, aue_miibus_statchg), > AFAIK there is no locks held when MII layer calls above methods but it _is_ called with a driver lock from its ioctl handler. It seems that aue(4) needs to access its register space whilst serving above MII methods. This also means it needs a recursive mutex if it have to serve MII request in the context. So I think the driver should be prepared with protecting the MII methods with its own lock. I've not tried but if you can use MTX_DEF mutex instead of MTX_RECURSE mutex in aue(4) you may be able to sleep on the MII methods. But I think sleeping is not a good way in the MII methods as it would confuse MII layers. See below. Btw, it seems that aue_csr_{read,write} checks sc->aue_dying so it wouldn't block on these functions. But checking sc->aue_dying without a lock held is questionable and setting sc->aue_dying before aue_stop() may result in inconsistent state as all register operations would be nop if sc->aue_dying == 1. > The problem with USB devices, is that the read-register process is very slow. > It can take up to several milliseconds. And if the device is suddenly > detached one has to think about adding exit code everywhere. > > The solution I see with USB devices is something like this: > > if (sc->device_gone) { > > exit mutexes ; > > kthread_exit(0); > } > > Of course I cannot "kthread_exit()" when the call comes from read/write/ioctl, > because there is a stack, that expects a returning call. If the kernel code > was objective C, then maybe one could throw an exception or do something > alike so that the processor gets out of the USB-read procedure. > > > Solutions: > > 1) use USB hardware polling, not releasing any mutexes, simply using DELAY(), > until read/writes complete. > I think you can immediately return from register read/write routines without DELAY() if you know the hardware was gone. > 2) pre-read all read registers regularly. How can I do this with "miibus"? > Because you have a aue_tick() which is called every hz you can cache several registers regularly. Your MII methods can copy the value without accessing registers with proper locks. However, this may confuse MII layers because it needs successive register accesses to read/write media related settings and that defeats use of cached contents of the registers. > > Anyone have any comments? > > --HPS -- Regards, Pyun YongHyeon