From: deraadt Date: Thu, 14 Dec 1995 05:16:06 +0000 (+0000) Subject: from netbsd: X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=9444ad3226a7cf2ca524af39dbb7c20a4b4339f4;p=openbsd from netbsd: 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. Only expect vm_fork() to return if __FORK_BRAINDAMAGE is defined. Eliminate unused third arg to vm_fork(). --- diff --git a/sys/vm/vm_extern.h b/sys/vm/vm_extern.h index 91e0417c78f..cca6f755a64 100644 --- a/sys/vm/vm_extern.h +++ b/sys/vm/vm_extern.h @@ -1,4 +1,4 @@ -/* $NetBSD: vm_extern.h,v 1.14 1995/09/27 20:30:17 thorpej Exp $ */ +/* $NetBSD: vm_extern.h,v 1.15 1995/12/09 04:28:16 mycroft Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -103,7 +103,11 @@ void vm_fault_copy_entry __P((vm_map_t, vm_map_t, vm_map_entry_t, vm_map_entry_t)); void vm_fault_unwire __P((vm_map_t, vm_offset_t, vm_offset_t)); int vm_fault_wire __P((vm_map_t, vm_offset_t, vm_offset_t)); -int vm_fork __P((struct proc *, struct proc *, int)); +#ifdef __FORK_BRAINDAMAGE +int vm_fork __P((struct proc *, struct proc *)); +#else +void vm_fork __P((struct proc *, struct proc *)); +#endif int vm_inherit __P((vm_map_t, vm_offset_t, vm_size_t, vm_inherit_t)); void vm_init_limits __P((struct proc *)); diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c index e8a668ec61f..08927c41330 100644 --- a/sys/vm/vm_glue.c +++ b/sys/vm/vm_glue.c @@ -1,4 +1,4 @@ -/* $NetBSD: vm_glue.c,v 1.46 1995/05/05 03:35:39 cgd Exp $ */ +/* $NetBSD: vm_glue.c,v 1.48 1995/12/09 04:28:19 mycroft Exp $ */ /* * Copyright (c) 1991, 1993 @@ -202,10 +202,13 @@ vsunlock(addr, len, dirtied) * after cpu_fork returns in the child process. We do nothing here * after cpu_fork returns. */ +#ifdef __FORK_BRAINDAMAGE int -vm_fork(p1, p2, isvfork) +#else +void +#endif +vm_fork(p1, p2) register struct proc *p1, *p2; - int isvfork; { register struct user *up; vm_offset_t addr; @@ -222,18 +225,14 @@ vm_fork(p1, p2, isvfork) #ifdef SYSVSHM if (p1->p_vmspace->vm_shm) - shmfork(p1, p2, isvfork); + shmfork(p1, p2); #endif #if !defined(i386) && !defined(pc532) /* * Allocate a wired-down (for now) pcb and kernel stack for the process */ -#ifdef pica - addr = kmem_alloc_upage(kernel_map, USPACE); -#else addr = kmem_alloc_pageable(kernel_map, USPACE); -#endif if (addr == 0) panic("vm_fork: no more kernel virtual memory"); vm_map_pageable(kernel_map, addr, addr + USPACE, FALSE); @@ -276,6 +275,8 @@ vm_fork(p1, p2, isvfork) (void)vm_map_inherit(vp, addr, VM_MAX_ADDRESS, VM_INHERIT_NONE); } #endif + +#ifdef __FORK_BRAINDAMAGE /* * cpu_fork will copy and update the kernel stack and pcb, * and make the child ready to run. It marks the child @@ -284,6 +285,15 @@ vm_fork(p1, p2, isvfork) * once in the child. */ return (cpu_fork(p1, p2)); +#else + /* + * cpu_fork will copy and update the kernel stack and pcb, + * and make the child ready to run. The child will exit + * directly to user mode on its first time slice, and will + * not return here. + */ + cpu_fork(p1, p2); +#endif } /* @@ -339,7 +349,7 @@ swapin(p) cpu_swapin(p); s = splstatclock(); if (p->p_stat == SRUN) - setrunqueue(p); + setrunqueue(p); p->p_flag |= P_INMEM; splx(s); p->p_swtime = 0; @@ -399,10 +409,6 @@ loop: printf("swapin: pid %d(%s)@%x, pri %d free %d\n", p->p_pid, p->p_comm, p->p_addr, ppri, cnt.v_free_count); -#endif -#ifdef pica - vm_map_pageable(kernel_map, (vm_offset_t)p->p_addr, - (vm_offset_t)p->p_addr + atop(USPACE), FALSE); #endif swapin(p); goto loop; diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index ea205439963..016dbc9565e 100644 --- a/sys/vm/vm_mmap.c +++ b/sys/vm/vm_mmap.c @@ -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. */ - 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); diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index 2dc50bb47c8..81bb806cfa8 100644 --- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -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.31 1995/12/06 00:38:11 pk Exp $ */ /* * Copyright (c) 1991, 1993 @@ -1418,17 +1418,17 @@ vm_object_prefer(object, offset, addr) register vm_page_t p; register vm_offset_t paddr; +#ifdef PMAP_PREFER if (object == NULL) - return; + goto first_map; -#ifdef PMAP_PREFER - vm_object_lock(object); /* * Look for the first page that the pmap layer has something * to say about. Since an object maps a contiguous range of * virutal addresses, this will determine the preferred origin * of the proposed mapping. */ + vm_object_lock(object); for (p = object->memq.tqh_first; p != NULL; p = p->listq.tqe_next) { if (p->flags & (PG_FAKE | PG_FICTITIOUS)) continue; @@ -1436,9 +1436,20 @@ vm_object_prefer(object, offset, addr) if (paddr == (vm_offset_t)-1) continue; *addr = paddr - (p->offset - offset); - break; + vm_object_unlock(object); + return; } vm_object_unlock(object); + +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; + #endif } /* diff --git a/sys/vm/vm_user.c b/sys/vm/vm_user.c index 26d8730445e..e0569fe2eff 100644 --- a/sys/vm/vm_user.c +++ b/sys/vm/vm_user.c @@ -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)