diff options
-rw-r--r-- | sys/kern/kern_lock.c | 15 | ||||
-rw-r--r-- | sys/kern/vfs_bio.c | 11 | ||||
-rw-r--r-- | sys/sys/buf.h | 11 | ||||
-rw-r--r-- | sys/sys/lockmgr.h | 1 |
4 files changed, 38 insertions, 0 deletions
diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c index c0b929a..32b43b8 100644 --- a/sys/kern/kern_lock.c +++ b/sys/kern/kern_lock.c @@ -566,6 +566,21 @@ lockcount(lkp) } /* + * Determine the number of waiters on a lock. + */ +int +lockwaiters(lkp) + struct lock *lkp; +{ + int count; + + 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. */ diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 37ef552..904e84c 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -1890,6 +1890,17 @@ restart: } /* + * Notify any waiters for the buffer lock about + * identity change by freeing the buffer. + */ + if (qindex == QUEUE_CLEAN && BUF_LOCKWAITERS(bp) > 0) { + bp->b_flags |= B_INVAL; + bfreekva(bp); + brelse(bp); + goto restart; + } + + /* * If we are overcomitted then recover the buffer and its * KVM space. This occurs in rare situations when multiple * processes are blocked in getnewbuf() or allocbuf(). diff --git a/sys/sys/buf.h b/sys/sys/buf.h index afa3e23..359be84 100644 --- a/sys/sys/buf.h +++ b/sys/sys/buf.h @@ -371,6 +371,17 @@ BUF_REFCNT(struct buf *bp) return ret; } + +/* + * 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)); +} + #endif /* _KERNEL */ struct buf_queue_head { diff --git a/sys/sys/lockmgr.h b/sys/sys/lockmgr.h index dd0eed9..9c9b59b 100644 --- a/sys/sys/lockmgr.h +++ b/sys/sys/lockmgr.h @@ -203,6 +203,7 @@ void transferlockers(struct lock *, struct lock *); void lockmgr_printinfo(struct lock *); int lockstatus(struct lock *, struct thread *); int lockcount(struct lock *); +int lockwaiters(struct lock *); #ifdef DDB int lockmgr_chain(struct thread *td, struct thread **ownerp); #endif |