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