NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/46592: lib/libc/sys/t_mmap cause kernel panic
The following reply was made to PR kern/46592; it has been noted by GNATS.
From: Manuel Bouyer <bouyer%antioche.eu.org@localhost>
To: gnats-bugs%NetBSD.org@localhost, netbsd-bugs%NetBSD.org@localhost
Cc:
Subject: Re: kern/46592: lib/libc/sys/t_mmap cause kernel panic
Date: Thu, 14 Jun 2012 18:56:05 +0200
On Tue, Jun 12, 2012 at 10:05:00AM +0000, bouyer%antioche.eu.org@localhost
wrote:
> As shown in automated run reports at:
> http://www-soc.lip6.fr/~bouyer/NetBSD-tests/xen/HEAD/
> amd64 and i386 kernels have been panicing on a t_mmap test for some
> time.
> lib/libc/sys/t_mmap (332/519): 8 test cases
> mmap_block: panic: kernel diagnostic assertion "vp ==
> vp->v_specnode->sn_dev->sd_bdevvp" failed: file
> "/home/builds/ab/HEAD/src/sys/miscfs/specfs/spec_vnops.c", line 891
> cpu1: Begin traceback...
This test does 2 reads at the mmaped memory: one before closing the
file descriptor used to mmap() the device, and one after closing.
It's the second read which causes the panic.
> kern_assert() at netbsd:kern_assert+0xae
> spec_strategy() at netbsd:spec_strategy+0x97
> VOP_STRATEGY() at netbsd:VOP_STRATEGY+0x33
> genfs_getpages() at netbsd:genfs_getpages+0x1161
> VOP_GETPAGES() at netbsd:VOP_GETPAGES+0x4f
> uvn_get() at netbsd:uvn_get+0x50
> uvm_fault_internal() at netbsd:uvm_fault_internal+0xcab
> trap() at netbsd:trap+0x4e4
I found the problem:
on the native anita run, the device used for tests is /dev/wd0d; on
xen anita run it is /dev/xbd0d.
With the native run, the panic doesn't happen because in genfs_getpage()
vp->v_size is 0, so it doesn't go to VOP_STRATEGY() and the process gets
a SEGV. With the Xen run vp->v_size is set to the size of the device.
The problem is in spec_open(), which does a uvm_vnp_setsize() at the end.
The problem is there:
if (cdev_type(dev) != D_DISK || error != 0)
return error;
But if dev is not a character device, cdev_type(dev) won't return the
right value. For wd0d it returns D_TTY:
brw-r----- 1 root operator 0, 3 May 3 2011 /dev/wd0d
crw-r----- 1 root operator 3, 3 May 3 2011 /dev/rwd0d
crw------- 1 root wheel 0, 0 Jun 14 13:51 console
crw------- 1 root wheel 0, 1 Jun 14 18:50 constty
cdev_type(dev) looks at the cons driver instead of wd in this case.
But for xbd0d it returns D_DISK, because the major is the same for
block and char:
brw-r----- 1 root operator 142, 3 May 3 2011 /dev/xbd0d
crw-r----- 1 root operator 142, 3 May 3 2011 /dev/rxbd0d
and so spec_open() goes to the end, where it does a uvm_vnp_setsize().
A quick fix would be:
Index: miscfs/specfs/spec_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/miscfs/specfs/spec_vnops.c,v
retrieving revision 1.135
diff -u -p -u -r1.135 spec_vnops.c
--- miscfs/specfs/spec_vnops.c 29 Apr 2012 22:54:00 -0000 1.135
+++ miscfs/specfs/spec_vnops.c 14 Jun 2012 16:53:09 -0000
@@ -541,7 +541,7 @@ spec_open(void *v)
}
mutex_exit(&device_lock);
- if (cdev_type(dev) != D_DISK || error != 0)
+ if (vp->v_type != VCHR || cdev_type(dev) != D_DISK || error != 0)
return error;
if (vp->v_type == VCHR)
but it looks like the intend of the code was to set the size for both block and
char disk devices, so I'm not sure what the right thing to do here really is.
--
Manuel Bouyer <bouyer%antioche.eu.org@localhost>
NetBSD: 26 ans d'experience feront toujours la difference
--
Home |
Main Index |
Thread Index |
Old Index