Messages in this thread Patch in this message | | | Date | Wed, 10 Sep 1997 19:27:48 +0200 | From | "Dr. Werner Fink" <> | Subject | Patch [Was: Final pre-2.0.31.. Expect this to be same as real 2.0.31] |
| |
> > And now the best part of the story. I have applied the patch I got from > Werner on top of "v-20" and got "v-21". I have made two standard tests > without external ping (once without any warnings, once with only one SCSI > reset) > > I have made also three tests with external ping -f -s 1024 myhost. All of > tests completed without any problems (no SCSI timeuts). The bonnies output > has shown that output transfer rate was even slightly faster. Block > inputs are slightly slower, but "getc" input is faster.
I've done some small changes on my last patch. From Gadi I got the valuable hint that kflushd calls via ll_rw_block() getblk() and therefore refill_freelist() (-> the `loop' device) ... in such a situation a call of kflushd within refill_freelist() is not a good idea. I would like to recommend the appended patch.
Changes:
* Clears my own change of find_candidate() to get them on work.
* Calls wakeup_bdflush() in refill_freelist() if the current task is _not_ kflushd ... if the current task _is_ kflushd we go the old way (that means: using Bill Hawes page protection ... now including a allow_interrupts() for SMP ... and a call of grow_buffers())
* A small change in try_to_free_page() (mm/vmscan.c) to make the above call of grow_buffers() more efficient.
... I've only a problem with aic7xxx: If CONFIG_AIC7XXX_PAGE_ENABLE is set the system runs into scsi timeouts/resets or sometimes it hangs on heavy I/O. With conservative (=default) the system _is_ stable and usable.
Werner
----------------------------------------------------------------------------- diff -urN linux-2.0.31-9/fs/buffer.c linux/fs/buffer.c --- linux-2.0.31-9/fs/buffer.c Mon Sep 8 14:32:14 1997 +++ linux/fs/buffer.c Wed Sep 10 14:24:01 1997 @@ -559,7 +559,7 @@ static struct buffer_head *find_candidate(struct buffer_head *bh, int *list_len, int size) { - int behind = 0; + int lookahead = 7; if (!bh) goto no_candidate; @@ -572,11 +572,12 @@ try_to_free_buffer(bh,&bh,1); if (!bh) break; + lookahead = 7; continue; } else if (buffer_locked(bh) && (bh->b_list == BUF_LOCKED || bh->b_list == BUF_LOCKED1)) { - if (behind++ > 10) { + if (!--lookahead) { (*list_len) = 0; goto no_candidate; } @@ -595,6 +596,7 @@ { struct buffer_head * bh; struct buffer_head * candidate[BUF_DIRTY]; + extern struct task_struct *bdflush_tsk; unsigned int best_time, winner; int buffers[BUF_DIRTY]; int i; @@ -661,21 +663,38 @@ /* Dirty buffers should not overtake, wakeup_bdflush(1) calls bdflush and sleeps, therefore kswapd does his important work. */ - if ((nr_buffers_type[BUF_DIRTY] > nr_buffers * bdf_prm.b_un.nfract/100) || - (nr_free_pages < min_free_pages)) + if (nr_buffers_type[BUF_DIRTY] > nr_buffers * bdf_prm.b_un.nfract/100) wakeup_bdflush(1); /* Too bad, that was not enough. Try a little harder to grow some. */ - if (nr_free_pages > min_free_pages + 5) { + if (nr_free_pages > ((min_free_pages + free_pages_low) >> 1)) { if (grow_buffers(GFP_BUFFER, size)) { needed -= PAGE_SIZE; goto repeat; }; } + /* If we are not bdflush we should wake up bdflush and try it again. */ + + if (current != bdflush_tsk) { + wakeup_bdflush(1); + needed -= PAGE_SIZE; + goto repeat; + } + + /* We are bdflush: let's try our best */ + + /* + * In order to protect our reserved pages, + * return now if we got any buffers. + */ + allow_interrupts(); + if (free_list[BUFSIZE_INDEX(size)]) + return; + /* and repeat until we find something good */ - wakeup_bdflush(1); + grow_buffers(GFP_BUFFER, size); /* decrease needed even if there is no success */ needed -= PAGE_SIZE; diff -urN linux-2.0.31-9/mm/vmscan.c linux/mm/vmscan.c --- linux-2.0.31-9/mm/vmscan.c Mon Sep 8 14:32:21 1997 +++ linux/mm/vmscan.c Wed Sep 10 14:03:25 1997 @@ -406,11 +406,8 @@ can_do_io = 1; if (wait) stop = 0; - if (priority == GFP_BUFFER) { - /* bdflush() should do the rest if we fail */ - stop = 3; + if (priority == GFP_BUFFER) can_do_io = 0; - } switch (state) { do { case 0:
| |