Source to osfmk/default_pager/default_pager.c
/*
* Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* The contents of this file constitute Original Code as defined in and
* are subject to the Apple Public Source License Version 1.1 (the
* "License"). You may not use this file except in compliance with the
* License. Please obtain a copy of the License at
* http://www.apple.com/publicsource and read it before using this file.
*
* This Original Code and all software distributed under the License are
* distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* @OSF_COPYRIGHT@
*/
/*
* HISTORY
* $Log: default_pager.c,v $
* Revision 1.1.1.1 2000/03/25 21:02:54 wsanchez
* Import of xnu-68.4
*
* Revision 1.5 2000/01/26 05:56:22 wsanchez
* Add APSL
*
* Revision 1.4 1999/07/20 02:55:34 lindak
* Merged PR-2291281-1 into Beaker (magee Kernel Components kobject groupings)
*
* Revision 1.3.674.1 1999/07/20 00:33:02 jmagee
* Workaround for partial EMMI components work
*
* Revision 1.3 1999/02/24 16:55:12 wsanchez
* PR-2308031
*
* Revision 1.2.168.1 1999/02/23 20:43:52 semeria
* Component Header files phase 1
*
* Revision 1.2 1998/12/01 00:24:41 wsanchez
* Merged in CDY_DP1 (chris: default pager)
*
* Revision 1.1.2.2 1998/11/25 21:32:17 youngwor
* fix errant comment format
*
* Revision 1.1.2.1 1998/11/24 22:39:57 youngwor
* Check-in of support for the in-kernel default pager
*
* Revision 1.1.1.1 1998/03/07 02:26:31 wsanchez
* Import of OSF Mach kernel (~mburg)
*
* Revision 1.2.84.2 1997/03/27 18:45:15 barbou
* submit adidtional picco changes
* [1996/09/12 22:09:29 robert]
* AXP pool merge.
* [97/02/25 barbou]
*
* Revision 1.2.84.1 1996/11/29 16:54:38 stephen
* nmklinux_1.0b3_shared into pmk1.1
* Added -v option (verbose flag) and tests before warning printfs
* [1996/07/29 12:25:54 stephen]
*
* Revision 1.2.34.16 1996/07/31 06:41:45 paire
* Merged with nmk20b7_shared (1.2.77.1)
* [96/05/30 paire]
*
* Revision 1.2.77.1 1996/04/12 06:30:58 paire
* Changed signature of default_pager_thread to (void ()(void *)).
* Replaced bzero() by memset().
* [96/01/30 paire]
*
* Revision 1.2.34.15 1995/08/21 20:52:09 devrcs
* Initialize dpt_initialized_p element of
* default_pager_thread_tb and set it to true after thread starts
* up. Wait until all threads have signalled ready before
* telling the bootstrap process that it's ok to go ahead.
* [95/07/10 randys]
*
* Revision 1.2.34.14 1995/06/12 18:44:00 dwm
* ri-osc CR1394 - allow argument from bootstrap to set cluster size,
* Usage: default_pager clsize=4 sd0b, for example
* [1995/06/12 18:40:21 dwm]
*
* Revision 1.2.34.13 1995/05/31 07:55:10 emcmanus
* Use mach_msg instead of mach_msg_overwrite_trap so that message
* operations can be interrupted without provoking a default-pager
* panic. Remote gdb does this.
* [1995/05/31 07:54:21 emcmanus]
*
* Revision 1.2.34.12 1995/05/25 20:36:39 mmp
* Removed TEMPORARILY_USE_OLD_INIT and the !TEMPORARILY_USE_OLD_INIT
* code. The change to use m_o_init was not temporary.
* [1995/05/25 19:59:17 mmp]
*
* Revision 1.2.34.11 1995/04/07 18:50:57 barbou
* Merged into mainline:
* Revision 1.2.34.10 1995/02/27 18:24:08 mmp
* Replaced m_o_notify with m_o_init; used m_o_change_attributes
* instead of m_o_establish; removed m_o_rejected.
* [1995/02/27 18:22:40 mmp]
* Revision 1.2.34.9 1995/02/23 21:15:48 alanl
* Use system_priority instead of server_priority. Fix locking
* with regards to pager_extend!
* Merged with DIPC2_SHARED.
* [1995/02/23 21:14:55 alanl]
* [95/03/08 barbou]
*
* VM-MK6 Merge.
* Started from the modified b26 file.
* Integrated the following MK6 changes:
*
* Fix ri-osc CR846: Avoid use of fixed BASEPRI_SYSTEM; use new
* host_info() interface to determine priority dynamically.
* [1994/12/23 15:39:32 bolinger]
* mk6 CR668 - 1.3b26 merge
* Correct local btodb() def; change port_to_ds() et al. to work
* with port names returned by current merged kernel.
* [1994/12/03 02:10:30 bolinger]
* mk6 CR668 - 1.3b26 merge
* Did not bring forward PAGING_MEMORY support. Did bring forward
* NORMA support -- can be deleted when proven no longer needed.
* [1994/11/10 15:32:12 bolinger]
* [95/01/10 barbou]
* [95/03/08 barbou]
*
* Revision 1.2.56.2 1995/02/13 14:40:41 barbou
* VM-MK6 Merge.
* Started from the modified b26 file.
* Integrated the following MK6 changes:
*
* Fix ri-osc CR846: Avoid use of fixed BASEPRI_SYSTEM; use new
* host_info() interface to determine priority dynamically.
* [1994/12/23 15:39:32 bolinger]
* mk6 CR668 - 1.3b26 merge
* Correct local btodb() def; change port_to_ds() et al. to work
* with port names returned by current merged kernel.
* [1994/12/03 02:10:30 bolinger]
* mk6 CR668 - 1.3b26 merge
* Did not bring forward PAGING_MEMORY support. Did bring forward
* NORMA support -- can be deleted when proven no longer needed.
* [1994/11/10 15:32:12 bolinger]
* [95/01/10 barbou]
*
* Revision 1.2.46.3 1994/11/02 14:57:23 barbou
* Use new task_swappable() interface to make our task unswappable.
* [94/11/02 barbou]
*
* Revision 1.2.46.2 1994/10/10 15:28:48 barbou
* VM Merge - Default Pager Clustering.
*
* Also split this file in three:
* default_pager.c contains code that deals with threads and
* incoming messages.
* dp_memory_object.c contains memory object management code.
* dp_backing_store.c contains backing store management code.
* [94/10/10 barbou]
*
* Revision 1.2.6.23 1994/05/16 16:43:50 jph
* CR8809 -- Fix messages when paging space is exhausted.
* CR10905 -- Disallow overlapped paging areas.
* [1994/05/16 16:43:04 jph]
*
* Revision 1.2.6.22 1994/04/01 18:42:34 jph
* CR10550 -- Add backing store info interfaces.
* CR10718 -- Fix pagein error path.
* [1994/04/01 18:40:13 jph]
*
* Revision 1.2.6.21 1994/03/04 18:34:49 jeffc
* CR10636 -- delete all NMK15_COMPAT support.
* [1994/03/04 14:50:44 jeffc]
*
* Revision 1.2.6.20 1994/02/16 14:22:24 jph
* CR10554 -- Multi-page requests now handled, albeit crudely.
* Fixed leak in data_request for partial page reads.
* Tidied up code to be at least consistent.
* Fixed ASSERTIONS option and bad assert (name_refs in terminate).
* [1994/02/16 14:20:47 jph]
*
* Revision 1.2.6.19 1994/02/07 22:41:25 jph
* Merged with changes from 1.2.6.18
* [1994/02/07 22:40:25 jph]
*
* CR10433 -- Upgrade default pager.
* Add device argument capability.
* Removed defunct file_io.h reference.
* Replaced pager_{lock_init,lock,unlock,lock_try} macros.
* Moved cthreads globals to top of file from middle.
* Removed "id" field of "partition_t" - not needed.
* Added "device", "offset", "count" and "record_shift" fields
* to "partition_t" to record backing store device info.
* Removed "p_read", "p_write" and "p_private" fields from
* "partition_t" - Unneeded filesystem abstraction.
* Merge "struct dstruct" fields into the "struct dpager",
* delete "struct dstruct" and "default_pager_t".
* Added "struct bstruct" and "all_backing_store" to hold list
* of all backing store ports.
* Simplify arguments to create_paging_partition().
* Delete part_id(), add_paging_file() and default_pager_setup() routines.
* Added backing_store_port_alloc(), log2() routine.
* Added vm_page_mask and vm_page_shift to augment vm_page_size.
* [1994/02/07 22:28:15 jph]
*
* Revision 1.2.6.18 1994/02/01 19:44:38 collins
* CR9926: Set the default pager scheduling policy to round-robin with
* a priority of BASEPRI_SYSTEM.
* [1994/02/01 14:56:05 collins]
*
* Revision 1.2.6.17 1994/01/27 17:04:21 chasb
* Expand Copyright markers
* [1994/01/27 16:32:40 chasb]
*
* Revision 1.2.6.16 1994/01/26 18:42:03 collins
* CR10474: Change any_t to void *.
* [1994/01/26 18:39:47 collins]
*
* Revision 1.2.6.15 1994/01/25 17:02:40 jeffc
* CR10107 -- Mach spec compliance - eliminate copy_call
* [1994/01/24 21:23:43 jeffc]
*
* Revision 1.2.6.14 1994/01/20 16:58:18 meissner
* CR 10468 - Make initialization have proper number of {}'s.
* [1994/01/19 19:02:57 meissner]
*
* Revision 1.2.6.13 1993/12/03 20:53:51 jvs
* Trusted pager throttling changes. CR 10108
* [1993/12/03 20:53:09 jvs]
*
* Revision 1.2.6.12 1993/12/02 17:22:34 jph
* CR10254 -- Fix warning about unused ledger/ security ports.
* [1993/12/02 15:59:30 jph]
*
* Revision 1.2.6.11 1993/11/24 20:30:31 jph
* CR9801 brezak merge, ledgers, security and NMK15_COMPAT
* [1993/11/23 22:52:33 jph]
*
* New bootstrap_ports() signature.
* [1993/11/23 20:58:25 jph]
*
* Revision 1.2.6.10 1993/11/23 18:05:47 watkins
* Increment send right for object in mo_notify.
* [1993/11/23 18:04:35 watkins]
*
* Revision 1.2.6.9 1993/11/16 21:49:42 watkins
* Remove pager_name argument from memory_object_terminate
* and memory_object_create, as per spec. Remove mo_init
* and flesh out mo_notify. Extend maps for reads beyond the
* end. Add xpr traces.
* [1993/11/16 21:29:43 watkins]
*
* Revision 1.2.6.8 1993/10/20 18:50:13 gm
* CR9928: Remove bootstrap_port lookup.
* CR9990: Remove code that deletes initial stack.
* [1993/10/20 12:34:40 gm]
*
* Revision 1.2.6.7 1993/10/08 17:32:08 jeffc
* CR9508 - Delete typed IPC code
* [1993/09/28 17:27:02 jeffc]
*
* Revision 1.2.6.6 1993/10/08 16:08:14 jeffc
* CR9792 - delete obsolete memory_object_data_write message.
* [1993/10/08 15:59:49 jeffc]
*
* Revision 1.2.6.5 1993/10/05 21:57:08 watkins
* New memory object attribute interfaces comply with spec.
* [1993/10/05 21:53:27 watkins]
*
* Revision 1.2.6.4 1993/09/16 18:38:39 jeffc
* CR9792 - delete defunct EMMI interfaces
* [1993/09/15 20:02:07 jeffc]
*
* Revision 1.2.6.3 1993/08/05 17:57:08 gm
* CR9627: Moved def_pager_setup and bootstrap code here. Removed
* EXT_PAGER code. Fixed up code problems with more agressive warning
* in gcc. Added full prototype support. Changed internal interfaces
* that had unions as return values to take pointer arguments instead.
* Delete bootstrap code since their is now a separate bootstrap task.
* Removed set_ras_address() since it should be provided by a machine
* dependent file on machines that need it. Changed to get priv
* ports using mach interfaces instead of argv.
* [1993/07/09 19:11:36 gm]
*
* Revision 1.2.6.2 1993/06/09 02:08:56 gm
* Conditionalize no_senders_check for untyped IPC. CR #9058.
* [1993/05/11 18:19:30 rod]
*
* Add header files to pick up definitions of Mach traps and
* wiring interfaces.
* [1993/05/14 15:37:15 jeffc]
*
* Fix ANSI C violations and warnings.
* [1993/05/13 21:05:22 jeffc]
*
* Remove dependency on own pathname.
* [1993/05/12 17:53:18 jeffc]
*
* Revision 1.2 1993/04/19 15:07:02 devrcs
* Added trailer support to untyped ipc. [[email protected], [email protected]]
* [1993/04/06 18:14:54 travos]
*
* Merge untyped ipc:
* Added untyped support to bootstrap_compat().
* [1993/04/02 17:37:59 rod]
*
* Share more code when building the in kernel version
* of the pager.
* [93/03/19 bernadat]
*
* Fix memory_object_synchronize hang.
* [1993/03/15 13:21:59 david]
*
* memory_object_synchronize define twice
* [1993/03/03 15:09:30 david]
*
* remerge with 1.1.2.3
* [1993/03/03 14:26:14 david]
*
* Add memory_object_synchronize stub
* [1993/03/03 11:04:05 david]
*
* Fixed a deadlock bug in internal pager configuration.
* [93/02/25 bernadat]
*
* moved out of mach_kernel directory
* [1993/02/27 13:56:35 david]
*
* Modified to use the same new interface (default_pager_object.defs) for both
* configurations.
* [1993/02/17 13:40:18 bruel]
*
* Added stubs for new exception interface.
* [93/02/11 bruel]
*
* Modified from mk78.
* Added the ufs_pager_option.
* [93/01/29 bruel]
*
* Yup, it works. Undefine CHECKSUM, debug and
* DEBUG_READER_CONFLICTS again.
* [92/12/03 ian]
*
* Update CHECKSUM to work with current dp_map union.
* [92/12/03 ian]
*
* Define debug CHECKSUM and DEBUG_READER_CONFLICTS.
* [92/11/28 ian]
*
* Eliminated use of old memory object calls (set_attributes, data_write, data_provided).
* [92/09/25 jsb]
*
* $EndLog$
*/
/* CMU_HIST */
/*
* Revision 2.12 92/07/20 13:32:18 cmaeda
* Added private version of set_ras_address for fast_tas support.
* [92/05/11 14:31:52 cmaeda]
*
* Revision 2.11 92/05/05 10:03:46 danner
* For merge purposes, backed-out the unstable stuff.
* [92/05/04 11:12:01 af]
*
* Now we can page an object across partitions.
* Initial rough ideas about automatically extending
* paging space.
* [92/03/11 02:23:58 af]
*
* Revision 2.10 92/03/06 13:58:48 rpd
* Fixed pager_dealloc_page calls in pager_dealloc (from af).
* Removed chatty printfs.
* [92/03/06 rpd]
*
* Revision 2.9 92/03/05 15:58:35 rpd
* Changed PAGEMAP_ENTRIES from 128 to 64. From af.
* [92/03/05 rpd]
*
* Revision 2.8 92/03/03 12:12:04 rpd
* Changed to catch exception messages and handle bootstrap requests.
* Added partition_init.
* [92/03/03 rpd]
*
* Revision 2.7 92/02/25 11:22:38 elf
* Accept creation of objects bigger than any one partition, in
* anticipation of the code that will page across partitions.
* Since we are at it, also proceed with no paging partitions:
* rely on killing unlucky objects on pageouts.
* [92/02/25 af]
*
* Revision 2.6 92/02/23 23:00:31 elf
* Copyright updated, corrected history.
* [92/02/23 elf]
*
* Revision 2.5 92/02/23 22:25:35 elf
* Improved handling of big objects, fixed a deadlock in
* object relocation, improved printouts.
* Now only crash if out of memory, otherwise use the old
* code that just marked the object as in-error.
* [92/02/23 13:25:49 af]
*
* As per jsb instructions, removed all NORMA conditionals.
* Rename port names to odd values, a trivial heuristic that
* makes name conflicts even more unlikely.
* [92/02/22 af]
*
* Refined the port name conflict problem. Instead of renaming
* ports that we send to, just set aside the memory that we cannot
* use. When objects get deleted put back the memory in the system.
* [92/02/21 af]
*
* Added renaming of request and name ports (from af).
* [92/02/21 danner]
*
* Many changes. Now supports adding/removing paging files, it does
* not immediately panic if a paging file fills up but relocates the
* object elsewhere, it uses the precious attribute in data_supply
* to reduce paging space usage (under USE_PRECIOUS conditional,
* enabled).
* [92/02/19 17:29:54 af]
*
* Two mods: changed bitmap ops to work one int at a time rather
* than one byte at a time. This helps under load, e.g. when the
* paging file is large and busy. Second mod to use port-to-pointer
* casting in lookups, rather than hash+list searching. This not
* only helps under load (I see >600 objects on my pmax) but also
* increases parallelism a little.
* Shrunk the code size by one page in the process.
* [92/02/14 01:44:23 af]
*
* Revision 2.4 92/01/23 15:19:41 rpd
* Changed to not include mig server interfaces.
* [92/01/23 rpd]
*
* Revision 2.3 92/01/14 16:43:14 rpd
* Moved mach/default_pager_object.defs to mach/default_pager.defs.
* Revised default_pager_info etc. for their new definitions.
* Removed (now) unnecessary #define's to rename kernel functions.
* [92/01/13 rpd]
* Added page_size to default_pager_info.
* Added default_pager_object_pages.
* [92/01/03 rpd]
*
* Updated to handle name ports from memory_object_create.
* Changed to remember the name ports associated with objects.
* Changed default_pager_objects to return the name ports.
* [91/12/28 rpd]
*
* Added default_pager_objects.
* [91/12/15 rpd]
*
* Revision 2.2 92/01/03 19:56:21 dbg
* Simplify locking.
* [91/10/02 dbg]
*
* Convert to run outside of kernel.
* [91/09/04 dbg]
*
* Revision 2.17 91/08/29 13:44:27 jsb
* A couple quick changes for NORMA_VM. Will be fixed later.
*
* Revision 2.16 91/08/28 16:59:29 jsb
* Fixed the default values of default_pager_internal_count and
* default_pager_external_count.
* [91/08/28 rpd]
*
* Revision 2.15 91/08/28 11:09:32 jsb
* Added seqnos_memory_object_change_completed.
* From dlb: use memory_object_data_supply for pagein when buffer is
* going to be deallocated.
* From me: don't use data_supply under NORMA_VM (will be fixed).
* [91/08/26 14:30:07 jsb]
*
* Changed to process requests in parallel when possible.
*
* Don't bother keeping track of mscount.
* [91/08/16 rpd]
* Added default_pager_info.
* [91/08/15 rpd]
*
* Added sequence numbers to the memory object interface.
* Changed to use no-senders notifications.
* Changed to keep track of port rights and not use mach_port_destroy.
* Added dummy supply-completed and data-return stubs.
* [91/08/13 rpd]
*
* Revision 2.14 91/05/18 14:28:32 rpd
* Don't give privileges to threads handling external objects.
* [91/04/06 rpd]
* Enhanced to use multiple threads, for performance and to avoid
* a deadlock caused by default_pager_object_create.
* Added locking to partitions.
* Added locking to pager_port_hashtable.
* Changed pager_port_hash to something reasonable.
* [91/04/03 rpd]
*
* Revision 2.13 91/05/14 15:21:41 mrt
* Correcting copyright
*
* Revision 2.12 91/03/16 14:41:26 rpd
* Updated for new kmem_alloc interface.
* Fixed memory_object_create to zero the new pager structure.
* [91/03/03 rpd]
* Removed thread_swappable.
* [91/01/18 rpd]
*
* Revision 2.11 91/02/05 17:00:49 mrt
* Changed to new copyright
* [91/01/28 14:54:31 mrt]
*
* Revision 2.10 90/09/09 14:31:01 rpd
* Use decl_simple_lock_data.
* [90/08/30 rpd]
*
* Revision 2.9 90/08/27 21:44:51 dbg
* Add definitions of NBBY, howmany.
* [90/07/16 dbg]
*
* Revision 2.8 90/06/02 14:45:22 rpd
* Changed default_pager_object_create so the out argument
* is a poly send right.
* [90/05/03 rpd]
* Removed references to keep_wired_memory.
* [90/04/29 rpd]
* Converted to new IPC.
* Removed data-request queue.
* [90/03/26 21:30:57 rpd]
*
* Revision 2.7 90/03/14 21:09:58 rwd
* Call default_pager_object_server and add
* default_pager_object_create
* [90/01/22 rwd]
*
* Revision 2.6 90/01/11 11:41:08 dbg
* Use bootstrap-task print routines.
* [89/12/20 dbg]
*
* De-lint.
* [89/12/06 dbg]
*
* Revision 2.5 89/12/08 19:52:03 rwd
* Turn off CHECKSUM
* [89/12/06 rwd]
*
* Revision 2.4 89/10/23 12:01:54 dbg
* Change pager_read_offset and pager_write_offset to return block
* number as function result. default_read()'s caller must now
* deallocate data if not the same as the data buffer passed in.
* Add register declarations and clean up loops a bit.
* [89/10/19 dbg]
*
* Oops - nothing like having your debugging code introduce bugs...
* [89/10/17 dbg]
*
* Revision 2.3 89/10/16 15:21:59 rwd
* debugging: checksum pages in each object.
* [89/10/04 dbg]
*
* Revision 2.2 89/09/08 11:22:06 dbg
* Wait for default_partition to be set.
* [89/09/01 dbg]
*
* Modified to call outside routines for read and write.
* Removed disk structure. Added part_create.
* Reorganized code.
* [89/07/11 dbg]
*
*/
/* CMU_ENDHIST */
/*
* Mach Operating System
* Copyright (c) 1991,1990,1989 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or [email protected]
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
/*
* Default pager.
* Threads management.
* Requests handling.
*/
#include "default_pager_internal.h"
#include <kern/host.h>
#include <kern/ledger.h>
#include <mach/host_info.h>
#include <ipc/ipc_space.h>
#include <vm/vm_kern.h>
char my_name[] = "(default pager): ";
#if DEFAULT_PAGER_DEBUG
int debug_mask = 0;
#endif /* DEFAULT_PAGER_DEBUG */
/*
* Use 16 Kbyte stacks instead of the default 64K.
* Use 4 Kbyte waiting stacks instead of the default 8K.
*/
vm_size_t cthread_stack_size = 16 *1024;
extern vm_size_t cthread_wait_stack_size;
int vm_page_mask;
int vm_page_shift;
int norma_mk;
boolean_t verbose;
/* task_t default_pager_self; */ /* Our task port. */
mutex_t dpt_lock; /* lock for the dpt array struct */
default_pager_thread_t **dpt_array;
MACH_PORT_FACE default_pager_default_set; /* Port set for "default" thread. */
MACH_PORT_FACE default_pager_default_port;/* Port for memory_object_create. */
MACH_PORT_FACE default_pager_internal_set; /* Port set for internal objects. */
MACH_PORT_FACE default_pager_external_set; /* Port set for external objects. */
#define DEFAULT_PAGER_INTERNAL_COUNT (4)
/* Memory created by default_pager_object_create should mostly be resident. */
#define DEFAULT_PAGER_EXTERNAL_COUNT (2)
unsigned int default_pager_internal_count = DEFAULT_PAGER_INTERNAL_COUNT;
/* Number of "internal" threads. */
unsigned int default_pager_external_count = DEFAULT_PAGER_EXTERNAL_COUNT;
/* Number of "external" threads. */
/*
* Forward declarations.
*/
boolean_t default_pager_notify_server(mach_msg_header_t *,
mach_msg_header_t *);
boolean_t default_pager_demux_object(mach_msg_header_t *,
mach_msg_header_t *);
boolean_t default_pager_demux_default(mach_msg_header_t *,
mach_msg_header_t *);
default_pager_thread_t *start_default_pager_thread(int, boolean_t);
void default_pager(void);
void default_pager_thread(void *);
void default_pager_initialize(MACH_PORT_FACE);
void default_pager_set_policy(MACH_PORT_FACE);
boolean_t dp_parse_argument(char *); /* forward; */
unsigned int d_to_i(char *); /* forward; */
extern int vstruct_def_clshift;
/*
* Initialize and Run the default pager
*/
void
default_pager(void)
{
int i, id;
static char here[] = "default_pager";
mach_msg_options_t server_options;
default_pager_thread_t dpt;
kern_return_t kr;
/*
* Give me space for the thread array and zero it.
*/
i = default_pager_internal_count + default_pager_external_count + 1;
dpt_array = (default_pager_thread_t **)
kalloc(i * sizeof(default_pager_thread_t *));
memset(dpt_array, 0, i * sizeof(default_pager_thread_t *));
/* Setup my thread structure. */
id = 0;
dpt.dpt_buffer = 0;
dpt.dpt_internal = FALSE;
dpt.dpt_initialized_p = TRUE;
dpt_array[0] = &dpt;
/*
* Now we create the threads that will actually
* manage objects.
*/
for (i = 0; i < default_pager_internal_count; i++) {
dpt_array[id] = (default_pager_thread_t *)
kalloc(sizeof (default_pager_thread_t));
if (dpt_array[id] == NULL)
Panic("alloc pager thread");
kr = vm_allocate(kernel_map, &((dpt_array[id])->dpt_buffer),
vm_page_size << vstruct_def_clshift, TRUE);
if (kr != KERN_SUCCESS)
Panic("alloc thread buffer");
kr = vm_map_wire(kernel_map, (dpt_array[id])->dpt_buffer,
((dpt_array[id])->dpt_buffer)
+(vm_page_size << vstruct_def_clshift),
VM_PROT_DEFAULT,
FALSE);
if (kr != KERN_SUCCESS)
Panic("wire thread buffer");
(dpt_array[id])->dpt_internal = TRUE;
(dpt_array[id])->dpt_initialized_p = TRUE;
(dpt_array[id])->checked_out = FALSE;
id++;
}
DPT_LOCK_INIT(dpt_lock);
}
/* simple utility: only works for 2^n */
int
local_log2(
unsigned int n)
{
register int i = 0;
if(n == 0) return 0;
while ((n & 1) == 0) {
i++;
n >>= 1;
}
return i;
}
/* another simple utility, d_to_i(char*) supporting only decimal
* and devoid of range checking; obscure name chosen deliberately
* to avoid confusion with semantic-rich POSIX routines */
unsigned int
d_to_i(char * arg)
{
unsigned int rval = 0;
char ch;
while ((ch = *arg++) && ch >= '0' && ch <= '9') {
rval *= 10;
rval += ch - '0';
}
return(rval);
}
/*
* Check for non-disk-partition arguments of the form
* attribute=argument
* returning TRUE if one if found
*/
boolean_t dp_parse_argument(char *av)
{
char *rhs = av;
static char here[] = "dp_parse_argument";
/* Check for '-v' flag */
if (av[0] == '-' && av[1] == 'v' && av[2] == 0) {
verbose = TRUE ;
return TRUE;
}
/*
* If we find a '=' followed by an argument in the string,
* check for known arguments
*/
while (*rhs && *rhs != '=')
rhs++;
if (*rhs && *++rhs) {
/* clsize=N pages */
if (strprefix(av,"cl")) {
if (!bs_set_default_clsize(d_to_i(rhs)))
dprintf(("Bad argument (%s) - ignored\n", av));
return(TRUE);
}
/* else if strprefix(av,"another_argument")) {
handle_another_argument(av);
return(TRUE);
} */
}
return(FALSE);
}
MACH_PORT_FACE default_pager_host_port = MACH_PORT_NULL;
int
start_def_pager(char *bs_device)
{
int my_node;
/*
MACH_PORT_FACE master_device_port;
*/
MACH_PORT_FACE security_port;
/*
MACH_PORT_FACE root_ledger_wired;
MACH_PORT_FACE root_ledger_paged;
*/
static char here[] = "main";
int need_dp_init = 1;
default_pager_host_port = ipc_port_make_send(realhost.host_priv_self);
/*
master_device_port = ipc_port_make_send(master_device_port);
root_ledger_wired = ipc_port_make_send(root_wired_ledger_port);
root_ledger_paged = ipc_port_make_send(root_paged_ledger_port);
*/
security_port = ipc_port_make_send(realhost.host_security_self);
#if NORMA_VM
norma_mk = 1;
#else
norma_mk = 0;
#endif
/* setup read buffers, etc */
default_pager_initialize(default_pager_host_port);
default_pager();
}
/*
* Return TRUE if string 2 is a prefix of string 1.
*/
boolean_t
strprefix(register const char *s1, register const char *s2)
{
register int c;
while ((c = *s2++) != '\0') {
if (c != *s1++)
return (FALSE);
}
return (TRUE);
}
kern_return_t
default_pager_info(
MACH_PORT_FACE pager,
default_pager_info_t *infop)
{
vm_size_t pages_total, pages_free;
if (pager != default_pager_default_port)
return KERN_INVALID_ARGUMENT;
bs_global_info(&pages_total, &pages_free);
infop->dpi_total_space = ptoa(pages_total);
infop->dpi_free_space = ptoa(pages_free);
infop->dpi_page_size = vm_page_size;
return KERN_SUCCESS;
}
void
default_pager_initialize(
MACH_PORT_FACE host_port)
{
kern_return_t kr;
static char here[] = "default_pager_initialize";
/*
* Exported DMM port.
*/
default_pager_default_port = ipc_port_alloc_kernel();
/*
* Export pager interfaces.
*/
#ifdef USER_PAGER
if ((kr = netname_check_in(name_server_port, "UserPager",
default_pager_self,
default_pager_default_port))
!= KERN_SUCCESS) {
dprintf(("netname_check_in returned 0x%x\n", kr));
exit(1);
}
#else /* USER_PAGER */
{
int clsize;
ipc_port_t DMM;
DMM = ipc_port_make_send(default_pager_default_port);
clsize = (vm_page_size << vstruct_def_clshift);
kr = host_default_memory_manager(host_port, &DMM, clsize);
if ((kr != KERN_SUCCESS) || (DMM != MACH_PORT_NULL))
Panic("default memory manager");
}
#endif /* USER_PAGER */
/*
* Vm variables.
*/
vm_page_mask = vm_page_size - 1;
vm_page_shift = local_log2(vm_page_size);
/*
* List of all vstructs.
*/
VSL_LOCK_INIT();
queue_init(&vstruct_list.vsl_queue);
queue_init(&vstruct_list.vsl_leak_queue);
vstruct_list.vsl_count = 0;
VSTATS_LOCK_INIT(&global_stats.gs_lock);
bs_initialize();
}