From owner-svn-src-all@FreeBSD.ORG Tue Jan 13 19:03:24 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4214F1065942; Tue, 13 Jan 2009 19:03:24 +0000 (UTC) (envelope-from thompsa@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id B611F8FC2F; Tue, 13 Jan 2009 19:03:23 +0000 (UTC) (envelope-from thompsa@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n0DJ3NAM012529; Tue, 13 Jan 2009 19:03:23 GMT (envelope-from thompsa@svn.freebsd.org) Received: (from thompsa@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n0DJ3NaH012524; Tue, 13 Jan 2009 19:03:23 GMT (envelope-from thompsa@svn.freebsd.org) Message-Id: <200901131903.n0DJ3NaH012524@svn.freebsd.org> From: Andrew Thompson Date: Tue, 13 Jan 2009 19:03:23 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r187174 - in head/sys/dev/usb2: controller core X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 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: Tue, 13 Jan 2009 19:03:28 -0000 Author: thompsa Date: Tue Jan 13 19:03:23 2009 New Revision: 187174 URL: http://svn.freebsd.org/changeset/base/187174 Log: MFp4: //depot/projects/usb@155842 Reduce the number of callback processes to 4 per USB controller. There are two rough categories: 1) Giant locked USB transfers. 2) Non-Giant locked USB transfers. On a real system with many USB devices plugged in the number of processes reported by "ps auxw | grep USBPROC" was reduced from 40 to 18. Submitted by: Hans Petter Selasky Modified: head/sys/dev/usb2/controller/usb2_bus.h head/sys/dev/usb2/controller/usb2_controller.c head/sys/dev/usb2/core/usb2_device.c head/sys/dev/usb2/core/usb2_transfer.c head/sys/dev/usb2/core/usb2_transfer.h Modified: head/sys/dev/usb2/controller/usb2_bus.h ============================================================================== --- head/sys/dev/usb2/controller/usb2_bus.h Tue Jan 13 19:03:12 2009 (r187173) +++ head/sys/dev/usb2/controller/usb2_bus.h Tue Jan 13 19:03:23 2009 (r187174) @@ -53,6 +53,13 @@ struct usb2_bus { struct usb2_bus_stat stats_ok; struct usb2_process explore_proc; struct usb2_process roothub_proc; + /* + * There are two callback processes. One for Giant locked + * callbacks. One for non-Giant locked callbacks. This should + * avoid congestion and reduce response time in most cases. + */ + struct usb2_process giant_callback_proc; + struct usb2_process non_giant_callback_proc; struct usb2_bus_msg explore_msg[2]; struct usb2_bus_msg detach_msg[2]; struct usb2_bus_msg attach_msg[2]; Modified: head/sys/dev/usb2/controller/usb2_controller.c ============================================================================== --- head/sys/dev/usb2/controller/usb2_controller.c Tue Jan 13 19:03:12 2009 (r187173) +++ head/sys/dev/usb2/controller/usb2_controller.c Tue Jan 13 19:03:23 2009 (r187174) @@ -166,6 +166,11 @@ usb2_detach(device_t dev) USB_BUS_UNLOCK(bus); + /* Get rid of USB callback processes */ + + usb2_proc_unsetup(&bus->giant_callback_proc); + usb2_proc_unsetup(&bus->non_giant_callback_proc); + /* Get rid of USB roothub process */ usb2_proc_unsetup(&bus->roothub_proc); @@ -391,8 +396,17 @@ usb2_attach_sub(device_t dev, struct usb bus->roothub_msg[1].hdr.pm_callback = &usb2_bus_roothub; bus->roothub_msg[1].bus = bus; - /* Create USB explore and roothub processes */ - if (usb2_proc_setup(&bus->roothub_proc, + /* Create USB explore, roothub and callback processes */ + + if (usb2_proc_setup(&bus->giant_callback_proc, + &bus->bus_mtx, USB_PRI_MED)) { + printf("WARNING: Creation of USB Giant " + "callback process failed.\n"); + } else if (usb2_proc_setup(&bus->non_giant_callback_proc, + &bus->bus_mtx, USB_PRI_HIGH)) { + printf("WARNING: Creation of USB non-Giant " + "callback process failed.\n"); + } else if (usb2_proc_setup(&bus->roothub_proc, &bus->bus_mtx, USB_PRI_HIGH)) { printf("WARNING: Creation of USB roothub " "process failed.\n"); Modified: head/sys/dev/usb2/core/usb2_device.c ============================================================================== --- head/sys/dev/usb2/core/usb2_device.c Tue Jan 13 19:03:12 2009 (r187173) +++ head/sys/dev/usb2/core/usb2_device.c Tue Jan 13 19:03:23 2009 (r187174) @@ -1742,8 +1742,18 @@ usb2_free_device(struct usb2_device *ude /* unsetup any leftover default USB transfers */ usb2_transfer_unsetup(udev->default_xfer, USB_DEFAULT_XFER_MAX); + /* template unsetup, if any */ (usb2_temp_unsetup_p) (udev); + /* + * Make sure that our clear-stall messages are not queued + * anywhere: + */ + USB_BUS_LOCK(udev->bus); + usb2_proc_mwait(&udev->bus->non_giant_callback_proc, + &udev->cs_msg[0], &udev->cs_msg[1]); + USB_BUS_UNLOCK(udev->bus); + sx_destroy(udev->default_sx); sx_destroy(udev->default_sx + 1); Modified: head/sys/dev/usb2/core/usb2_transfer.c ============================================================================== --- head/sys/dev/usb2/core/usb2_transfer.c Tue Jan 13 19:03:12 2009 (r187173) +++ head/sys/dev/usb2/core/usb2_transfer.c Tue Jan 13 19:03:23 2009 (r187174) @@ -819,13 +819,12 @@ usb2_transfer_setup(struct usb2_device * info->done_m[1].hdr.pm_callback = &usb2_callback_proc; info->done_m[1].xroot = info; - /* create a callback thread */ - - if (usb2_proc_setup(&info->done_p, - &udev->bus->bus_mtx, USB_PRI_HIGH)) { - parm.err = USB_ERR_NO_INTR_THREAD; - goto done; - } + if (xfer_mtx == &Giant) + info->done_p = + &udev->bus->giant_callback_proc; + else + info->done_p = + &udev->bus->non_giant_callback_proc; } /* reset sizes */ @@ -1045,10 +1044,11 @@ usb2_transfer_unsetup_sub(struct usb2_xf temp = usb2_get_dma_delay(info->bus); usb2_pause_mtx(&info->bus->bus_mtx, temp); } - USB_BUS_UNLOCK(info->bus); - /* wait for interrupt thread to exit */ - usb2_proc_unsetup(&info->done_p); + /* make sure that our done messages are not queued anywhere */ + usb2_proc_mwait(info->done_p, &info->done_m[0], &info->done_m[1]); + + USB_BUS_UNLOCK(info->bus); /* free DMA'able memory, if any */ pc = info->dma_page_cache_start; @@ -1811,7 +1811,7 @@ usb2_callback_ss_done_defer(struct usb2_ * will have a Lock Order Reversal, LOR, if we try to * proceed ! */ - if (usb2_proc_msignal(&info->done_p, + if (usb2_proc_msignal(info->done_p, &info->done_m[0], &info->done_m[1])) { /* ignore */ } @@ -1851,7 +1851,7 @@ usb2_callback_wrapper(struct usb2_xfer_q * will have a Lock Order Reversal, LOR, if we try to * proceed ! */ - if (usb2_proc_msignal(&info->done_p, + if (usb2_proc_msignal(info->done_p, &info->done_m[0], &info->done_m[1])) { /* ignore */ } @@ -2195,7 +2195,8 @@ usb2_pipe_start(struct usb2_xfer_queue * udev, NULL, pipe); } else if (udev->default_xfer[1]) { info = udev->default_xfer[1]->xroot; - if (usb2_proc_msignal(&info->done_p, + if (usb2_proc_msignal( + &info->bus->non_giant_callback_proc, &udev->cs_msg[0], &udev->cs_msg[1])) { /* ignore */ } Modified: head/sys/dev/usb2/core/usb2_transfer.h ============================================================================== --- head/sys/dev/usb2/core/usb2_transfer.h Tue Jan 13 19:03:12 2009 (r187173) +++ head/sys/dev/usb2/core/usb2_transfer.h Tue Jan 13 19:03:23 2009 (r187174) @@ -47,8 +47,8 @@ struct usb2_xfer_root { struct usb2_done_msg done_m[2]; struct cv cv_drain; struct usb2_dma_parent_tag dma_parent_tag; - struct usb2_process done_p; + struct usb2_process *done_p; /* pointer to callback process */ void *memory_base; struct mtx *xfer_mtx; /* cannot be changed during operation */ struct usb2_page_cache *dma_page_cache_start;