lkml.org 
[lkml]   [1997]   [Feb]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject2.0.x Disk Performance Problem - Solved
A month or so ago tenthumbs@cybernex.net and I both reported performance
problems with disk I/O in recent 2.0.x kernels. In my case, the most serious
problem was an e2fsck run that took 60 minutes when it should have taken 5 or
6. I'd also noticed problems with mke2fs for several months but had never
gotten around to investigating further. I've now tracked this problem down and
corrected it.

It turns out this performance problem was inadvertently introduced by a
correction made to fs/buffer.c in the 2.0.21 patch. The addition of a missing
"++nr_buffers_size[isize];" revealed a latent problem in the load average
computations in maybe_shrink_lav_buffers, which caused shrink_specific_buffers
to be called inappropriately, wasting many cycles trying to reclaim buffers
where there were none to be had.

Specifically, the first calculation in the comparison

bdf_prm.b_un.lav_const * buffers_lav[nlist]*total_n_buffers <
total_lav * (nr_buffers_size[nlist] - nr_buffers_st[nlist][BUF_SHARED]))

can become negative or overflow. When it becomes negative, the comparison will
succeeed when it should not. One of the failures I logged was:

1884 * 73 * 21375 < 8812 * ( 57 - 0 )

The enclosed patch divides both sides of this comparison by total_lav *
total_n_buffers, which preserves the comparison while avoiding large
multiplications.

Leonard


--- linux/fs/buffer.c- Fri Sep 20 07:00:35 1996
+++ linux/fs/buffer.c Thu Feb 13 23:21:42 1997
@@ -1535,10 +1535,11 @@
if (n_sizes > 1)
for(nlist = 0; nlist < NR_SIZES; nlist++)
{
- if(nlist == isize) continue;
- if(nr_buffers_size[nlist] &&
- bdf_prm.b_un.lav_const * buffers_lav[nlist]*total_n_buffers <
- total_lav * (nr_buffers_size[nlist] - nr_buffers_st[nlist][BUF_SHARED]))
+ if (nlist == isize) continue;
+ if (nr_buffers_size[nlist] > 0 &&
+ total_lav > 0 && total_n_buffers > 0 &&
+ bdf_prm.b_un.lav_const * buffers_lav[nlist] / total_lav <
+ (nr_buffers_size[nlist] - nr_buffers_st[nlist][BUF_SHARED]) / total_n_buffers)
if(shrink_specific_buffers(6, bufferindex_size[nlist]))
return 1;
}
\
 
 \ /
  Last update: 2005-03-22 13:38    [W:0.052 / U:0.192 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site