lkml.org 
[lkml]   [1999]   [May]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
SubjectRe: PATCH: rewritten bdflush
Date
From
On Wed, 12 May 1999 16:09:26 -0400 (EDT), Steve Willer wrote:
>
>On Wed, 12 May 1999, Zack Weinberg wrote:
>
>> I think I know what is doing this, but I would like to be certain. The
>> max-writes-per-cycle choke didn't used to apply to the five-second
>> writebacks, now it does. I didn't think that would cause trouble, but
>> I appear to have been wrong. Can you please rerun your test after
>> doing
>>
>> # echo "40 5000 64 256 5 3000 500 1884 2" >/proc/sys/vm/bdflush
>
>I've tried it, and it appears to be better. I spent a lot of time playing
>around with these settings (before I got your email), trying to get
>once-per-second writes cheaply, before I realized bdflush was a thread and
>therefore interruptable.
>
>The 5000 blocks makes it behave better. It seems to keep up with my
>particular I/O test. However, that just means it scales up as far as this
>particular test system. With all the talk about 'enterprise' systems,
>perhaps the algorithm should be made more self-aware, and also more safe.
>The safety issue comes from the fact that without a periodic sync, there
>appears to be no limit to how old a buffer can get.

Yes - and 5000 is as high as that parameter will go, so it won't keep
up with a heavier load. I'm a little worried about your vmstat
numbers still, the repeated 2500 figure indicates that the per-cycle
write limit is getting halved somewhere.

There was an age limit (35 secs, tunable) in the previous (2.2.7)
version of this code. I removed it accidentally. Your self-tuning
ideas are interesting, but for now let's just put back the age limit.

The appended patch *should* correct the problem. I have not even
compiled it; if I get a chance, I'll try later tonight. Linus, since
you put my patch into 2.2.8, this needs to be considered for 2.2.9 and
2.3.1. And could you please look at what I've done and make sure I
haven't missed something else? I don't know the buffer cache all that
well, and I was not expecting the patch to get incorporated without a
few rounds of testing first.

zw

--- buffer.c.228 Wed May 12 18:23:34 1999
+++ buffer.c Wed May 12 18:39:03 1999
@@ -1580,7 +1580,7 @@
* with running out of free buffers for loop's "real" device).
*/

-static inline void sync_old_buffers(void)
+static inline void sync_old_buffers(int all)
{
int i;
int ndirty = 0;
@@ -1618,7 +1618,7 @@
bh = lru_list[BUF_DIRTY];
if(bh)
for (i = nr_buffers_type[BUF_DIRTY];
- i-- > 0 && ndirty < bdf_prm.b_un.ndirty;
+ i-- > 0 && (all || ndirty < bdf_prm.b_un.ndirty);
bh = next) {
/* We may have stalled while waiting for
I/O to complete. */
@@ -1644,22 +1644,31 @@
next->b_count++;
bh->b_count++;
ndirty++;
+ /* If not short of memory, flush only older buffers */
+ if (all && time_before(jiffies, bh->b_flushtime))
+ continue;
+#ifdef DEBUG
+ nwritten++;
+#endif
bh->b_flushtime = 0;
if (MAJOR(bh->b_dev) == LOOP_MAJOR) {
ll_rw_block(wrta_cmd,1, &bh);
wrta_cmd = WRITEA;
- if (buffer_dirty(bh))
+ if (buffer_dirty(bh)) {
--ndirty;
+#ifdef DEBUG
+ --nwritten;
+#endif
+ }
}
else
ll_rw_block(WRITE, 1, &bh);
bh->b_count--;
next->b_count--;
}
- /* If we didn't write anything, but there are still
- * dirty buffers, then make the next write to a
- * loop device to be a blocking write.
- * This lets us block--which we _must_ do! */
+ /* If we didn't write anything and there are dirty
+ * buffers, make the next write to a loop device be a
+ * blocking write. This lets us block--which we _must_ do! */
if (ndirty == 0
&& nr_buffers_type[BUF_DIRTY] > 0 && wrta_cmd != WRITE) {
wrta_cmd = WRITE;
@@ -1732,6 +1741,7 @@
{
long remaining = HZ * bdf_prm.b_un.interval;
struct task_struct *tsk = current;
+ int all;

/*
* We have a bare-bones task_struct, and really should fill
@@ -1774,11 +1784,13 @@
sync_supers(0);
sync_inodes(0);
remaining = HZ * bdf_prm.b_un.interval;
- }
+ all = 1;
+ } else
+ all = 0;

/* Keep flushing till there aren't very many dirty buffers */
do {
- sync_old_buffers();
+ sync_old_buffers(all);
} while(nr_buffers_type[BUF_DIRTY] > nr_buffers * bdf_prm.b_un.nfract/100);

wake_up(&bdflush_done);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:51    [W:0.066 / U:0.252 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site