- 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:
Attilio Rao 2008-02-15 21:04:36 +00:00
parent 5a14b2bf8e
commit 24463dbbee
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=176320
5 changed files with 71 additions and 64 deletions

View file

@ -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) {

View file

@ -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));
}

View file

@ -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.

View file

@ -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

View file

@ -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;