diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2001-11-07 01:18:02 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2001-11-07 01:18:02 +0000 |
commit | c1c5c105f41ad5a43d2d86df94c7b57a4e86d03f (patch) | |
tree | f35ef0cfc30ec497901dac2701302652e736c1f4 /sys/uvm | |
parent | 0cf5ca3327d0f3f051ffeeedbbf725cdb3b5b201 (diff) |
Add an alignment argument to uvm_map that specifies an alignment hint
for the virtual address.
Diffstat (limited to 'sys/uvm')
-rw-r--r-- | sys/uvm/uvm_extern.h | 7 | ||||
-rw-r--r-- | sys/uvm/uvm_km.c | 16 | ||||
-rw-r--r-- | sys/uvm/uvm_map.c | 84 | ||||
-rw-r--r-- | sys/uvm/uvm_map.h | 9 | ||||
-rw-r--r-- | sys/uvm/uvm_mmap.c | 6 | ||||
-rw-r--r-- | sys/uvm/uvm_page.c | 4 | ||||
-rw-r--r-- | sys/uvm/uvm_pager.c | 6 | ||||
-rw-r--r-- | sys/uvm/uvm_unix.c | 6 |
8 files changed, 89 insertions, 49 deletions
diff --git a/sys/uvm/uvm_extern.h b/sys/uvm/uvm_extern.h index c294b3d2987..3f6eaa5aeb6 100644 --- a/sys/uvm/uvm_extern.h +++ b/sys/uvm/uvm_extern.h @@ -1,5 +1,5 @@ -/* $OpenBSD: uvm_extern.h,v 1.28 2001/11/06 18:41:10 art Exp $ */ -/* $NetBSD: uvm_extern.h,v 1.48 2000/08/12 22:41:55 thorpej Exp $ */ +/* $OpenBSD: uvm_extern.h,v 1.29 2001/11/07 01:18:01 art Exp $ */ +/* $NetBSD: uvm_extern.h,v 1.49 2000/09/13 15:00:25 thorpej Exp $ */ /* * @@ -486,7 +486,8 @@ void uvm_km_free_poolpage1 __P((vm_map_t, vaddr_t)); /* uvm_map.c */ int uvm_map __P((vm_map_t, vaddr_t *, vsize_t, - struct uvm_object *, voff_t, uvm_flag_t)); + struct uvm_object *, voff_t, vsize_t, + uvm_flag_t)); int uvm_map_pageable __P((vm_map_t, vaddr_t, vaddr_t, boolean_t, int)); int uvm_map_pageable_all __P((vm_map_t, int, vsize_t)); diff --git a/sys/uvm/uvm_km.c b/sys/uvm/uvm_km.c index 3ff1ea1140a..08f373e54de 100644 --- a/sys/uvm/uvm_km.c +++ b/sys/uvm/uvm_km.c @@ -1,5 +1,5 @@ -/* $OpenBSD: uvm_km.c,v 1.18 2001/11/06 13:36:52 art Exp $ */ -/* $NetBSD: uvm_km.c,v 1.38 2000/07/24 20:10:53 jeffs Exp $ */ +/* $OpenBSD: uvm_km.c,v 1.19 2001/11/07 01:18:01 art Exp $ */ +/* $NetBSD: uvm_km.c,v 1.39 2000/09/13 15:00:25 thorpej Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -235,7 +235,7 @@ uvm_km_init(start, end) uvm_map_setup(&kernel_map_store, base, end, VM_MAP_PAGEABLE); kernel_map_store.pmap = pmap_kernel(); if (uvm_map(&kernel_map_store, &base, start - base, NULL, - UVM_UNKNOWN_OFFSET, UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, + UVM_UNKNOWN_OFFSET, 0, UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_NONE, UVM_ADV_RANDOM,UVM_FLAG_FIXED)) != KERN_SUCCESS) panic("uvm_km_init: could not reserve space for kernel"); @@ -273,7 +273,7 @@ uvm_km_suballoc(map, min, max, size, flags, fixed, submap) * first allocate a blank spot in the parent map */ - if (uvm_map(map, min, size, NULL, UVM_UNKNOWN_OFFSET, + if (uvm_map(map, min, size, NULL, UVM_UNKNOWN_OFFSET, 0, UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_NONE, UVM_ADV_RANDOM, mapflags)) != KERN_SUCCESS) { panic("uvm_km_suballoc: unable to allocate space in parent map"); @@ -539,7 +539,7 @@ uvm_km_kmemalloc(map, obj, size, flags) */ if (__predict_false(uvm_map(map, &kva, size, obj, UVM_UNKNOWN_OFFSET, - UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_NONE, + 0, UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_NONE, UVM_ADV_RANDOM, (flags & UVM_KMF_TRYLOCK))) != KERN_SUCCESS)) { UVMHIST_LOG(maphist, "<- done (no VM)",0,0,0,0); @@ -684,7 +684,7 @@ uvm_km_alloc1(map, size, zeroit) */ if (__predict_false(uvm_map(map, &kva, size, uvm.kernel_object, - UVM_UNKNOWN_OFFSET, UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, + UVM_UNKNOWN_OFFSET, 0, UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_NONE, UVM_ADV_RANDOM, 0)) != KERN_SUCCESS)) { UVMHIST_LOG(maphist,"<- done (no VM)",0,0,0,0); @@ -785,7 +785,7 @@ uvm_km_valloc(map, size) */ if (__predict_false(uvm_map(map, &kva, size, uvm.kernel_object, - UVM_UNKNOWN_OFFSET, UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, + UVM_UNKNOWN_OFFSET, 0, UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_NONE, UVM_ADV_RANDOM, 0)) != KERN_SUCCESS)) { UVMHIST_LOG(maphist, "<- done (no VM)", 0,0,0,0); @@ -833,7 +833,7 @@ uvm_km_valloc_prefer_wait(map, size, prefer) */ if (__predict_true(uvm_map(map, &kva, size, uvm.kernel_object, - prefer, UVM_MAPFLAG(UVM_PROT_ALL, + prefer, 0, UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_NONE, UVM_ADV_RANDOM, 0)) == KERN_SUCCESS)) { UVMHIST_LOG(maphist,"<- done (kva=0x%x)", kva,0,0,0); diff --git a/sys/uvm/uvm_map.c b/sys/uvm/uvm_map.c index b754d9ccde4..d3d00972295 100644 --- a/sys/uvm/uvm_map.c +++ b/sys/uvm/uvm_map.c @@ -1,5 +1,5 @@ -/* $OpenBSD: uvm_map.c,v 1.27 2001/11/06 13:36:52 art Exp $ */ -/* $NetBSD: uvm_map.c,v 1.80 2000/08/01 00:53:11 wiz Exp $ */ +/* $OpenBSD: uvm_map.c,v 1.28 2001/11/07 01:18:01 art Exp $ */ +/* $NetBSD: uvm_map.c,v 1.81 2000/09/13 15:00:25 thorpej Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -456,16 +456,23 @@ uvm_map_clip_end(map, entry, end) * case [4] is for kernel mappings where we don't know the offset until * we've found a virtual address. note that kernel object offsets are * always relative to vm_map_min(kernel_map). + * + * => if `align' is non-zero, we try to align the virtual address to + * the specified alignment. this is only a hint; if we can't + * do it, the address will be unaligned. this is provided as + * a mechanism for large pages. + * * => XXXCDC: need way to map in external amap? */ int -uvm_map(map, startp, size, uobj, uoffset, flags) +uvm_map(map, startp, size, uobj, uoffset, align, flags) vm_map_t map; vaddr_t *startp; /* IN/OUT */ vsize_t size; struct uvm_object *uobj; voff_t uoffset; + vsize_t align; uvm_flag_t flags; { vm_map_entry_t prev_entry, new_entry; @@ -500,7 +507,7 @@ uvm_map(map, startp, size, uobj, uoffset, flags) vm_map_lock(map); /* could sleep here */ } if ((prev_entry = uvm_map_findspace(map, *startp, size, startp, - uobj, uoffset, flags & UVM_FLAG_FIXED)) == NULL) { + uobj, uoffset, align, flags)) == NULL) { UVMHIST_LOG(maphist,"<- uvm_map_findspace failed!",0,0,0,0); vm_map_unlock(map); return (KERN_NO_SPACE); @@ -775,39 +782,54 @@ uvm_map_lookup_entry(map, address, entry) return (FALSE); } - /* * uvm_map_findspace: find "length" sized space in "map". * - * => "hint" is a hint about where we want it, unless fixed is true - * (in which case we insist on using "hint"). + * => "hint" is a hint about where we want it, unless FINDSPACE_FIXED is + * set (in which case we insist on using "hint"). * => "result" is VA returned * => uobj/uoffset are to be used to handle VAC alignment, if required + * => if `align' is non-zero, we attempt to align to that value. * => caller must at least have read-locked map * => returns NULL on failure, or pointer to prev. map entry if success * => note this is a cross between the old vm_map_findspace and vm_map_find */ vm_map_entry_t -uvm_map_findspace(map, hint, length, result, uobj, uoffset, fixed) +uvm_map_findspace(map, hint, length, result, uobj, uoffset, align, flags) vm_map_t map; vaddr_t hint; vsize_t length; vaddr_t *result; /* OUT */ struct uvm_object *uobj; voff_t uoffset; - boolean_t fixed; + vsize_t align; + int flags; { vm_map_entry_t entry, next, tmp; - vaddr_t end; + vaddr_t end, orig_hint; UVMHIST_FUNC("uvm_map_findspace"); UVMHIST_CALLED(maphist); - UVMHIST_LOG(maphist, "(map=0x%x, hint=0x%x, len=%d, fixed=%d)", - map, hint, length, fixed); + UVMHIST_LOG(maphist, "(map=0x%x, hint=0x%x, len=%d, flags=0x%x)", + map, hint, length, flags); + +#ifdef DIAGNOSTIC + if ((align & (align - 1)) != 0) + panic("uvm_map_findspace: alignment not power of 2"); + if ((flags & UVM_FLAG_FIXED) != 0 && align != 0) + panic("uvm_map_findslace: fixed and alignment both specified"); +#endif + + /* + * remember the original hint. if we are aligning, then we + * may have to try again with no alignment constraint if + * we fail the first time. + */ + orig_hint = hint; if (hint < map->min_offset) { /* check ranges ... */ - if (fixed) { + if (flags & UVM_FLAG_FIXED) { UVMHIST_LOG(maphist,"<- VA below map range",0,0,0,0); return(NULL); } @@ -824,13 +846,13 @@ uvm_map_findspace(map, hint, length, result, uobj, uoffset, fixed) * something at this address, we have to start after it. */ - if (!fixed && hint == map->min_offset) { + if ((flags & UVM_FLAG_FIXED) == 0 && hint == map->min_offset) { if ((entry = map->first_free) != &map->header) hint = entry->end; } else { if (uvm_map_lookup_entry(map, hint, &tmp)) { /* "hint" address already in use ... */ - if (fixed) { + if (flags & UVM_FLAG_FIXED) { UVMHIST_LOG(maphist,"<- fixed & VA in use", 0, 0, 0, 0); return(NULL); @@ -860,18 +882,33 @@ uvm_map_findspace(map, hint, length, result, uobj, uoffset, fixed) * push hint forward as needed to avoid VAC alias problems. * we only do this if a valid offset is specified. */ - if (!fixed && uoffset != UVM_UNKNOWN_OFFSET) - PMAP_PREFER(uoffset, &hint); + if ((flags & UVM_FLAG_FIXED) == 0 && + uoffset != UVM_UNKNOWN_OFFSET) + PMAP_PREFER(uoffset, &hint); #endif + if (align != 0) { + if ((hint & (align - 1)) != 0) + hint = roundup(hint, align); + /* + * XXX Should we PMAP_PREFER() here again? + */ + } end = hint + length; if (end > map->max_offset || end < hint) { UVMHIST_LOG(maphist,"<- failed (off end)", 0,0,0,0); + if (align != 0) { + UVMHIST_LOG(maphist, + "calling recursively, no align", + 0,0,0,0); + return (uvm_map_findspace(map, orig_hint, + length, result, uobj, uoffset, 0, flags)); + } return (NULL); } next = entry->next; if (next == &map->header || next->start >= end) break; - if (fixed) { + if (flags & UVM_FLAG_FIXED) { UVMHIST_LOG(maphist,"<- fixed mapping failed", 0,0,0,0); return(NULL); /* only one shot at it ... */ } @@ -961,7 +998,7 @@ uvm_unmap_remove(map, start, end, entry_list) UVM_MAP_CLIP_END(map, entry, end); next = entry->next; len = entry->end - entry->start; - + /* * unwire before removing addresses from the pmap; otherwise * unwiring will put the entries back into the pmap (XXX). @@ -1156,10 +1193,11 @@ uvm_unmap_detach(first_entry, amap_unref_flags) */ int -uvm_map_reserve(map, size, offset, raddr) +uvm_map_reserve(map, size, offset, align, raddr) vm_map_t map; vsize_t size; - vaddr_t offset; /* hint for pmap_prefer */ + vaddr_t offset; /* hint for pmap_prefer */ + vsize_t align; /* alignment hint */ vaddr_t *raddr; /* IN:hint, OUT: reserved VA */ { UVMHIST_FUNC("uvm_map_reserve"); UVMHIST_CALLED(maphist); @@ -1175,7 +1213,7 @@ uvm_map_reserve(map, size, offset, raddr) * reserve some virtual space. */ - if (uvm_map(map, raddr, size, NULL, offset, + if (uvm_map(map, raddr, size, NULL, offset, 0, UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, UVM_INH_NONE, UVM_ADV_RANDOM, UVM_FLAG_NOMERGE)) != KERN_SUCCESS) { UVMHIST_LOG(maphist, "<- done (no VM)", 0,0,0,0); @@ -1353,7 +1391,7 @@ uvm_map_extract(srcmap, start, len, dstmap, dstaddrp, flags) */ dstaddr = vm_map_min(dstmap); - if (uvm_map_reserve(dstmap, len, start, &dstaddr) == FALSE) + if (uvm_map_reserve(dstmap, len, start, 0, &dstaddr) == FALSE) return(ENOMEM); *dstaddrp = dstaddr; /* pass address back to caller */ UVMHIST_LOG(maphist, " dstaddr=0x%x", dstaddr,0,0,0); diff --git a/sys/uvm/uvm_map.h b/sys/uvm/uvm_map.h index 951c282cfd7..f3ac92f0cdb 100644 --- a/sys/uvm/uvm_map.h +++ b/sys/uvm/uvm_map.h @@ -1,5 +1,5 @@ -/* $OpenBSD: uvm_map.h,v 1.12 2001/11/06 13:36:52 art Exp $ */ -/* $NetBSD: uvm_map.h,v 1.21 2000/08/16 16:32:06 thorpej Exp $ */ +/* $OpenBSD: uvm_map.h,v 1.13 2001/11/07 01:18:01 art Exp $ */ +/* $NetBSD: uvm_map.h,v 1.22 2000/09/13 15:00:25 thorpej Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -330,7 +330,7 @@ vm_map_t uvm_map_create __P((pmap_t, vaddr_t, vaddr_t, int)); int uvm_map_extract __P((vm_map_t, vaddr_t, vsize_t, vm_map_t, vaddr_t *, int)); vm_map_entry_t uvm_map_findspace __P((vm_map_t, vaddr_t, vsize_t, vaddr_t *, - struct uvm_object *, voff_t, boolean_t)); + struct uvm_object *, voff_t, vsize_t, int)); int uvm_map_inherit __P((vm_map_t, vaddr_t, vaddr_t, vm_inherit_t)); int uvm_map_advice __P((vm_map_t, vaddr_t, vaddr_t, int)); void uvm_map_init __P((void)); @@ -339,7 +339,8 @@ MAP_INLINE void uvm_map_reference __P((vm_map_t)); int uvm_map_replace __P((vm_map_t, vaddr_t, vaddr_t, vm_map_entry_t, int)); -int uvm_map_reserve __P((vm_map_t, vsize_t, vaddr_t, vaddr_t *)); +int uvm_map_reserve __P((vm_map_t, vsize_t, vaddr_t, vsize_t, + vaddr_t *)); void uvm_map_setup __P((vm_map_t, vaddr_t, vaddr_t, int)); int uvm_map_submap __P((vm_map_t, vaddr_t, vaddr_t, vm_map_t)); MAP_INLINE diff --git a/sys/uvm/uvm_mmap.c b/sys/uvm/uvm_mmap.c index 44b831447fe..2aba0283ac7 100644 --- a/sys/uvm/uvm_mmap.c +++ b/sys/uvm/uvm_mmap.c @@ -1,5 +1,5 @@ -/* $OpenBSD: uvm_mmap.c,v 1.23 2001/11/06 01:35:04 art Exp $ */ -/* $NetBSD: uvm_mmap.c,v 1.43 2000/06/27 17:29:28 mrg Exp $ */ +/* $OpenBSD: uvm_mmap.c,v 1.24 2001/11/07 01:18:01 art Exp $ */ +/* $NetBSD: uvm_mmap.c,v 1.44 2000/09/13 15:00:25 thorpej Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -1211,7 +1211,7 @@ uvm_mmap(map, addr, size, prot, maxprot, flags, handle, foff, locklimit) * do it! */ - retval = uvm_map(map, addr, size, uobj, foff, uvmflag); + retval = uvm_map(map, addr, size, uobj, foff, 0, uvmflag); if (retval == KERN_SUCCESS) { /* diff --git a/sys/uvm/uvm_page.c b/sys/uvm/uvm_page.c index 1c2e7157baf..bc80f041f57 100644 --- a/sys/uvm/uvm_page.c +++ b/sys/uvm/uvm_page.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_page.c,v 1.27 2001/11/06 13:36:52 art Exp $ */ +/* $OpenBSD: uvm_page.c,v 1.28 2001/11/07 01:18:01 art Exp $ */ /* $NetBSD: uvm_page.c,v 1.40 2000/08/02 20:25:11 thorpej Exp $ */ /* @@ -1070,7 +1070,7 @@ uvm_pagealloc_contig(size, low, high, alignment) &pglist, 1, FALSE)) return 0; addr = vm_map_min(kernel_map); - if (uvm_map(kernel_map, &addr, size, NULL, UVM_UNKNOWN_OFFSET, + if (uvm_map(kernel_map, &addr, size, NULL, UVM_UNKNOWN_OFFSET, 0, UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_NONE, UVM_ADV_RANDOM, 0)) != KERN_SUCCESS) { uvm_pglistfree(&pglist); diff --git a/sys/uvm/uvm_pager.c b/sys/uvm/uvm_pager.c index 15dce897e17..1ac5457b1fa 100644 --- a/sys/uvm/uvm_pager.c +++ b/sys/uvm/uvm_pager.c @@ -1,5 +1,5 @@ -/* $OpenBSD: uvm_pager.c,v 1.18 2001/11/06 01:35:04 art Exp $ */ -/* $NetBSD: uvm_pager.c,v 1.32 2000/06/27 17:29:32 mrg Exp $ */ +/* $OpenBSD: uvm_pager.c,v 1.19 2001/11/07 01:18:01 art Exp $ */ +/* $NetBSD: uvm_pager.c,v 1.33 2000/09/13 15:00:25 thorpej Exp $ */ /* * @@ -153,7 +153,7 @@ ReStart: kva = 0; /* let system choose VA */ if (uvm_map(pager_map, &kva, size, NULL, - UVM_UNKNOWN_OFFSET, UVM_FLAG_NOMERGE) != KERN_SUCCESS) { + UVM_UNKNOWN_OFFSET, 0, UVM_FLAG_NOMERGE) != KERN_SUCCESS) { if ((flags & UVMPAGER_MAPIN_WAITOK) == 0) { if (aio) FREE(aio, M_TEMP); diff --git a/sys/uvm/uvm_unix.c b/sys/uvm/uvm_unix.c index 1cccce72d29..294b28b0c98 100644 --- a/sys/uvm/uvm_unix.c +++ b/sys/uvm/uvm_unix.c @@ -1,5 +1,5 @@ -/* $OpenBSD: uvm_unix.c,v 1.15 2001/11/06 13:36:52 art Exp $ */ -/* $NetBSD: uvm_unix.c,v 1.17 2000/09/07 05:01:43 chs Exp $ */ +/* $OpenBSD: uvm_unix.c,v 1.16 2001/11/07 01:18:01 art Exp $ */ +/* $NetBSD: uvm_unix.c,v 1.18 2000/09/13 15:00:25 thorpej Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -96,7 +96,7 @@ sys_obreak(p, v, retval) */ if (diff > 0) { rv = uvm_map(&vm->vm_map, &old, diff, NULL, UVM_UNKNOWN_OFFSET, - UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_COPY, + 0, UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_COPY, UVM_ADV_NORMAL, UVM_FLAG_AMAPPAD|UVM_FLAG_FIXED| UVM_FLAG_OVERLAY|UVM_FLAG_COPYONW)); if (rv == KERN_SUCCESS) { |