Date: Wed, 28 Jun 2006 06:12:32 GMT From: Kip Macy <kmacy@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 100186 for review Message-ID: <200606280612.k5S6CWch060931@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=100186 Change 100186 by kmacy@kmacy_storage:sun4v_work_sleepq on 2006/06/28 06:11:51 add LK_INTERLOCK and LK_CANRECURSE semantics - finally earning the name SX but Uglier Affected files ... .. //depot/projects/kmacy_sun4v/src/sys/kern/kern_sxu.c#5 edit .. //depot/projects/kmacy_sun4v/src/sys/sys/sxu.h#4 edit Differences ... ==== //depot/projects/kmacy_sun4v/src/sys/kern/kern_sxu.c#5 (text+ko) ==== @@ -135,7 +135,7 @@ int -_sxu_slock(struct sxu *sx, int timo, const char *file, int line) +_sxu_slock(struct sxu *sx, int timo, struct mtx *interlkp, const char *file, int line) { int contested, error; @@ -145,6 +145,10 @@ error = 0; mtx_lock(sx->sxu_lock); + if (interlkp) { + mxt_assert(m, MA_OWNED); + mtx_unlock(m); + } KASSERT(sx->sxu_xholder != curthread, ("%s (%s): slock while xlock is held @ %s:%d\n", __func__, sx->sxu_object.lo_name, file, line)); @@ -183,25 +187,30 @@ } int -_sxu_try_slock(struct sxu *sx, const char *file, int line) +_sxu_try_slock(struct sxu *sx, struct mtx *interlkp, const char *file, int line) { - + int error; mtx_lock(sx->sxu_lock); + if (interlkp) { + mxt_assert(interlkp, MA_OWNED); + mtx_unlock(interlkp); + } if (sx->sxu_cnt >= 0) { sx->sxu_cnt++; LOCK_LOG_TRY("SLOCK", &sx->sxu_object, 0, 1, file, line); WITNESS_LOCK(&sx->sxu_object, LOP_TRYLOCK, file, line); - mtx_unlock(sx->sxu_lock); - return (1); + error = 1; + } else { LOCK_LOG_TRY("SLOCK", &sx->sxu_object, 0, 0, file, line); - mtx_unlock(sx->sxu_lock); - return (0); + error = 0; } + mtx_unlock(sx->sxu_lock); + return (error); } int -_sxu_xlock(struct sxu *sx, int timo, const char *file, int line) +_sxu_xlock(struct sxu *sx, int timo, struct mtx *interlkp, int canrecurse, const char *file, int line) { int contested, error; @@ -211,7 +220,10 @@ waittime= 0; mtx_lock(sx->sxu_lock); - + if (interlkp) { + mxt_assert(interlkp, MA_OWNED); + mtx_unlock(interlkp); + } /* * With sx locks, we're absolutely not permitted to recurse on * xlocks, as it is fatal (deadlock). Normally, recursion is handled @@ -219,15 +231,20 @@ * xlock while in here, we consider it API abuse and put it under * INVARIANTS. */ - KASSERT(sx->sxu_xholder != curthread, - ("%s (%s): xlock already held @ %s:%d", __func__, - sx->sxu_object.lo_name, file, line)); + if (!canrecurse) { + KASSERT(sx->sxu_xholder != curthread, + ("%s (%s): xlock already held @ %s:%d", __func__, + sx->sxu_object.lo_name, file, line)); + + } else if (canrecurse && sx->sxu_xholder == curthread) { + sx->sxu_cnt--; + goto done; + } WITNESS_CHECKORDER(&sx->sxu_object, LOP_NEWORDER | LOP_EXCLUSIVE, file, - line); + line); + /* Loop in case we lose the race for lock acquisition. */ - /* Loop in case we lose the race for lock acquisition. */ - if (sx->sxu_cnt) - lock_profile_waitstart(&waittime); + lock_profile_waitstart(&waittime); while (sx->sxu_cnt != 0) { sx->sxu_excl_wcnt++; lock_profile_obtain_lock_failed(&sx->sxu_object, &contested); @@ -238,7 +255,7 @@ sx->sxu_excl_wcnt--; if (error) - goto fail; + goto done; } MPASS(sx->sxu_cnt == 0); @@ -251,29 +268,38 @@ LOCK_LOG_LOCK("XLOCK", &sx->sxu_object, 0, 0, file, line); WITNESS_LOCK(&sx->sxu_object, LOP_EXCLUSIVE, file, line); - fail: + done: mtx_unlock(sx->sxu_lock); return (error); } int -_sxu_try_xlock(struct sxu *sx, const char *file, int line) +_sxu_try_xlock(struct sxu *sx, struct mtx *interlkp, int canrecurse, const char *file, int line) { + int error; mtx_lock(sx->sxu_lock); - if (sx->sxu_cnt == 0) { + if (interlkp) { + mxt_assert(interlkp, MA_OWNED); + mtx_unlock(interlkp); + } + KASSERT((sx->sxu_cnt >= 0) || canrecurse, ("recursing on non-recursable lock")); + if (sx->sxu_cnt <= 0) { sx->sxu_cnt--; sx->sxu_xholder = curthread; - LOCK_LOG_TRY("XLOCK", &sx->sxu_object, 0, 1, file, line); - WITNESS_LOCK(&sx->sxu_object, LOP_EXCLUSIVE | LOP_TRYLOCK, file, - line); - mtx_unlock(sx->sxu_lock); - return (1); + if (!canrecurse) { + LOCK_LOG_TRY("XLOCK", &sx->sxu_object, 0, 1, file, line); + WITNESS_LOCK(&sx->sxu_object, LOP_EXCLUSIVE | LOP_TRYLOCK, file, + line); + } + error = 1; } else { LOCK_LOG_TRY("XLOCK", &sx->sxu_object, 0, 0, file, line); - mtx_unlock(sx->sxu_lock); - return (0); + error = 0; } + mtx_unlock(sx->sxu_lock); + + return (error); } void @@ -322,6 +348,9 @@ /* Release. */ sx->sxu_cnt++; + if (sx->sxu_cnt < 0) + goto done; + sx->sxu_xholder = NULL; lock_profile_release_lock(&sx->sxu_object); @@ -336,6 +365,7 @@ cv_signal(sx->sxu_drain_cvp); LOCK_LOG_LOCK("XUNLOCK", &sx->sxu_object, 0, 0, file, line); + done: mtx_unlock(sx->sxu_lock); } ==== //depot/projects/kmacy_sun4v/src/sys/sys/sxu.h#4 (text+ko) ==== @@ -50,10 +50,10 @@ void sxu_sysinit(void *arg); void sxu_init(struct sxu *sx, const char *description); void sxu_destroy(struct sxu *sx); -void _sxu_slock(struct sxu *sx, int timo, const char *file, int line); -void _sxu_xlock(struct sxu *sx, int timo, const char *file, int line); -int _sxu_try_slock(struct sxu *sx, const char *file, int line); -int _sxu_try_xlock(struct sxu *sx, const char *file, int line); +void _sxu_slock(struct sxu *sx, int timo, struct mtx *interlkp, const char *file, int line); +void _sxu_xlock(struct sxu *sx, int timo, int interlkp, int canrecurse, const char *file, int line); +int _sxu_try_slock(struct sxu *sx, mtx *interlkp, const char *file, int line); +int _sxu_try_xlock(struct sxu *sx, struct mtx *interlkp, int canrecurse, const char *file, int line); void _sxu_sunlock(struct sxu *sx, const char *file, int line); void _sxu_xunlock(struct sxu *sx, const char *file, int line); int _sxu_try_upgrade(struct sxu *sx, const char *file, int line); @@ -79,18 +79,33 @@ SYSUNINIT(name##_sxu_sysuninit, SI_SUB_LOCK, SI_ORDER_MIDDLE, \ sxu_destroy, (sxa)) -#define sxu_slock(sx) _sxu_slock((sx), (0), LOCK_FILE, LOCK_LINE) -#define sxu_xlock(sx) _sxu_xlock((sx), (0), LOCK_FILE, LOCK_LINE) -#define sxu_slock_timedwait(sx, timo) _sxu_slock((sx), (timo), LOCK_FILE, LOCK_LINE) -#define sxu_xlock_timedwait(sx, timo) _sxu_xlock((sx), (timo), LOCK_FILE, LOCK_LINE) -#define sxu_try_slock(sx) _sxu_try_slock((sx), LOCK_FILE, LOCK_LINE) -#define sxu_try_xlock(sx) _sxu_try_xlock((sx), LOCK_FILE, LOCK_LINE) +#define sxu_slock(sx) \ + _sxu_slock((sx), (0), NULL, LOCK_FILE, LOCK_LINE) +#define sxu_xlock(sx, canrecurse) \ + _sxu_xlock((sx), (0), NULL, (canrecurse), LOCK_FILE, LOCK_LINE) +#define sxu_slock_interlocked(sx, interlkp) \ + _sxu_slock((sx), (0), interlkp, LOCK_FILE, LOCK_LINE) +#define sxu_xlock_interlocked(sx, interlkp, canrecurse) \ + _sxu_xlock((sx), (0), interlkp, LOCK_FILE, LOCK_LINE) +#define sxu_try_slock(sx) \ + _sxu_try_slock((sx), (NULL), LOCK_FILE, LOCK_LINE) +#define sxu_try_xlock(sx, int canrecurse) \ + _sxu_try_xlock((sx), (NULL), (canrecurse), LOCK_FILE, LOCK_LINE) +#define sxu_try_slock_interlocked(sx, interlkp) \ + _sxu_try_slock((sx), (interlkp), LOCK_FILE, LOCK_LINE) +#define sxu_try_xlock_interlocked(sx, interlkp, int canrecurse) \ + _sxu_try_xlock((sx), (interlkp), (canrecurse), LOCK_FILE, LOCK_LINE) + +#define sxu_xlock_interlock_timedwait(sx, timo, interlkp, canrecurse) \ + _sxu_xlock((sx), (timo), (interlkp), (canrecurse), LOCK_FILE, LOCK_LINE) + #define sxu_sunlock(sx) _sxu_sunlock((sx), LOCK_FILE, LOCK_LINE) #define sxu_xunlock(sx) _sxu_xunlock((sx), LOCK_FILE, LOCK_LINE) #define sxu_try_upgrade(sx) _sxu_try_upgrade((sx), LOCK_FILE, LOCK_LINE) #define sxu_downgrade(sx) _sxu_downgrade((sx), LOCK_FILE, LOCK_LINE) #define sxu_drain(sx, cv) _sxu_drain((sx), (cv), LOCK_FILE, LOCK_LINE) + #define sxu_unlock(sx) do { \ if ((sx)->sx_cnt < 0) \ sxu_xunlock(sx); \
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200606280612.k5S6CWch060931>