1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _VM_SEG_SPT_H 27 #define _VM_SEG_SPT_H 28 29 #pragma ident "%Z%%M% %I% %E% SMI" 30 31 #ifdef __cplusplus 32 extern "C" { 33 #endif 34 35 #ifndef _ASM 36 37 #include <sys/types.h> 38 #include <sys/t_lock.h> 39 #include <sys/lgrp.h> 40 41 /* 42 * Passed data when creating spt segment. 43 */ 44 struct segspt_crargs { 45 struct seg *seg_spt; 46 struct anon_map *amp; 47 uint_t prot; 48 uint_t flags; 49 uint_t szc; 50 }; 51 52 typedef struct spt_data { 53 struct vnode *spt_vp; 54 struct anon_map *spt_amp; 55 size_t spt_realsize; 56 struct page **spt_ppa; 57 ushort_t *spt_ppa_lckcnt; 58 uint_t spt_prot; 59 kmutex_t spt_lock; 60 size_t spt_pcachecnt; /* # of times in pcache */ 61 uint_t spt_flags; /* Dynamic ISM or regular ISM */ 62 kcondvar_t spt_cv; 63 ushort_t spt_gen; /* only updated for DISM */ 64 /* 65 * Initial memory allocation policy 66 * used during pre-allocation done in shmat() 67 */ 68 lgrp_mem_policy_info_t spt_policy_info; 69 } spt_data_t; 70 71 /* 72 * Private data for spt_shm segment. 73 */ 74 typedef struct shm_data { 75 struct as *shm_sptas; 76 struct anon_map *shm_amp; 77 spgcnt_t shm_softlockcnt; /* # outstanding lock operations */ 78 struct seg *shm_sptseg; /* pointer to spt segment */ 79 char *shm_vpage; /* indicating locked pages */ 80 spgcnt_t shm_lckpgs; /* # of locked pages per attached seg */ 81 /* 82 * Memory allocation policy after shmat() 83 */ 84 lgrp_mem_policy_info_t shm_policy_info; 85 kmutex_t shm_segfree_syncmtx; /* barrier lock for segspt_shmfree() */ 86 } shm_data_t; 87 88 #define DISM_PG_LOCKED 0x1 /* DISM page is locked */ 89 #define DISM_PPA_CHANGED 0x2 /* DISM new lock, need to rebuild ppa */ 90 91 #define DISM_LOCK_MAX 0xfffe /* max number of locks per DISM page */ 92 #endif 93 94 #ifdef _KERNEL 95 96 #ifndef _ASM 97 98 /* 99 * Functions used in shm.c to call ISM. 100 */ 101 int sptcreate(size_t size, struct seg **sptseg, struct anon_map *amp, 102 uint_t prot, uint_t flags, uint_t szc); 103 void sptdestroy(struct as *, struct anon_map *); 104 int segspt_shmattach(struct seg *, caddr_t *); 105 106 #define isspt(sp) ((sp)->shm_sptinfo ? (sp)->shm_sptinfo->sptas : NULL) 107 #define spt_locked(a) ((a) & SHM_SHARE_MMU) 108 #define spt_pageable(a) ((a) & SHM_PAGEABLE) 109 #define spt_invalid(a) (spt_locked((a)) && spt_pageable((a))) 110 111 /* 112 * This can be applied to a segment with seg->s_ops == &segspt_shmops 113 * to determine the real size of the ISM segment. 114 */ 115 #define spt_realsize(seg) (((struct spt_data *)(((struct shm_data *)\ 116 ((seg)->s_data))->shm_sptseg->s_data))->spt_realsize) 117 118 /* 119 * This can be applied to a segment with seg->s_ops == &segspt_ops 120 * to determine the flags of the {D}ISM segment. 121 */ 122 #define spt_flags(seg) (((struct spt_data *)((seg)->s_data))->spt_flags) 123 124 /* 125 * For large page support 126 */ 127 extern int segvn_anypgsz; 128 129 #endif 130 131 /* 132 * In a 64-bit address space, we'll try to put ISM segments between 133 * PREDISM_BASE and PREDISM_BOUND. The HAT may use these constants to 134 * predict that a VA is contained by an ISM segment, which may optimize 135 * translation. The range must _only_ be treated as advisory; ISM segments 136 * may fall outside of the range, and non-ISM segments may be contained 137 * within the range. 138 * In order to avoid collision between ISM/DISM addresses with e.g. 139 * process heap addresses we will try to put ISM/DISM segments above 140 * PREDISM_1T_BASESHIFT (1T). 141 * The HAT is still expecting that any VA larger than PREDISM_BASESHIFT 142 * may belong to ISM/DISM (so on tlb miss it will probe first for 4M 143 * translation) 144 */ 145 #define PREDISM_BASESHIFT 33 146 #define PREDISM_1T_BASESHIFT 40 147 #define PREDISM_BASE ((uintptr_t)1 << PREDISM_BASESHIFT) 148 #define PREDISM_1T_BASE ((uintptr_t)1 << PREDISM_1T_BASESHIFT) 149 #define PREDISM_BOUND ((uintptr_t)1 << 63) 150 151 #endif /* _KERNEL */ 152 153 #ifdef __cplusplus 154 } 155 #endif 156 157 #endif /* _VM_SEG_SPT_H */ 158