Messages in this thread Patch in this message | | | Date | Tue, 1 Jul 1997 20:00:51 +0200 | From | "Dr. Werner Fink" <> | Subject | Re: Bug in write request flushing !!! |
| |
> Hi all > > I'm currently working on small extension to monitor kernel activities. > I noticed that write disk requests successfully reach to the device driver > request queue but if there isn't generated any read request from the time > the write requests was put into queue, they stay in the queue and device > driver isn't kicked to process them. On my machine I discovered that write > requests could stay in device request queue forever, until some read request > or sync is made - Ohhh, Ahhh. These write requests are made by bdflush and > the sys_bdflush syscall. There is missing the kick to the device driver. > > Here is a one line patch which solves this bug for 2.0.30. Probably similar > patch should be applied to 2.1.43 too. > > > Please reply personally > > with regards > Pavel Krauz <kra@elanor.cz>
Thanks for this hint. And have a look at the end of this mail for an other patch to fs/buffer.c.
Werner
----------------------------------------------------------------------------------- --- ../../linux-2.0.30-clean/fs/buffer.c Tue Apr 8 17:47:46 1997 +++ ../../linux-2.0.31-clean/fs/buffer.c Tue Jun 10 12:58:46 1997 @@ -524,7 +524,9 @@ if (bh->b_size == size) continue; + bhnext->b_count++; wait_on_buffer(bh); + bhnext->b_count--; if (bh->b_dev == dev && bh->b_size != size) { clear_bit(BH_Dirty, &bh->b_state); clear_bit(BH_Uptodate, &bh->b_state); @@ -569,6 +571,8 @@ of other sizes, this is necessary now that we no longer have the lav code. */ try_to_free_buffer(bh,&bh,1); + if (!bh) + break; continue; } @@ -612,14 +616,15 @@ } repeat: + if(needed <= 0) + return; + /* OK, we cannot grow the buffer cache, now try to get some from the lru list */ /* First set the candidate pointers to usable buffers. This should be quick nearly all of the time. */ - if(needed <= 0) return; - for(i=0; i<BUF_DIRTY; i++){ buffers[i] = nr_buffers_type[i]; candidate[i] = find_candidate(lru_list[i], &buffers[i], size); @@ -652,12 +657,9 @@ if (candidate[i] && !can_reclaim(candidate[i],size)) candidate[i] = find_candidate(candidate[i],&buffers[i], size); } - if (needed >= 0) - goto repeat; + goto repeat; } - if(needed <= 0) return; - /* Too bad, that was not enough. Try a little harder to grow some. */ if (nr_free_pages > min_free_pages + 5) { @@ -668,9 +670,10 @@ } /* and repeat until we find something good */ - if (!grow_buffers(GFP_ATOMIC, size)) + if (grow_buffers(GFP_ATOMIC, size)) + needed -= PAGE_SIZE; + else wakeup_bdflush(1); - needed -= PAGE_SIZE; goto repeat; } @@ -1520,6 +1523,7 @@ ndirty++; if(bh->b_flushtime > jiffies) continue; nwritten++; + next->b_count++; bh->b_count++; bh->b_flushtime = 0; #ifdef DEBUG @@ -1527,6 +1531,7 @@ #endif ll_rw_block(WRITE, 1, &bh); bh->b_count--; + next->b_count--; } } #ifdef DEBUG @@ -1660,6 +1665,7 @@ currently dirty buffers are not shared, so it does not matter */ if (refilled && major == LOOP_MAJOR) continue; + next->b_count++; bh->b_count++; ndirty++; bh->b_flushtime = 0; @@ -1675,6 +1681,7 @@ if(nlist != BUF_DIRTY) ncount++; #endif bh->b_count--; + next->b_count--; } } #ifdef DEBUG
| |