From owner-freebsd-usb@FreeBSD.ORG Sat Apr 2 15:33:01 2005 Return-Path: Delivered-To: freebsd-usb@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 7F68116A58B for ; Sat, 2 Apr 2005 15:33:01 +0000 (GMT) Received: from salmon.maths.tcd.ie (salmon.maths.tcd.ie [134.226.81.11]) by mx1.FreeBSD.org (Postfix) with SMTP id 7F14D43D55 for ; Sat, 2 Apr 2005 15:33:00 +0000 (GMT) (envelope-from iedowse@maths.tcd.ie) Received: from walton.maths.tcd.ie by salmon.maths.tcd.ie with SMTP id ; 2 Apr 2005 16:32:52 +0100 (BST) To: ticso@cicely.de In-Reply-To: Your message of "Sat, 02 Apr 2005 12:36:25 +0200." <20050402103624.GS2072@cicely12.cicely.de> Date: Sat, 02 Apr 2005 16:32:50 +0100 From: Ian Dowse Message-ID: <200504021632.aa50758@salmon.maths.tcd.ie> cc: ticso@cicely12.cicely.de cc: iedowse@maths.tcd.ie cc: sebastien.b@swissinfo.org cc: freebsd-usb@FreeBSD.ORG Subject: Re: panic: uhci_abort_xfer: not in process context X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 02 Apr 2005 15:33:01 -0000 In message <20050402103624.GS2072@cicely12.cicely.de>, Bernd Walter writes: >In ohci.c it does: > if (xfer->device->bus->intr_context || !curproc) > panic("ohci_abort_xfer: not in process context"); >OK - this one is from ohci, but they are all the same. >intr_context is raised on interrupt handler start and decreased later. >It seems that there is an artifical limitation that we are not allowed >to sleep when processing USB interrupts. >If one really goes to sleep a userland call might come in and has >this variable raised. >I don't know why it enforces not to be in interrupt context, maybe >because of the long delays required to take an abort. >But in this case it triggers wrong. >In the meantime it should be safe not to check the intr_context part. Just a few general comments on this: Event processing systems can be either synchronous (blocking) or asynchronous (callback based). It is easy to make efficient use of an asynchronous system from synchronous code, but to do the reverse without holding up other requests you need to perform each blocking operation in a separate thread. That's why underlying event systems tend to be asynchronous. Mixing the two models improperly, such as allowing blocking from callbacks, results in something much worse than either model on its own: events may be delayed waiting for other unrelated events, and you open up a new class of race conditions by losing the normal atomicity of asynchronous event processing. We should give driver writers the option of using either event model, as for many drivers it is much simpler to write them using the synchronous model. For example, most USB drivers could set up one thread per USB pipe (and maybe one per-device thread) and then just do everything synchronously. A typical USB network driver would have one pipe's thread always blocking on an input pipe. There might be some extra things that the taskqueue code could do to make it easier to implement such threads. It would be possible to implement an asynchronous version of usbd_abort_pipe() that invokes a callback on completion. That seems like a good idea, as it would allow us to handle the cases where we need to initiate the abort from a callback. We can add an #ifdef DIAGNOSTIC check to usb_transfer_complete() to catch callbacks that sleep, by doing something along the lines of the `dont_sleep_in_callout' approach in kern_timeout.c. In summary: non-blocking: good! blocking: good! blocking from non-blocking contexts: bad! Ian