On Mon, Feb 01, 2010 at 11:30:06PM -0500, Ted Unangst wrote:
> I think this fixes the problem with sleeping and holding pseg_lck.
>
> Index: uvm_extern.h
> ===================================================================
> RCS file: /home/tedu/cvs/src/sys/uvm/uvm_extern.h,v
> retrieving revision 1.82
> diff -u -r1.82 uvm_extern.h
> --- uvm_extern.h 11 Aug 2009 18:43:33 -0000 1.82
> +++ uvm_extern.h 2 Feb 2010 04:28:09 -0000
> @@ -517,8 +517,9 @@
> vaddr_t *, vsize_t, int,
> boolean_t, vm_map_t);
> vaddr_t uvm_km_valloc(vm_map_t, vsize_t);
> -vaddr_t uvm_km_valloc_align(vm_map_t, vsize_t, vsize_t);
> +vaddr_t uvm_km_valloc_try(vm_map_t, vsize_t);
> vaddr_t uvm_km_valloc_wait(vm_map_t, vsize_t);
> +vaddr_t uvm_km_valloc_align(struct vm_map *, vsize_t,
> vsize_t, int);
> vaddr_t uvm_km_valloc_prefer_wait(vm_map_t, vsize_t,
> voff_t);
> void *uvm_km_getpage(boolean_t, int *);
> Index: uvm_km.c
> ===================================================================
> RCS file: /home/tedu/cvs/src/sys/uvm/uvm_km.c,v
> retrieving revision 1.75
> diff -u -r1.75 uvm_km.c
> --- uvm_km.c 25 Jul 2009 12:55:40 -0000 1.75
> +++ uvm_km.c 2 Feb 2010 04:27:35 -0000
> @@ -571,11 +571,17 @@
> vaddr_t
> uvm_km_valloc(struct vm_map *map, vsize_t size)
> {
> - return(uvm_km_valloc_align(map, size, 0));
> + return(uvm_km_valloc_align(map, size, 0, 0));
> }
>
> vaddr_t
> -uvm_km_valloc_align(struct vm_map *map, vsize_t size, vsize_t align)
> +uvm_km_valloc_try(struct vm_map *map, vsize_t size)
> +{
> + return(uvm_km_valloc_align(map, size, 0, UVM_FLAG_TRYLOCK));
> +}
> +
> +vaddr_t
> +uvm_km_valloc_align(struct vm_map *map, vsize_t size, vsize_t align, int
> flags)
> {
> vaddr_t kva;
> UVMHIST_FUNC("uvm_km_valloc"); UVMHIST_CALLED(maphist);
> @@ -592,7 +598,7 @@
>
> if (__predict_false(uvm_map(map, &kva, size, uvm.kernel_object,
> UVM_UNKNOWN_OFFSET, align, UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL,
> - UVM_INH_NONE, UVM_ADV_RANDOM, 0)) != 0)) {
> + UVM_INH_NONE, UVM_ADV_RANDOM, flags)) != 0)) {
> UVMHIST_LOG(maphist, "<- done (no VM)", 0,0,0,0);
> return(0);
> }
> Index: uvm_pager.c
> ===================================================================
> RCS file: /home/tedu/cvs/src/sys/uvm/uvm_pager.c,v
> retrieving revision 1.54
> diff -u -r1.54 uvm_pager.c
> --- uvm_pager.c 22 Jul 2009 21:05:37 -0000 1.54
> +++ uvm_pager.c 2 Feb 2010 04:23:57 -0000
> @@ -138,7 +138,7 @@
> {
> KASSERT(pseg->start == 0);
> KASSERT(pseg->use == 0);
> - pseg->start = uvm_km_valloc(kernel_map, MAX_PAGER_SEGS * MAXBSIZE);
> + pseg->start = uvm_km_valloc_try(kernel_map, MAX_PAGER_SEGS * MAXBSIZE);
> }
This won't build on sparc64 (the only caller of valloc_align). If you
fix that, then I am ok with this diff.
Though to be honest, most of the valloc functions could mostly just be
replaced with uvm_km_kmemalloc (valloc_wait and valloc_align can't
without changes). The code called is equivalent in action to:
valloc() -> kmemalloc(,,,, VALLOC)
valloc_try() -> kmemalloc(,,,,TRYLOCK | VALLOC)
One thing at a time though. uvm_km.c has 3 or 4 allocators that are all
almost identical (some differ in flags, but not much else). I'll look
into clearing it up.
Reviewing that last paragraph, I notice that kmemalloc doesn't lock the
object that it is called with. I'll fix that soon...
Cheers,
-0-
--
If you keep anything long enough, you can throw it away.