mirror of
https://github.com/opnsense/src.git
synced 2026-06-08 16:22:46 -04:00
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
This commit is contained in:
parent
13bd84042e
commit
edf1048c85
5 changed files with 48 additions and 16 deletions
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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 usb2_bus *bus)
|
|||
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");
|
||||
|
|
|
|||
|
|
@ -1742,8 +1742,18 @@ usb2_free_device(struct usb2_device *udev)
|
|||
/* 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);
|
||||
|
||||
|
|
|
|||
|
|
@ -819,13 +819,12 @@ usb2_transfer_setup(struct usb2_device *udev,
|
|||
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_xfer_root *info, uint8_t needs_delay)
|
|||
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_xfer *xfer)
|
|||
* 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_queue *pq)
|
|||
* 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 *pq)
|
|||
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 */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue