PERFORCE change 155842 for review

Hans Petter Selasky hselasky at FreeBSD.org
Thu Jan 8 16:18:29 PST 2009


http://perforce.freebsd.org/chv.cgi?CH=155842

Change 155842 by hselasky at 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;


More information about the p4-projects mailing list