On 9 dec 2010, at 08:32, Ariane van der Steldt wrote: > I'm not yet convinced. What are you trying to do?
Pretty much as I described: I allocate kernel memory through uvm_km_kmemalloc() from kernel_map, and then free it through uvm_km_free(), returning it to the kernel_map. The code I'm working on is a bit large as a test-case, but I've abused diskmap(4) to reproduce the panic: Index: diskmap.c =================================================================== RCS file: /cvs/openbsd/src/sys/dev/diskmap.c,v retrieving revision 1.2 diff -u -a -r1.2 diskmap.c --- diskmap.c 14 Jun 2010 16:51:55 -0000 1.2 +++ diskmap.c 9 Dec 2010 09:04:56 -0000 @@ -37,6 +37,9 @@ #include <sys/proc.h> #include <sys/vnode.h> +#include <uvm/uvm_extern.h> +#define DIOCBOOM _IO('d', 42) + int diskmapopen(dev_t dev, int flag, int fmt, struct proc *p) { @@ -59,6 +62,18 @@ struct vnode *vp = NULL, *ovp; char *devname; int fd, error = EINVAL; + + if (cmd == DIOCBOOM) { + vaddr_t addr; + + addr = uvm_km_kmemalloc(kernel_map, NULL, PAGE_SIZE, + UVM_KMF_CANFAIL | UVM_KMF_ZERO); + if (addr == NULL) + return (ENOMEM); + uvm_km_free(kernel_map, addr, PAGE_SIZE); + + return (0); + } if (cmd != DIOCMAP) return EINVAL; This triggers the panic with the following test program: #include <err.h> #include <sys/fcntl.h> #include <sys/dkio.h> #define DIOCBOOM _IO('d', 42) int main() { int fd; fd = open("/dev/diskmap", O_RDWR, 0); if (fd < 0) err(1, "open(/dev/diskmap)"); if (ioctl(fd, DIOCBOOM, 0) < 0) err(1, "DIOCBOOM"); close(fd); return (0); } This is in -current from a few days ago, basically in GENERIC on amd64 but with an ISA ne2k driver added (as bochs' PCI ne2k and OpenBSD don't agree much). DDB output: panic: pmap_remove_pte: managed page without PG_PVLIST for 0xffff80000607b000 Stopped at Debugger+0x5: leave RUN AT LEAST 'trace' AND 'ps' AND INCLUDE OUTPUT WHEN REPORTING THIS PANIC! DO NOT EVEN BOTHER REPORTING THIS WITHOUT INCLUDING THAT INFORMATION! ddb> trace Debugger() at Debugger+0x5 panic() at panic+0xe4 pmap_remove_pte() at pmap_remove_pte+0x109 pmap_do_remove() at pmap_do_remove+0x377 uvm_unmap_remove() at uvm_unmap_remove+0x19c uvm_unmap_p() at uvm_unmap_p+0x4c diskmapioctl() at diskmapioctl+0x26b VOP_IOCTL() at VOP_IOCTL+0x39 vn_ioctl() at vn_ioctl+0x71 sys_ioctl() at sys_ioctl+0x111 syscall() at syscall+0x14f --- syscall (number 54) --- end of kernel end trace frame: 0x7f7fffff4820, count: -11 0x20d9b5d0a: ddb> ps PID PPID PGRP UID S FLAGS WAIT COMMAND *10340 22013 10340 0 7 0x4000 boom 3266 0 0 0 3 0x100280 nfsidl nfsio 26078 0 0 0 3 0x100280 nfsidl nfsio 24745 0 0 0 3 0x100280 nfsidl nfsio 20995 0 0 0 3 0x100280 nfsidl nfsio 22818 1 22818 77 3 0x180 poll dhclient 4157 1 5372 0 3 0x80 poll dhclient 22013 1 22013 0 3 0x4080 pause sh 10 0 0 0 3 0x100200 aiodoned aiodoned 9 0 0 0 3 0x100200 syncer update 8 0 0 0 3 0x100200 cleaner cleaner 7 0 0 0 3 0x100200 reaper reaper 6 0 0 0 3 0x100200 pgdaemon pagedaemon 5 0 0 0 3 0x100200 bored crypto 4 0 0 0 3 0x100200 pftm pfpurge 3 0 0 0 3 0x100200 bored syswq 2 0 0 0 3 0x40100200 idle0 1 0 1 0 3 0x4080 wait init 0 -1 0 0 3 0x80200 scheduler swapper (system wasn't running multi-user, so there's not much going on) > Coming back to your error: >> ("pmap_remove_pte: managed page without PG_PVLIST for <address>" on amd64), > That's actually an error from the pmap layer. While uvm controls a lot > of the pmap layer, many parts of the kernel will manage pages themselves > (often using pmap_kenter_pa). > The error message complains that you are freeing a managed page (one > that was entered using pmap_enter) but it's pvlist is missing. The > pvlist is a list that keeps track of which pmaps use that page. The > missing pvlist usually happens when the page was entered using > pmap_kenter_pa. > The kernel_map in uvm consists of managed pages, only kmem_map (and > other intrsafe maps) may contain unmanaged pages. Unmanaged pages cannot > be shared across processes (because the invalidation of such a page is > impossible due to the lack of pvlist). But I'm not doing anything special with pmap, and I'm not using kmem_map (no need to be intrsafe). My own code pretty much only adds a pmap_extract() to the above testcase, but not calling pmap_extract() doesn't prevent the testcase from crashing. Is this actually a bug instead of an undocumented bit of the UVM interface? Thanks, Wouter