- Introduce lockmgr_args() in the lockmgr space. This function performs
the same operation of lockmgr() but accepting a custom wmesg, prio and timo for the particular lock instance, overriding default values lkp->lk_wmesg, lkp->lk_prio and lkp->lk_timo. - Use lockmgr_args() in order to implement BUF_TIMELOCK() - Cleanup BUF_LOCK() - Remove LK_INTERNAL as it is nomore used in the lockmgr namespace Tested by: Andrea Barberio <insomniac at slackware dot it>
This commit is contained in:
parent
5a14b2bf8e
commit
24463dbbee
@ -118,8 +118,10 @@ unlock_lockmgr(struct lock_object *lock)
|
||||
#define LK_ALL (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE | \
|
||||
LK_SHARE_NONZERO | LK_WAIT_NONZERO)
|
||||
|
||||
static int acquire(struct lock **lkpp, int extflags, int wanted, int *contested, uint64_t *waittime);
|
||||
static int acquiredrain(struct lock *lkp, int extflags) ;
|
||||
static int acquire(struct lock **lkpp, int extflags, int wanted,
|
||||
const char *wmesg, int prio, int timo, int *contested, uint64_t *waittime);
|
||||
static int acquiredrain(struct lock *lkp, int extflags, const char *wmesg,
|
||||
int prio, int timo);
|
||||
|
||||
static __inline void
|
||||
sharelock(struct thread *td, struct lock *lkp, int incr) {
|
||||
@ -146,10 +148,17 @@ shareunlock(struct thread *td, struct lock *lkp, int decr) {
|
||||
}
|
||||
|
||||
static int
|
||||
acquire(struct lock **lkpp, int extflags, int wanted, int *contested, uint64_t *waittime)
|
||||
acquire(struct lock **lkpp, int extflags, int wanted, const char *wmesg,
|
||||
int prio, int timo, int *contested, uint64_t *waittime)
|
||||
{
|
||||
struct lock *lkp = *lkpp;
|
||||
int error;
|
||||
const char *iwmesg;
|
||||
int error, iprio, itimo;
|
||||
|
||||
iwmesg = (wmesg != LK_WMESG_DEFAULT) ? wmesg : lkp->lk_wmesg;
|
||||
iprio = (prio != LK_PRIO_DEFAULT) ? prio : lkp->lk_prio;
|
||||
itimo = (timo != LK_TIMO_DEFAULT) ? timo : lkp->lk_timo;
|
||||
|
||||
CTR3(KTR_LOCK,
|
||||
"acquire(): lkp == %p, extflags == 0x%x, wanted == 0x%x",
|
||||
lkp, extflags, wanted);
|
||||
@ -166,9 +175,8 @@ acquire(struct lock **lkpp, int extflags, int wanted, int *contested, uint64_t *
|
||||
lkp, lkp->lk_flags);
|
||||
lkp->lk_flags |= LK_WAIT_NONZERO;
|
||||
lkp->lk_waitcount++;
|
||||
error = msleep(lkp, lkp->lk_interlock, lkp->lk_prio,
|
||||
lkp->lk_wmesg,
|
||||
((extflags & LK_TIMELOCK) ? lkp->lk_timo : 0));
|
||||
error = msleep(lkp, lkp->lk_interlock, iprio, iwmesg,
|
||||
((extflags & LK_TIMELOCK) ? itimo : 0));
|
||||
lkp->lk_waitcount--;
|
||||
if (lkp->lk_waitcount == 0)
|
||||
lkp->lk_flags &= ~LK_WAIT_NONZERO;
|
||||
@ -198,8 +206,8 @@ acquire(struct lock **lkpp, int extflags, int wanted, int *contested, uint64_t *
|
||||
* accepted shared locks and shared-to-exclusive upgrades to go away.
|
||||
*/
|
||||
int
|
||||
_lockmgr(struct lock *lkp, u_int flags, struct mtx *interlkp, char *file,
|
||||
int line)
|
||||
_lockmgr_args(struct lock *lkp, u_int flags, struct mtx *interlkp,
|
||||
const char *wmesg, int prio, int timo, char *file, int line)
|
||||
|
||||
{
|
||||
struct thread *td;
|
||||
@ -220,12 +228,12 @@ _lockmgr(struct lock *lkp, u_int flags, struct mtx *interlkp, char *file,
|
||||
panic("%s: %p lockmgr is destroyed", __func__, lkp);
|
||||
}
|
||||
#endif
|
||||
if ((flags & LK_INTERNAL) == 0)
|
||||
mtx_lock(lkp->lk_interlock);
|
||||
mtx_lock(lkp->lk_interlock);
|
||||
CTR6(KTR_LOCK,
|
||||
"lockmgr(): lkp == %p (lk_wmesg == \"%s\"), owner == %p, exclusivecount == %d, flags == 0x%x, "
|
||||
"td == %p", lkp, lkp->lk_wmesg, lkp->lk_lockholder,
|
||||
lkp->lk_exclusivecount, flags, td);
|
||||
"td == %p", lkp, (wmesg != LK_WMESG_DEFAULT) ? wmesg :
|
||||
lkp->lk_wmesg, lkp->lk_lockholder, lkp->lk_exclusivecount, flags,
|
||||
td);
|
||||
#ifdef DEBUG_LOCKS
|
||||
{
|
||||
struct stack stack; /* XXX */
|
||||
@ -242,7 +250,8 @@ _lockmgr(struct lock *lkp, u_int flags, struct mtx *interlkp, char *file,
|
||||
if ((flags & (LK_NOWAIT|LK_RELEASE)) == 0)
|
||||
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK,
|
||||
&lkp->lk_interlock->lock_object,
|
||||
"Acquiring lockmgr lock \"%s\"", lkp->lk_wmesg);
|
||||
"Acquiring lockmgr lock \"%s\"",
|
||||
(wmesg != LK_WMESG_DEFAULT) ? wmesg : lkp->lk_wmesg);
|
||||
|
||||
if (panicstr != NULL) {
|
||||
mtx_unlock(lkp->lk_interlock);
|
||||
@ -274,7 +283,8 @@ _lockmgr(struct lock *lkp, u_int flags, struct mtx *interlkp, char *file,
|
||||
lockflags = LK_HAVE_EXCL;
|
||||
if (!(td->td_pflags & TDP_DEADLKTREAT))
|
||||
lockflags |= LK_WANT_EXCL | LK_WANT_UPGRADE;
|
||||
error = acquire(&lkp, extflags, lockflags, &contested, &waitstart);
|
||||
error = acquire(&lkp, extflags, lockflags, wmesg,
|
||||
prio, timo, &contested, &waitstart);
|
||||
if (error)
|
||||
break;
|
||||
sharelock(td, lkp, 1);
|
||||
@ -336,7 +346,8 @@ _lockmgr(struct lock *lkp, u_int flags, struct mtx *interlkp, char *file,
|
||||
* drop to zero, then take exclusive lock.
|
||||
*/
|
||||
lkp->lk_flags |= LK_WANT_UPGRADE;
|
||||
error = acquire(&lkp, extflags, LK_SHARE_NONZERO, &contested, &waitstart);
|
||||
error = acquire(&lkp, extflags, LK_SHARE_NONZERO, wmesg,
|
||||
prio, timo, &contested, &waitstart);
|
||||
lkp->lk_flags &= ~LK_WANT_UPGRADE;
|
||||
|
||||
if (error) {
|
||||
@ -399,14 +410,17 @@ _lockmgr(struct lock *lkp, u_int flags, struct mtx *interlkp, char *file,
|
||||
/*
|
||||
* Try to acquire the want_exclusive flag.
|
||||
*/
|
||||
error = acquire(&lkp, extflags, (LK_HAVE_EXCL | LK_WANT_EXCL), &contested, &waitstart);
|
||||
error = acquire(&lkp, extflags, (LK_HAVE_EXCL | LK_WANT_EXCL),
|
||||
wmesg, prio, timo, &contested, &waitstart);
|
||||
if (error)
|
||||
break;
|
||||
lkp->lk_flags |= LK_WANT_EXCL;
|
||||
/*
|
||||
* Wait for shared locks and upgrades to finish.
|
||||
*/
|
||||
error = acquire(&lkp, extflags, LK_HAVE_EXCL | LK_WANT_UPGRADE | LK_SHARE_NONZERO, &contested, &waitstart);
|
||||
error = acquire(&lkp, extflags, LK_HAVE_EXCL | LK_WANT_UPGRADE |
|
||||
LK_SHARE_NONZERO, wmesg, prio, timo,
|
||||
&contested, &waitstart);
|
||||
lkp->lk_flags &= ~LK_WANT_EXCL;
|
||||
if (error) {
|
||||
if (lkp->lk_flags & LK_WAIT_NONZERO)
|
||||
@ -462,7 +476,7 @@ _lockmgr(struct lock *lkp, u_int flags, struct mtx *interlkp, char *file,
|
||||
if (lkp->lk_lockholder == td)
|
||||
panic("lockmgr: draining against myself");
|
||||
|
||||
error = acquiredrain(lkp, extflags);
|
||||
error = acquiredrain(lkp, extflags, wmesg, prio, timo);
|
||||
if (error)
|
||||
break;
|
||||
lkp->lk_flags |= LK_DRAINING | LK_HAVE_EXCL;
|
||||
@ -493,17 +507,23 @@ _lockmgr(struct lock *lkp, u_int flags, struct mtx *interlkp, char *file,
|
||||
}
|
||||
|
||||
static int
|
||||
acquiredrain(struct lock *lkp, int extflags) {
|
||||
int error;
|
||||
acquiredrain(struct lock *lkp, int extflags, const char *wmesg, int prio,
|
||||
int timo)
|
||||
{
|
||||
const char *iwmesg;
|
||||
int error, iprio, itimo;
|
||||
|
||||
iwmesg = (wmesg != LK_WMESG_DEFAULT) ? wmesg : lkp->lk_wmesg;
|
||||
iprio = (prio != LK_PRIO_DEFAULT) ? prio : lkp->lk_prio;
|
||||
itimo = (timo != LK_TIMO_DEFAULT) ? timo : lkp->lk_timo;
|
||||
|
||||
if ((extflags & LK_NOWAIT) && (lkp->lk_flags & LK_ALL)) {
|
||||
return EBUSY;
|
||||
}
|
||||
while (lkp->lk_flags & LK_ALL) {
|
||||
lkp->lk_flags |= LK_WAITDRAIN;
|
||||
error = msleep(&lkp->lk_flags, lkp->lk_interlock, lkp->lk_prio,
|
||||
lkp->lk_wmesg,
|
||||
((extflags & LK_TIMELOCK) ? lkp->lk_timo : 0));
|
||||
error = msleep(&lkp->lk_flags, lkp->lk_interlock, iprio, iwmesg,
|
||||
((extflags & LK_TIMELOCK) ? itimo : 0));
|
||||
if (error)
|
||||
return error;
|
||||
if (extflags & LK_SLEEPFAIL) {
|
||||
|
@ -263,7 +263,8 @@ vop_stdlock(ap)
|
||||
{
|
||||
struct vnode *vp = ap->a_vp;
|
||||
|
||||
return (_lockmgr(vp->v_vnlock, ap->a_flags, VI_MTX(vp), ap->a_file,
|
||||
return (_lockmgr_args(vp->v_vnlock, ap->a_flags, VI_MTX(vp),
|
||||
LK_WMESG_DEFAULT, LK_PRIO_DEFAULT, LK_TIMO_DEFAULT, ap->a_file,
|
||||
ap->a_line));
|
||||
}
|
||||
|
||||
|
@ -266,42 +266,16 @@ extern const char *buf_wmesg; /* Default buffer lock message */
|
||||
*
|
||||
* Get a lock sleeping non-interruptably until it becomes available.
|
||||
*/
|
||||
static __inline int BUF_LOCK(struct buf *, int, struct mtx *);
|
||||
static __inline int
|
||||
BUF_LOCK(struct buf *bp, int locktype, struct mtx *interlock)
|
||||
{
|
||||
int s, ret;
|
||||
#define BUF_LOCK(bp, locktype, interlock) \
|
||||
(lockmgr(&(bp)->b_lock, (locktype), (interlock)))
|
||||
|
||||
s = splbio();
|
||||
mtx_lock(bp->b_lock.lk_interlock);
|
||||
locktype |= LK_INTERNAL;
|
||||
bp->b_lock.lk_wmesg = buf_wmesg;
|
||||
bp->b_lock.lk_prio = PRIBIO + 4;
|
||||
ret = lockmgr(&(bp)->b_lock, locktype, interlock);
|
||||
splx(s);
|
||||
return ret;
|
||||
}
|
||||
/*
|
||||
* Get a lock sleeping with specified interruptably and timeout.
|
||||
*/
|
||||
static __inline int BUF_TIMELOCK(struct buf *, int, struct mtx *,
|
||||
char *, int, int);
|
||||
static __inline int
|
||||
BUF_TIMELOCK(struct buf *bp, int locktype, struct mtx *interlock,
|
||||
char *wmesg, int catch, int timo)
|
||||
{
|
||||
int s, ret;
|
||||
#define BUF_TIMELOCK(bp, locktype, interlock, wmesg, catch, timo) \
|
||||
(lockmgr_args(&(bp)->b_lock, (locktype) | LK_TIMELOCK, \
|
||||
(interlock), (wmesg), (PRIBIO + 4) | (catch), (timo)))
|
||||
|
||||
s = splbio();
|
||||
mtx_lock(bp->b_lock.lk_interlock);
|
||||
locktype |= LK_INTERNAL | LK_TIMELOCK;
|
||||
bp->b_lock.lk_wmesg = wmesg;
|
||||
bp->b_lock.lk_prio = (PRIBIO + 4) | catch;
|
||||
bp->b_lock.lk_timo = timo;
|
||||
ret = lockmgr(&(bp)->b_lock, (locktype), interlock);
|
||||
splx(s);
|
||||
return ret;
|
||||
}
|
||||
/*
|
||||
* Release a lock. Only the acquiring process may free the lock unless
|
||||
* it has been handed off to biodone.
|
||||
|
@ -137,14 +137,20 @@ struct lock {
|
||||
#define LK_HAVE_EXCL 0x00040000 /* exclusive lock obtained */
|
||||
#define LK_WAITDRAIN 0x00080000 /* process waiting for lock to drain */
|
||||
#define LK_DRAINING 0x00100000 /* lock is being drained */
|
||||
#define LK_INTERNAL 0x00200000/* The internal lock is already held */
|
||||
#define LK_DESTROYED 0x00400000 /* lock is destroyed */
|
||||
#define LK_DESTROYED 0x00200000 /* lock is destroyed */
|
||||
/*
|
||||
* Internal state flags corresponding to lk_sharecount, and lk_waitcount
|
||||
*/
|
||||
#define LK_SHARE_NONZERO 0x01000000
|
||||
#define LK_WAIT_NONZERO 0x02000000
|
||||
|
||||
/*
|
||||
* Default values for lockmgr_args().
|
||||
*/
|
||||
#define LK_WMESG_DEFAULT (NULL)
|
||||
#define LK_PRIO_DEFAULT (-1)
|
||||
#define LK_TIMO_DEFAULT (0)
|
||||
|
||||
/*
|
||||
* Assertion flags.
|
||||
*/
|
||||
@ -189,8 +195,8 @@ void lockinit(struct lock *, int prio, const char *wmesg,
|
||||
int timo, int flags);
|
||||
void lockdestroy(struct lock *);
|
||||
|
||||
int _lockmgr(struct lock *, u_int flags, struct mtx *, char *file,
|
||||
int line);
|
||||
int _lockmgr_args(struct lock *, u_int flags, struct mtx *,
|
||||
const char *wmesg, int prio, int timo, char *file, int line);
|
||||
#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
|
||||
void _lockmgr_assert(struct lock *, int what, const char *, int);
|
||||
#endif
|
||||
@ -200,9 +206,13 @@ int lockstatus(struct lock *, struct thread *);
|
||||
int lockwaiters(struct lock *);
|
||||
|
||||
#define lockmgr(lock, flags, mtx) \
|
||||
_lockmgr((lock), (flags), (mtx), LOCK_FILE, LOCK_LINE)
|
||||
_lockmgr_args((lock), (flags), (mtx), LK_WMESG_DEFAULT, \
|
||||
LK_PRIO_DEFAULT, LK_TIMO_DEFAULT, LOCK_FILE, LOCK_LINE)
|
||||
#define lockmgr_disown(lock) \
|
||||
_lockmgr_disown((lock), LOCK_FILE, LOCK_LINE)
|
||||
#define lockmgr_args(lock, flags, mtx, wmesg, prio, timo) \
|
||||
_lockmgr_args((lock), (flags), (mtx), (wmesg), (prio), (timo), \
|
||||
LOCK_FILE, LOCK_LINE)
|
||||
#define lockmgr_recursed(lkp) \
|
||||
((lkp)->lk_exclusivecount > 1)
|
||||
#ifdef INVARIANTS
|
||||
|
@ -370,8 +370,9 @@ ffs_lock(ap)
|
||||
flags |= LK_INTERLOCK;
|
||||
}
|
||||
lkp = vp->v_vnlock;
|
||||
result = _lockmgr(lkp, flags, VI_MTX(vp), ap->a_file,
|
||||
ap->a_line);
|
||||
result = _lockmgr_args(lkp, flags, VI_MTX(vp),
|
||||
LK_WMESG_DEFAULT, LK_PRIO_DEFAULT, LK_TIMO_DEFAULT,
|
||||
ap->a_file, ap->a_line);
|
||||
if (lkp == vp->v_vnlock || result != 0)
|
||||
break;
|
||||
/*
|
||||
@ -382,7 +383,8 @@ ffs_lock(ap)
|
||||
* right lock. Release it, and try to get the
|
||||
* new lock.
|
||||
*/
|
||||
(void) _lockmgr(lkp, LK_RELEASE, VI_MTX(vp),
|
||||
(void) _lockmgr_args(lkp, LK_RELEASE, VI_MTX(vp),
|
||||
LK_WMESG_DEFAULT, LK_PRIO_DEFAULT, LK_TIMO_DEFAULT,
|
||||
ap->a_file, ap->a_line);
|
||||
if ((flags & LK_TYPE_MASK) == LK_UPGRADE)
|
||||
flags = (flags & ~LK_TYPE_MASK) | LK_EXCLUSIVE;
|
||||
|
Loading…
x
Reference in New Issue
Block a user