small patch to buffer.c (2.0.x, stop wasting cycles).

Gordon Oliver (
Fri, 4 Apr 1997 01:57:25 -0400 (CST)

This little patch takes the cli()/restore_flags() out of the loop.
It has been running on my system for a while without problems.
If the relevant code is still in 2.1.x it should probably be fixed there
too... Though this code doesn't probably effect performance much (based
on previous profiles posted), It seems silly to do multiple cli()'s where
one would do.

I tested it and noticed that a program I had reduced both user and system
time by 10 percent (seemed dubious). Seems that rebooting the system cause
_both_ user and system time to drop by about 10 percent for a heavily
calculation/write intensive program (it does huge numbers of floating point
calculations and writes a log to disk). The typical log file is on the
order of 5-10 MBytes.

... Running the simulation that generates ~ 10 MBytes, the performance
degrades about 10 percent in 5 runs (running that program over and over
without other, intervening commands)

--- fs/buffer.c.original Tue Apr 1 21:15:32 1997
+++ fs/buffer.c Tue Apr 1 21:20:52 1997
@@ -1023,21 +1023,29 @@
* to be IRQ-safe here (but note that interrupts only _add_ to the
* reuse_list, never take away. So we don't need to worry about the
* reuse_list magically emptying).
+ *
+ * Changed the code to copy out the list at the beginning instead of
+ * locking it for every entry. This could be made into a while loop, but
+ * that doesn't seem to have much purpose, since this code is called
+ * every time we want a buffer.
static inline void recover_reusable_buffer_heads(void)
if (reuse_list) {
+ struct buffer_head *head;
struct buffer_head *bh;
unsigned long flags;

- do {
- cli();
- bh = reuse_list;
- reuse_list = bh->b_next_free;
- restore_flags(flags);
+ cli();
+ head = reuse_list;
+ reuse_list = NULL;
+ restore_flags(flags);
+ while (head) {
+ bh = head;
+ head = bh->b_next_free;
- } while (reuse_list);
+ }