Date: Mon, 25 Jul 2011 16:11:52 +0000 (UTC) From: Marius Strobl <marius@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org Subject: svn commit: r224327 - stable/7/sys/dev/mpt Message-ID: <201107251611.p6PGBq7O064179@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: marius Date: Mon Jul 25 16:11:52 2011 New Revision: 224327 URL: http://svn.freebsd.org/changeset/base/224327 Log: MFC: r198262 Use callout_init_mtx on FreeBSD versions recent enough. This closes the race where interrupt thread can complete the request for which timeout has fired and while mpt_timeout has blocked on mpt_lock. Modified: stable/7/sys/dev/mpt/mpt.c stable/7/sys/dev/mpt/mpt.h stable/7/sys/dev/mpt/mpt_cam.c stable/7/sys/dev/mpt/mpt_raid.c Directory Properties: stable/7/sys/ (props changed) stable/7/sys/cddl/contrib/opensolaris/ (props changed) stable/7/sys/contrib/dev/acpica/ (props changed) stable/7/sys/contrib/pf/ (props changed) Modified: stable/7/sys/dev/mpt/mpt.c ============================================================================== --- stable/7/sys/dev/mpt/mpt.c Mon Jul 25 15:14:03 2011 (r224326) +++ stable/7/sys/dev/mpt/mpt.c Mon Jul 25 16:11:52 2011 (r224327) @@ -1239,7 +1239,6 @@ retry: req->state = REQ_STATE_ALLOCATED; req->chain = NULL; mpt_assign_serno(mpt, req); - mpt_callout_init(&req->callout); } else if (sleep_ok != 0) { mpt->getreqwaiter = 1; mpt_sleep(mpt, &mpt->request_free_list, PUSER, "mptgreq", 0); @@ -2252,6 +2251,7 @@ mpt_core_attach(struct mpt_softc *mpt) for (val = 0; val < MPT_MAX_REQUESTS(mpt); val++) { request_t *req = &mpt->request_pool[val]; req->state = REQ_STATE_ALLOCATED; + mpt_callout_init(mpt, &req->callout); mpt_free_request(mpt, req); } MPT_UNLOCK(mpt); @@ -2335,10 +2335,18 @@ mpt_core_shutdown(struct mpt_softc *mpt) void mpt_core_detach(struct mpt_softc *mpt) { + int val; + /* * XXX: FREE MEMORY */ mpt_disable_ints(mpt); + + /* Make sure no request has pending timeouts. */ + for (val = 0; val < MPT_MAX_REQUESTS(mpt); val++) { + request_t *req = &mpt->request_pool[val]; + mpt_callout_drain(mpt, &req->callout); + } } int Modified: stable/7/sys/dev/mpt/mpt.h ============================================================================== --- stable/7/sys/dev/mpt/mpt.h Mon Jul 25 15:14:03 2011 (r224326) +++ stable/7/sys/dev/mpt/mpt.h Mon Jul 25 16:11:52 2011 (r224327) @@ -303,13 +303,6 @@ void mpt_map_rquest(void *, bus_dma_segm kthread_exit(status) #endif -/****************************** Timer Facilities ******************************/ -#if __FreeBSD_version > 500000 -#define mpt_callout_init(c) callout_init(c, /*mpsafe*/1); -#else -#define mpt_callout_init(c) callout_init(c); -#endif - /********************************** Endianess *********************************/ #define MPT_2_HOST64(ptr, tag) ptr->tag = le64toh(ptr->tag) #define MPT_2_HOST32(ptr, tag) ptr->tag = le32toh(ptr->tag) @@ -897,6 +890,10 @@ mpt_sleep(struct mpt_softc *mpt, void *i callout_reset(&(req)->callout, (ticks), (func), (arg)); #define mpt_req_untimeout(req, func, arg) \ callout_stop(&(req)->callout) +#define mpt_callout_init(mpt, c) \ + callout_init(c) +#define mpt_callout_drain(mpt, c) \ + callout_stop(c) #else #if 1 @@ -919,9 +916,13 @@ mpt_sleep(struct mpt_softc *mpt, void *i #define mpt_sleep(mpt, ident, priority, wmesg, timo) \ msleep(ident, &(mpt)->mpt_lock, priority, wmesg, timo) #define mpt_req_timeout(req, ticks, func, arg) \ - callout_reset(&(req)->callout, (ticks), (func), (arg)); + callout_reset(&(req)->callout, (ticks), (func), (arg)) #define mpt_req_untimeout(req, func, arg) \ callout_stop(&(req)->callout) +#define mpt_callout_init(mpt, c) \ + callout_init_mtx(c, &(mpt)->mpt_lock, 0) +#define mpt_callout_drain(mpt, c) \ + callout_drain(c) #else @@ -934,18 +935,18 @@ mpt_sleep(struct mpt_softc *mpt, void *i #define MPTLOCK_2_CAMLOCK(mpt) #define CAMLOCK_2_MPTLOCK(mpt) +#define mpt_req_timeout(req, ticks, func, arg) \ + callout_reset(&(req)->callout, (ticks), (func), (arg)) +#define mpt_req_untimeout(req, func, arg) \ + callout_stop(&(req)->callout) +#define mpt_callout_init(mpt, c) \ + callout_init(c, 0) +#define mpt_callout_drain(mpt, c) \ + callout_drain(c) + static __inline int mpt_sleep(struct mpt_softc *, void *, int, const char *, int); -#define mpt_ccb_timeout(ccb, ticks, func, arg) \ - do { \ - (ccb)->ccb_h.timeout_ch = timeout((func), (arg), (ticks)); \ - } while (0) -#define mpt_ccb_untimeout(ccb, func, arg) \ - untimeout((func), (arg), (ccb)->ccb_h.timeout_ch) -#define mpt_ccb_timeout_init(ccb) \ - callout_handle_init(&(ccb)->ccb_h.timeout_ch) - static __inline int mpt_sleep(struct mpt_softc *mpt, void *i, int p, const char *w, int t) { Modified: stable/7/sys/dev/mpt/mpt_cam.c ============================================================================== --- stable/7/sys/dev/mpt/mpt_cam.c Mon Jul 25 15:14:03 2011 (r224326) +++ stable/7/sys/dev/mpt/mpt_cam.c Mon Jul 25 16:11:52 2011 (r224327) @@ -1250,7 +1250,10 @@ mpt_timeout(void *arg) ccb = (union ccb *)arg; mpt = ccb->ccb_h.ccb_mpt_ptr; +#if __FreeBSD_version < 500000 MPT_LOCK(mpt); +#endif + MPT_LOCK_ASSERT(mpt); req = ccb->ccb_h.ccb_req_ptr; mpt_prt(mpt, "request %p:%u timed out for ccb %p (req->ccb %p)\n", req, req->serno, ccb, req->ccb); @@ -1261,7 +1264,9 @@ mpt_timeout(void *arg) req->state |= REQ_STATE_TIMEDOUT; mpt_wakeup_recovery_thread(mpt); } +#if __FreeBSD_version < 500000 MPT_UNLOCK(mpt); +#endif } /* Modified: stable/7/sys/dev/mpt/mpt_raid.c ============================================================================== --- stable/7/sys/dev/mpt/mpt_raid.c Mon Jul 25 15:14:03 2011 (r224326) +++ stable/7/sys/dev/mpt/mpt_raid.c Mon Jul 25 16:11:52 2011 (r224327) @@ -271,7 +271,7 @@ mpt_raid_attach(struct mpt_softc *mpt) mpt_handler_t handler; int error; - mpt_callout_init(&mpt->raid_timer); + mpt_callout_init(mpt, &mpt->raid_timer); error = mpt_spawn_raid_thread(mpt); if (error != 0) { @@ -320,10 +320,10 @@ mpt_raid_detach(struct mpt_softc *mpt) struct ccb_setasync csa; mpt_handler_t handler; - callout_stop(&mpt->raid_timer); + mpt_callout_drain(mpt, &mpt->raid_timer); + MPT_LOCK(mpt); mpt_terminate_raid_thread(mpt); - handler.reply_handler = mpt_raid_reply_handler; mpt_deregister_handler(mpt, MPT_HANDLER_REPLY, handler, raid_handler_id); @@ -1570,9 +1570,14 @@ mpt_raid_timer(void *arg) struct mpt_softc *mpt; mpt = (struct mpt_softc *)arg; +#if __FreeBSD_version < 500000 MPT_LOCK(mpt); +#endif + MPT_LOCK_ASSERT(mpt); mpt_raid_wakeup(mpt); +#if __FreeBSD_version < 500000 MPT_UNLOCK(mpt); +#endif } void
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201107251611.p6PGBq7O064179>