From owner-p4-projects@FreeBSD.ORG Fri Jan 9 00:18:29 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id C7C481065672; Fri, 9 Jan 2009 00:18:28 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 87FCD106564A for ; Fri, 9 Jan 2009 00:18:28 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 75DB88FC16 for ; Fri, 9 Jan 2009 00:18:28 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n090ISII014133 for ; Fri, 9 Jan 2009 00:18:28 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n090ISsS014131 for perforce@freebsd.org; Fri, 9 Jan 2009 00:18:28 GMT (envelope-from hselasky@FreeBSD.org) Date: Fri, 9 Jan 2009 00:18:28 GMT Message-Id: <200901090018.n090ISsS014131@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Cc: Subject: PERFORCE change 155842 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 09 Jan 2009 00:18:29 -0000 http://perforce.freebsd.org/chv.cgi?CH=155842 Change 155842 by hselasky@hselasky_laptop001 on 2009/01/09 00:18:19 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. Affected files ... .. //depot/projects/usb/src/sys/dev/usb2/controller/usb2_bus.h#12 edit .. //depot/projects/usb/src/sys/dev/usb2/controller/usb2_controller.c#23 edit .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_device.c#47 edit .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_transfer.c#38 edit .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_transfer.h#14 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb2/controller/usb2_bus.h#12 (text+ko) ==== @@ -53,6 +53,13 @@ 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]; ==== //depot/projects/usb/src/sys/dev/usb2/controller/usb2_controller.c#23 (text+ko) ==== @@ -166,6 +166,11 @@ 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 @@ 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"); ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_device.c#47 (text+ko) ==== @@ -1742,8 +1742,18 @@ /* 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); ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_transfer.c#38 (text+ko) ==== @@ -819,13 +819,12 @@ 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,11 +1044,12 @@ temp = usb2_get_dma_delay(info->bus); usb2_pause_mtx(&info->bus->bus_mtx, temp); } + + /* 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); - /* wait for interrupt thread to exit */ - usb2_proc_unsetup(&info->done_p); - /* free DMA'able memory, if any */ pc = info->dma_page_cache_start; while (pc != info->dma_page_cache_end) { @@ -1811,7 +1811,7 @@ * 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 @@ * 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 @@ 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 */ } ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_transfer.h#14 (text+ko) ==== @@ -47,8 +47,8 @@ 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;