vm_init.c revision 252330
152284Sobrien/*- 252284Sobrien * Copyright (c) 1991, 1993 352284Sobrien * The Regents of the University of California. All rights reserved. 452284Sobrien * 552284Sobrien * This code is derived from software contributed to Berkeley by 652284Sobrien * The Mach Operating System project at Carnegie-Mellon University. 752284Sobrien * 852284Sobrien * Redistribution and use in source and binary forms, with or without 952284Sobrien * modification, are permitted provided that the following conditions 1052284Sobrien * are met: 1152284Sobrien * 1. Redistributions of source code must retain the above copyright 1252284Sobrien * notice, this list of conditions and the following disclaimer. 1352284Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1452284Sobrien * notice, this list of conditions and the following disclaimer in the 1552284Sobrien * documentation and/or other materials provided with the distribution. 1652284Sobrien * 4. Neither the name of the University nor the names of its contributors 1752284Sobrien * may be used to endorse or promote products derived from this software 1852284Sobrien * without specific prior written permission. 1952284Sobrien * 2052284Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2152284Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2252284Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2352284Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2452284Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2552284Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2652284Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2752284Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2852284Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2952284Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3052284Sobrien * SUCH DAMAGE. 3152284Sobrien * 3252284Sobrien * from: @(#)vm_init.c 8.1 (Berkeley) 6/11/93 3352284Sobrien * 3452284Sobrien * 3552284Sobrien * Copyright (c) 1987, 1990 Carnegie-Mellon University. 3652284Sobrien * All rights reserved. 3752284Sobrien * 3852284Sobrien * Authors: Avadis Tevanian, Jr., Michael Wayne Young 3952284Sobrien * 4052284Sobrien * Permission to use, copy, modify and distribute this software and 4152284Sobrien * its documentation is hereby granted, provided that both the copyright 4252284Sobrien * notice and this permission notice appear in all copies of the 4352284Sobrien * software, derivative works or modified versions, and any portions 4452284Sobrien * thereof, and that both notices appear in supporting documentation. 4552284Sobrien * 4652284Sobrien * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 4752284Sobrien * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 4852284Sobrien * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 4952284Sobrien * 5052284Sobrien * Carnegie Mellon requests users of this software to return to 5152284Sobrien * 5252284Sobrien * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 5352284Sobrien * School of Computer Science 5452284Sobrien * Carnegie Mellon University 5552284Sobrien * Pittsburgh PA 15213-3890 5652284Sobrien * 5752284Sobrien * any improvements or extensions that they make and grant Carnegie the 5852284Sobrien * rights to redistribute these changes. 5952284Sobrien */ 6052284Sobrien 6152284Sobrien/* 6252284Sobrien * Initialize the Virtual Memory subsystem. 6352284Sobrien */ 6452284Sobrien 6552284Sobrien#include <sys/cdefs.h> 6652284Sobrien__FBSDID("$FreeBSD: head/sys/vm/vm_init.c 252330 2013-06-28 03:51:20Z jeff $"); 6752284Sobrien 6852284Sobrien#include <sys/param.h> 6952284Sobrien#include <sys/kernel.h> 7052284Sobrien#include <sys/lock.h> 7152284Sobrien#include <sys/proc.h> 7252284Sobrien#include <sys/rwlock.h> 7352284Sobrien#include <sys/sysctl.h> 7452284Sobrien#include <sys/systm.h> 7552284Sobrien#include <sys/selinfo.h> 7652284Sobrien#include <sys/pipe.h> 7752284Sobrien#include <sys/bio.h> 7852284Sobrien#include <sys/buf.h> 7952284Sobrien#include <sys/vmem.h> 8052284Sobrien 8152284Sobrien#include <vm/vm.h> 8252284Sobrien#include <vm/vm_param.h> 8352284Sobrien#include <vm/vm_kern.h> 8452284Sobrien#include <vm/vm_object.h> 8552284Sobrien#include <vm/vm_page.h> 8652284Sobrien#include <vm/vm_map.h> 8752284Sobrien#include <vm/vm_pager.h> 8852284Sobrien#include <vm/vm_extern.h> 8952284Sobrien 9052284Sobrienlong physmem; 9152284Sobrien 9252284Sobrienstatic int exec_map_entries = 16; 9352284SobrienTUNABLE_INT("vm.exec_map_entries", &exec_map_entries); 9452284SobrienSYSCTL_INT(_vm, OID_AUTO, exec_map_entries, CTLFLAG_RD, &exec_map_entries, 0, 9552284Sobrien "Maximum number of simultaneous execs"); 9652284Sobrien 9752284Sobrien/* 9852284Sobrien * System initialization 9952284Sobrien */ 10052284Sobrienstatic void vm_mem_init(void *); 10152284SobrienSYSINIT(vm_mem, SI_SUB_VM, SI_ORDER_FIRST, vm_mem_init, NULL); 10252284Sobrien 10352284Sobrien/* 10452284Sobrien * vm_init initializes the virtual memory system. 10552284Sobrien * This is done only by the first cpu up. 10652284Sobrien * 10752284Sobrien * The start and end address of physical memory is passed in. 10852284Sobrien */ 10952284Sobrien/* ARGSUSED*/ 11052284Sobrienstatic void 11152284Sobrienvm_mem_init(dummy) 11252284Sobrien void *dummy; 11352284Sobrien{ 11452284Sobrien /* 11552284Sobrien * Initializes resident memory structures. From here on, all physical 11652284Sobrien * memory is accounted for, and we use only virtual addresses. 11752284Sobrien */ 11852284Sobrien vm_set_page_size(); 11952284Sobrien virtual_avail = vm_page_startup(virtual_avail); 12052284Sobrien 12152284Sobrien /* 12252284Sobrien * Initialize other VM packages 12352284Sobrien */ 12452284Sobrien vmem_startup(); 12552284Sobrien vm_object_init(); 12652284Sobrien vm_map_startup(); 12752284Sobrien kmem_init(virtual_avail, virtual_end); 12852284Sobrien pmap_init(); 12952284Sobrien vm_pager_init(); 13052284Sobrien} 13152284Sobrien 13252284Sobrienvoid 13352284Sobrienvm_ksubmap_init(struct kva_md_info *kmi) 13452284Sobrien{ 13552284Sobrien vm_offset_t firstaddr; 13652284Sobrien caddr_t v; 13752284Sobrien vm_size_t size = 0; 13852284Sobrien long physmem_est; 13952284Sobrien vm_offset_t minaddr; 14052284Sobrien vm_offset_t maxaddr; 14152284Sobrien vm_map_t clean_map; 14252284Sobrien 14352284Sobrien /* 14452284Sobrien * Allocate space for system data structures. 14552284Sobrien * The first available kernel virtual address is in "v". 14652284Sobrien * As pages of kernel virtual memory are allocated, "v" is incremented. 14752284Sobrien * As pages of memory are allocated and cleared, 14852284Sobrien * "firstaddr" is incremented. 14952284Sobrien * An index into the kernel page table corresponding to the 15052284Sobrien * virtual memory address maintained in "v" is kept in "mapaddr". 15152284Sobrien */ 15252284Sobrien 15352284Sobrien /* 15452284Sobrien * Make two passes. The first pass calculates how much memory is 15552284Sobrien * needed and allocates it. The second pass assigns virtual 15652284Sobrien * addresses to the various data structures. 15752284Sobrien */ 15852284Sobrien firstaddr = 0; 15952284Sobrienagain: 16052284Sobrien v = (caddr_t)firstaddr; 16152284Sobrien 16252284Sobrien /* 16352284Sobrien * Discount the physical memory larger than the size of kernel_map 16452284Sobrien * to avoid eating up all of KVA space. 16552284Sobrien */ 16652284Sobrien physmem_est = lmin(physmem, btoc(kernel_map->max_offset - 16752284Sobrien kernel_map->min_offset)); 16852284Sobrien 16952284Sobrien v = kern_vfs_bio_buffer_alloc(v, physmem_est); 17052284Sobrien 17152284Sobrien /* 17252284Sobrien * End of first pass, size has been calculated so allocate memory 17352284Sobrien */ 17452284Sobrien if (firstaddr == 0) { 17552284Sobrien size = (vm_size_t)v; 17652284Sobrien firstaddr = kmem_alloc(kernel_map, round_page(size)); 17752284Sobrien if (firstaddr == 0) 17852284Sobrien panic("startup: no room for tables"); 17952284Sobrien goto again; 18052284Sobrien } 18152284Sobrien 18252284Sobrien /* 18352284Sobrien * End of second pass, addresses have been assigned 18452284Sobrien */ 18552284Sobrien if ((vm_size_t)((char *)v - firstaddr) != size) 18652284Sobrien panic("startup: table size inconsistency"); 18752284Sobrien 18852284Sobrien size = (long)nbuf * BKVASIZE + (long)nswbuf * MAXPHYS + 18952284Sobrien (long)bio_transient_maxcnt * MAXPHYS; 19052284Sobrien clean_map = kmem_suballoc(kernel_map, &kmi->clean_sva, &kmi->clean_eva, 19152284Sobrien size, TRUE); 19252284Sobrien 19352284Sobrien size = (long)nbuf * BKVASIZE; 19452284Sobrien kmi->buffer_sva = kmem_alloc_nofault(clean_map, size); 19552284Sobrien kmi->buffer_eva = kmi->buffer_sva + size; 19652284Sobrien vmem_init(buffer_arena, "buffer arena", kmi->buffer_sva, size, 19752284Sobrien PAGE_SIZE, 0, 0); 19852284Sobrien 19952284Sobrien size = (long)nswbuf * MAXPHYS; 20052284Sobrien swapbkva = kmem_alloc_nofault(clean_map, size); 20152284Sobrien if (!swapbkva) 20252284Sobrien panic("Not enough clean_map VM space for pager buffers"); 20352284Sobrien 20452284Sobrien if (bio_transient_maxcnt != 0) { 20552284Sobrien size = (long)bio_transient_maxcnt * MAXPHYS; 20652284Sobrien vmem_init(transient_arena, "transient arena", 20752284Sobrien kmem_alloc_nofault(clean_map, size), 20852284Sobrien size, PAGE_SIZE, 0, 0); 20952284Sobrien } 21052284Sobrien exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, 21152284Sobrien exec_map_entries * round_page(PATH_MAX + ARG_MAX), FALSE); 21252284Sobrien pipe_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, maxpipekva, 21352284Sobrien FALSE); 21452284Sobrien} 21552284Sobrien 21652284Sobrien