On Wed, Dec 08, 2010 at 04:49:16PM +0100, Wouter Coene wrote:
> Having spent quite some hours figuring out why the kernel panics when I free
> memory allocated through uvm_km_kmemalloc() with uvm_km_free()
> ("pmap_remove_pte: managed page without PG_PVLIST for <address>" on amd64),
> I added the following clarification to uvm(9):
>
> Index: uvm.9
> ===================================================================
> RCS file: /cvs/openbsd/src/share/man/man9/uvm.9,v
> retrieving revision 1.42
> diff -u -a -r1.42 uvm.9
> --- uvm.9 9 Nov 2010 16:03:38 -0000 1.42
> +++ uvm.9 8 Dec 2010 15:41:28 -0000
> @@ -518,7 +518,7 @@
> .Fn uvm_km_zalloc
> functions allocate
> .Fa size
> -bytes of wired kernel memory in map
> +bytes of page-aligned wired kernel memory in map
> .Fa map .
> In addition to allocation,
> .Fn uvm_km_zalloc
> @@ -532,9 +532,15 @@
> .Fn uvm_km_alloc1
> function allocates and returns
> .Fa size
> -bytes of wired memory in the kernel map, zeroing the memory if the
> +bytes of page-aligned wired memory in the kernel map, zeroing the memory if
> +the
> .Fa zeroit
> -argument is non-zero.
> +argument is non-zero. Unless called on an interrupt-safe map, if memory is
> +currently unavailable,
> +.Fn uvm_km_alloc1
> +may sleep to wait for resources to be released by other processes. If not
> +enough memory is available, this function returns
> +.Dv NULL .
> .Pp
> The
> .Fn uvm_km_kmemalloc
> @@ -607,10 +613,15 @@
> .Fa size
> bytes of memory in the kernel map, starting at address
> .Fa addr .
> +The memory must have been allocated with
> +.Fn uvm_km_alloc ,
> +.Fn uvm_km_zalloc
> +or
> +.Fn uvm_km_alloc1 .
uvm_km_alloc and uvm_km_zalloc are already mentioned as being
implemented in terms of uvm_km_alloc1. So they don't need explicit
mention here. The list of functions is also incomplete.
> .Fn uvm_km_free_wakeup
> -calls
> -.Fn thread_wakeup
> -on the map before unlocking the map.
> +wakes up any processes waiting for memory on the map (via
> +.Fn thread_wakeup )
> +before unlocking the map.
No objections.
> .Sh ALLOCATION OF PHYSICAL MEMORY
> .nr nS 1
> .Ft struct vm_page *
>
> Is this correct?
Uvm can only deal with page-aligned addresses and sizes. For smaller
sizes, either malloc(9) or pool(9) will have to do. If the
page-alignment note is really needed, it should be put in the
description or notes section.
I would recommend getting hold of CDC paper on uvm to understand it
better.
> And if so, any chance this could go in?
I'm not yet convinced. What are you trying to do?
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).
Ciao,
--
Ariane