usr/src/uts/common/vm/page.h
author johansen
Tue, 19 Dec 2006 23:13:06 -0800
changeset 3290 256464cbb73c
parent 3253 c929f34b62c5
child 3446 5903aece022d
permissions -rw-r--r--
4894692 caching data in heap inflates crash dump 6499454 time to increase size of kmem default allocation caches 6499459 vm should stop checking kvp directly
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     1
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     2
 * CDDL HEADER START
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     3
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
1841
9d7ebafcda38 6256083 Need a lightweight file page mapping mechanism to substitute segmap
praks
parents: 1373
diff changeset
     5
 * Common Development and Distribution License (the "License").
9d7ebafcda38 6256083 Need a lightweight file page mapping mechanism to substitute segmap
praks
parents: 1373
diff changeset
     6
 * You may not use this file except in compliance with the License.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     7
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    11
 * and limitations under the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    12
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    18
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    19
 * CDDL HEADER END
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    20
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    21
/*
1373
21e3b2045b46 6351310 assertion failed: (plcnt[mnode][mtype].plc_mt_clpgcnt...) vm_pagelist.c, line: 2239]
kchow
parents: 973
diff changeset
    22
 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    23
 * Use is subject to license terms.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    24
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    25
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    26
/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
/*	  All Rights Reserved  	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    30
 * University Copyright- Copyright (c) 1982, 1986, 1988
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    31
 * The Regents of the University of California
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
 * All Rights Reserved
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
 * University Acknowledgment- Portions of this document are derived from
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
 * software developed by the University of California, Berkeley, and its
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
 * contributors.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
#ifndef	_VM_PAGE_H
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
#define	_VM_PAGE_H
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
#pragma ident	"%Z%%M%	%I%	%E% SMI"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
#include <vm/seg.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
#ifdef	__cplusplus
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
extern "C" {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
#if defined(_KERNEL) || defined(_KMEMUSER)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
 * Shared/Exclusive lock.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    55
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
 * Types of page locking supported by page_lock & friends.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
typedef enum {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
	SE_SHARED,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
	SE_EXCL			/* exclusive lock (value == -1) */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    62
} se_t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    63
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
 * For requesting that page_lock reclaim the page from the free list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    66
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
typedef enum {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
	P_RECLAIM,		/* reclaim page from free list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
	P_NO_RECLAIM		/* DON`T reclaim the page	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
} reclaim_t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
 * Callers of page_try_reclaim_lock and page_lock_es can use this flag
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
 * to get SE_EXCL access before reader/writers are given access.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    76
#define	SE_EXCL_WANTED	0x02
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    77
917
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
    78
/*
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
    79
 * All page_*lock() requests will be denied unless this flag is set in
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
    80
 * the 'es' parameter.
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
    81
 */
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
    82
#define	SE_RETIRED	0x04
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
    83
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
#endif	/* _KERNEL | _KMEMUSER */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
typedef int	selock_t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
 * Define VM_STATS to turn on all sorts of statistic gathering about
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
 * the VM layer.  By default, it is only turned on when DEBUG is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
 * also defined.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    93
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    94
#define	VM_STATS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    95
#endif	/* DEBUG */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
#ifdef VM_STATS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
#define	VM_STAT_ADD(stat)			(stat)++
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
#define	VM_STAT_COND_ADD(cond, stat)		((void) (!(cond) || (stat)++))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
#define	VM_STAT_ADD(stat)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
#define	VM_STAT_COND_ADD(cond, stat)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   103
#endif	/* VM_STATS */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
#ifdef _KERNEL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
 * Macros to acquire and release the page logical lock.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   109
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
#define	page_struct_lock(pp)	mutex_enter(&page_llock)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   111
#define	page_struct_unlock(pp)	mutex_exit(&page_llock)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   112
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
#endif	/* _KERNEL */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   114
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   115
#include <sys/t_lock.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   116
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   117
struct as;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
 * Each physical page has a page structure, which is used to maintain
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
 * these pages as a cache.  A page can be found via a hashed lookup
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
 * based on the [vp, offset].  If a page has an [vp, offset] identity,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
 * then it is entered on a doubly linked circular list off the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
 * vnode using the vpnext/vpprev pointers.   If the p_free bit
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
 * is on, then the page is also on a doubly linked circular free
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   126
 * list using next/prev pointers.  If the "p_selock" and "p_iolock"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   127
 * are held, then the page is currently being read in (exclusive p_selock)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   128
 * or written back (shared p_selock).  In this case, the next/prev pointers
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
 * are used to link the pages together for a consecutive i/o request.  If
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
 * the page is being brought in from its backing store, then other processes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
 * will wait for the i/o to complete before attaching to the page since it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
 * will have an "exclusive" lock.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
 * Each page structure has the locks described below along with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
 * the fields they protect:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
 *	p_selock	This is a per-page shared/exclusive lock that is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
 *			used to implement the logical shared/exclusive
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
 *			lock for each page.  The "shared" lock is normally
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
 *			used in most cases while the "exclusive" lock is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
 *			required to destroy or retain exclusive access to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
 *			a page (e.g., while reading in pages).  The appropriate
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
 *			lock is always held whenever there is any reference
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
 *			to a page structure (e.g., during i/o).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
 *			(Note that with the addition of the "writer-lock-wanted"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
 *			semantics (via SE_EWANTED), threads must not acquire
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
 *			multiple reader locks or else a deadly embrace will
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
 *			occur in the following situation: thread 1 obtains a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
 *			reader lock; next thread 2 fails to get a writer lock
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
 *			but specified SE_EWANTED so it will wait by either
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
 *			blocking (when using page_lock_es) or spinning while
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
 *			retrying (when using page_try_reclaim_lock) until the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
 *			reader lock is released; then thread 1 attempts to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
 *			get another reader lock but is denied due to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
 *			SE_EWANTED being set, and now both threads are in a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
 *			deadly embrace.)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
 *				p_hash
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
 *				p_vnode
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
 *				p_offset
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
 *				p_free
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
 *				p_age
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
 *	p_iolock	This is a binary semaphore lock that provides
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
 *			exclusive access to the i/o list links in each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
 *			page structure.  It is always held while the page
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
 *			is on an i/o list (i.e., involved in i/o).  That is,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
 *			even though a page may be only `shared' locked
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   170
 *			while it is doing a write, the following fields may
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   171
 *			change anyway.  Normally, the page must be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   172
 *			`exclusively' locked to change anything in it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
 *				p_next
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
 *				p_prev
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
 * The following fields are protected by the global page_llock:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
 *				p_lckcnt
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
 *				p_cowcnt
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   182
 * The following lists are protected by the global page_freelock:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   183
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   184
 *				page_cachelist
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
 *				page_freelist
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
 * The following, for our purposes, are protected by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   188
 * the global freemem_lock:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   189
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
 *				freemem
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
 *				freemem_wait
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   192
 *				freemem_cv
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
 * The following fields are protected by hat layer lock(s).  When a page
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   195
 * structure is not mapped and is not associated with a vnode (after a call
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   196
 * to page_hashout() for example) the p_nrm field may be modified with out
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   197
 * holding the hat layer lock:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   199
 *				p_nrm
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
 *				p_mapping
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
 *				p_share
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
 * The following field is file system dependent.  How it is used and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
 * the locking strategies applied are up to the individual file system
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
 * implementation.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
 *				p_fsdata
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
 * The page structure is used to represent and control the system's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
 * physical pages.  There is one instance of the structure for each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
 * page that is not permenately allocated.  For example, the pages that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
 * hold the page structures are permanently held by the kernel
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
 * and hence do not need page structures to track them.  The array
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
 * of page structures is allocated early on in the kernel's life and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   215
 * is based on the amount of available physical memory.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   216
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
 * Each page structure may simultaneously appear on several linked lists.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
 * The lists are:  hash list, free or in i/o list, and a vnode's page list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
 * Each type of list is protected by a different group of mutexes as described
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
 * below:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
 * The hash list is used to quickly find a page when the page's vnode and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
 * offset within the vnode are known.  Each page that is hashed is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
 * connected via the `p_hash' field.  The anchor for each hash is in the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
 * array `page_hash'.  An array of mutexes, `ph_mutex', protects the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
 * lists anchored by page_hash[].  To either search or modify a given hash
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
 * list, the appropriate mutex in the ph_mutex array must be held.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
 * The free list contains pages that are `free to be given away'.  For
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
 * efficiency reasons, pages on this list are placed in two catagories:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
 * pages that are still associated with a vnode, and pages that are not
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
 * associated with a vnode.  Free pages always have their `p_free' bit set,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
 * free pages that are still associated with a vnode also have their
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
 * `p_age' bit set.  Pages on the free list are connected via their
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
 * `p_next' and `p_prev' fields.  When a page is involved in some sort
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
 * of i/o, it is not free and these fields may be used to link associated
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
 * pages together.  At the moment, the free list is protected by a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
 * single mutex `page_freelock'.  The list of free pages still associated
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
 * with a vnode is anchored by `page_cachelist' while other free pages
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
 * are anchored in architecture dependent ways (to handle page coloring etc.).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
 * Pages associated with a given vnode appear on a list anchored in the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
 * vnode by the `v_pages' field.  They are linked together with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
 * `p_vpnext' and `p_vpprev'.  The field `p_offset' contains a page's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
 * offset within the vnode.  The pages on this list are not kept in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
 * offset order.  These lists, in a manner similar to the hash lists,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
 * are protected by an array of mutexes called `vph_hash'.  Before
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   248
 * searching or modifying this chain the appropriate mutex in the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   249
 * vph_hash[] array must be held.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   250
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   251
 * Again, each of the lists that a page can appear on is protected by a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   252
 * mutex.  Before reading or writing any of the fields comprising the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   253
 * list, the appropriate lock must be held.  These list locks should only
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   254
 * be held for very short intervals.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   255
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   256
 * In addition to the list locks, each page structure contains a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   257
 * shared/exclusive lock that protects various fields within it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   258
 * To modify one of these fields, the `p_selock' must be exclusively held.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   259
 * To read a field with a degree of certainty, the lock must be at least
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   260
 * held shared.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   261
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   262
 * Removing a page structure from one of the lists requires holding
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   263
 * the appropriate list lock and the page's p_selock.  A page may be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   264
 * prevented from changing identity, being freed, or otherwise modified
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   265
 * by acquiring p_selock shared.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   266
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   267
 * To avoid deadlocks, a strict locking protocol must be followed.  Basically
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   268
 * there are two cases:  In the first case, the page structure in question
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   269
 * is known ahead of time (e.g., when the page is to be added or removed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   270
 * from a list).  In the second case, the page structure is not known and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   271
 * must be found by searching one of the lists.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   272
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   273
 * When adding or removing a known page to one of the lists, first the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   274
 * page must be exclusively locked (since at least one of its fields
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   275
 * will be modified), second the lock protecting the list must be acquired,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   276
 * third the page inserted or deleted, and finally the list lock dropped.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   277
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
 * The more interesting case occures when the particular page structure
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
 * is not known ahead of time.  For example, when a call is made to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
 * page_lookup(), it is not known if a page with the desired (vnode and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
 * offset pair) identity exists.  So the appropriate mutex in ph_mutex is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   282
 * acquired, the hash list searched, and if the desired page is found
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
 * an attempt is made to lock it.  The attempt to acquire p_selock must
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
 * not block while the hash list lock is held.  A deadlock could occure
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   285
 * if some other process was trying to remove the page from the list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   286
 * The removing process (following the above protocol) would have exclusively
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   287
 * locked the page, and be spinning waiting to acquire the lock protecting
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   288
 * the hash list.  Since the searching process holds the hash list lock
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
 * and is waiting to acquire the page lock, a deadlock occurs.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   290
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   291
 * The proper scheme to follow is: first, lock the appropriate list,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   292
 * search the list, and if the desired page is found either use
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   293
 * page_trylock() (which will not block) or pass the address of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   294
 * list lock to page_lock().  If page_lock() can not acquire the page's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   295
 * lock, it will drop the list lock before going to sleep.  page_lock()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   296
 * returns a value to indicate if the list lock was dropped allowing the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   297
 * calling program to react appropriately (i.e., retry the operation).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   298
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   299
 * If the list lock was dropped before the attempt at locking the page
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   300
 * was made, checks would have to be made to ensure that the page had
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   301
 * not changed identity before its lock was obtained.  This is because
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   302
 * the interval between dropping the list lock and acquiring the page
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   303
 * lock is indeterminate.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   305
 * In addition, when both a hash list lock (ph_mutex[]) and a vnode list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   306
 * lock (vph_mutex[]) are needed, the hash list lock must be acquired first.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   307
 * The routine page_hashin() is a good example of this sequence.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   308
 * This sequence is ASSERTed by checking that the vph_mutex[] is not held
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   309
 * just before each acquisition of one of the mutexs in ph_mutex[].
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   310
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   311
 * So, as a quick summary:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   312
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   313
 * 	pse_mutex[]'s protect the p_selock and p_cv fields.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   314
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   315
 * 	p_selock protects the p_free, p_age, p_vnode, p_offset and p_hash,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   316
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   317
 * 	ph_mutex[]'s protect the page_hash[] array and its chains.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   318
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   319
 * 	vph_mutex[]'s protect the v_pages field and the vp page chains.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   320
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   321
 *	First lock the page, then the hash chain, then the vnode chain.  When
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   322
 *	this is not possible `trylocks' must be used.  Sleeping while holding
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   323
 *	any of these mutexes (p_selock is not a mutex) is not allowed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   324
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   325
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   326
 *	field		reading		writing		    ordering
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   327
 *	======================================================================
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   328
 *	p_vnode		p_selock(E,S)	p_selock(E)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   329
 *	p_offset
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   330
 *	p_free
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   331
 *	p_age
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   332
 *	=====================================================================
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   333
 *	p_hash		p_selock(E,S)	p_selock(E) &&	    p_selock, ph_mutex
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   334
 *					ph_mutex[]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   335
 *	=====================================================================
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   336
 *	p_vpnext	p_selock(E,S)	p_selock(E) &&	    p_selock, vph_mutex
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   337
 *	p_vpprev			vph_mutex[]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   338
 *	=====================================================================
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   339
 *	When the p_free bit is set:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   340
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   341
 *	p_next		p_selock(E,S)	p_selock(E) &&	    p_selock,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   342
 *	p_prev				page_freelock	    page_freelock
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   343
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   344
 *	When the p_free bit is not set:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   345
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   346
 *	p_next		p_selock(E,S)	p_selock(E) &&	    p_selock, p_iolock
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   347
 *	p_prev				p_iolock
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   348
 *	=====================================================================
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   349
 *	p_selock	pse_mutex[]	pse_mutex[]	    can`t acquire any
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   350
 *	p_cv						    other mutexes or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   351
 *							    sleep while holding
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   352
 *							    this lock.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   353
 *	=====================================================================
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   354
 *	p_lckcnt	p_selock(E,S)	p_selock(E) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   355
 *	p_cowcnt			page_llock
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   356
 *	=====================================================================
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   357
 *	p_nrm		hat layer lock	hat layer lock
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   358
 *	p_mapping
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   359
 *	p_pagenum
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   360
 *	=====================================================================
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   361
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   362
 *	where:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   363
 *		E----> exclusive version of p_selock.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   364
 *		S----> shared version of p_selock.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   365
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   366
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   367
 *	Global data structures and variable:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   368
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   369
 *	field		reading		writing		    ordering
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   370
 *	=====================================================================
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   371
 *	page_hash[]	ph_mutex[]	ph_mutex[]	    can hold this lock
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   372
 *							    before acquiring
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   373
 *							    a vph_mutex or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   374
 *							    pse_mutex.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   375
 *	=====================================================================
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   376
 *	vp->v_pages	vph_mutex[]	vph_mutex[]	    can only acquire
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   377
 *							    a pse_mutex while
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   378
 *							    holding this lock.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   379
 *	=====================================================================
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   380
 *	page_cachelist	page_freelock	page_freelock	    can't acquire any
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   381
 *	page_freelist	page_freelock	page_freelock
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   382
 *	=====================================================================
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   383
 *	freemem		freemem_lock	freemem_lock	    can't acquire any
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   384
 *	freemem_wait					    other mutexes while
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   385
 *	freemem_cv					    holding this mutex.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   386
 *	=====================================================================
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   387
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   388
 * Page relocation, PG_NORELOC and P_NORELOC.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   389
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   390
 * Pages may be relocated using the page_relocate() interface. Relocation
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   391
 * involves moving the contents and identity of a page to another, free page.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   392
 * To relocate a page, the SE_EXCL lock must be obtained. The way to prevent
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   393
 * a page from being relocated is to hold the SE_SHARED lock (the SE_EXCL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   394
 * lock must not be held indefinitely). If the page is going to be held
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   395
 * SE_SHARED indefinitely, then the PG_NORELOC hint should be passed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   396
 * to page_create_va so that pages that are prevented from being relocated
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   397
 * can be managed differently by the platform specific layer.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   398
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   399
 * Pages locked in memory using page_pp_lock (p_lckcnt/p_cowcnt != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   400
 * are guaranteed to be held in memory, but can still be relocated
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   401
 * providing the SE_EXCL lock can be obtained.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   402
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   403
 * The P_NORELOC bit in the page_t.p_state field is provided for use by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   404
 * the platform specific code in managing pages when the PG_NORELOC
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   405
 * hint is used.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   406
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   407
 * Memory delete and page locking.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   408
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   409
 * The set of all usable pages is managed using the global page list as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   410
 * implemented by the memseg structure defined below. When memory is added
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   411
 * or deleted this list changes. Additions to this list guarantee that the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   412
 * list is never corrupt.  In order to avoid the necessity of an additional
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   413
 * lock to protect against failed accesses to the memseg being deleted and,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   414
 * more importantly, the page_ts, the memseg structure is never freed and the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   415
 * page_t virtual address space is remapped to a page (or pages) of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   416
 * zeros.  If a page_t is manipulated while it is p_selock'd, or if it is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   417
 * locked indirectly via a hash or freelist lock, it is not possible for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   418
 * memory delete to collect the page and so that part of the page list is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   419
 * prevented from being deleted. If the page is referenced outside of one
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   420
 * of these locks, it is possible for the page_t being referenced to be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   421
 * deleted.  Examples of this are page_t pointers returned by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   422
 * page_numtopp_nolock, page_first and page_next.  Providing the page_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   423
 * is re-checked after taking the p_selock (for p_vnode != NULL), the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   424
 * remapping to the zero pages will be detected.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   425
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   426
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   427
 * Page size (p_szc field) and page locking.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   428
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   429
 * p_szc field of free pages is changed by free list manager under freelist
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   430
 * locks and is of no concern to the rest of VM subsystem.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   431
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   432
 * p_szc changes of allocated anonymous (swapfs) can only be done only after
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   433
 * exclusively locking all constituent pages and calling hat_pageunload() on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   434
 * each of them. To prevent p_szc changes of non free anonymous (swapfs) large
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   435
 * pages it's enough to either lock SHARED any of constituent pages or prevent
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   436
 * hat_pageunload() by holding hat level lock that protects mapping lists (this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   437
 * method is for hat code only)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   438
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   439
 * To increase (promote) p_szc of allocated non anonymous file system pages
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   440
 * one has to first lock exclusively all involved constituent pages and call
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   441
 * hat_pageunload() on each of them. To prevent p_szc promote it's enough to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   442
 * either lock SHARED any of constituent pages that will be needed to make a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   443
 * large page or prevent hat_pageunload() by holding hat level lock that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   444
 * protects mapping lists (this method is for hat code only).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   445
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   446
 * To decrease (demote) p_szc of an allocated non anonymous file system large
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   447
 * page one can either use the same method as used for changeing p_szc of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   448
 * anonymous large pages or if it's not possible to lock all constituent pages
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   449
 * exclusively a different method can be used. In the second method one only
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   450
 * has to exclusively lock one of constituent pages but then one has to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   451
 * acquire further locks by calling page_szc_lock() and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   452
 * hat_page_demote(). hat_page_demote() acquires hat level locks and then
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   453
 * demotes the page. This mechanism relies on the fact that any code that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   454
 * needs to prevent p_szc of a file system large page from changeing either
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   455
 * locks all constituent large pages at least SHARED or locks some pages at
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   456
 * least SHARED and calls page_szc_lock() or uses hat level page locks.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   457
 * Demotion using this method is implemented by page_demote_vp_pages().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   458
 * Please see comments in front of page_demote_vp_pages(), hat_page_demote()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   459
 * and page_szc_lock() for more details.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   460
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   461
 * Lock order: p_selock, page_szc_lock, ph_mutex/vph_mutex/freelist,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   462
 * hat level locks.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   463
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   464
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   465
typedef struct page {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   466
	u_offset_t	p_offset;	/* offset into vnode for this page */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   467
	struct vnode	*p_vnode;	/* vnode that this page is named by */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   468
	selock_t	p_selock;	/* shared/exclusive lock on the page */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   469
#if defined(_LP64)
1841
9d7ebafcda38 6256083 Need a lightweight file page mapping mechanism to substitute segmap
praks
parents: 1373
diff changeset
   470
	uint_t		p_vpmref;	/* vpm ref - index of the vpmap_t */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   471
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   472
	struct page	*p_hash;	/* hash by [vnode, offset] */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   473
	struct page	*p_vpnext;	/* next page in vnode list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   474
	struct page	*p_vpprev;	/* prev page in vnode list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   475
	struct page	*p_next;	/* next page in free/intrans lists */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   476
	struct page	*p_prev;	/* prev page in free/intrans lists */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   477
	ushort_t	p_lckcnt;	/* number of locks on page data */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   478
	ushort_t	p_cowcnt;	/* number of copy on write lock */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   479
	kcondvar_t	p_cv;		/* page struct's condition var */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   480
	kcondvar_t	p_io_cv;	/* for iolock */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   481
	uchar_t		p_iolock_state;	/* replaces p_iolock */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   482
	volatile uchar_t p_szc;		/* page size code */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   483
	uchar_t		p_fsdata;	/* file system dependent byte */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   484
	uchar_t		p_state;	/* p_free, p_noreloc */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   485
	uchar_t		p_nrm;		/* non-cache, ref, mod readonly bits */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   486
#if defined(__sparc)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   487
	uchar_t		p_vcolor;	/* virtual color */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   488
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   489
	uchar_t		p_embed;	/* x86 - changes p_mapping & p_index */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   490
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   491
	uchar_t		p_index;	/* MPSS mapping info. Not used on x86 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   492
	uchar_t		p_toxic;	/* page has an unrecoverable error */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   493
	void		*p_mapping;	/* hat specific translation info */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   494
	pfn_t		p_pagenum;	/* physical page number */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   495
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   496
	uint_t		p_share;	/* number of translations */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   497
#if defined(_LP64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   498
	uint_t		p_sharepad;	/* pad for growing p_share */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   499
#endif
2414
4349245e130c 4614772 MPSS to be extended to shared memory
aguzovsk
parents: 2048
diff changeset
   500
	uint_t		p_slckcnt;	/* number of softlocks */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   501
#if defined(__sparc)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   502
	uint_t		p_kpmref;	/* number of kpm mapping sharers */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   503
	struct kpme	*p_kpmelist;	/* kpm specific mapping info */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   504
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   505
	/* index of entry in p_map when p_embed is set */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   506
	uint_t		p_mlentry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   507
#endif
1841
9d7ebafcda38 6256083 Need a lightweight file page mapping mechanism to substitute segmap
praks
parents: 1373
diff changeset
   508
#if defined(_LP64)
9d7ebafcda38 6256083 Need a lightweight file page mapping mechanism to substitute segmap
praks
parents: 1373
diff changeset
   509
	kmutex_t	p_ilock;	/* protects p_vpmref */
9d7ebafcda38 6256083 Need a lightweight file page mapping mechanism to substitute segmap
praks
parents: 1373
diff changeset
   510
#else
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   511
	uint64_t	p_msresv_2;	/* page allocation debugging */
1841
9d7ebafcda38 6256083 Need a lightweight file page mapping mechanism to substitute segmap
praks
parents: 1373
diff changeset
   512
#endif
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   513
} page_t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   514
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   515
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   516
typedef	page_t	devpage_t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   517
#define	devpage	page
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   518
2414
4349245e130c 4614772 MPSS to be extended to shared memory
aguzovsk
parents: 2048
diff changeset
   519
#define	PAGE_LOCK_MAXIMUM \
4349245e130c 4614772 MPSS to be extended to shared memory
aguzovsk
parents: 2048
diff changeset
   520
	((1 << (sizeof (((page_t *)0)->p_lckcnt) * NBBY)) - 1)
4349245e130c 4614772 MPSS to be extended to shared memory
aguzovsk
parents: 2048
diff changeset
   521
4349245e130c 4614772 MPSS to be extended to shared memory
aguzovsk
parents: 2048
diff changeset
   522
#define	PAGE_SLOCK_MAXIMUM UINT_MAX
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   523
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   524
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   525
 * Page hash table is a power-of-two in size, externally chained
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   526
 * through the hash field.  PAGE_HASHAVELEN is the average length
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   527
 * desired for this chain, from which the size of the page_hash
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   528
 * table is derived at boot time and stored in the kernel variable
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   529
 * page_hashsz.  In the hash function it is given by PAGE_HASHSZ.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   530
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   531
 * PAGE_HASH_FUNC returns an index into the page_hash[] array.  This
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   532
 * index is also used to derive the mutex that protects the chain.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   533
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   534
 * In constructing the hash function, first we dispose of unimportant bits
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   535
 * (page offset from "off" and the low 3 bits of "vp" which are zero for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   536
 * struct alignment). Then shift and sum the remaining bits a couple times
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   537
 * in order to get as many source bits from the two source values into the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   538
 * resulting hashed value.  Note that this will perform quickly, since the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   539
 * shifting/summing are fast register to register operations with no additional
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   540
 * memory references).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   541
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   542
#if NCPU < 4
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   543
#define	PH_TABLE_SIZE	16
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   544
#define	VP_SHIFT	7
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   545
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   546
#define	PH_TABLE_SIZE	128
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   547
#define	VP_SHIFT	9
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   548
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   549
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   550
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   551
 * The amount to use for the successive shifts in the hash function below.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   552
 * The actual value is LOG2(PH_TABLE_SIZE), so that as many bits as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   553
 * possible will filter thru PAGE_HASH_FUNC() and PAGE_HASH_MUTEX().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   554
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   555
#define	PH_SHIFT_SIZE   (7)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   556
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   557
#define	PAGE_HASHSZ	page_hashsz
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   558
#define	PAGE_HASHAVELEN		4
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   559
#define	PAGE_HASH_FUNC(vp, off) \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   560
	((((uintptr_t)(off) >> PAGESHIFT) + \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   561
		((uintptr_t)(off) >> (PAGESHIFT + PH_SHIFT_SIZE)) + \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   562
		((uintptr_t)(vp) >> 3) + \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   563
		((uintptr_t)(vp) >> (3 + PH_SHIFT_SIZE)) + \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   564
		((uintptr_t)(vp) >> (3 + 2 * PH_SHIFT_SIZE))) & \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   565
		(PAGE_HASHSZ - 1))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   566
#ifdef _KERNEL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   567
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   568
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   569
 * The page hash value is re-hashed to an index for the ph_mutex array.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   570
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   571
 * For 64 bit kernels, the mutex array is padded out to prevent false
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   572
 * sharing of cache sub-blocks (64 bytes) of adjacent mutexes.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   573
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   574
 * For 32 bit kernels, we don't want to waste kernel address space with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   575
 * padding, so instead we rely on the hash function to introduce skew of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   576
 * adjacent vnode/offset indexes (the left shift part of the hash function).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   577
 * Since sizeof (kmutex_t) is 8, we shift an additional 3 to skew to a different
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   578
 * 64 byte sub-block.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   579
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   580
typedef struct pad_mutex {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   581
	kmutex_t	pad_mutex;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   582
#ifdef _LP64
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   583
	char		pad_pad[64 - sizeof (kmutex_t)];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   584
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   585
} pad_mutex_t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   586
extern pad_mutex_t ph_mutex[];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   587
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   588
#define	PAGE_HASH_MUTEX(x) \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   589
	&(ph_mutex[((x) + ((x) >> VP_SHIFT) + ((x) << 3)) & \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   590
		(PH_TABLE_SIZE - 1)].pad_mutex)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   591
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   592
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   593
 * Flags used while creating pages.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   594
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   595
#define	PG_EXCL		0x0001
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   596
#define	PG_WAIT		0x0002
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   597
#define	PG_PHYSCONTIG	0x0004		/* NOT SUPPORTED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   598
#define	PG_MATCH_COLOR	0x0008		/* SUPPORTED by free list routines */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   599
#define	PG_NORELOC	0x0010		/* Non-relocatable alloc hint. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   600
					/* Page must be PP_ISNORELOC */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   601
#define	PG_PANIC	0x0020		/* system will panic if alloc fails */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   602
#define	PG_PUSHPAGE	0x0040		/* alloc may use reserve */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   603
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   604
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   605
 * When p_selock has the SE_EWANTED bit set, threads waiting for SE_EXCL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   606
 * access are given priority over all other waiting threads.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   607
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   608
#define	SE_EWANTED	0x40000000
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   609
#define	PAGE_LOCKED(pp)		(((pp)->p_selock & ~SE_EWANTED) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   610
#define	PAGE_SHARED(pp)		(((pp)->p_selock & ~SE_EWANTED) > 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   611
#define	PAGE_EXCL(pp)		((pp)->p_selock < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   612
#define	PAGE_LOCKED_SE(pp, se)	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   613
	((se) == SE_EXCL ? PAGE_EXCL(pp) : PAGE_SHARED(pp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   614
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   615
extern	long page_hashsz;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   616
extern	page_t **page_hash;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   617
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   618
extern	kmutex_t page_llock;		/* page logical lock mutex */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   619
extern	kmutex_t freemem_lock;		/* freemem lock */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   620
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   621
extern	pgcnt_t	total_pages;		/* total pages in the system */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   622
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   623
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   624
 * Variables controlling locking of physical memory.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   625
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   626
extern	pgcnt_t	pages_pp_maximum;	/* tuning: lock + claim <= max */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   627
extern	void init_pages_pp_maximum(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   628
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   629
struct lgrp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   630
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   631
/* page_list_{add,sub} flags */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   632
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   633
/* which list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   634
#define	PG_FREE_LIST	0x0001
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   635
#define	PG_CACHE_LIST	0x0002
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   636
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   637
/* where on list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   638
#define	PG_LIST_TAIL	0x0010
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   639
#define	PG_LIST_HEAD	0x0020
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   640
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   641
/* called from */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   642
#define	PG_LIST_ISINIT	0x1000
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   643
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   644
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   645
 * Page frame operations.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   646
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   647
page_t	*page_lookup(struct vnode *, u_offset_t, se_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   648
page_t	*page_lookup_create(struct vnode *, u_offset_t, se_t, page_t *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   649
	spgcnt_t *, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   650
page_t	*page_lookup_nowait(struct vnode *, u_offset_t, se_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   651
page_t	*page_find(struct vnode *, u_offset_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   652
page_t	*page_exists(struct vnode *, u_offset_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   653
int	page_exists_physcontig(vnode_t *, u_offset_t, uint_t, page_t *[]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   654
int	page_exists_forreal(struct vnode *, u_offset_t, uint_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   655
void	page_needfree(spgcnt_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   656
page_t	*page_create(struct vnode *, u_offset_t, size_t, uint_t);
749
d7f9da43aeb7 6310079 contention for pidlock is a major bottleneck for the kenbus benchmark
susans
parents: 414
diff changeset
   657
int	page_alloc_pages(struct vnode *, struct seg *, caddr_t, page_t **,
d7f9da43aeb7 6310079 contention for pidlock is a major bottleneck for the kenbus benchmark
susans
parents: 414
diff changeset
   658
	page_t **, uint_t, int);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   659
page_t  *page_create_va_large(vnode_t *vp, u_offset_t off, size_t bytes,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   660
	uint_t flags, struct seg *seg, caddr_t vaddr, void *arg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   661
page_t	*page_create_va(struct vnode *, u_offset_t, size_t, uint_t,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   662
	struct seg *, caddr_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   663
int	page_create_wait(size_t npages, uint_t flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   664
void    page_create_putback(ssize_t npages);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   665
void	page_free(page_t *, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   666
void	page_free_at_startup(page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   667
void	page_free_pages(page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   668
void	free_vp_pages(struct vnode *, u_offset_t, size_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   669
int	page_reclaim(page_t *, kmutex_t *);
3253
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
   670
int	page_reclaim_pages(page_t *, kmutex_t *, uint_t);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   671
void	page_destroy(page_t *, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   672
void	page_destroy_pages(page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   673
void	page_destroy_free(page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   674
void	page_rename(page_t *, struct vnode *, u_offset_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   675
int	page_hashin(page_t *, struct vnode *, u_offset_t, kmutex_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   676
void	page_hashout(page_t *, kmutex_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   677
int	page_num_hashin(pfn_t, struct vnode *, u_offset_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   678
void	page_add(page_t **, page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   679
void	page_add_common(page_t **, page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   680
void	page_sub(page_t **, page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   681
void	page_sub_common(page_t **, page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   682
page_t	*page_get_freelist(struct vnode *, u_offset_t, struct seg *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   683
		caddr_t, size_t, uint_t, struct lgrp *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   684
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   685
page_t	*page_get_cachelist(struct vnode *, u_offset_t, struct seg *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   686
		caddr_t, uint_t, struct lgrp *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   687
void	page_list_add(page_t *, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   688
void	page_boot_demote(page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   689
void	page_promote_size(page_t *, uint_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   690
void	page_list_add_pages(page_t *, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   691
void	page_list_sub(page_t *, int);
917
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   692
void	page_list_sub_pages(page_t *, uint_t);
414
c62c3f13a640 6286816 page_numtopp_nolock is inefficent
kchow
parents: 73
diff changeset
   693
void	page_list_xfer(page_t *, int, int);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   694
void	page_list_break(page_t **, page_t **, size_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   695
void	page_list_concat(page_t **, page_t **);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   696
void	page_vpadd(page_t **, page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   697
void	page_vpsub(page_t **, page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   698
int	page_lock(page_t *, se_t, kmutex_t *, reclaim_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   699
int	page_lock_es(page_t *, se_t, kmutex_t *, reclaim_t, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   700
void page_lock_clr_exclwanted(page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   701
int	page_trylock(page_t *, se_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   702
int	page_try_reclaim_lock(page_t *, se_t, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   703
int	page_tryupgrade(page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   704
void	page_downgrade(page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   705
void	page_unlock(page_t *);
3253
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
   706
void	page_unlock_nocapture(page_t *);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   707
void	page_lock_delete(page_t *);
3253
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
   708
int	page_deleted(page_t *);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   709
int	page_pp_lock(page_t *, int, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   710
void	page_pp_unlock(page_t *, int, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   711
int	page_resv(pgcnt_t, uint_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   712
void	page_unresv(pgcnt_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   713
void	page_pp_useclaim(page_t *, page_t *, uint_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   714
int	page_addclaim(page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   715
int	page_subclaim(page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   716
int	page_addclaim_pages(page_t **);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   717
int	page_subclaim_pages(page_t **);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   718
pfn_t	page_pptonum(page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   719
page_t	*page_numtopp(pfn_t, se_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   720
page_t	*page_numtopp_noreclaim(pfn_t, se_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   721
page_t	*page_numtopp_nolock(pfn_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   722
page_t	*page_numtopp_nowait(pfn_t, se_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   723
page_t  *page_first();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   724
page_t  *page_next(page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   725
page_t  *page_list_next(page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   726
page_t	*page_nextn(page_t *, ulong_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   727
page_t	*page_next_scan_init(void **);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   728
page_t	*page_next_scan_large(page_t *, ulong_t *, void **);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   729
void    prefetch_page_r(void *);
3253
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
   730
int	ppcopy(page_t *, page_t *);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   731
void	page_relocate_hash(page_t *, page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   732
void	pagezero(page_t *, uint_t, uint_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   733
void	pagescrub(page_t *, uint_t, uint_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   734
void	page_io_lock(page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   735
void	page_io_unlock(page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   736
int	page_io_trylock(page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   737
int	page_iolock_assert(page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   738
void	page_iolock_init(page_t *);
2999
3caa9d682245 6393251 data corruption caused by VMODSORT problem
stans
parents: 2961
diff changeset
   739
void	page_io_wait(page_t *);
3caa9d682245 6393251 data corruption caused by VMODSORT problem
stans
parents: 2961
diff changeset
   740
int	page_io_locked(page_t *);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   741
pgcnt_t	page_busy(int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   742
void	page_lock_init(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   743
ulong_t	page_share_cnt(page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   744
int	page_isshared(page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   745
int	page_isfree(page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   746
int	page_isref(page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   747
int	page_ismod(page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   748
int	page_release(page_t *, int);
917
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   749
void	page_retire_init(void);
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   750
int	page_retire(uint64_t, uchar_t);
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   751
int	page_retire_check(uint64_t, uint64_t *);
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   752
int	page_unretire(uint64_t);
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   753
int	page_unretire_pp(page_t *, int);
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   754
void	page_tryretire(page_t *);
3253
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
   755
void	page_retire_mdboot();
917
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   756
void	page_clrtoxic(page_t *, uchar_t);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   757
void	page_settoxic(page_t *, uchar_t);
917
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   758
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   759
int	page_mem_avail(pgcnt_t);
2048
8ceabdf91507 4034947 anon_swap_adjust() should call kmem_reap() if availrmem is low.
stans
parents: 1841
diff changeset
   760
int	page_reclaim_mem(pgcnt_t, pgcnt_t, int);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   761
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   762
void page_set_props(page_t *, uint_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   763
void page_clr_all_props(page_t *);
917
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   764
int page_clear_lck_cow(page_t *, int);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   765
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   766
kmutex_t	*page_vnode_mutex(struct vnode *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   767
kmutex_t	*page_se_mutex(struct page *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   768
kmutex_t	*page_szc_lock(struct page *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   769
int		page_szc_lock_assert(struct page *pp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   770
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   771
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   772
 * Page relocation interfaces. page_relocate() is generic.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   773
 * page_get_replacement_page() is provided by the PSM.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   774
 * page_free_replacement_page() is generic.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   775
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   776
int group_page_trylock(page_t *, se_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   777
void group_page_unlock(page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   778
int page_relocate(page_t **, page_t **, int, int, spgcnt_t *, struct lgrp *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   779
int do_page_relocate(page_t **, page_t **, int, spgcnt_t *, struct lgrp *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   780
page_t *page_get_replacement_page(page_t *, struct lgrp *, uint_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   781
void page_free_replacement_page(page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   782
int page_relocate_cage(page_t **, page_t **);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   783
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   784
int page_try_demote_pages(page_t *);
917
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   785
int page_try_demote_free_pages(page_t *);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   786
void page_demote_free_pages(page_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   787
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   788
struct anon_map;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   789
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   790
void page_mark_migrate(struct seg *, caddr_t, size_t, struct anon_map *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   791
    ulong_t, vnode_t *, u_offset_t, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   792
void page_migrate(struct seg *, caddr_t, page_t **, pgcnt_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   793
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   794
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   795
 * Tell the PIM we are adding physical memory
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   796
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   797
void add_physmem(page_t *, size_t, pfn_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   798
void add_physmem_cb(page_t *, pfn_t);	/* callback for page_t part */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   799
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   800
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   801
 * hw_page_array[] is configured with hardware supported page sizes by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   802
 * platform specific code.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   803
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   804
typedef struct {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   805
	size_t	hp_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   806
	uint_t	hp_shift;
2961
8b33bed4151e PSARC 2006/236 Hashed Cache index support
dp78419
parents: 2414
diff changeset
   807
	uint_t  hp_colors;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   808
	pgcnt_t	hp_pgcnt;	/* base pagesize cnt */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   809
} hw_pagesize_t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   810
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   811
extern hw_pagesize_t	hw_page_array[];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   812
extern uint_t		page_coloring_shift;
2961
8b33bed4151e PSARC 2006/236 Hashed Cache index support
dp78419
parents: 2414
diff changeset
   813
extern uint_t		page_colors_mask;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   814
extern int		cpu_page_colors;
2961
8b33bed4151e PSARC 2006/236 Hashed Cache index support
dp78419
parents: 2414
diff changeset
   815
extern uint_t		colorequiv;
8b33bed4151e PSARC 2006/236 Hashed Cache index support
dp78419
parents: 2414
diff changeset
   816
extern uchar_t		colorequivszc[];
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   817
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   818
uint_t	page_num_pagesizes(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   819
uint_t	page_num_user_pagesizes(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   820
size_t	page_get_pagesize(uint_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   821
size_t	page_get_user_pagesize(uint_t n);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   822
pgcnt_t	page_get_pagecnt(uint_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   823
uint_t	page_get_shift(uint_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   824
int	page_szc(size_t);
73
d6a2308c356e 6288365 memcntl panics on debug sun4v kernels for 4M pages
mec
parents: 0
diff changeset
   825
int	page_szc_user_filtered(size_t);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   826
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   827
/* page_get_replacement page flags */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   828
#define	PGR_SAMESZC	0x1	/* only look for page size same as orig */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   829
#define	PGR_NORELOC	0x2	/* allocate a P_NORELOC page */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   830
2961
8b33bed4151e PSARC 2006/236 Hashed Cache index support
dp78419
parents: 2414
diff changeset
   831
/*
8b33bed4151e PSARC 2006/236 Hashed Cache index support
dp78419
parents: 2414
diff changeset
   832
 * macros for "masked arithmetic"
8b33bed4151e PSARC 2006/236 Hashed Cache index support
dp78419
parents: 2414
diff changeset
   833
 * The purpose is to step through all combinations of a set of bits while
8b33bed4151e PSARC 2006/236 Hashed Cache index support
dp78419
parents: 2414
diff changeset
   834
 * keeping some other bits fixed. Fixed bits need not be contiguous. The
8b33bed4151e PSARC 2006/236 Hashed Cache index support
dp78419
parents: 2414
diff changeset
   835
 * variable bits need not be contiguous either, or even right aligned. The
8b33bed4151e PSARC 2006/236 Hashed Cache index support
dp78419
parents: 2414
diff changeset
   836
 * trick is to set all fixed bits to 1, then increment, then restore the
8b33bed4151e PSARC 2006/236 Hashed Cache index support
dp78419
parents: 2414
diff changeset
   837
 * fixed bits. If incrementing causes a carry from a low bit position, the
8b33bed4151e PSARC 2006/236 Hashed Cache index support
dp78419
parents: 2414
diff changeset
   838
 * carry propagates thru the fixed bits, because they are temporarily set to 1.
8b33bed4151e PSARC 2006/236 Hashed Cache index support
dp78419
parents: 2414
diff changeset
   839
 *	v is the value
8b33bed4151e PSARC 2006/236 Hashed Cache index support
dp78419
parents: 2414
diff changeset
   840
 *	i is the increment
8b33bed4151e PSARC 2006/236 Hashed Cache index support
dp78419
parents: 2414
diff changeset
   841
 *	eq_mask defines the fixed bits
8b33bed4151e PSARC 2006/236 Hashed Cache index support
dp78419
parents: 2414
diff changeset
   842
 *	mask limits the size of the result
8b33bed4151e PSARC 2006/236 Hashed Cache index support
dp78419
parents: 2414
diff changeset
   843
 */
8b33bed4151e PSARC 2006/236 Hashed Cache index support
dp78419
parents: 2414
diff changeset
   844
#define	ADD_MASKED(v, i, eq_mask, mask) \
8b33bed4151e PSARC 2006/236 Hashed Cache index support
dp78419
parents: 2414
diff changeset
   845
	(((((v) | (eq_mask)) + (i)) & (mask) & ~(eq_mask)) | ((v) & (eq_mask)))
8b33bed4151e PSARC 2006/236 Hashed Cache index support
dp78419
parents: 2414
diff changeset
   846
8b33bed4151e PSARC 2006/236 Hashed Cache index support
dp78419
parents: 2414
diff changeset
   847
/*
8b33bed4151e PSARC 2006/236 Hashed Cache index support
dp78419
parents: 2414
diff changeset
   848
 * convenience macro which increments by 1
8b33bed4151e PSARC 2006/236 Hashed Cache index support
dp78419
parents: 2414
diff changeset
   849
 */
8b33bed4151e PSARC 2006/236 Hashed Cache index support
dp78419
parents: 2414
diff changeset
   850
#define	INC_MASKED(v, eq_mask, mask) ADD_MASKED(v, 1, eq_mask, mask)
8b33bed4151e PSARC 2006/236 Hashed Cache index support
dp78419
parents: 2414
diff changeset
   851
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   852
#endif	/* _KERNEL */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   853
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   854
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   855
 * Constants used for the p_iolock_state
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   856
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   857
#define	PAGE_IO_INUSE	0x1
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   858
#define	PAGE_IO_WANTED	0x2
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   859
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   860
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   861
 * Constants used for page_release status
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   862
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   863
#define	PGREL_NOTREL    0x1
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   864
#define	PGREL_CLEAN	0x2
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   865
#define	PGREL_MOD	0x3
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   866
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   867
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   868
 * The p_state field holds what used to be the p_age and p_free
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   869
 * bits.  These fields are protected by p_selock (see above).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   870
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   871
#define	P_FREE		0x80		/* Page on free list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   872
#define	P_NORELOC	0x40		/* Page is non-relocatable */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   873
#define	P_MIGRATE	0x20		/* Migrate page on next touch */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   874
#define	P_SWAP		0x10		/* belongs to vnode that is V_ISSWAP */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   875
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   876
#define	PP_ISFREE(pp)		((pp)->p_state & P_FREE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   877
#define	PP_ISAGED(pp)		(((pp)->p_state & P_FREE) && \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   878
					((pp)->p_vnode == NULL))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   879
#define	PP_ISNORELOC(pp)	((pp)->p_state & P_NORELOC)
3290
256464cbb73c 4894692 caching data in heap inflates crash dump
johansen
parents: 3253
diff changeset
   880
#define	PP_ISKAS(pp)		(((pp)->p_vnode == &kvp) || \
256464cbb73c 4894692 caching data in heap inflates crash dump
johansen
parents: 3253
diff changeset
   881
					    ((pp)->p_vnode == &zvp))
256464cbb73c 4894692 caching data in heap inflates crash dump
johansen
parents: 3253
diff changeset
   882
#define	PP_ISNORELOCKERNEL(pp)	(PP_ISNORELOC(pp) && PP_ISKAS(pp))
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   883
#define	PP_ISMIGRATE(pp)	((pp)->p_state & P_MIGRATE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   884
#define	PP_ISSWAP(pp)		((pp)->p_state & P_SWAP)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   885
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   886
#define	PP_SETFREE(pp)		((pp)->p_state = ((pp)->p_state & ~P_MIGRATE) \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   887
				| P_FREE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   888
#define	PP_SETAGED(pp)		ASSERT(PP_ISAGED(pp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   889
#define	PP_SETNORELOC(pp)	((pp)->p_state |= P_NORELOC)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   890
#define	PP_SETMIGRATE(pp)	((pp)->p_state |= P_MIGRATE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   891
#define	PP_SETSWAP(pp)		((pp)->p_state |= P_SWAP)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   892
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   893
#define	PP_CLRFREE(pp)		((pp)->p_state &= ~P_FREE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   894
#define	PP_CLRAGED(pp)		ASSERT(!PP_ISAGED(pp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   895
#define	PP_CLRNORELOC(pp)	((pp)->p_state &= ~P_NORELOC)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   896
#define	PP_CLRMIGRATE(pp)	((pp)->p_state &= ~P_MIGRATE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   897
#define	PP_CLRSWAP(pp)		((pp)->p_state &= ~P_SWAP)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   898
917
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   899
/*
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   900
 * Flags for page_t p_toxic, for tracking memory hardware errors.
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   901
 *
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   902
 * These flags are OR'ed into p_toxic with page_settoxic() to track which
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   903
 * error(s) have occurred on a given page. The flags are cleared with
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   904
 * page_clrtoxic(). Both page_settoxic() and page_cleartoxic use atomic
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   905
 * primitives to manipulate the p_toxic field so no other locking is needed.
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   906
 *
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   907
 * When an error occurs on a page, p_toxic is set to record the error. The
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   908
 * error could be a memory error or something else (i.e. a datapath). The Page
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   909
 * Retire mechanism does not try to determine the exact cause of the error;
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   910
 * Page Retire rightly leaves that sort of determination to FMA's Diagnostic
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   911
 * Engine (DE).
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   912
 *
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   913
 * Note that, while p_toxic bits can be set without holding any locks, they
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   914
 * should only be cleared while holding the page exclusively locked.
3253
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
   915
 * There is one exception to this, the PR_CAPTURE bit is protected by a mutex
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
   916
 * within the page capture logic and thus to set or clear the bit, that mutex
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
   917
 * needs to be held.  The page does not need to be locked but the page_clrtoxic
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
   918
 * function must be used as we need an atomic operation.
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
   919
 * Also note that there is what amounts to a hack to prevent recursion with
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
   920
 * large pages such that if we are unlocking a page and the PR_CAPTURE bit is
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
   921
 * set, we will only try to capture the page if the current threads T_CAPTURING
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
   922
 * flag is not set.  If the flag is set, the unlock will not try to capture
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
   923
 * the page even though the PR_CAPTURE bit is set.
917
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   924
 *
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   925
 * Pages with PR_UE or PR_FMA flags are retired unconditionally, while pages
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   926
 * with PR_MCE are retired if the system has not retired too many of them.
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   927
 *
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   928
 * A page must be exclusively locked to be retired. Pages can be retired if
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   929
 * they are mapped, modified, or both, as long as they are not marked PR_UE,
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   930
 * since pages with uncorrectable errors cannot be relocated in memory.
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   931
 * Once a page has been successfully retired it is zeroed, attached to the
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   932
 * retired_pages vnode and, finally, PR_RETIRED is set in p_toxic. The other
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   933
 * p_toxic bits are NOT cleared. Pages are not left locked after retiring them
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   934
 * to avoid special case code throughout the kernel; rather, page_*lock() will
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   935
 * fail to lock the page, unless SE_RETIRED is passed as an argument.
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   936
 *
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   937
 * While we have your attention, go take a look at the comments at the
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   938
 * beginning of page_retire.c too.
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   939
 */
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   940
#define	PR_OK		0x00	/* no problem */
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   941
#define	PR_MCE		0x01	/* page has seen two or more CEs */
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   942
#define	PR_UE		0x02	/* page has an unhandled UE */
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   943
#define	PR_UE_SCRUBBED	0x04	/* page has seen a UE but was cleaned */
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   944
#define	PR_FMA		0x08	/* A DE wants this page retired */
3253
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
   945
#define	PR_CAPTURE	0x10	/* Generic page capture flag */
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
   946
#define	PR_RESV		0x20	/* Reserved for future use */
917
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   947
#define	PR_MSG		0x40	/* message(s) already printed for this page */
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   948
#define	PR_RETIRED	0x80	/* This page has been retired */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   949
917
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   950
#define	PR_REASONS	(PR_UE | PR_MCE | PR_FMA)
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   951
#define	PR_TOXIC	(PR_UE)
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   952
#define	PR_ERRMASK	(PR_UE | PR_UE_SCRUBBED | PR_MCE | PR_FMA)
3253
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
   953
#define	PR_TOXICFLAGS	(0xCF)
917
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   954
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   955
#define	PP_RETIRED(pp)	((pp)->p_toxic & PR_RETIRED)
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   956
#define	PP_TOXIC(pp)	((pp)->p_toxic & PR_TOXIC)
a3d1e8247fa0 4908967 toxic page handling on shutdown takes disproportionate amount of time
elowe
parents: 749
diff changeset
   957
#define	PP_PR_REQ(pp)	(((pp)->p_toxic & PR_REASONS) && !PP_RETIRED(pp))
973
d16e094eee6e 6272608 gcc and pcfs don't get along
elowe
parents: 917
diff changeset
   958
#define	PP_PR_NOSHARE(pp)						\
d16e094eee6e 6272608 gcc and pcfs don't get along
elowe
parents: 917
diff changeset
   959
	((((pp)->p_toxic & (PR_RETIRED | PR_FMA | PR_UE)) == PR_FMA) &&	\
3290
256464cbb73c 4894692 caching data in heap inflates crash dump
johansen
parents: 3253
diff changeset
   960
	!PP_ISKAS(pp))
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   961
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   962
/*
3253
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
   963
 * Flags for page_unretire_pp
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
   964
 */
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
   965
#define	PR_UNR_FREE	0x1
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
   966
#define	PR_UNR_CLEAN	0x2
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
   967
#define	PR_UNR_TEMP	0x4
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
   968
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
   969
/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   970
 * kpm large page description.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   971
 * The virtual address range of segkpm is divided into chunks of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   972
 * kpm_pgsz. Each chunk is controlled by a kpm_page_t. The ushort
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   973
 * is sufficient for 2^^15 * PAGESIZE, so e.g. the maximum kpm_pgsz
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   974
 * for 8K is 256M and 2G for 64K pages. It it kept as small as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   975
 * possible to save physical memory space.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   976
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   977
 * There are 2 segkpm mapping windows within in the virtual address
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   978
 * space when we have to prevent VAC alias conflicts. The so called
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   979
 * Alias window (mappings are always by PAGESIZE) is controlled by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   980
 * kp_refcnta. The regular window is controlled by kp_refcnt for the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   981
 * normal operation, which is to use the largest available pagesize.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   982
 * When VAC alias conflicts are present within a chunk in the regular
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   983
 * window the large page mapping is broken up into smaller PAGESIZE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   984
 * mappings. kp_refcntc is used to control the pages that are invoked
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   985
 * in the conflict and kp_refcnts holds the active mappings done
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   986
 * with the small page size. In non vac conflict mode kp_refcntc is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   987
 * also used as "go" indication (-1) for the trap level tsbmiss
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   988
 * handler.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   989
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   990
typedef struct kpm_page {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   991
	short kp_refcnt;	/* pages mapped large */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   992
	short kp_refcnta;	/* pages mapped in Alias window */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   993
	short kp_refcntc;	/* TL-tsbmiss flag; #vac alias conflict pages */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   994
	short kp_refcnts;	/* vac alias: pages mapped small */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   995
} kpm_page_t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   996
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   997
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   998
 * Note: khl_lock offset changes must be reflected in sfmmu_asm.s
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   999
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1000
typedef struct kpm_hlk {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1001
	kmutex_t khl_mutex;	/* kpm_page mutex */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1002
	uint_t   khl_lock;	/* trap level tsbmiss handling */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1003
} kpm_hlk_t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1004
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1005
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1006
 * kpm small page description.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1007
 * When kpm_pgsz is equal to PAGESIZE a smaller representation is used
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1008
 * to save memory space. Alias range mappings and regular segkpm
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1009
 * mappings are done in units of PAGESIZE and can share the mapping
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1010
 * information and the mappings are always distinguishable by their
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1011
 * virtual address. Other information neeeded for VAC conflict prevention
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1012
 * is already available on a per page basis. There are basically 3 states
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1013
 * a kpm_spage can have: not mapped (0), mapped in Alias range or virtually
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1014
 * uncached (1) and mapped in the regular segkpm window (-1). The -1 value
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1015
 * is also used as "go" indication for the segkpm trap level tsbmiss
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1016
 * handler for small pages (value is kept the same as it is used for large
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1017
 * mappings).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1018
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1019
typedef struct kpm_spage {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1020
	char	kp_mapped;	/* page mapped small */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1021
} kpm_spage_t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1022
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1023
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1024
 * Note: kshl_lock offset changes must be reflected in sfmmu_asm.s
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1025
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1026
typedef struct kpm_shlk {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1027
	uint_t   kshl_lock;	/* trap level tsbmiss handling */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1028
} kpm_shlk_t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1029
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1030
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1031
 * Each segment of physical memory is described by a memseg struct.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1032
 * Within a segment, memory is considered contiguous. The members
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1033
 * can be categorized as follows:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1034
 * . Platform independent:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1035
 *         pages, epages, pages_base, pages_end, next, lnext.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1036
 * . 64bit only but platform independent:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1037
 *         kpm_pbase, kpm_nkpmpgs, kpm_pages, kpm_spages.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1038
 * . Really platform or mmu specific:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1039
 *         pagespa, epagespa, nextpa, kpm_pagespa.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1040
 * . Mixed:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1041
 *         msegflags.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1042
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1043
struct memseg {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1044
	page_t *pages, *epages;		/* [from, to] in page array */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1045
	pfn_t pages_base, pages_end;	/* [from, to] in page numbers */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1046
	struct memseg *next;		/* next segment in list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1047
#if defined(__sparc)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1048
	struct memseg *lnext;		/* next segment in deleted list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1049
	uint64_t pagespa, epagespa;	/* [from, to] page array physical */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1050
	uint64_t nextpa;		/* physical next pointer */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1051
	pfn_t	kpm_pbase;		/* start of kpm range */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1052
	pgcnt_t kpm_nkpmpgs;		/* # of kpm_pgsz pages */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1053
	union _mseg_un {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1054
		kpm_page_t  *kpm_lpgs;	/* ptr to kpm_page array */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1055
		kpm_spage_t *kpm_spgs;	/* ptr to kpm_spage array */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1056
	} mseg_un;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1057
	uint64_t kpm_pagespa;		/* physical ptr to kpm (s)pages array */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1058
	uint_t msegflags;		/* memseg flags */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1059
#endif /* __sparc */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1060
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1061
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1062
/* memseg union aliases */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1063
#define	kpm_pages	mseg_un.kpm_lpgs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1064
#define	kpm_spages	mseg_un.kpm_spgs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1065
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1066
/* msegflags */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1067
#define	MEMSEG_DYNAMIC		0x1	/* DR: memory was added dynamically */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1068
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1069
/* memseg support macros */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1070
#define	MSEG_NPAGES(SEG)	((SEG)->pages_end - (SEG)->pages_base)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1071
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1072
/* memseg hash */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1073
#define	MEM_HASH_SHIFT		0x9
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1074
#define	N_MEM_SLOTS		0x200		/* must be a power of 2 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1075
#define	MEMSEG_PFN_HASH(pfn)	(((pfn)/mhash_per_slot) & (N_MEM_SLOTS - 1))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1076
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1077
/* memseg  externals */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1078
extern struct memseg *memsegs;		/* list of memory segments */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1079
extern ulong_t mhash_per_slot;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1080
extern uint64_t memsegspa;		/* memsegs as physical address */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1081
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1082
void build_pfn_hash();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1083
extern struct memseg *page_numtomemseg_nolock(pfn_t pfnum);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1084
3253
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1085
/*
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1086
 * page capture related info:
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1087
 * The page capture routines allow us to asynchronously capture given pages
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1088
 * for the explicit use of the requestor.  New requestors can be added by
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1089
 * explicitly adding themselves to the PC_* flags below and incrementing
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1090
 * PC_NUM_CALLBACKS as necessary.
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1091
 *
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1092
 * Subsystems using page capture must register a callback before attempting
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1093
 * to capture a page.  A duration of -1 will indicate that we will never give
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1094
 * up while trying to capture a page and will only stop trying to capture the
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1095
 * given page once we have successfully captured it.  Thus the user needs to be
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1096
 * aware of the behavior of all callers who have a duration of -1.
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1097
 *
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1098
 * For now, only /dev/physmem and page retire use the page capture interface
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1099
 * and only a single request can be outstanding for a given page.  Thus, if
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1100
 * /dev/phsymem wants a page and page retire also wants the same page, only
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1101
 * the page retire request will be honored until the point in time that the
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1102
 * page is actually retired, at which point in time, subsequent requests by
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1103
 * /dev/physmem will succeed if the CAPTURE_GET_RETIRED flag was set.
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1104
 */
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1105
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1106
#define	PC_RETIRE		(0)
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1107
#define	PC_PHYSMEM		(1)
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1108
#define	PC_NUM_CALLBACKS	(2)
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1109
#define	PC_MASK			((1 << PC_NUM_CALLBACKS) - 1)
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1110
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1111
#define	CAPTURE_RETIRE		(1 << PC_RETIRE)
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1112
#define	CAPTURE_PHYSMEM		(1 << PC_PHYSMEM)
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1113
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1114
#define	CAPTURE_ASYNC		(0x0200)
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1115
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1116
#define	CAPTURE_GET_RETIRED	(0x1000)
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1117
#define	CAPTURE_GET_CAGE	(0x2000)
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1118
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1119
struct page_capture_callback {
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1120
	int cb_active;		/* 1 means active, 0 means inactive */
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1121
	clock_t duration;	/* the length in time that we'll attempt to */
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1122
				/* capture this page asynchronously. (in HZ) */
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1123
	krwlock_t cb_rwlock;
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1124
	int (*cb_func)(page_t *, void *, uint_t); /* callback function */
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1125
};
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1126
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1127
extern kcondvar_t pc_cv;
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1128
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1129
void page_capture_register_callback(uint_t index, clock_t duration,
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1130
    int (*cb_func)(page_t *, void *, uint_t));
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1131
void page_capture_unregister_callback(uint_t index);
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1132
int page_trycapture(page_t *pp, uint_t szc, uint_t flags, void *datap);
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1133
void page_unlock_capture(page_t *pp);
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1134
int page_capture_unretire_pp(page_t *);
c929f34b62c5 PSARC 2006/360 Page retire and caged memory kstats
mec
parents: 2999
diff changeset
  1135
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1136
#ifdef	__cplusplus
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1137
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1138
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1139
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1140
#endif	/* _VM_PAGE_H */