Date: Wed, 19 Dec 2007 21:56:33 GMT From: Hans Petter Selasky <hselasky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 131257 for review Message-ID: <200712192156.lBJLuXt3055062@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=131257 Change 131257 by hselasky@hselasky_laptop001 on 2007/12/19 21:55:33 Switch over to using kthread instead of SWI's. I caught several panics when using "intr_event_destroy". Suggested by "John Baldwin". Affected files ... .. //depot/projects/usb/src/sys/dev/usb/usb_subr.h#81 edit .. //depot/projects/usb/src/sys/dev/usb/usb_transfer.c#80 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb/usb_subr.h#81 (text+ko) ==== @@ -632,8 +632,7 @@ LIST_HEAD(, usbd_xfer) dma_head; LIST_HEAD(, usbd_xfer) done_head; - struct intr_event *done_event; /* software interrupt event */ - void *done_cookie; /* software interrupt thread cookie */ + struct proc *done_thread; void *memory_base; struct mtx *priv_mtx; struct mtx *usb_mtx; @@ -659,6 +658,7 @@ * called */ uint8_t dma_tag_max; + uint8_t done_sleep; /* set if done thread is sleeping */ }; struct usbd_mbuf { ==== //depot/projects/usb/src/sys/dev/usb/usb_transfer.c#80 (text+ko) ==== @@ -43,8 +43,8 @@ #include <sys/kernel.h> #include <sys/lock.h> #include <sys/malloc.h> -#include <sys/bus.h> -#include <sys/interrupt.h> +#include <sys/kthread.h> +#include <sys/unistd.h> #include <dev/usb/usb_port.h> #include <dev/usb/usb.h> @@ -55,15 +55,16 @@ static void usbd_pipe_enter_wrapper(struct usbd_xfer *xfer); static void usbd_compute_max_frame_size(struct usbd_xfer *xfer); -static void usbd_drop_refcount(struct usbd_memory_info *info, uint8_t dropcount); static uint8_t usbd_start_hardware_sub(struct usbd_xfer *xfer); static void usbd_premature_callback(struct usbd_xfer *xfer, usbd_status_t error); static void usbd_delayed_transfer_start(void *arg); static void usbd_bdma_work_loop(struct usbd_memory_info *info); static void usbd_bdma_cancel_event(struct usbd_xfer *xfer); static usbd_status_t usbd_handle_request(struct usbd_xfer *xfer); -static driver_intr_t usbd_callback_intr_td; +static void usbd_callback_intr_td(void *arg); static void usbd_transfer_unsetup_sub(struct usbd_memory_info *info); +static void usbd_callback_intr_sched(struct usbd_memory_info *info); + #ifdef USB_DEBUG void @@ -835,12 +836,10 @@ LIST_INIT(&(info->done_head)); - /* create our interrupt thread */ - if (swi_add(&(info->done_event), "usbcb", - &usbd_callback_intr_td, info, SWI_CAMBIO, - INTR_MPSAFE, &(info->done_cookie))) { - info->done_cookie = NULL; - info->done_event = NULL; + if (usb_thread_create + (&usbd_callback_intr_td, info, + &(info->done_thread), "USB interrupt thread")) { + info->done_thread = NULL; parm.err = USBD_NO_INTR_THREAD; goto done; } @@ -1018,23 +1017,6 @@ } /*------------------------------------------------------------------------* - * usbd_drop_refcount - * - * This function is called from various places, and its job is to - * wakeup "usbd_transfer_unsetup", when is safe to free the memory. - *------------------------------------------------------------------------*/ -static void -usbd_drop_refcount(struct usbd_memory_info *info, uint8_t dropcount) -{ - mtx_assert(info->usb_mtx, MA_OWNED); - - if ((info->memory_refcount -= dropcount) == 0) { - wakeup(info); - } - return; -} - -/*------------------------------------------------------------------------* * usbd_dma_delay * * The following function is called when we need to @@ -1075,16 +1057,16 @@ usbd_transfer_unsetup_sub(struct usbd_memory_info *info) { struct usbd_page_cache *pc; - int error; + + /* wait for interrupt thread to exit */ + + while (info->done_thread) { - /* - * wait for any USB callbacks to - * return - */ + usbd_callback_intr_sched(info); - while (info->memory_refcount > 0) { - error = mtx_sleep(info, info->usb_mtx, 0, - "usbdwait", 0); + if (mtx_sleep(&(info->done_thread), info->usb_mtx, + 0, "usbdwait", 0)) { + } } mtx_unlock(info->usb_mtx); @@ -1110,11 +1092,6 @@ usbd_dma_tag_unsetup(info->dma_tag_p, info->dma_tag_max); - /* teardown the interrupt thread, if any */ - if (info->done_cookie) { - swi_remove(info->done_cookie); - intr_event_destroy(info->done_event); - } /* * free the "memory_base" last, * hence the "info" structure is @@ -2116,6 +2093,18 @@ return; } +static void +usbd_callback_intr_sched(struct usbd_memory_info *info) +{ + mtx_assert(info->usb_mtx, MA_OWNED); + + if (info->done_sleep) { + info->done_sleep = 0; + wakeup(info); + } + return; +} + /*------------------------------------------------------------------------* * usbd_callback_intr_td * @@ -2190,12 +2179,23 @@ mtx_unlock(info->priv_mtx); mtx_lock(info->usb_mtx); - usbd_drop_refcount(info, dropcount); + info->memory_refcount -= dropcount; goto repeat; } else { - mtx_unlock(info->usb_mtx); + if (info->memory_refcount != 0) { + info->done_sleep = 1; + if (mtx_sleep(info, info->usb_mtx, 0, "usbdone", 0)) { + /* should not happen */ + } + goto repeat; + } } + + wakeup(&(info->done_thread)); + info->done_thread = NULL; + mtx_unlock(info->usb_mtx); + usb_thread_exit(0); return; } @@ -2313,7 +2313,7 @@ info->memory_refcount++; LIST_INSERT_HEAD(&(info->done_head), xfer, done_list); - swi_sched(info->done_cookie, 0); + usbd_callback_intr_sched(info); } return; } else {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200712192156.lBJLuXt3055062>