--- //depot/vendor/freebsd/src/sys/kern/kern_lock.c 2008/02/25 18:50:26 +++ //depot/user/attilio/attilio_schedlock/kern/kern_lock.c 2008/02/26 23:32:26 @@ -546,11 +546,14 @@ { int iflags; + KASSERT((flags & (LK_NOWAIT | LK_SLEEPFAIL)) == 0, + ("%s: Invalid flags passed with mask 0x%x", __func__, + flags & LK_EXTFLG_MASK)); CTR5(KTR_LOCK, "lockinit(): lkp == %p, prio == %d, wmesg == \"%s\", " "timo == %d, flags = 0x%x\n", lkp, prio, wmesg, timo, flags); lkp->lk_interlock = mtx_pool_alloc(mtxpool_lockbuilder); - lkp->lk_flags = (flags & LK_EXTFLG_MASK) & ~(LK_NOWITNESS | LK_NODUP); + lkp->lk_flags = (flags & LK_EXTFLG_MASK) & ~(LK_FUNC_MASK); lkp->lk_sharecount = 0; lkp->lk_waitcount = 0; lkp->lk_exclusivecount = 0; @@ -561,8 +564,12 @@ iflags = LO_RECURSABLE | LO_SLEEPABLE | LO_UPGRADABLE; if (!(flags & LK_NODUP)) iflags |= LO_DUPOK; + if (flags & LK_NOPROFILE) + iflags |= LO_NOPROFILE; if (!(flags & LK_NOWITNESS)) iflags |= LO_WITNESS; + if (flags & LK_QUIET) + iflags |= LO_QUIET; #ifdef DEBUG_LOCKS stack_zero(&lkp->lk_stack); #endif @@ -644,23 +651,6 @@ } /* - * Determine the number of waiters on a lock. - */ -int -lockwaiters(lkp) - struct lock *lkp; -{ - int count; - - KASSERT((lkp->lk_flags & LK_DESTROYED) == 0, - ("%s: %p lockmgr is destroyed", __func__, lkp)); - mtx_lock(lkp->lk_interlock); - count = lkp->lk_waitcount; - mtx_unlock(lkp->lk_interlock); - return (count); -} - -/* * Print out information about state of a lock. Used by VOP_PRINT * routines to display status about contained locks. */ --- //depot/vendor/freebsd/src/sys/sys/buf.h 2008/02/25 18:50:26 +++ //depot/user/attilio/attilio_schedlock/sys/buf.h 2008/02/26 23:32:26 @@ -114,6 +114,7 @@ uint32_t b_flags; /* B_* flags. */ b_xflags_t b_xflags; /* extra flags */ struct lock b_lock; /* Buffer lock */ + uint32_t b_wcnt; /* Number of waiters. */ long b_bufsize; /* Allocated buffer size. */ long b_runningbufspace; /* when I/O is running, pipelining */ caddr_t b_kvabase; /* base kva for buffer */ @@ -260,55 +261,88 @@ /* * Initialize a lock. */ -#define BUF_LOCKINIT(bp) \ - lockinit(&(bp)->b_lock, PRIBIO + 4, buf_wmesg, 0, 0) +static __inline void +BUF_LOCKINIT(struct buf *bp) +{ + + bp->b_wcnt = 0; + lockinit(&bp->b_lock, PRIBIO + 4, buf_wmesg, 0, 0); +} + /* - * * Get a lock sleeping non-interruptably until it becomes available. */ -#define BUF_LOCK(bp, locktype, interlock) \ - (lockmgr(&(bp)->b_lock, (locktype), (interlock))) +static __inline int +BUF_LOCK(struct buf *bp, u_int locktype, struct mtx *interlock) +{ + int error; + + bp->b_wcnt++; + error = lockmgr(&bp->b_lock, locktype, interlock); + bp->b_wcnt--; + return (error); +} /* * Get a lock sleeping with specified interruptably and timeout. */ -#define BUF_TIMELOCK(bp, locktype, interlock, wmesg, catch, timo) \ - (lockmgr_args(&(bp)->b_lock, (locktype) | LK_TIMELOCK, \ - (interlock), (wmesg), (PRIBIO + 4) | (catch), (timo))) +static __inline int +BUF_TIMELOCK(struct buf *bp, u_int locktype, struct mtx *interlock, + const char *wmesg, int catch, int timo) +{ + int error; + + bp->b_wcnt++; + error = lockmgr_args(&bp->b_lock, locktype | LK_TIMELOCK, interlock, + wmesg, (PRIBIO + 4) | catch, timo); + bp->b_wcnt--; + return (error); +} /* * Release a lock. Only the acquiring process may free the lock unless * it has been handed off to biodone. */ -static __inline void BUF_UNLOCK(struct buf *); static __inline void BUF_UNLOCK(struct buf *bp) { - int s; - s = splbio(); KASSERT((bp->b_flags & B_REMFREE) == 0, ("BUF_UNLOCK %p while B_REMFREE is still set.", bp)); - lockmgr(&(bp)->b_lock, LK_RELEASE, NULL); - splx(s); + (void)lockmgr(&(bp)->b_lock, LK_RELEASE, NULL); } /* * Check if a buffer lock is recursed. */ -#define BUF_LOCKRECURSED(bp) \ - (lockmgr_recursed(&(bp)->b_lock)) +static __inline int +BUF_LOCKRECURSED(struct buf *bp) +{ + + return (lockmgr_recursed(&bp->b_lock)); +} /* * Check if a buffer lock is currently held. */ -#define BUF_ISLOCKED(bp) \ - (lockstatus(&(bp)->b_lock)) +static __inline int +BUF_ISLOCKED(struct buf *bp) +{ + + return (lockstatus(&bp->b_lock)); +} + /* * Free a buffer lock. */ -#define BUF_LOCKFREE(bp) \ - (lockdestroy(&(bp)->b_lock)) +static __inline void +BUF_LOCKFREE(struct buf *bp) +{ + + KASSERT(bp->b_wcnt == 0, + ("BUF_LOCKFREE %p while there are still waiters", bp)); + lockdestroy(&bp->b_lock); +} /* * Buffer lock assertions. @@ -342,7 +376,6 @@ * original owning process can no longer acquire it recursively, but must * wait until the I/O is completed and the lock has been freed by biodone. */ -static __inline void BUF_KERNPROC(struct buf *); static __inline void BUF_KERNPROC(struct buf *bp) { @@ -354,11 +387,11 @@ /* * Find out the number of waiters on a lock. */ -static __inline int BUF_LOCKWAITERS(struct buf *); static __inline int BUF_LOCKWAITERS(struct buf *bp) { - return (lockwaiters(&bp->b_lock)); + + return (bp->b_wcnt); } #endif /* _KERNEL */ --- //depot/vendor/freebsd/src/sys/sys/lockmgr.h 2008/02/25 18:50:26 +++ //depot/user/attilio/attilio_schedlock/sys/lockmgr.h 2008/02/26 23:32:26 @@ -111,7 +111,7 @@ * These may be set in lock_init to set their mode permanently, * or passed in as arguments to the lock manager. */ -#define LK_EXTFLG_MASK 0x00000ff0 /* mask of external flags */ +#define LK_EXTFLG_MASK 0x0000fff0 /* mask of external flags */ #define LK_NOWAIT 0x00000010 /* do not sleep to await lock */ #define LK_SLEEPFAIL 0x00000020 /* sleep, then return failure */ #define LK_CANRECURSE 0x00000040 /* allow recursive exclusive lock */ @@ -119,37 +119,41 @@ #define LK_TIMELOCK 0x00000100 /* use lk_timo, else no timeout */ #define LK_NOWITNESS 0x00000200 /* disable WITNESS */ #define LK_NODUP 0x00000400 /* enable duplication logging */ +#define LK_NOPROFILE 0x00000800 /* disable lock profiling */ +#define LK_QUIET 0x00001000 /* disable lock operations tracking */ +#define LK_FUNC_MASK (LK_NODUP | LK_NOPROFILE | LK_NOWITNESS | LK_QUIET) /* * Nonpersistent external flags. */ -#define LK_RETRY 0x00001000 /* vn_lock: retry until locked */ -#define LK_INTERLOCK 0x00002000 /* +#define LK_RETRY 0x00010000 /* vn_lock: retry until locked */ +#define LK_INTERLOCK 0x00020000 /* * unlock passed mutex after getting * lk_interlock */ + /* + * Default values for lockmgr_args(). + */ +#define LK_WMESG_DEFAULT (NULL) +#define LK_PRIO_DEFAULT (-1) +#define LK_TIMO_DEFAULT (0) + +/* * Internal lock flags. * * These flags are used internally to the lock manager. */ -#define LK_WANT_UPGRADE 0x00010000 /* waiting for share-to-excl upgrade */ -#define LK_WANT_EXCL 0x00020000 /* exclusive lock sought */ -#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_DESTROYED 0x00200000 /* lock is destroyed */ +#define LK_WANT_UPGRADE 0x00100000 /* waiting for share-to-excl upgrade */ +#define LK_WANT_EXCL 0x00200000 /* exclusive lock sought */ +#define LK_HAVE_EXCL 0x00400000 /* exclusive lock obtained */ +#define LK_WAITDRAIN 0x00800000 /* process waiting for lock to drain */ +#define LK_DRAINING 0x01000000 /* lock is being drained */ +#define LK_DESTROYED 0x02000000 /* 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) +#define LK_SHARE_NONZERO 0x10000000 +#define LK_WAIT_NONZERO 0x20000000 /* * Assertion flags. @@ -203,7 +207,6 @@ void _lockmgr_disown(struct lock *, const char *, int); void lockmgr_printinfo(struct lock *); int lockstatus(struct lock *); -int lockwaiters(struct lock *); #define lockmgr(lock, flags, mtx) \ _lockmgr_args((lock), (flags), (mtx), LK_WMESG_DEFAULT, \