lkml.org 
[lkml]   [1997]   [Jul]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: 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
\
 
 \ /
  Last update: 2005-03-22 13:39    [W:0.064 / U:0.272 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site