From c4df96359ae35da7b72c09f633437f5c4a8f33b7 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Sat, 28 Jun 2008 17:59:51 +0000 Subject: [PATCH] Replace the bwillwrite() subsystem to make it more fair to processes. * Add new API functions, bwillread(), bwillwrite(), bwillinode() which the kernel calls when it intends to read, write, or make inode modifications. * Redo the backend. Add bd_heatup() and bd_wait(). bd_heatup() heats up the buf_daemon, starting it flushing before we hit any blocking conditions (similar to the previous algorith). * The new bwill*() blocking functions no longer introduce escalating delays to keep the number of dirty buffers under control. Instead it takes a page from HAMMER and estimates the load caused by the caller, then waits for a specific number of dirty buffers to complete their write I/O's before returning. If the buffers can be retired quickly these functions will return more quickly. --- sys/conf/files | 3 +- sys/kern/kern_iosched.c | 89 ++++++++++++++++++ sys/kern/vfs_bio.c | 223 +++++++++++++++++----------------------------- sys/kern/vfs_syscalls.c | 20 ++--- sys/kern/vfs_vnops.c | 21 +++-- sys/sys/buf.h | 5 +- sys/sys/iosched.h | 40 +++++++++ sys/sys/proc.h | 5 +- sys/vfs/ufs/ffs_softdep.c | 4 +- 9 files changed, 250 insertions(+), 160 deletions(-) create mode 100644 sys/kern/kern_iosched.c create mode 100644 sys/sys/iosched.h diff --git a/sys/conf/files b/sys/conf/files index dd97aba073..b031ad2987 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1,5 +1,5 @@ # $FreeBSD: src/sys/conf/files,v 1.340.2.137 2003/06/04 17:10:30 sam Exp $ -# $DragonFly: src/sys/conf/files,v 1.220 2008/06/27 14:02:14 swildner Exp $ +# $DragonFly: src/sys/conf/files,v 1.221 2008/06/28 17:59:46 dillon Exp $ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and @@ -556,6 +556,7 @@ kern/kern_upcall.c standard kern/kern_sfbuf.c standard kern/kern_msfbuf.c standard kern/kern_subr.c standard +kern/kern_iosched.c standard kern/kern_usched.c standard kern/usched_bsd4.c standard kern/usched_dummy.c standard diff --git a/sys/kern/kern_iosched.c b/sys/kern/kern_iosched.c new file mode 100644 index 0000000000..7b36c4e6ee --- /dev/null +++ b/sys/kern/kern_iosched.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2008 The DragonFly Project. All rights reserved. + * + * This code is derived from software contributed to The DragonFly Project + * by Matthew Dillon + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of The DragonFly Project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific, prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $DragonFly: src/sys/kern/kern_iosched.c,v 1.1 2008/06/28 17:59:49 dillon Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +/* + * Caller intends to write (bytes) + */ +void +bwillwrite(int bytes) +{ + int count; + + count = bd_heatup(); + if (count > 0) + bd_wait(count / 2); +} + +/* + * Caller intends to read (bytes) + */ +void +bwillread(int bytes) +{ +} + +/* + * Call intends to do an inode-modifying operation of some sort. + */ +void +bwillinode(int n) +{ + int count; + + count = bd_heatup(); + if (count > 0) + bd_wait(1); +} + diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 9d8c5e49d8..fe31828169 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -12,7 +12,7 @@ * John S. Dyson. * * $FreeBSD: src/sys/kern/vfs_bio.c,v 1.242.2.20 2003/05/28 18:38:10 alc Exp $ - * $DragonFly: src/sys/kern/vfs_bio.c,v 1.105 2008/06/19 23:27:35 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_bio.c,v 1.106 2008/06/28 17:59:49 dillon Exp $ */ /* @@ -81,6 +81,9 @@ enum bufq_type { typedef enum bufq_type bufq_type_t; +#define BD_WAKE_SIZE 128 +#define BD_WAKE_MASK (BD_WAKE_SIZE - 1) + TAILQ_HEAD(bqueues, buf) bufqueues[BUFFER_QUEUES]; static MALLOC_DEFINE(M_BIOBUF, "BIO buffer", "BIO buffer"); @@ -98,8 +101,10 @@ static void vfs_setdirty(struct buf *bp); static void vfs_vmio_release(struct buf *bp); static int flushbufqueues(bufq_type_t q); +static void bd_signal(void); static void buf_daemon(void); static void buf_daemon_hw(void); + /* * bogus page -- for I/O to/from partially complete buffers * this is a temporary solution to the problem, but it is not @@ -122,10 +127,11 @@ int runningbufspace, runningbufcount; static int numfreebuffers, lofreebuffers, hifreebuffers; static int getnewbufcalls; static int getnewbufrestarts; -static int hidirtywait; static int needsbuffer; /* locked by needsbuffer_spin */ static int bd_request; /* locked by needsbuffer_spin */ static int bd_request_hw; /* locked by needsbuffer_spin */ +static u_int bd_wake_ary[BD_WAKE_SIZE]; +static u_int bd_wake_index; static struct spinlock needsbuffer_spin; /* @@ -188,41 +194,11 @@ char *buf_wmesg = BUF_WMESG; extern int vm_swap_size; #define VFS_BIO_NEED_ANY 0x01 /* any freeable buffer */ -#define VFS_BIO_NEED_DIRTYFLUSH 0x02 /* waiting for dirty buffer flush */ +#define VFS_BIO_NEED_UNUSED02 0x02 #define VFS_BIO_NEED_FREE 0x04 /* wait for free bufs, hi hysteresis */ #define VFS_BIO_NEED_BUFSPACE 0x08 /* wait for buf space, lo hysteresis */ /* - * numdirtywakeup: - * - * If someone is blocked due to there being too many dirty buffers, - * and numdirtybuffers is now reasonable, wake them up. - */ -static __inline void -numdirtywakeup(void) -{ - if (runningbufcount + numdirtybuffers <= - (lodirtybuffers + hidirtybuffers) / 2) { - if (needsbuffer & VFS_BIO_NEED_DIRTYFLUSH) { - spin_lock_wr(&needsbuffer_spin); - needsbuffer &= ~VFS_BIO_NEED_DIRTYFLUSH; - spin_unlock_wr(&needsbuffer_spin); - wakeup(&needsbuffer); - } - - /* - * Heuristical wakeup for flstik. If the I/O is draining - * in large bursts we can allow new dirty buffers to be - * queued immediately. - */ - if (hidirtywait) { - hidirtywait = 0; - wakeup(&hidirtybuffers); - } - } -} - -/* * bufspacewakeup: * * Called when buffer space is potentially available for recovery. @@ -264,7 +240,7 @@ runningbufwakeup(struct buf *bp) runningbufreq = 0; wakeup(&runningbufreq); } - numdirtywakeup(); + bd_signal(); } } @@ -340,31 +316,21 @@ vfs_buf_test_cache(struct buf *bp, } /* - * bd_wakeup: - * - * Wake up the buffer daemon if the number of outstanding dirty buffers - * is above specified threshold 'dirtybuflevel'. - * - * The buffer daemons are explicitly woken up when (a) the pending number - * of dirty buffers exceeds the recovery and stall mid-point value, - * (b) during bwillwrite() or (c) buf freelist was exhausted. + * bd_speedup: * - * The buffer daemons will generally not stop flushing until the dirty - * buffer count goes below lodirtybuffers. + * Unconditionally speed-up the buf_daemon */ static __inline__ void -bd_wakeup(int dirtybuflevel) +bd_speedup(void) { - if (bd_request == 0 && numdirtybuffers && - runningbufcount + numdirtybuffers >= dirtybuflevel) { + if (bd_request == 0 && numdirtybuffers) { spin_lock_wr(&needsbuffer_spin); bd_request = 1; spin_unlock_wr(&needsbuffer_spin); wakeup(&bd_request); } - if (bd_request_hw == 0 && numdirtybuffershw && - numdirtybuffershw >= dirtybuflevel) { + if (bd_request_hw == 0 && numdirtybuffershw) { spin_lock_wr(&needsbuffer_spin); bd_request_hw = 1; spin_unlock_wr(&needsbuffer_spin); @@ -373,16 +339,77 @@ bd_wakeup(int dirtybuflevel) } /* - * bd_speedup: + * bd_heatup() * - * Speed up the buffer cache flushing process. + * Get the buf_daemon heated up when the number of running and dirty + * buffers exceeds the mid-point. */ +int +bd_heatup(void) +{ + int mid1; + int mid2; + int count; -static __inline__ + mid1 = lodirtybuffers + (hidirtybuffers - lodirtybuffers) / 2; + + count = runningbufcount + numdirtybuffers; + if (count >= mid1) { + bd_speedup(); + mid2 = mid1 + (hidirtybuffers - mid1) / 2; + if (count >= mid2) + return(count - mid2); + } + return(0); +} + +/* + * bd_wait() + * + * Wait for the buffer cache to flush (count) buffers, then return. + * + * Regardless this function blocks while the number of dirty buffers + * exceeds hidirtybuffers. + */ void -bd_speedup(void) +bd_wait(int count) +{ + u_int i; + + while (count > 0) { + bd_heatup(); + crit_enter(); + if (count > runningbufcount + numdirtybuffers) + count = runningbufcount + numdirtybuffers; + if (count >= BD_WAKE_SIZE) + count = BD_WAKE_SIZE - 1; + i = (bd_wake_index + count) & BD_WAKE_MASK; + ++bd_wake_ary[i]; + tsleep(&bd_wake_ary[i], 0, "flstik", hz); + crit_exit(); + + count = runningbufcount + numdirtybuffers - hidirtybuffers; + } +} + +/* + * bd_signal() + * + * This function is called whenever runningbufcount or numdirtybuffers + * is decremented. Track threads waiting for run+dirty buffer I/O + * complete. + */ +static void +bd_signal(void) { - bd_wakeup(1); + u_int i; + + i = atomic_fetchadd_int(&bd_wake_index, 1); + i &= BD_WAKE_MASK; + if (bd_wake_ary[i]) { + bd_wake_ary[i] = 0; + wakeup(&bd_wake_ary[i]); + } } /* @@ -838,13 +865,6 @@ bdwrite(struct buf *bp) bqrelse(bp); /* - * Wakeup the buffer flushing daemon if we have a lot of dirty - * buffers (midpoint between our recovery point and our stall - * point). - */ - bd_wakeup((lodirtybuffers + hidirtybuffers) / 2); - - /* * note: we cannot initiate I/O from a bdwrite even if we wanted to, * due to the softdep code. */ @@ -884,7 +904,7 @@ bdirty(struct buf *bp) ++numdirtybuffers; if (bp->b_flags & B_HEAVY) ++numdirtybuffershw; - bd_wakeup((lodirtybuffers + hidirtybuffers) / 2); + bd_heatup(); } } @@ -927,7 +947,7 @@ bundirty(struct buf *bp) --numdirtybuffers; if (bp->b_flags & B_HEAVY) --numdirtybuffershw; - numdirtywakeup(); + bd_signal(); } /* * Since it is now being written, we can clear its deferred write flag. @@ -967,78 +987,6 @@ bowrite(struct buf *bp) } /* - * bwillwrite: - * - * Called prior to the locking of any vnodes when we are expecting to - * write. We do not want to starve the buffer cache with too many - * dirty buffers so we block here. By blocking prior to the locking - * of any vnodes we attempt to avoid the situation where a locked vnode - * prevents the various system daemons from flushing related buffers. - */ -void -bwillwrite(void) -{ - int mid1 = hidirtybuffers / 2; - int mid2 = mid1 + hidirtybuffers / 4; - int delay; - int count; - int priority = 0; - - count = runningbufcount + numdirtybuffers; - - /* - * Nothing to do if nothing is stressed. - */ - if (count < mid1) - return; - - /* - * Get the buffer daemon heated up - */ - bd_wakeup(1); - - while (count >= mid2) { - /* - * Start slowing down writes, down to 1 per second. - */ - if (count < hidirtybuffers) { - delay = (count - mid2) * hz / (hidirtybuffers - mid2); - delay = delay * 10 / (10 + priority); - if (delay == 0) - delay = 1; - ++hidirtywait; - tsleep(&hidirtybuffers, 0, "flstik", delay); - return; - } - - /* - * Now we are really in trouble. - */ - bd_wakeup(1); - spin_lock_wr(&needsbuffer_spin); - count = runningbufcount + numdirtybuffers; - if (count >= hidirtybuffers) { - needsbuffer |= VFS_BIO_NEED_DIRTYFLUSH; - msleep(&needsbuffer, &needsbuffer_spin, 0, "flswai", 0); - spin_unlock_wr(&needsbuffer_spin); - } - count = runningbufcount + numdirtybuffers; - } -#if 0 - /* FUTURE - maybe */ - else if (runningbufcount + numdirtybuffershw > hidirtybuffers / 2) { - bd_wakeup(1); - - while (runningbufcount + numdirtybuffershw > hidirtybuffers) { - needsbuffer |= VFS_BIO_NEED_DIRTYFLUSH; - tsleep(&needsbuffer, slpflags, "newbuf", - slptimeo); - } - } -#endif -} - -/* * buf_dirty_count_severe: * * Return true if we have too many dirty buffers. @@ -1115,7 +1063,7 @@ brelse(struct buf *bp) --numdirtybuffers; if (bp->b_flags & B_HEAVY) --numdirtybuffershw; - numdirtywakeup(); + bd_signal(); } bp->b_flags &= ~(B_DELWRI | B_CACHE); } @@ -2039,12 +1987,10 @@ buf_daemon(void) if (flushbufqueues(BQUEUE_DIRTY) == 0) break; waitrunningbufspace(); - numdirtywakeup(); } if (runningbufcount + numdirtybuffers > lodirtybuffers) { waitrunningbufspace(); } - numdirtywakeup(); /* * Only clear bd_request if we have reached our low water @@ -2105,7 +2051,6 @@ buf_daemon_hw(void) if (flushbufqueues(BQUEUE_DIRTY_HW) == 0) break; waitrunningbufspace(); - numdirtywakeup(); } if (runningbufcount + numdirtybuffershw > lodirtybuffers) { waitrunningbufspace(); diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index b347bb65f1..c05d07387f 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -37,7 +37,7 @@ * * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 * $FreeBSD: src/sys/kern/vfs_syscalls.c,v 1.151.2.18 2003/04/04 20:35:58 tegge Exp $ - * $DragonFly: src/sys/kern/vfs_syscalls.c,v 1.132 2008/06/23 17:21:58 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_syscalls.c,v 1.133 2008/06/28 17:59:49 dillon Exp $ */ #include @@ -1860,7 +1860,7 @@ kern_mknod(struct nlookupdata *nd, int mode, int rmajor, int rminor) if (error) return (error); - bwillwrite(); + bwillinode(1); nd->nl_flags |= NLC_CREATE | NLC_REFDVP; if ((error = nlookup(nd)) != 0) return (error); @@ -1940,7 +1940,7 @@ kern_mkfifo(struct nlookupdata *nd, int mode) struct vnode *vp; int error; - bwillwrite(); + bwillinode(1); nd->nl_flags |= NLC_CREATE | NLC_REFDVP; if ((error = nlookup(nd)) != 0) @@ -2041,7 +2041,7 @@ kern_link(struct nlookupdata *nd, struct nlookupdata *linknd) * * XXX relookup on vget failure / race ? */ - bwillwrite(); + bwillinode(1); if ((error = nlookup(nd)) != 0) return (error); vp = nd->nl_nch.ncp->nc_vp; @@ -2114,7 +2114,7 @@ kern_symlink(struct nlookupdata *nd, char *path, int mode) struct vnode *dvp; int error; - bwillwrite(); + bwillinode(1); nd->nl_flags |= NLC_CREATE | NLC_REFDVP; if ((error = nlookup(nd)) != 0) return (error); @@ -2172,7 +2172,7 @@ sys_undelete(struct undelete_args *uap) int error; error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0); - bwillwrite(); + bwillinode(1); nd.nl_flags |= NLC_DELETE | NLC_REFDVP; if (error == 0) error = nlookup(&nd); @@ -2191,7 +2191,7 @@ kern_unlink(struct nlookupdata *nd) { int error; - bwillwrite(); + bwillinode(1); nd->nl_flags |= NLC_DELETE | NLC_REFDVP; if ((error = nlookup(nd)) != 0) return (error); @@ -3100,7 +3100,7 @@ kern_rename(struct nlookupdata *fromnd, struct nlookupdata *tond) struct mount *mp; int error; - bwillwrite(); + bwillinode(1); fromnd->nl_flags |= NLC_REFDVP; if ((error = nlookup(fromnd)) != 0) return (error); @@ -3296,7 +3296,7 @@ kern_mkdir(struct nlookupdata *nd, int mode) struct vattr vattr; int error; - bwillwrite(); + bwillinode(1); nd->nl_flags |= NLC_WILLBEDIR | NLC_CREATE | NLC_REFDVP; if ((error = nlookup(nd)) != 0) return (error); @@ -3340,7 +3340,7 @@ kern_rmdir(struct nlookupdata *nd) { int error; - bwillwrite(); + bwillinode(1); nd->nl_flags |= NLC_DELETE | NLC_REFDVP; if ((error = nlookup(nd)) != 0) return (error); diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 240ccc8b12..fa99e6f31f 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -37,7 +37,7 @@ * * @(#)vfs_vnops.c 8.2 (Berkeley) 1/21/94 * $FreeBSD: src/sys/kern/vfs_vnops.c,v 1.87.2.13 2002/12/29 18:19:53 dillon Exp $ - * $DragonFly: src/sys/kern/vfs_vnops.c,v 1.57 2008/05/09 17:52:17 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_vnops.c,v 1.58 2008/06/28 17:59:49 dillon Exp $ */ #include @@ -156,7 +156,7 @@ vn_open(struct nlookupdata *nd, struct file *fp, int fmode, int cmode) nd->nl_flags |= NLC_FOLLOW; nd->nl_flags |= NLC_CREATE; nd->nl_flags |= NLC_REFDVP; - bwillwrite(); + bwillinode(1); error = nlookup(nd); } else { /* @@ -519,8 +519,16 @@ vn_rdwr_inchunks(enum uio_rw rw, struct vnode *vp, caddr_t base, int len, if (chunk > len) chunk = len; - if (rw != UIO_READ && vp->v_type == VREG) - bwillwrite(); + if (vp->v_type == VREG) { + switch(rw) { + case UIO_READ: + bwillread(chunk); + break; + case UIO_WRITE: + bwillwrite(chunk); + break; + } + } error = vn_rdwr(rw, vp, base, chunk, offset, segflg, ioflg, cred, aresid); len -= chunk; /* aresid calc already includes length */ @@ -662,8 +670,11 @@ vn_write(struct file *fp, struct uio *uio, struct ucred *cred, int flags) KASSERT(uio->uio_td == curthread, ("uio_td %p is not p %p", uio->uio_td, curthread)); vp = (struct vnode *)fp->f_data; +#if 0 + /* VOP_WRITE should handle this now */ if (vp->v_type == VREG || vp->v_type == VDATABASE) bwillwrite(); +#endif vp = (struct vnode *)fp->f_data; /* XXX needed? */ ioflag = IO_UNIT; @@ -737,7 +748,7 @@ svn_write(struct file *fp, struct uio *uio, struct ucred *cred, int flags) goto done; } if (vp->v_type == VREG) - bwillwrite(); + bwillwrite(uio->uio_resid); vp = (struct vnode *)fp->f_data; /* XXX needed? */ if ((dev = vp->v_rdev) == NULL) { diff --git a/sys/sys/buf.h b/sys/sys/buf.h index 112805ca98..8aa8bcd0a6 100644 --- a/sys/sys/buf.h +++ b/sys/sys/buf.h @@ -37,7 +37,7 @@ * * @(#)buf.h 8.9 (Berkeley) 3/30/95 * $FreeBSD: src/sys/sys/buf.h,v 1.88.2.10 2003/01/25 19:02:23 dillon Exp $ - * $DragonFly: src/sys/sys/buf.h,v 1.48 2008/06/19 23:27:36 dillon Exp $ + * $DragonFly: src/sys/sys/buf.h,v 1.49 2008/06/28 17:59:47 dillon Exp $ */ #ifndef _SYS_BUF_H_ @@ -369,7 +369,8 @@ extern int nswbuf; /* Number of swap I/O buffer headers. */ struct uio; void bufinit (void); -void bwillwrite (void); +int bd_heatup (void); +void bd_wait (int count); int buf_dirty_count_severe (void); void initbufbio(struct buf *); void reinitbufbio(struct buf *); diff --git a/sys/sys/iosched.h b/sys/sys/iosched.h new file mode 100644 index 0000000000..3e6677e106 --- /dev/null +++ b/sys/sys/iosched.h @@ -0,0 +1,40 @@ +/* + * SYS/IOSCHED.H + * + * I/O Scheduler + * + * $DragonFly: src/sys/sys/iosched.h,v 1.1 2008/06/28 17:59:47 dillon Exp $ + */ + +#ifndef _SYS_IOSCHED_H_ +#define _SYS_IOSCHED_H_ + +#if defined(_KERNEL) || defined(_KERNEL_STRUCTURES) + +#ifndef _SYS_TYPES_H_ +#include +#endif +#ifndef _SYS_QUEUE_H_ +#include +#endif +#ifndef _SYS_SYSTIMER_H_ +#include +#endif + +struct iosched_data { + int iorbytes; + int iowbytes; +}; + +#endif /* _KERNEL || _KERNEL_STRUCTURES */ + +#ifdef _KERNEL + +void bwillwrite(int bytes); +void bwillread(int bytes); +void bwillinode(int count); + +#endif + +#endif + diff --git a/sys/sys/proc.h b/sys/sys/proc.h index f563cb7aa1..7e15a5c385 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -37,7 +37,7 @@ * * @(#)proc.h 8.15 (Berkeley) 5/19/95 * $FreeBSD: src/sys/sys/proc.h,v 1.99.2.9 2003/06/06 20:21:32 tegge Exp $ - * $DragonFly: src/sys/sys/proc.h,v 1.119 2008/06/13 00:25:01 dillon Exp $ + * $DragonFly: src/sys/sys/proc.h,v 1.120 2008/06/28 17:59:47 dillon Exp $ */ #ifndef _SYS_PROC_H_ @@ -69,6 +69,7 @@ #include #endif #include +#include #include #include /* Machine-dependent proc substruct. */ #include /* Machine-dependent proc substruct. */ @@ -199,6 +200,7 @@ struct lwp { struct rusage lwp_ru; /* stats for this lwp */ union usched_data lwp_usdata; /* User scheduler specific */ + struct iosched_data lwp_iosdata; /* Dynamic I/O scheduling data */ #define lwp_startcopy lwp_cpumask cpumask_t lwp_cpumask; @@ -243,6 +245,7 @@ struct proc { struct proclist p_children; /* Pointer to list of children. */ struct callout p_ithandle; /* for scheduling p_realtimer */ struct varsymset p_varsymset; + struct iosched_data p_iosdata; /* Dynamic I/O scheduling data */ pid_t p_oppid; /* Save parent pid during ptrace. XXX */ diff --git a/sys/vfs/ufs/ffs_softdep.c b/sys/vfs/ufs/ffs_softdep.c index 29ccf10538..3a811f5cc3 100644 --- a/sys/vfs/ufs/ffs_softdep.c +++ b/sys/vfs/ufs/ffs_softdep.c @@ -37,7 +37,7 @@ * * from: @(#)ffs_softdep.c 9.59 (McKusick) 6/21/00 * $FreeBSD: src/sys/ufs/ffs/ffs_softdep.c,v 1.57.2.11 2002/02/05 18:46:53 dillon Exp $ - * $DragonFly: src/sys/vfs/ufs/ffs_softdep.c,v 1.56 2008/06/19 23:27:39 dillon Exp $ + * $DragonFly: src/sys/vfs/ufs/ffs_softdep.c,v 1.57 2008/06/28 17:59:51 dillon Exp $ */ /* @@ -648,7 +648,7 @@ softdep_process_worklist(struct mount *matchmnt) * we are really being a buffer hog, we will stop and wait. */ if (loopcount++ % 128 == 0) - bwillwrite(); + bwillinode(1); /* * Never allow processing to run for more than one * second. Otherwise the other syncer tasks may get -- 2.11.4.GIT