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:
pk 1995-12-05 22:54:36 +00:00
parent 9c784e07c1
commit 801712f01a
3 changed files with 60 additions and 25 deletions

View File

@ -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);

View File

@ -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
}

View File

@ -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)