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/u...@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;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to