summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/vm/seg_spt.h
blob: ebc2ebf465dd74e75c08e21d49adfadf9ecdb453 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef	_VM_SEG_SPT_H
#define	_VM_SEG_SPT_H

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#ifdef	__cplusplus
extern "C" {
#endif

#ifndef _ASM

#include <sys/types.h>
#include <sys/t_lock.h>
#include <sys/lgrp.h>

/*
 * Passed data when creating spt segment.
 */
struct  segspt_crargs {
	struct	seg	*seg_spt;
	struct anon_map *amp;
	uint_t		prot;
	uint_t		flags;
	uint_t		szc;
};

typedef struct spt_data {
	struct vnode	*spt_vp;
	struct anon_map	*spt_amp;
	size_t 		spt_realsize;
	struct page	**spt_ppa;
	ushort_t	*spt_ppa_lckcnt;
	uint_t		spt_prot;
	kmutex_t 	spt_lock;
	size_t		spt_pcachecnt;	/* # of times in pcache */
	uint_t		spt_flags;	/* Dynamic ISM or regular ISM */
	kcondvar_t	spt_cv;
	ushort_t	spt_gen;	/* only updated for DISM */
	/*
	 * Initial memory allocation policy
	 * used during pre-allocation done in shmat()
	 */
	lgrp_mem_policy_info_t	spt_policy_info;
} spt_data_t;

/*
 * Private data for spt_shm segment.
 */
typedef struct shm_data {
	struct as	*shm_sptas;
	struct anon_map *shm_amp;
	spgcnt_t	shm_softlockcnt; /* # outstanding lock operations */
	struct seg 	*shm_sptseg;	/* pointer to spt segment */
	char		*shm_vpage;	/* indicating locked pages */
	spgcnt_t	shm_lckpgs;	/* # of locked pages per attached seg */
	/*
	 * Memory allocation policy after shmat()
	 */
	lgrp_mem_policy_info_t	shm_policy_info;
	kmutex_t shm_segfree_syncmtx;	/* barrier lock for segspt_shmfree() */
} shm_data_t;

#define	DISM_PG_LOCKED		0x1	/* DISM page is locked */
#define	DISM_PPA_CHANGED	0x2	/* DISM new lock, need to rebuild ppa */

#define	DISM_LOCK_MAX		0xfffe	/* max number of locks per DISM page */
#endif

#ifdef _KERNEL

#ifndef _ASM

/*
 * Functions used in shm.c to call ISM.
 */
int	sptcreate(size_t size, struct seg **sptseg, struct anon_map *amp,
	    uint_t prot, uint_t flags, uint_t szc);
void	sptdestroy(struct as *, struct anon_map *);
int	segspt_shmattach(struct seg *, caddr_t *);

#define	isspt(sp)	((sp)->shm_sptinfo ? (sp)->shm_sptinfo->sptas : NULL)
#define	spt_locked(a)	((a) & SHM_SHARE_MMU)
#define	spt_pageable(a)	((a) & SHM_PAGEABLE)
#define	spt_invalid(a)	(spt_locked((a)) && spt_pageable((a)))

/*
 * This can be applied to a segment with seg->s_ops == &segspt_shmops
 * to determine the real size of the ISM segment.
 */
#define	spt_realsize(seg) (((struct spt_data *)(((struct shm_data *)\
			((seg)->s_data))->shm_sptseg->s_data))->spt_realsize)

/*
 * This can be applied to a segment with seg->s_ops == &segspt_ops
 * to determine the flags of the {D}ISM segment.
 */
#define	spt_flags(seg) (((struct spt_data *)((seg)->s_data))->spt_flags)

/*
 * For large page support
 */
extern int segvn_anypgsz;

#endif

/*
 * In a 64-bit address space, we'll try to put ISM segments between
 * PREDISM_BASE and PREDISM_BOUND.  The HAT may use these constants to
 * predict that a VA is contained by an ISM segment, which may optimize
 * translation.  The range must _only_ be treated as advisory; ISM segments
 * may fall outside of the range, and non-ISM segments may be contained
 * within the range.
 * In order to avoid collision between ISM/DISM addresses with e.g.
 * process heap addresses we will try to put ISM/DISM segments above
 * PREDISM_1T_BASESHIFT (1T).
 * The HAT is still expecting that any VA larger than PREDISM_BASESHIFT
 * may belong to ISM/DISM (so on tlb miss it will probe first for 4M
 * translation)
 */
#define	PREDISM_BASESHIFT	33
#define	PREDISM_1T_BASESHIFT	40
#define	PREDISM_BASE		((uintptr_t)1 << PREDISM_BASESHIFT)
#define	PREDISM_1T_BASE		((uintptr_t)1 << PREDISM_1T_BASESHIFT)
#define	PREDISM_BOUND		((uintptr_t)1 << 63)

#endif	/* _KERNEL */

#ifdef	__cplusplus
}
#endif

#endif	/* _VM_SEG_SPT_H */