From owner-p4-projects@FreeBSD.ORG Wed Dec 19 21:56:35 2007 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id E4B5816A473; Wed, 19 Dec 2007 21:56:34 +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 8082316A421 for ; Wed, 19 Dec 2007 21:56:34 +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 76C0413C46A for ; Wed, 19 Dec 2007 21:56:34 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id lBJLuYgY055065 for ; Wed, 19 Dec 2007 21:56:34 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id lBJLuXt3055062 for perforce@freebsd.org; Wed, 19 Dec 2007 21:56:33 GMT (envelope-from hselasky@FreeBSD.org) Date: Wed, 19 Dec 2007 21:56:33 GMT Message-Id: <200712192156.lBJLuXt3055062@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 131257 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: Wed, 19 Dec 2007 21:56:35 -0000 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 #include #include -#include -#include +#include +#include #include #include @@ -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 {