bdflush-related reboots (was Re: PATCH for 2.3.12: swap-related deadlock)

Kevin Buhr (buhr@stat.wisc.edu)
02 Aug 1999 18:50:48 -0500


I was wrong about the cause of the reboots.

After some additional testing, I found I could get the following to
reboot during a big "fsck":

- 2.3.11 with spinlock fix;
- 2.3.11 with spinlock fix plus lock_kernel()/unlock_kernel()
around "sys_bdflush"'s current->mm = NULL statement;
- 2.3.11 with spinlock fix plus your (David's) patch.

while I could *not* make the following reboot under similar
conditions:

- 2.3.11 with spinlock fix but with lazy TLB code removed
entirely from "sys_bdflush";
- 2.3.12 with spinlock fix.

After some careful comparisons between 2.3.11 and 2.3.12, I came up
with the following patch to 2.3.11 which mimics 2.3.12's lazy TLB
handling within the 2.3.11 framework:

diff -r -u linux-2.3.11/fs/buffer.c linux-2.3.11-1/fs/buffer.c
--- linux-2.3.11/fs/buffer.c Mon Aug 2 13:40:58 1999
+++ linux-2.3.11-1/fs/buffer.c Mon Aug 2 18:33:05 1999
@@ -44,6 +44,8 @@
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/bitops.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>

#define NR_SIZES 7
static char buffersize_index[65] =
@@ -1969,23 +1971,32 @@
goto out;

if (func == 1) {
- struct mm_struct *user_mm;
+ struct mm_struct *mm, *active_mm;
/*
* bdflush will spend all of it's time in kernel-space,
* without touching user-space, so we can switch it into
* 'lazy TLB mode' to reduce the cost of context-switches
* to and from bdflush.
*/
- user_mm = current->mm;
- atomic_inc(&user_mm->mm_count);
+ mm = current->mm;
current->mm = NULL;
+ atomic_inc(&mm->mm_count);
/* active_mm is still 'user_mm' */

error = sync_old_buffers();

- current->mm = user_mm;
- mmdrop(current->active_mm);
- current->active_mm = user_mm;
+ active_mm = current->active_mm;
+ current->mm = mm;
+ if (mm != active_mm) {
+ current->active_mm = mm;
+
+ /* Re-load page tables */
+ SET_PAGE_DIR(current, mm->pgd);
+ activate_context(current);
+ clear_bit(current->processor, &active_mm->cpu_vm_mask);
+ set_bit(current->processor, &mm->cpu_vm_mask);
+ }
+ mmdrop(active_mm);

goto out;
}

This stopped the reboots. Therefore, it would seem they were caused
by page table weirdnesses that have been fixed in 2.3.12 and are no
longer a concern.

That's not to say that there aren't still race conditions involved.
In addition to "swap_out()" and friends which your patch addresses,
the "/proc" filesystem would be another candidate for having a
"tsk->mm" stolen out from under it by "start_lazy_tlb()".

Kevin <buhr@stat.wisc.edu>

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/