Subject: kern/11125: UVM leaves stale vm map hint
To: None <gnats-bugs@gnats.netbsd.org>
From: ITOH Yasufumi <itohy@netbsd.org>
List: netbsd-bugs
Date: 10/03/2000 17:33:28
>Number: 11125
>Category: kern
>Synopsis: UVM leaves stale vm map hint
>Confidential: no
>Severity: critical
>Priority: high
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Oct 03 17:33:01 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator: ITOH Yasufumi
>Release: 1.5G (Oct. 3, 2000)
>Organization:
>Environment:
System: NetBSD acha.my.domain 1.5G NetBSD 1.5G (ACHA) #58: Tue Oct 3 21:06:48 JST 2000 itohy@pino.my.domain:/usr/src/sys/arch/x68k/compile/ACHA x68k
Machine: X68030, MPU: MC68030 (25MHz), Main memory: 12MB
>Description:
The UVM may possibly leave stale vm map hint,
which points at freed vm map entry.
This causes random crashes and any sort of inconsistency
in the kernel.
The 1.4 and 1.5 trees are also affected.
>How-To-Repeat:
I'm not sure.
However, fortunately(?), cdrecord-1.9 (pkgsrc/sysutils/cdrecord) pkg
crashes my x68k in more than 95% probability.
Here is a script (crash.sh):
#! /bin/sh
ulimit -d unlimited; ulimit -m unlimited; ulimit -s unlimited
cdrecord -dummy -v dev=/dev/rcd0c driver=cdr_simul speed=2 fs=2m -
You need not have a CD-R drive connected to your machine.
System crashes before opening the device.
I think the mlockall(2) call helps the problem to appear.
# sh crash.sh
Cdrecord 1.9 (--) Copyright (C) 1995-2000 Jorg Schilling
TOC-Type: CD-ROM
uvm_fault(0x15ace4, 0x20620000, 0, 0x1) -> 0x1
type 8, code [mmu,,ssw]: 401074d
trap type 8, code = 0x401074d, v = 0x2062000b
kernel program counter = 0xf665e
kernel: MMU fault trap
pid = 16, pc = 000F665E, ps = 2009, sfc = 1, dfc = 1
Registers:
(register dump)
Kernel stack (006A1D04):
(stack dump)
panic: MMU fault
Stopped in cdrecord at _cpu_Debugger+0x6: unlk a6
db> t
_cpu_Debugger(...) + 6
_panic(...) + 60
_trap(8,401074d,c50af0b) + 244
_uvm_map_lookup_entry(665384,ffffa000,6a1efc) + 4e
_uvm_fault(665384,ffffa000,0,3) + e0
_trap(8,4020709,ffffafc0) + 55a
faultstkadj() + 0
db>
>Fix:
uvm_map_entry_unlink() deletes an entry from the vm map,
and if the hint points at the entry, the hint becomes stale.
Here's a fix.
I confirmed this case occurs and that this change fixes the problem,
but I don't know
whether the locking is necessary,
whether the "if (map->hint == entry)" is necessary,
what value should be set to the hint,
etc...,
and I'll leave it to the UVM gru.
diff -uF^[a-zA-Z_][a-z A-Z0-9_]*([^;]*$ sys/uvm/uvm_map.c.orig sys/uvm/uvm_map.c
--- sys/uvm/uvm_map.c.orig Thu Sep 14 13:21:17 2000
+++ sys/uvm/uvm_map.c Wed Oct 4 00:11:55 2000
@@ -1089,6 +1089,13 @@ uvm_unmap_remove(map, start, end, entry_
* that we've nuked. then go do next entry.
*/
UVMHIST_LOG(maphist, " removed map entry 0x%x", entry, 0, 0,0);
+
+ /* critical! prevents stale hint */
+ simple_lock(&map->hint_lock);
+ if (map->hint == entry)
+ map->hint = entry->prev;
+ simple_unlock(&map->hint_lock);
+
uvm_map_entry_unlink(map, entry);
map->size -= len;
entry->next = first_entry;
>Release-Note:
>Audit-Trail:
>Unformatted: