1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate /* 31*7c478bd9Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988 32*7c478bd9Sstevel@tonic-gate * The Regents of the University of California 33*7c478bd9Sstevel@tonic-gate * All Rights Reserved 34*7c478bd9Sstevel@tonic-gate * 35*7c478bd9Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from 36*7c478bd9Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its 37*7c478bd9Sstevel@tonic-gate * contributors. 38*7c478bd9Sstevel@tonic-gate */ 39*7c478bd9Sstevel@tonic-gate 40*7c478bd9Sstevel@tonic-gate #ifndef _VM_SEG_H 41*7c478bd9Sstevel@tonic-gate #define _VM_SEG_H 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 44*7c478bd9Sstevel@tonic-gate 45*7c478bd9Sstevel@tonic-gate #include <sys/vnode.h> 46*7c478bd9Sstevel@tonic-gate #include <sys/avl.h> 47*7c478bd9Sstevel@tonic-gate #include <vm/seg_enum.h> 48*7c478bd9Sstevel@tonic-gate #include <vm/faultcode.h> 49*7c478bd9Sstevel@tonic-gate #include <vm/hat.h> 50*7c478bd9Sstevel@tonic-gate 51*7c478bd9Sstevel@tonic-gate #ifdef __cplusplus 52*7c478bd9Sstevel@tonic-gate extern "C" { 53*7c478bd9Sstevel@tonic-gate #endif 54*7c478bd9Sstevel@tonic-gate 55*7c478bd9Sstevel@tonic-gate /* 56*7c478bd9Sstevel@tonic-gate * VM - Segments. 57*7c478bd9Sstevel@tonic-gate */ 58*7c478bd9Sstevel@tonic-gate 59*7c478bd9Sstevel@tonic-gate /* 60*7c478bd9Sstevel@tonic-gate * kstat statistics for segment advise 61*7c478bd9Sstevel@tonic-gate */ 62*7c478bd9Sstevel@tonic-gate typedef struct { 63*7c478bd9Sstevel@tonic-gate kstat_named_t MADV_FREE_hit; 64*7c478bd9Sstevel@tonic-gate kstat_named_t MADV_FREE_miss; 65*7c478bd9Sstevel@tonic-gate } segadvstat_t; 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate /* 68*7c478bd9Sstevel@tonic-gate * memory object ids 69*7c478bd9Sstevel@tonic-gate */ 70*7c478bd9Sstevel@tonic-gate typedef struct memid { u_longlong_t val[2]; } memid_t; 71*7c478bd9Sstevel@tonic-gate 72*7c478bd9Sstevel@tonic-gate /* 73*7c478bd9Sstevel@tonic-gate * An address space contains a set of segments, managed by drivers. 74*7c478bd9Sstevel@tonic-gate * Drivers support mapped devices, sharing, copy-on-write, etc. 75*7c478bd9Sstevel@tonic-gate * 76*7c478bd9Sstevel@tonic-gate * The seg structure contains a lock to prevent races, the base virtual 77*7c478bd9Sstevel@tonic-gate * address and size of the segment, a back pointer to the containing 78*7c478bd9Sstevel@tonic-gate * address space, pointers to maintain an AVL tree of segments in the 79*7c478bd9Sstevel@tonic-gate * same address space, and procedure and data hooks for the driver. 80*7c478bd9Sstevel@tonic-gate * The AVL tree of segments for the address space is sorted by 81*7c478bd9Sstevel@tonic-gate * ascending base addresses and overlapping segments are not allowed. 82*7c478bd9Sstevel@tonic-gate * 83*7c478bd9Sstevel@tonic-gate * After a segment is created, faults may occur on pages of the segment. 84*7c478bd9Sstevel@tonic-gate * When a fault occurs, the fault handling code must get the desired 85*7c478bd9Sstevel@tonic-gate * object and set up the hardware translation to the object. For some 86*7c478bd9Sstevel@tonic-gate * objects, the fault handling code also implements copy-on-write. 87*7c478bd9Sstevel@tonic-gate * 88*7c478bd9Sstevel@tonic-gate * When the hat wants to unload a translation, it can call the unload 89*7c478bd9Sstevel@tonic-gate * routine which is responsible for processing reference and modify bits. 90*7c478bd9Sstevel@tonic-gate * 91*7c478bd9Sstevel@tonic-gate * Each segment is protected by it's containing address space lock. To 92*7c478bd9Sstevel@tonic-gate * access any field in the segment structure, the "as" must be locked. 93*7c478bd9Sstevel@tonic-gate * If a segment field is to be modified, the address space lock must be 94*7c478bd9Sstevel@tonic-gate * write locked. 95*7c478bd9Sstevel@tonic-gate */ 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate struct seg { 98*7c478bd9Sstevel@tonic-gate caddr_t s_base; /* base virtual address */ 99*7c478bd9Sstevel@tonic-gate size_t s_size; /* size in bytes */ 100*7c478bd9Sstevel@tonic-gate uint_t s_szc; /* max page size code */ 101*7c478bd9Sstevel@tonic-gate uint_t s_flags; /* flags for segment, see below */ 102*7c478bd9Sstevel@tonic-gate struct as *s_as; /* containing address space */ 103*7c478bd9Sstevel@tonic-gate avl_node_t s_tree; /* AVL tree links to segs in this as */ 104*7c478bd9Sstevel@tonic-gate struct seg_ops *s_ops; /* ops vector: see below */ 105*7c478bd9Sstevel@tonic-gate void *s_data; /* private data for instance */ 106*7c478bd9Sstevel@tonic-gate }; 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate #define S_PURGE (0x01) /* seg should be purged in as_gap() */ 109*7c478bd9Sstevel@tonic-gate 110*7c478bd9Sstevel@tonic-gate struct seg_ops { 111*7c478bd9Sstevel@tonic-gate int (*dup)(struct seg *, struct seg *); 112*7c478bd9Sstevel@tonic-gate int (*unmap)(struct seg *, caddr_t, size_t); 113*7c478bd9Sstevel@tonic-gate void (*free)(struct seg *); 114*7c478bd9Sstevel@tonic-gate faultcode_t (*fault)(struct hat *, struct seg *, caddr_t, size_t, 115*7c478bd9Sstevel@tonic-gate enum fault_type, enum seg_rw); 116*7c478bd9Sstevel@tonic-gate faultcode_t (*faulta)(struct seg *, caddr_t); 117*7c478bd9Sstevel@tonic-gate int (*setprot)(struct seg *, caddr_t, size_t, uint_t); 118*7c478bd9Sstevel@tonic-gate int (*checkprot)(struct seg *, caddr_t, size_t, uint_t); 119*7c478bd9Sstevel@tonic-gate int (*kluster)(struct seg *, caddr_t, ssize_t); 120*7c478bd9Sstevel@tonic-gate size_t (*swapout)(struct seg *); 121*7c478bd9Sstevel@tonic-gate int (*sync)(struct seg *, caddr_t, size_t, int, uint_t); 122*7c478bd9Sstevel@tonic-gate size_t (*incore)(struct seg *, caddr_t, size_t, char *); 123*7c478bd9Sstevel@tonic-gate int (*lockop)(struct seg *, caddr_t, size_t, int, int, ulong_t *, 124*7c478bd9Sstevel@tonic-gate size_t); 125*7c478bd9Sstevel@tonic-gate int (*getprot)(struct seg *, caddr_t, size_t, uint_t *); 126*7c478bd9Sstevel@tonic-gate u_offset_t (*getoffset)(struct seg *, caddr_t); 127*7c478bd9Sstevel@tonic-gate int (*gettype)(struct seg *, caddr_t); 128*7c478bd9Sstevel@tonic-gate int (*getvp)(struct seg *, caddr_t, struct vnode **); 129*7c478bd9Sstevel@tonic-gate int (*advise)(struct seg *, caddr_t, size_t, uint_t); 130*7c478bd9Sstevel@tonic-gate void (*dump)(struct seg *); 131*7c478bd9Sstevel@tonic-gate int (*pagelock)(struct seg *, caddr_t, size_t, struct page ***, 132*7c478bd9Sstevel@tonic-gate enum lock_type, enum seg_rw); 133*7c478bd9Sstevel@tonic-gate int (*setpagesize)(struct seg *, caddr_t, size_t, uint_t); 134*7c478bd9Sstevel@tonic-gate int (*getmemid)(struct seg *, caddr_t, memid_t *); 135*7c478bd9Sstevel@tonic-gate struct lgrp_mem_policy_info *(*getpolicy)(struct seg *, caddr_t); 136*7c478bd9Sstevel@tonic-gate }; 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate #ifdef _KERNEL 139*7c478bd9Sstevel@tonic-gate /* 140*7c478bd9Sstevel@tonic-gate * Generic segment operations 141*7c478bd9Sstevel@tonic-gate */ 142*7c478bd9Sstevel@tonic-gate extern void seg_init(void); 143*7c478bd9Sstevel@tonic-gate extern struct seg *seg_alloc(struct as *as, caddr_t base, size_t size); 144*7c478bd9Sstevel@tonic-gate extern int seg_attach(struct as *as, caddr_t base, size_t size, 145*7c478bd9Sstevel@tonic-gate struct seg *seg); 146*7c478bd9Sstevel@tonic-gate extern void seg_unmap(struct seg *seg); 147*7c478bd9Sstevel@tonic-gate extern void seg_free(struct seg *seg); 148*7c478bd9Sstevel@tonic-gate 149*7c478bd9Sstevel@tonic-gate /* 150*7c478bd9Sstevel@tonic-gate * functions for pagelock cache support 151*7c478bd9Sstevel@tonic-gate */ 152*7c478bd9Sstevel@tonic-gate extern void seg_ppurge(struct seg *seg); 153*7c478bd9Sstevel@tonic-gate extern void seg_ppurge_seg(int (*callback)()); 154*7c478bd9Sstevel@tonic-gate extern void seg_pinactive(struct seg *seg, caddr_t addr, size_t len, 155*7c478bd9Sstevel@tonic-gate struct page **pp, enum seg_rw rw, int (*callback)()); 156*7c478bd9Sstevel@tonic-gate extern int seg_pinsert_check(struct seg *seg, size_t len, uint_t flags); 157*7c478bd9Sstevel@tonic-gate extern int seg_pinsert(struct seg *seg, caddr_t addr, size_t len, 158*7c478bd9Sstevel@tonic-gate struct page **pp, enum seg_rw rw, uint_t flags, 159*7c478bd9Sstevel@tonic-gate int (*callback)()); 160*7c478bd9Sstevel@tonic-gate extern struct page **seg_plookup(struct seg *seg, caddr_t addr, 161*7c478bd9Sstevel@tonic-gate size_t len, enum seg_rw rw); 162*7c478bd9Sstevel@tonic-gate extern void seg_pasync_thread(void); 163*7c478bd9Sstevel@tonic-gate extern void seg_preap(void); 164*7c478bd9Sstevel@tonic-gate 165*7c478bd9Sstevel@tonic-gate extern int seg_preapahead; 166*7c478bd9Sstevel@tonic-gate extern segadvstat_t segadvstat; 167*7c478bd9Sstevel@tonic-gate /* 168*7c478bd9Sstevel@tonic-gate * Flags for pagelock cache support 169*7c478bd9Sstevel@tonic-gate */ 170*7c478bd9Sstevel@tonic-gate #define SEGP_ASYNC_FLUSH 0x1 /* flushed by async thread */ 171*7c478bd9Sstevel@tonic-gate #define SEGP_FORCE_WIRED 0x2 /* skip check against seg_pwindow */ 172*7c478bd9Sstevel@tonic-gate 173*7c478bd9Sstevel@tonic-gate /* 174*7c478bd9Sstevel@tonic-gate * Return values for seg_pinsert and seg_pinsert_check functions. 175*7c478bd9Sstevel@tonic-gate */ 176*7c478bd9Sstevel@tonic-gate #define SEGP_SUCCESS 0 /* seg_pinsert() succeeded */ 177*7c478bd9Sstevel@tonic-gate #define SEGP_FAIL 1 /* seg_pinsert() failed */ 178*7c478bd9Sstevel@tonic-gate 179*7c478bd9Sstevel@tonic-gate /* Page status bits for segop_incore */ 180*7c478bd9Sstevel@tonic-gate #define SEG_PAGE_INCORE 0x01 /* VA has a page backing it */ 181*7c478bd9Sstevel@tonic-gate #define SEG_PAGE_LOCKED 0x02 /* VA has a page that is locked */ 182*7c478bd9Sstevel@tonic-gate #define SEG_PAGE_HASCOW 0x04 /* VA has a page with a copy-on-write */ 183*7c478bd9Sstevel@tonic-gate #define SEG_PAGE_SOFTLOCK 0x08 /* VA has a page with softlock held */ 184*7c478bd9Sstevel@tonic-gate #define SEG_PAGE_VNODEBACKED 0x10 /* Segment is backed by a vnode */ 185*7c478bd9Sstevel@tonic-gate #define SEG_PAGE_ANON 0x20 /* VA has an anonymous page */ 186*7c478bd9Sstevel@tonic-gate #define SEG_PAGE_VNODE 0x40 /* VA has a vnode page backing it */ 187*7c478bd9Sstevel@tonic-gate 188*7c478bd9Sstevel@tonic-gate #define SEGOP_DUP(s, n) (*(s)->s_ops->dup)((s), (n)) 189*7c478bd9Sstevel@tonic-gate #define SEGOP_UNMAP(s, a, l) (*(s)->s_ops->unmap)((s), (a), (l)) 190*7c478bd9Sstevel@tonic-gate #define SEGOP_FREE(s) (*(s)->s_ops->free)((s)) 191*7c478bd9Sstevel@tonic-gate #define SEGOP_FAULT(h, s, a, l, t, rw) \ 192*7c478bd9Sstevel@tonic-gate (*(s)->s_ops->fault)((h), (s), (a), (l), (t), (rw)) 193*7c478bd9Sstevel@tonic-gate #define SEGOP_FAULTA(s, a) (*(s)->s_ops->faulta)((s), (a)) 194*7c478bd9Sstevel@tonic-gate #define SEGOP_SETPROT(s, a, l, p) (*(s)->s_ops->setprot)((s), (a), (l), (p)) 195*7c478bd9Sstevel@tonic-gate #define SEGOP_CHECKPROT(s, a, l, p) (*(s)->s_ops->checkprot)((s), (a), (l), (p)) 196*7c478bd9Sstevel@tonic-gate #define SEGOP_KLUSTER(s, a, d) (*(s)->s_ops->kluster)((s), (a), (d)) 197*7c478bd9Sstevel@tonic-gate #define SEGOP_SWAPOUT(s) (*(s)->s_ops->swapout)((s)) 198*7c478bd9Sstevel@tonic-gate #define SEGOP_SYNC(s, a, l, atr, f) \ 199*7c478bd9Sstevel@tonic-gate (*(s)->s_ops->sync)((s), (a), (l), (atr), (f)) 200*7c478bd9Sstevel@tonic-gate #define SEGOP_INCORE(s, a, l, v) (*(s)->s_ops->incore)((s), (a), (l), (v)) 201*7c478bd9Sstevel@tonic-gate #define SEGOP_LOCKOP(s, a, l, atr, op, b, p) \ 202*7c478bd9Sstevel@tonic-gate (*(s)->s_ops->lockop)((s), (a), (l), (atr), (op), (b), (p)) 203*7c478bd9Sstevel@tonic-gate #define SEGOP_GETPROT(s, a, l, p) (*(s)->s_ops->getprot)((s), (a), (l), (p)) 204*7c478bd9Sstevel@tonic-gate #define SEGOP_GETOFFSET(s, a) (*(s)->s_ops->getoffset)((s), (a)) 205*7c478bd9Sstevel@tonic-gate #define SEGOP_GETTYPE(s, a) (*(s)->s_ops->gettype)((s), (a)) 206*7c478bd9Sstevel@tonic-gate #define SEGOP_GETVP(s, a, vpp) (*(s)->s_ops->getvp)((s), (a), (vpp)) 207*7c478bd9Sstevel@tonic-gate #define SEGOP_ADVISE(s, a, l, b) (*(s)->s_ops->advise)((s), (a), (l), (b)) 208*7c478bd9Sstevel@tonic-gate #define SEGOP_DUMP(s) (*(s)->s_ops->dump)((s)) 209*7c478bd9Sstevel@tonic-gate #define SEGOP_PAGELOCK(s, a, l, p, t, rw) \ 210*7c478bd9Sstevel@tonic-gate (*(s)->s_ops->pagelock)((s), (a), (l), (p), (t), (rw)) 211*7c478bd9Sstevel@tonic-gate #define SEGOP_SETPAGESIZE(s, a, l, szc) \ 212*7c478bd9Sstevel@tonic-gate (*(s)->s_ops->setpagesize)((s), (a), (l), (szc)) 213*7c478bd9Sstevel@tonic-gate #define SEGOP_GETMEMID(s, a, mp) (*(s)->s_ops->getmemid)((s), (a), (mp)) 214*7c478bd9Sstevel@tonic-gate #define SEGOP_GETPOLICY(s, a) (*(s)->s_ops->getpolicy)((s), (a)) 215*7c478bd9Sstevel@tonic-gate 216*7c478bd9Sstevel@tonic-gate #define seg_page(seg, addr) \ 217*7c478bd9Sstevel@tonic-gate (((uintptr_t)((addr) - (seg)->s_base)) >> PAGESHIFT) 218*7c478bd9Sstevel@tonic-gate 219*7c478bd9Sstevel@tonic-gate #define seg_pages(seg) \ 220*7c478bd9Sstevel@tonic-gate (((uintptr_t)((seg)->s_size + PAGEOFFSET)) >> PAGESHIFT) 221*7c478bd9Sstevel@tonic-gate 222*7c478bd9Sstevel@tonic-gate #define IE_NOMEM -1 /* internal to seg layer */ 223*7c478bd9Sstevel@tonic-gate #define IE_RETRY -2 /* internal to seg layer */ 224*7c478bd9Sstevel@tonic-gate #define IE_REATTACH -3 /* internal to seg layer */ 225*7c478bd9Sstevel@tonic-gate 226*7c478bd9Sstevel@tonic-gate /* Delay/retry factors for seg_p_mem_config_pre_del */ 227*7c478bd9Sstevel@tonic-gate #define SEGP_PREDEL_DELAY_FACTOR 4 228*7c478bd9Sstevel@tonic-gate /* 229*7c478bd9Sstevel@tonic-gate * As a workaround to being unable to purge the pagelock 230*7c478bd9Sstevel@tonic-gate * cache during a DR delete memory operation, we use 231*7c478bd9Sstevel@tonic-gate * a stall threshold that is twice the maximum seen 232*7c478bd9Sstevel@tonic-gate * during testing. This workaround will be removed 233*7c478bd9Sstevel@tonic-gate * when a suitable fix is found. 234*7c478bd9Sstevel@tonic-gate */ 235*7c478bd9Sstevel@tonic-gate #define SEGP_STALL_SECONDS 25 236*7c478bd9Sstevel@tonic-gate #define SEGP_STALL_THRESHOLD \ 237*7c478bd9Sstevel@tonic-gate (SEGP_STALL_SECONDS * SEGP_PREDEL_DELAY_FACTOR) 238*7c478bd9Sstevel@tonic-gate 239*7c478bd9Sstevel@tonic-gate #ifdef VMDEBUG 240*7c478bd9Sstevel@tonic-gate 241*7c478bd9Sstevel@tonic-gate uint_t seg_page(struct seg *, caddr_t); 242*7c478bd9Sstevel@tonic-gate uint_t seg_pages(struct seg *); 243*7c478bd9Sstevel@tonic-gate 244*7c478bd9Sstevel@tonic-gate #endif /* VMDEBUG */ 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 247*7c478bd9Sstevel@tonic-gate 248*7c478bd9Sstevel@tonic-gate #ifdef __cplusplus 249*7c478bd9Sstevel@tonic-gate } 250*7c478bd9Sstevel@tonic-gate #endif 251*7c478bd9Sstevel@tonic-gate 252*7c478bd9Sstevel@tonic-gate #endif /* _VM_SEG_H */ 253