Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F163263986
D55680.id173245.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D55680.id173245.diff
View Options
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -908,9 +908,9 @@
{
mtx_lock(&rbreqlock);
- if (runningbufreq) {
- runningbufreq = 0;
- wakeup(&runningbufreq);
+ if (runningbufreq > 0) {
+ runningbufreq--;
+ wakeup_one(&runningbufreq);
}
mtx_unlock(&rbreqlock);
}
@@ -943,6 +943,7 @@
runningwakeup();
}
+/* Do we need to return this? Everybody ignores it now */
long
runningbufclaim(struct buf *bp, int space)
{
@@ -970,10 +971,8 @@
{
mtx_lock(&rbreqlock);
- while (runningbufspace > hirunningspace) {
- runningbufreq = 1;
- msleep(&runningbufreq, &rbreqlock, PVM, "wdrain", 0);
- }
+ runningbufreq++;
+ msleep(&runningbufreq, &rbreqlock, PVM, "wdrain", 0);
mtx_unlock(&rbreqlock);
}
@@ -2318,9 +2317,8 @@
bufwrite(struct buf *bp)
{
struct vnode *vp;
- long space;
int oldflags, retval;
- bool vp_md;
+ bool vp_md, waited = false;
CTR3(KTR_BUF, "bufwrite(%p) vp %p flags %X", bp, bp->b_vp, bp->b_flags);
if ((bp->b_bufobj->bo_flag & BO_DEAD) != 0) {
@@ -2345,6 +2343,32 @@
vp = bp->b_vp;
vp_md = vp != NULL && (vp->v_vflag & VV_MD) != 0;
+ /*
+ * If we're going to do runningbuf throttling, do it before we do
+ * expensive things to start the write. We're woken up one at a time
+ * when we're sleeping, so it's OK not to loop here.
+ *
+ * Don't allow the async write to saturate the I/O system. We do not
+ * block here if it is the update or syncer daemon trying to clean up as
+ * that can lead to deadlock.
+ */
+ if ((bp->b_flags & B_ASYNC) != 0 &&
+ (curthread->td_pflags & TDP_NORUNNINGBUF) == 0 &&
+ !vp_md &&
+ runningbufspace >= hirunningspace) {
+ waitrunningbufspace();
+ waited = true;
+ } else if ((bp->b_flags & B_ASYNC) == 0 &&
+ runningbufspace >= hirunningspace) {
+ /*
+ * If we're over the limit and this is a sync write, go ahead
+ * and wakeup one more async write if we have it. This will
+ * help keep us from starving async writes for too long a
+ * period, while still allowing us to throttle them into the
+ * lower layer.
+ */
+ runningwakeup();
+ }
/*
* Mark the buffer clean. Increment the bufobj write count
* before bundirty() call, to prevent other thread from seeing
@@ -2364,7 +2388,7 @@
/*
* Normal bwrites pipeline writes
*/
- space = runningbufclaim(bp, bp->b_bufsize);
+ runningbufclaim(bp, bp->b_bufsize);
#ifdef RACCT
if (racct_enable) {
@@ -2384,17 +2408,17 @@
retval = bufwait(bp);
brelse(bp);
return (retval);
- } else if (space > hirunningspace) {
- /*
- * Don't allow the async write to saturate the I/O
- * system. We do not block here if it is the update
- * or syncer daemon trying to clean up as that can
- * lead to deadlock.
- */
- if ((curthread->td_pflags & TDP_NORUNNINGBUF) == 0 && !vp_md)
- waitrunningbufspace();
}
+ /*
+ * For Async I/O, if there's still space, go ahead and wakeup one. We
+ * need to do this because we're only waking one up at a time. So if
+ * after submitting this I/O if there's space, wakeup one more. Note, we
+ * do this only if we waited.
+ */
+ if (waited && runningbufspace < hirunningspace)
+ runningwakeup();
+
return (0);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Jul 22, 1:52 PM (2 h, 12 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35366120
Default Alt Text
D55680.id173245.diff (3 KB)
Attached To
Mode
D55680: vfs: Move runningbufs delay to top of bufwrite
Attached
Detach File
Event Timeline
Log In to Comment