fstat triggered INVARIANTS panic in memrw()

Mark W. Krentel krentel at dreamscape.com
Thu Jan 20 14:45:02 PST 2005


First, let me check that your panic requires three things to trigger:
(1) heavy load, in your case ports building, (2) INVARIANTS compiled
into the kernel, and (3) many calls to fstat(1).  Is that right?

Also, you're running 6.0-current on an x86 SMP machine?  Can you bound
the problem between two dates, that is, you compiled kernel/world on
date X and it was ok, and updated on date Y and it panicked?  Are you
changing the default kernel address space (3 Gig user and 1 Gig
kernel) via KVA_PAGES?

Following Alan's diagnosis, I added some printf()s to check the
arguments to kernacc() and vm_map_check_protection().  I didn't get a
panic, but I can confirm that kernacc() is being called with arguments
that constitute address wrap.  My tests were on a single-CPU P3-933.
I ran buildworld along with a loop of fstat(1)s, and the address wrap
happened within seconds.  It required both (1) and (3) above,
INVARIANTS may be a red herring, I'm not sure.

How long did it take for your machine to panic?  Mine didn't panic,
but maybe I didn't run the test long enough, or maybe I don't have
enough open files.

Anyway, try this patch, see if it avoids the panic for you.

--Mark

Index: vm_glue.c
===================================================================
RCS file: /data/ncvs/src/sys/vm/vm_glue.c,v
retrieving revision 1.209
diff -u -r1.209 vm_glue.c
--- vm_glue.c	7 Jan 2005 02:29:27 -0000	1.209
+++ vm_glue.c	20 Jan 2005 22:01:21 -0000
@@ -133,6 +133,11 @@
 
 	KASSERT((rw & ~VM_PROT_ALL) == 0,
 	    ("illegal ``rw'' argument to kernacc (%x)\n", rw));
+
+	if ((vm_offset_t)addr + len > kernel_map->max_offset ||
+	    (vm_offset_t)addr + len < (vm_offset_t)addr)
+		return (FALSE);
+
 	prot = rw;
 	saddr = trunc_page((vm_offset_t)addr);
 	eaddr = round_page((vm_offset_t)addr + len);




More information about the freebsd-current mailing list