summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2008-03-23 13:45:24 +0000
committerkib <kib@FreeBSD.org>2008-03-23 13:45:24 +0000
commit5ddf5664ccd9a5fa53eda81e8ec89445bfaf3c41 (patch)
tree72ecaa475ca0981f6c6e503a2d9814052b1078e5
parent5e55dd67176633e7adc6e3726f22960f15941c9a (diff)
downloadFreeBSD-src-5ddf5664ccd9a5fa53eda81e8ec89445bfaf3c41.zip
FreeBSD-src-5ddf5664ccd9a5fa53eda81e8ec89445bfaf3c41.tar.gz
Yield the cpu in the kernel while iterating the list of the
vnodes belonging to the mountpoint. Also, yield when in the softdep_process_worklist() even when we are not going to sleep due to buffer drain. It is believed that the ULE fixed the problem [1], but the yielding seems to be needed at least for the 4BSD case. Discussed: on stable@, with bde Reviewed by: tegge, jeff [1] MFC after: 2 weeks
-rw-r--r--sys/kern/vfs_mount.c6
-rw-r--r--sys/sys/vnode.h2
-rw-r--r--sys/ufs/ffs/ffs_softdep.c1
3 files changed, 9 insertions, 0 deletions
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
index 0f829a9..3961022 100644
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -2008,6 +2008,12 @@ __mnt_vnode_next(struct vnode **mvp, struct mount *mp)
mtx_assert(MNT_MTX(mp), MA_OWNED);
KASSERT((*mvp)->v_mount == mp, ("marker vnode mount list mismatch"));
+ if ((*mvp)->v_yield++ == 500) {
+ MNT_IUNLOCK(mp);
+ (*mvp)->v_yield = 0;
+ uio_yield();
+ MNT_ILOCK(mp);
+ }
vp = TAILQ_NEXT(*mvp, v_nmntvnodes);
while (vp != NULL && vp->v_type == VMARKER)
vp = TAILQ_NEXT(vp, v_nmntvnodes);
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index a1ec516..ba23b18 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -124,6 +124,7 @@ struct vnode {
struct socket *vu_socket; /* v unix domain net (VSOCK) */
struct cdev *vu_cdev; /* v device (VCHR, VBLK) */
struct fifoinfo *vu_fifoinfo; /* v fifo (VFIFO) */
+ int vu_yield; /* yield count (VMARKER) */
} v_un;
/*
@@ -178,6 +179,7 @@ struct vnode {
#define v_socket v_un.vu_socket
#define v_rdev v_un.vu_cdev
#define v_fifoinfo v_un.vu_fifoinfo
+#define v_yield v_un.vu_yield
/* XXX: These are temporary to avoid a source sweep at this time */
#define v_object v_bufobj.bo_object
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c
index 7cb7b40..255723c 100644
--- a/sys/ufs/ffs/ffs_softdep.c
+++ b/sys/ufs/ffs/ffs_softdep.c
@@ -857,6 +857,7 @@ softdep_process_worklist(mp, full)
*/
if (loopcount++ % 128 == 0) {
FREE_LOCK(&lk);
+ uio_yield();
bwillwrite();
ACQUIRE_LOCK(&lk);
}
OpenPOWER on IntegriCloud