Extend use of vm_object_prefer() to vm_allocate_with_pager().
Make vm_object_prefer() call MD aligner for "pageless" objects too, so we can have more control over the virtual address to be used. Implementation could be simpler if we by-pass the object to mapped, but we'd loose the ability to adapt alignment to objects that were previously mmap'ed with MAP_FIXED on.
This commit is contained in:
parent
9c784e07c1
commit
801712f01a
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: vm_mmap.c,v 1.42 1995/10/10 01:27:11 mycroft Exp $ */
|
||||
/* $NetBSD: vm_mmap.c,v 1.43 1995/12/05 22:54:42 pk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 University of Utah.
|
||||
@ -827,15 +827,13 @@ vm_mmap(map, addr, size, prot, maxprot, flags, handle, foff)
|
||||
vm_offset_t off;
|
||||
|
||||
/* locate and allocate the target address space */
|
||||
vm_map_lock(map);
|
||||
if (fitit) {
|
||||
/*
|
||||
* We cannot call vm_map_find() because
|
||||
* a proposed address may be vetoed by
|
||||
* the pmap module.
|
||||
* So we look for space ourselves, validate
|
||||
* it and insert it into the map.
|
||||
* Find space in the map at a location
|
||||
* that is compatible with the object/offset
|
||||
* we're going to attach there.
|
||||
*/
|
||||
vm_map_lock(map);
|
||||
again:
|
||||
if (vm_map_findspace(map, *addr, size,
|
||||
addr) == 1) {
|
||||
@ -843,33 +841,40 @@ vm_mmap(map, addr, size, prot, maxprot, flags, handle, foff)
|
||||
} else {
|
||||
vm_object_prefer(object, foff, addr);
|
||||
rv = vm_map_insert(map, NULL,
|
||||
(vm_offset_t)0,
|
||||
*addr, *addr+size);
|
||||
(vm_offset_t)0,
|
||||
*addr, *addr+size);
|
||||
/*
|
||||
* vm_map_insert() may fail if
|
||||
* vm_object_prefer() has altered
|
||||
* the initial address.
|
||||
* If so, we start again.
|
||||
*/
|
||||
if (rv == KERN_NO_SPACE)
|
||||
/*
|
||||
* Modified address didn't fit
|
||||
* after all, the gap must
|
||||
* have been to small.
|
||||
*/
|
||||
goto again;
|
||||
}
|
||||
vm_map_unlock(map);
|
||||
} else {
|
||||
rv = vm_map_find(map, NULL, (vm_offset_t)0,
|
||||
addr, size, 0);
|
||||
rv = vm_map_insert(map, NULL, (vm_offset_t)0,
|
||||
*addr, *addr + size);
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* Check against PMAP preferred address. If
|
||||
* there's a mismatch, these pages should not
|
||||
* be shared with others. <howto?>
|
||||
*/
|
||||
if (rv == KERN_SUCCESS) {
|
||||
if (rv == KERN_SUCCESS &&
|
||||
(mmapdebug & MDB_MAPIT)) {
|
||||
vm_offset_t paddr = *addr;
|
||||
vm_object_prefer(object, foff, &paddr);
|
||||
if (paddr != *addr)
|
||||
printf("vm_mmap: pmap botch!\n");
|
||||
printf(
|
||||
"vm_mmap: pmap botch! "
|
||||
"[foff %x, addr %x, paddr %x]\n",
|
||||
foff, *addr, paddr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
vm_map_unlock(map);
|
||||
|
||||
if (rv != KERN_SUCCESS) {
|
||||
vm_object_deallocate(object);
|
||||
@ -879,7 +884,7 @@ vm_mmap(map, addr, size, prot, maxprot, flags, handle, foff)
|
||||
VM_MIN_ADDRESS+size, TRUE);
|
||||
off = VM_MIN_ADDRESS;
|
||||
rv = vm_allocate_with_pager(tmap, &off, size,
|
||||
TRUE, pager,
|
||||
FALSE, pager,
|
||||
foff, FALSE);
|
||||
if (rv != KERN_SUCCESS) {
|
||||
vm_object_deallocate(object);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: vm_object.c,v 1.29 1995/07/13 12:35:29 pk Exp $ */
|
||||
/* $NetBSD: vm_object.c,v 1.30 1995/12/05 22:54:36 pk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1991, 1993
|
||||
@ -1419,7 +1419,7 @@ vm_object_prefer(object, offset, addr)
|
||||
register vm_offset_t paddr;
|
||||
|
||||
if (object == NULL)
|
||||
return;
|
||||
goto first_map;
|
||||
|
||||
#ifdef PMAP_PREFER
|
||||
vm_object_lock(object);
|
||||
@ -1436,8 +1436,19 @@ vm_object_prefer(object, offset, addr)
|
||||
if (paddr == (vm_offset_t)-1)
|
||||
continue;
|
||||
*addr = paddr - (p->offset - offset);
|
||||
break;
|
||||
vm_object_unlock(object);
|
||||
return;
|
||||
}
|
||||
|
||||
first_map:
|
||||
/*
|
||||
* No physical page attached; ask for a preferred address based
|
||||
* only on the given virtual address.
|
||||
*/
|
||||
paddr = PMAP_PREFER((vm_offset_t)-1, *addr);
|
||||
if (paddr != (vm_offset_t)-1)
|
||||
*addr = paddr;
|
||||
|
||||
vm_object_unlock(object);
|
||||
#endif
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: vm_user.c,v 1.11 1994/10/20 04:27:34 cgd Exp $ */
|
||||
/* $NetBSD: vm_user.c,v 1.12 1995/12/05 22:54:39 pk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1991, 1993
|
||||
@ -276,6 +276,7 @@ vm_allocate_with_pager(map, addr, size, anywhere, pager, poffset, internal)
|
||||
{
|
||||
register vm_object_t object;
|
||||
register int result;
|
||||
vm_offset_t start;
|
||||
|
||||
if (map == NULL)
|
||||
return(KERN_INVALID_ARGUMENT);
|
||||
@ -309,7 +310,25 @@ vm_allocate_with_pager(map, addr, size, anywhere, pager, poffset, internal)
|
||||
cnt.v_nzfod -= atop(size);
|
||||
}
|
||||
|
||||
result = vm_map_find(map, object, poffset, addr, size, anywhere);
|
||||
start = *addr;
|
||||
vm_map_lock(map);
|
||||
if (anywhere) {
|
||||
again:
|
||||
if (vm_map_findspace(map, start, size, addr))
|
||||
result = KERN_NO_SPACE;
|
||||
else {
|
||||
vm_object_prefer(object, poffset, addr);
|
||||
start = *addr;
|
||||
result = vm_map_insert(map, object, poffset,
|
||||
start, start + size);
|
||||
if (result == KERN_NO_SPACE)
|
||||
goto again;
|
||||
}
|
||||
} else
|
||||
result = vm_map_insert(map, object, poffset,
|
||||
start, start + size);
|
||||
vm_map_unlock(map);
|
||||
|
||||
if (result != KERN_SUCCESS)
|
||||
vm_object_deallocate(object);
|
||||
else if (pager != NULL)
|
||||
|
Loading…
Reference in New Issue
Block a user