xref: /onnv-gate/usr/src/uts/common/sys/lgrp.h (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #ifndef	_LGRP_H
28*0Sstevel@tonic-gate #define	_LGRP_H
29*0Sstevel@tonic-gate 
30*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
31*0Sstevel@tonic-gate 
32*0Sstevel@tonic-gate /*
33*0Sstevel@tonic-gate  * locality group definitions for kernel
34*0Sstevel@tonic-gate  */
35*0Sstevel@tonic-gate 
36*0Sstevel@tonic-gate #include <sys/types.h>
37*0Sstevel@tonic-gate 
38*0Sstevel@tonic-gate #ifdef	__cplusplus
39*0Sstevel@tonic-gate extern "C" {
40*0Sstevel@tonic-gate #endif
41*0Sstevel@tonic-gate 
42*0Sstevel@tonic-gate #define	LGRP_NONE	(-1)		/* non-existent lgroup ID */
43*0Sstevel@tonic-gate 
44*0Sstevel@tonic-gate 
45*0Sstevel@tonic-gate typedef id_t		lgrp_id_t;	/* lgroup ID */
46*0Sstevel@tonic-gate 
47*0Sstevel@tonic-gate #if (!defined(_KERNEL) && !defined(_KMEMUSER))
48*0Sstevel@tonic-gate typedef struct lgrp_mem_policy_info { int opaque[2]; }	lgrp_mem_policy_info_t;
49*0Sstevel@tonic-gate #endif	/* !_KERNEL && !_KMEMUSER */
50*0Sstevel@tonic-gate 
51*0Sstevel@tonic-gate #if (defined(_KERNEL) || defined(_KMEMUSER))
52*0Sstevel@tonic-gate #include <sys/cpuvar.h>
53*0Sstevel@tonic-gate #include <sys/bitmap.h>
54*0Sstevel@tonic-gate #include <sys/vnode.h>
55*0Sstevel@tonic-gate #include <vm/anon.h>
56*0Sstevel@tonic-gate #include <vm/seg.h>
57*0Sstevel@tonic-gate #include <sys/lgrp_user.h>
58*0Sstevel@tonic-gate #include <sys/param.h>
59*0Sstevel@tonic-gate 
60*0Sstevel@tonic-gate typedef	uint32_t	lgrp_load_t;	/* lgrp_loadavg type */
61*0Sstevel@tonic-gate typedef uintptr_t	lgrp_handle_t;	/* lgrp handle */
62*0Sstevel@tonic-gate 
63*0Sstevel@tonic-gate #define	LGRP_NONE_SUCH		LGRP_NONE	/* non-existent lgroup ID */
64*0Sstevel@tonic-gate /* null platform handle */
65*0Sstevel@tonic-gate #define	LGRP_NULL_HANDLE	((lgrp_handle_t)0xbadbad)
66*0Sstevel@tonic-gate #define	LGRP_DEFAULT_HANDLE	((lgrp_handle_t)0xbabecafe) /* uma handle */
67*0Sstevel@tonic-gate #define	LGRP_ROOTID		(0)		/* root lgroup ID */
68*0Sstevel@tonic-gate 
69*0Sstevel@tonic-gate /*
70*0Sstevel@tonic-gate  * Maximum number of lgrps a platform may define.
71*0Sstevel@tonic-gate  */
72*0Sstevel@tonic-gate 
73*0Sstevel@tonic-gate #define	NLGRPS_MAX		64
74*0Sstevel@tonic-gate #define	NLGRP_LEAVES_MAX	24
75*0Sstevel@tonic-gate #define	LGRP_LOADAVG_MAX	UINT32_MAX
76*0Sstevel@tonic-gate #define	LPL_RSET_MAX		NLGRP_LEAVES_MAX
77*0Sstevel@tonic-gate #define	LPL_RSET_ARRYSZ		(LPL_RSET_MAX + 1)
78*0Sstevel@tonic-gate 
79*0Sstevel@tonic-gate /*
80*0Sstevel@tonic-gate  * The load-average we expect for one cpu-bound thread's worth of load
81*0Sstevel@tonic-gate  */
82*0Sstevel@tonic-gate #define	LGRP_LOADAVG_THREAD_MAX		65516
83*0Sstevel@tonic-gate 
84*0Sstevel@tonic-gate /*
85*0Sstevel@tonic-gate  * The input to the load-average generating function for one cpu-bound thread's
86*0Sstevel@tonic-gate  * worth of load
87*0Sstevel@tonic-gate  */
88*0Sstevel@tonic-gate 
89*0Sstevel@tonic-gate #define	LGRP_LOADAVG_IN_THREAD_MAX	128
90*0Sstevel@tonic-gate 
91*0Sstevel@tonic-gate /*
92*0Sstevel@tonic-gate  * LPL actions
93*0Sstevel@tonic-gate  */
94*0Sstevel@tonic-gate 
95*0Sstevel@tonic-gate typedef enum {
96*0Sstevel@tonic-gate 	LPL_INCREMENT,
97*0Sstevel@tonic-gate 	LPL_DECREMENT
98*0Sstevel@tonic-gate } lpl_act_t;
99*0Sstevel@tonic-gate 
100*0Sstevel@tonic-gate /*
101*0Sstevel@tonic-gate  * lgroup statistics.  Most of these are counters that are updated
102*0Sstevel@tonic-gate  * dynamically so they are hashed to CPU buckets to reduce cache
103*0Sstevel@tonic-gate  * interference.  The remaining statistics are snapshots of kernel
104*0Sstevel@tonic-gate  * data, so they aren't stored in the array of counter stats.
105*0Sstevel@tonic-gate  *
106*0Sstevel@tonic-gate  * For the hashed stats to make sense, you have to sum all the buckets for
107*0Sstevel@tonic-gate  * that stat, hence macros are provided to read the stats.
108*0Sstevel@tonic-gate  */
109*0Sstevel@tonic-gate 
110*0Sstevel@tonic-gate #define	LGRP_NUM_CPU_BUCKETS	8	/* must be power of 2 */
111*0Sstevel@tonic-gate #define	LGRP_CPU_BUCKET_MASK	(LGRP_NUM_CPU_BUCKETS - 1)
112*0Sstevel@tonic-gate 
113*0Sstevel@tonic-gate /*
114*0Sstevel@tonic-gate  * Flags for what to do with lgroup memory policy
115*0Sstevel@tonic-gate  * Used for heap and stack where policy is extended to new segments added to
116*0Sstevel@tonic-gate  * the end
117*0Sstevel@tonic-gate  */
118*0Sstevel@tonic-gate #define	LGRP_MP_FLAG_EXTEND_UP		0x1	/* policy should extend up */
119*0Sstevel@tonic-gate #define	LGRP_MP_FLAG_EXTEND_DOWN	0x2	/* policy should extend down */
120*0Sstevel@tonic-gate 
121*0Sstevel@tonic-gate #define	LGRP_STAT(stats, bucket, whichstat) \
122*0Sstevel@tonic-gate 	((stats)->ls_data[bucket][whichstat])
123*0Sstevel@tonic-gate 
124*0Sstevel@tonic-gate /* Return a pointer suitable for an atomic 64-bit op on the bucket */
125*0Sstevel@tonic-gate #define	LGRP_STAT_WRITE_PTR(stats, whichstat) \
126*0Sstevel@tonic-gate 	(&LGRP_STAT(stats, (CPU->cpu_id) & LGRP_CPU_BUCKET_MASK, \
127*0Sstevel@tonic-gate 	    whichstat))
128*0Sstevel@tonic-gate 
129*0Sstevel@tonic-gate /* Sum up all the buckets and return the value in 'val' */
130*0Sstevel@tonic-gate #define	LGRP_STAT_READ(stats, whichstat, val) {				\
131*0Sstevel@tonic-gate 	int bkt;							\
132*0Sstevel@tonic-gate 	for (val = 0, bkt = 0; bkt < LGRP_NUM_CPU_BUCKETS; bkt++)	\
133*0Sstevel@tonic-gate 		val += LGRP_STAT(stats, bkt, whichstat);		\
134*0Sstevel@tonic-gate }
135*0Sstevel@tonic-gate 
136*0Sstevel@tonic-gate /* Reset all buckets for the stat to 0 */
137*0Sstevel@tonic-gate #define	LGRP_STAT_RESET(stats, stat) {					\
138*0Sstevel@tonic-gate 	int i;								\
139*0Sstevel@tonic-gate 	for (i = 0; i < LGRP_NUM_CPU_BUCKETS; i++)			\
140*0Sstevel@tonic-gate 		LGRP_STAT(stats, i, stat) = 0;				\
141*0Sstevel@tonic-gate }
142*0Sstevel@tonic-gate 
143*0Sstevel@tonic-gate /*
144*0Sstevel@tonic-gate  * Define all of the statistics that are kept for lgrp kstats,
145*0Sstevel@tonic-gate  * and their corresponding text names.
146*0Sstevel@tonic-gate  */
147*0Sstevel@tonic-gate 
148*0Sstevel@tonic-gate typedef enum lgrp_stat_types {
149*0Sstevel@tonic-gate 	LGRP_NUM_MIGR,		/* # migrations away from this lgrp */
150*0Sstevel@tonic-gate 	LGRP_NUM_ALLOC_FAIL,	/* # times alloc fails for chosen lgrp */
151*0Sstevel@tonic-gate 	LGRP_PM_SRC_PGS,	/* # pages migrated from this lgrp */
152*0Sstevel@tonic-gate 	LGRP_PM_DEST_PGS,	/* # pages migrated to this lgrp */
153*0Sstevel@tonic-gate 	LGRP_PM_FAIL_ALLOC_PGS,	/* # pages failed to migrate to this lgrp */
154*0Sstevel@tonic-gate 	LGRP_PM_FAIL_LOCK_PGS,	/* # pages failed to migrate from this lgrp */
155*0Sstevel@tonic-gate 	LGRP_PMM_PGS,		/* # pages marked to migrate from this lgrp */
156*0Sstevel@tonic-gate 	LGRP_PMM_FAIL_PGS,	/* # pages marked to migrate from this lgrp */
157*0Sstevel@tonic-gate 	LGRP_NUM_DEFAULT,	/* # of times default policy applied */
158*0Sstevel@tonic-gate 	LGRP_NUM_NEXT,		/* # of times next touch policy applied */
159*0Sstevel@tonic-gate 	LGRP_NUM_RANDOM,	/* # of times random policy applied */
160*0Sstevel@tonic-gate 	LGRP_NUM_RANDOM_PROC,	/* # of times random proc policy applied */
161*0Sstevel@tonic-gate 	LGRP_NUM_RANDOM_PSET,	/* # of times random pset policy applied */
162*0Sstevel@tonic-gate 	LGRP_NUM_ROUNDROBIN,	/* # of times round robin policy applied */
163*0Sstevel@tonic-gate 	LGRP_NUM_COUNTER_STATS,	/* always last */
164*0Sstevel@tonic-gate 	LGRP_CTR_STATS_ALLOC = 16	/* cache-align pad - multiple of 8 */
165*0Sstevel@tonic-gate 				/* always keep >= LGRP_NUM_COUNTER_STATS */
166*0Sstevel@tonic-gate } lgrp_stat_t;
167*0Sstevel@tonic-gate 
168*0Sstevel@tonic-gate typedef enum lgrp_snap_stat_types {
169*0Sstevel@tonic-gate 	LGRP_NUM_CPUS,		/* number of CPUs */
170*0Sstevel@tonic-gate 	LGRP_NUM_PG_FREE,	/* # of free pages */
171*0Sstevel@tonic-gate 	LGRP_NUM_PG_AVAIL,	/* # of allocatable physical pages */
172*0Sstevel@tonic-gate 	LGRP_NUM_PG_INSTALL,	/* # of installed physical pages */
173*0Sstevel@tonic-gate 	LGRP_LOADAVG,		/* "load average" of this lgrp */
174*0Sstevel@tonic-gate 	LGRP_NUM_SNAPSHOT_STATS	/* always last */
175*0Sstevel@tonic-gate } lgrp_snap_stat_t;
176*0Sstevel@tonic-gate 
177*0Sstevel@tonic-gate #define	LGRP_KSTAT_NAMES		\
178*0Sstevel@tonic-gate static char *lgrp_kstat_names[] = {	\
179*0Sstevel@tonic-gate 					\
180*0Sstevel@tonic-gate 	/* Counter stats */		\
181*0Sstevel@tonic-gate 	"lwp migrations",		\
182*0Sstevel@tonic-gate 	"alloc fail",			\
183*0Sstevel@tonic-gate 	"pages migrated from",		\
184*0Sstevel@tonic-gate 	"pages migrated to",		\
185*0Sstevel@tonic-gate 	"pages failed to migrate to",	\
186*0Sstevel@tonic-gate 	"pages failed to migrate from",	\
187*0Sstevel@tonic-gate 	"pages marked for migration",	\
188*0Sstevel@tonic-gate 	"pages failed to mark",		\
189*0Sstevel@tonic-gate 	"default policy",		\
190*0Sstevel@tonic-gate 	"next-touch policy",		\
191*0Sstevel@tonic-gate 	"random policy",		\
192*0Sstevel@tonic-gate 	"span process policy",		\
193*0Sstevel@tonic-gate 	"span psrset policy",		\
194*0Sstevel@tonic-gate 	"round robin policy",		\
195*0Sstevel@tonic-gate 					\
196*0Sstevel@tonic-gate 	/* Snapshot stats */		\
197*0Sstevel@tonic-gate 	"cpus",				\
198*0Sstevel@tonic-gate 	"pages free",			\
199*0Sstevel@tonic-gate 	"pages avail",			\
200*0Sstevel@tonic-gate 	"pages installed",		\
201*0Sstevel@tonic-gate 	"load average"			\
202*0Sstevel@tonic-gate }
203*0Sstevel@tonic-gate 
204*0Sstevel@tonic-gate #define	LGRP_NUM_STATS	((int)LGRP_NUM_COUNTER_STATS +			\
205*0Sstevel@tonic-gate 	(int)LGRP_NUM_SNAPSHOT_STATS)
206*0Sstevel@tonic-gate 
207*0Sstevel@tonic-gate /*
208*0Sstevel@tonic-gate  * The contents of this structure are opaque and should only be
209*0Sstevel@tonic-gate  * accessed through the LGRP_STAT macro.
210*0Sstevel@tonic-gate  */
211*0Sstevel@tonic-gate struct lgrp_stats {
212*0Sstevel@tonic-gate 	int64_t ls_data[LGRP_NUM_CPU_BUCKETS][LGRP_CTR_STATS_ALLOC];
213*0Sstevel@tonic-gate };
214*0Sstevel@tonic-gate 
215*0Sstevel@tonic-gate /* The kernel's version of a bitmap of lgroups */
216*0Sstevel@tonic-gate typedef uint64_t klgrpset_t;
217*0Sstevel@tonic-gate 
218*0Sstevel@tonic-gate /*
219*0Sstevel@tonic-gate  * This really belongs in memnode.h, but it must be defined here to avoid
220*0Sstevel@tonic-gate  * recursive inclusion problems. Note that memnode.h includes this header.
221*0Sstevel@tonic-gate  */
222*0Sstevel@tonic-gate typedef	uint64_t	mnodeset_t;
223*0Sstevel@tonic-gate 
224*0Sstevel@tonic-gate /*
225*0Sstevel@tonic-gate  * lgroup structure
226*0Sstevel@tonic-gate  *
227*0Sstevel@tonic-gate  * Visible to generic code and contains the lgroup ID, CPUs in this lgroup,
228*0Sstevel@tonic-gate  * and a platform handle used to identify this lgroup to the lgroup platform
229*0Sstevel@tonic-gate  * support code
230*0Sstevel@tonic-gate  */
231*0Sstevel@tonic-gate typedef struct lgrp {
232*0Sstevel@tonic-gate 
233*0Sstevel@tonic-gate 	lgrp_id_t 	lgrp_id;	/* which lgroup	*/
234*0Sstevel@tonic-gate 	int		lgrp_latency;
235*0Sstevel@tonic-gate 	lgrp_handle_t  	lgrp_plathand;	/* handle for platform calls */
236*0Sstevel@tonic-gate 	struct lgrp	*lgrp_parent;	/* parent lgroup */
237*0Sstevel@tonic-gate 	uint_t		lgrp_reserved1;	/* filler */
238*0Sstevel@tonic-gate 	uint_t		lgrp_childcnt;	/* number of children lgroups */
239*0Sstevel@tonic-gate 	klgrpset_t	lgrp_children;	/* children lgroups */
240*0Sstevel@tonic-gate 	klgrpset_t	lgrp_leaves;	/* (direct decendant) leaf lgroups */
241*0Sstevel@tonic-gate 
242*0Sstevel@tonic-gate 	/*
243*0Sstevel@tonic-gate 	 * set of lgroups containing a given type of resource
244*0Sstevel@tonic-gate 	 * at this level of locality
245*0Sstevel@tonic-gate 	 */
246*0Sstevel@tonic-gate 	klgrpset_t	lgrp_set[LGRP_RSRC_COUNT];
247*0Sstevel@tonic-gate 
248*0Sstevel@tonic-gate 	mnodeset_t	lgrp_mnodes;	/* set of memory nodes in this lgroup */
249*0Sstevel@tonic-gate 	uint_t		lgrp_nmnodes;	/* number of memnodes */
250*0Sstevel@tonic-gate 	uint_t		lgrp_reserved2;	/* filler */
251*0Sstevel@tonic-gate 
252*0Sstevel@tonic-gate 	struct cpu	*lgrp_cpu;	/* pointer to a cpu may be null */
253*0Sstevel@tonic-gate 	uint_t		lgrp_cpucnt;	/* number of cpus in this lgrp	*/
254*0Sstevel@tonic-gate 	uint_t		lgrp_chipcnt;
255*0Sstevel@tonic-gate 	struct chip	*lgrp_chips;	/* pointer to chips in this lgrp */
256*0Sstevel@tonic-gate 	kstat_t		*lgrp_kstat;	/* per-lgrp kstats */
257*0Sstevel@tonic-gate } lgrp_t;
258*0Sstevel@tonic-gate 
259*0Sstevel@tonic-gate /*
260*0Sstevel@tonic-gate  * lgroup load average structure
261*0Sstevel@tonic-gate  */
262*0Sstevel@tonic-gate 
263*0Sstevel@tonic-gate typedef struct lgrp_ld {
264*0Sstevel@tonic-gate 	lgrp_load_t	lpl_loadavg;	/* load average		*/
265*0Sstevel@tonic-gate 	uint_t		lpl_ncpu;	/* how many cpus	*/
266*0Sstevel@tonic-gate 	lgrp_id_t	lpl_lgrpid;	/* which group this lpl part of */
267*0Sstevel@tonic-gate 	lgrp_t		*lpl_lgrp;	/* ptr to lpl's lgrp */
268*0Sstevel@tonic-gate 	struct lgrp_ld	*lpl_parent;	/* lpl of parent lgrp */
269*0Sstevel@tonic-gate 	struct cpu	*lpl_cpus;	/* list of cpus in lpl */
270*0Sstevel@tonic-gate 					/* NULL for non-leaf lgrps */
271*0Sstevel@tonic-gate 	uint_t		lpl_nrset;	/* no. of leaf lpls for lgrp */
272*0Sstevel@tonic-gate 	int		lpl_hint;	/* where to start looking in parent */
273*0Sstevel@tonic-gate 	hrtime_t	lpl_homed_time;	/* time of last homing to this lpl */
274*0Sstevel@tonic-gate 	struct lgrp_ld	*lpl_rset[LPL_RSET_ARRYSZ]; /* leaf lpls for lgrp */
275*0Sstevel@tonic-gate 					/* contains ptr to self for leaf lgrp */
276*0Sstevel@tonic-gate } lpl_t;
277*0Sstevel@tonic-gate 
278*0Sstevel@tonic-gate /*
279*0Sstevel@tonic-gate  * 1 << LGRP_MAX_EFFECT_SHFT ==  lgrp_loadavg_max_effect
280*0Sstevel@tonic-gate  */
281*0Sstevel@tonic-gate #define	LGRP_MAX_EFFECT_SHFT 16
282*0Sstevel@tonic-gate 
283*0Sstevel@tonic-gate /*
284*0Sstevel@tonic-gate  * Operations handled by lgrp_config()
285*0Sstevel@tonic-gate  */
286*0Sstevel@tonic-gate typedef enum lgrp_config_flag {
287*0Sstevel@tonic-gate 	LGRP_CONFIG_NOP,
288*0Sstevel@tonic-gate 	LGRP_CONFIG_CPU_ADD,
289*0Sstevel@tonic-gate 	LGRP_CONFIG_CPU_DEL,
290*0Sstevel@tonic-gate 	LGRP_CONFIG_CPU_ONLINE,
291*0Sstevel@tonic-gate 	LGRP_CONFIG_CPU_OFFLINE,
292*0Sstevel@tonic-gate 	LGRP_CONFIG_CPUPART_ADD,
293*0Sstevel@tonic-gate 	LGRP_CONFIG_CPUPART_DEL,
294*0Sstevel@tonic-gate 	LGRP_CONFIG_MEM_ADD,
295*0Sstevel@tonic-gate 	LGRP_CONFIG_MEM_DEL,
296*0Sstevel@tonic-gate 	LGRP_CONFIG_MEM_RENAME,
297*0Sstevel@tonic-gate 	LGRP_CONFIG_GEN_UPDATE,
298*0Sstevel@tonic-gate 	LGRP_CONFIG_FLATTEN,
299*0Sstevel@tonic-gate 	LGRP_CONFIG_LATENCY_CHANGE
300*0Sstevel@tonic-gate } lgrp_config_flag_t;
301*0Sstevel@tonic-gate 
302*0Sstevel@tonic-gate /*
303*0Sstevel@tonic-gate  * Memory allocation policies
304*0Sstevel@tonic-gate  */
305*0Sstevel@tonic-gate typedef enum lgrp_mem_policy {
306*0Sstevel@tonic-gate 	LGRP_MEM_POLICY_DEFAULT,
307*0Sstevel@tonic-gate 	LGRP_MEM_POLICY_NEXT,		/* near LWP to next touch */
308*0Sstevel@tonic-gate 	LGRP_MEM_POLICY_RANDOM_PROC,	/* randomly across process */
309*0Sstevel@tonic-gate 	LGRP_MEM_POLICY_RANDOM_PSET,	/* randomly across processor set */
310*0Sstevel@tonic-gate 	LGRP_MEM_POLICY_RANDOM,		/* randomly across all lgroups */
311*0Sstevel@tonic-gate 	LGRP_MEM_POLICY_ROUNDROBIN,	/* round robin across all lgroups */
312*0Sstevel@tonic-gate 	LGRP_MEM_POLICY_NEXT_CPU,	/* Near next CPU to touch memory */
313*0Sstevel@tonic-gate 	LGRP_NUM_MEM_POLICIES
314*0Sstevel@tonic-gate } lgrp_mem_policy_t;
315*0Sstevel@tonic-gate 
316*0Sstevel@tonic-gate /*
317*0Sstevel@tonic-gate  * Search scopes for finding resouces
318*0Sstevel@tonic-gate  */
319*0Sstevel@tonic-gate typedef	enum lgrp_res_ss {
320*0Sstevel@tonic-gate 	LGRP_SRCH_LOCAL,		/* Search local lgroup only */
321*0Sstevel@tonic-gate 	LGRP_SRCH_HIER			/* Search entire hierarchy */
322*0Sstevel@tonic-gate } lgrp_res_ss_t;
323*0Sstevel@tonic-gate 
324*0Sstevel@tonic-gate /*
325*0Sstevel@tonic-gate  * Cookie used for lgrp mnode selection
326*0Sstevel@tonic-gate  */
327*0Sstevel@tonic-gate typedef struct lgrp_mnode_cookie {
328*0Sstevel@tonic-gate 	lgrp_t		*lmc_lgrp;	/* lgrp under consideration */
329*0Sstevel@tonic-gate 	mnodeset_t	lmc_nodes;	/* nodes not yet tried in lgrp */
330*0Sstevel@tonic-gate 	int		lmc_cnt;	/* how many nodes in untried set */
331*0Sstevel@tonic-gate 	mnodeset_t	lmc_tried;	/* nodes already tried */
332*0Sstevel@tonic-gate 	int		lmc_ntried;	/* how many nodes in tried set */
333*0Sstevel@tonic-gate 	lgrp_res_ss_t	lmc_scope;	/* consider non-local nodes? */
334*0Sstevel@tonic-gate 	ushort_t	lmc_rand;	/* a "random" number */
335*0Sstevel@tonic-gate } lgrp_mnode_cookie_t;
336*0Sstevel@tonic-gate 
337*0Sstevel@tonic-gate /*
338*0Sstevel@tonic-gate  * Information needed to implement memory allocation policy
339*0Sstevel@tonic-gate  */
340*0Sstevel@tonic-gate typedef struct lgrp_mem_policy_info {
341*0Sstevel@tonic-gate 	int	mem_policy;			/* memory allocation policy */
342*0Sstevel@tonic-gate 	int	mem_reserved;			/* reserved */
343*0Sstevel@tonic-gate } lgrp_mem_policy_info_t;
344*0Sstevel@tonic-gate 
345*0Sstevel@tonic-gate /*
346*0Sstevel@tonic-gate  * Shared memory policy segment
347*0Sstevel@tonic-gate  */
348*0Sstevel@tonic-gate typedef struct lgrp_shm_policy_seg {
349*0Sstevel@tonic-gate 	u_offset_t		shm_off;	/* offset into shared object */
350*0Sstevel@tonic-gate 	size_t			shm_size;	/* size of segment */
351*0Sstevel@tonic-gate 	lgrp_mem_policy_info_t	shm_policy;	/* memory allocation policy */
352*0Sstevel@tonic-gate 	avl_node_t		shm_tree;	/* AVL tree */
353*0Sstevel@tonic-gate } lgrp_shm_policy_seg_t;
354*0Sstevel@tonic-gate 
355*0Sstevel@tonic-gate /*
356*0Sstevel@tonic-gate  * Shared memory locality info
357*0Sstevel@tonic-gate  */
358*0Sstevel@tonic-gate typedef struct lgrp_shm_locality {
359*0Sstevel@tonic-gate 	size_t		loc_count;		/* reference count */
360*0Sstevel@tonic-gate 	avl_tree_t	*loc_tree;		/* policy segment tree */
361*0Sstevel@tonic-gate 	krwlock_t	loc_lock;		/* protects tree */
362*0Sstevel@tonic-gate } lgrp_shm_locality_t;
363*0Sstevel@tonic-gate 
364*0Sstevel@tonic-gate /*
365*0Sstevel@tonic-gate  * Queries that may be made to determine lgroup memory size
366*0Sstevel@tonic-gate  */
367*0Sstevel@tonic-gate typedef enum {
368*0Sstevel@tonic-gate 	LGRP_MEM_SIZE_FREE,		/* number of free pages */
369*0Sstevel@tonic-gate 	LGRP_MEM_SIZE_AVAIL,		/* number of pages in phys_avail */
370*0Sstevel@tonic-gate 	LGRP_MEM_SIZE_INSTALL		/* number of pages in phys_install */
371*0Sstevel@tonic-gate } lgrp_mem_query_t;
372*0Sstevel@tonic-gate 
373*0Sstevel@tonic-gate /*
374*0Sstevel@tonic-gate  * Argument for the memory copy-rename operation, contains the source and the
375*0Sstevel@tonic-gate  * destination platform handles.
376*0Sstevel@tonic-gate  */
377*0Sstevel@tonic-gate typedef struct lgrp_config_mem_rename {
378*0Sstevel@tonic-gate 	lgrp_handle_t lmem_rename_from;
379*0Sstevel@tonic-gate 	lgrp_handle_t lmem_rename_to;
380*0Sstevel@tonic-gate } lgrp_config_mem_rename_t;
381*0Sstevel@tonic-gate 
382*0Sstevel@tonic-gate /* Macro to clear an lgroup bitmap */
383*0Sstevel@tonic-gate #define	klgrpset_clear(klgrpset) \
384*0Sstevel@tonic-gate 	(klgrpset) = (klgrpset_t)0
385*0Sstevel@tonic-gate 
386*0Sstevel@tonic-gate /* Macro to fill an lgroup bitmap */
387*0Sstevel@tonic-gate #define	klgrpset_fill(klgrpset) \
388*0Sstevel@tonic-gate 	(klgrpset) = (klgrpset_t)(-1)
389*0Sstevel@tonic-gate 
390*0Sstevel@tonic-gate /* Macro to add an lgroup to an lgroup bitmap */
391*0Sstevel@tonic-gate #define	klgrpset_add(klgrpset, lgrpid) \
392*0Sstevel@tonic-gate 	(klgrpset) |= ((klgrpset_t)1 << (lgrpid))
393*0Sstevel@tonic-gate 
394*0Sstevel@tonic-gate /* Macro to delete an lgroup from an lgroup bitmap */
395*0Sstevel@tonic-gate #define	klgrpset_del(klgrpset, lgrpid) \
396*0Sstevel@tonic-gate 	(klgrpset) &= ~((klgrpset_t)1 << (lgrpid))
397*0Sstevel@tonic-gate 
398*0Sstevel@tonic-gate /* Macro to copy a klgrpset into another klgrpset */
399*0Sstevel@tonic-gate #define	klgrpset_copy(klgrpset_to, klgrpset_from) \
400*0Sstevel@tonic-gate 	(klgrpset_to) = (klgrpset_from)
401*0Sstevel@tonic-gate 
402*0Sstevel@tonic-gate /* Macro to perform an 'and' operation on a pair of lgroup bitmaps */
403*0Sstevel@tonic-gate #define	klgrpset_and(klgrpset_rslt, klgrpset_arg) \
404*0Sstevel@tonic-gate 	(klgrpset_rslt) &= (klgrpset_arg)
405*0Sstevel@tonic-gate 
406*0Sstevel@tonic-gate /* Macro to perform an 'or' operation on a pair of lgroup bitmaps */
407*0Sstevel@tonic-gate #define	klgrpset_or(klgrpset_rslt, klgrpset_arg) \
408*0Sstevel@tonic-gate 	(klgrpset_rslt) |= (klgrpset_arg)
409*0Sstevel@tonic-gate 
410*0Sstevel@tonic-gate /* Macro to perform a 'diff' operation on a pair of lgroup bitmaps */
411*0Sstevel@tonic-gate #define	klgrpset_diff(klgrpset_rslt, klgrpset_arg) \
412*0Sstevel@tonic-gate 	(klgrpset_rslt) &= ~(klgrpset_arg)
413*0Sstevel@tonic-gate 
414*0Sstevel@tonic-gate /* Macro to check if an lgroup is a member of an lgrpset */
415*0Sstevel@tonic-gate #define	klgrpset_ismember(klgrpset, lgrpid) \
416*0Sstevel@tonic-gate 	((klgrpset) & ((klgrpset_t)1 << (lgrpid)))
417*0Sstevel@tonic-gate 
418*0Sstevel@tonic-gate /* Macro to check if an lgroup bitmap is empty */
419*0Sstevel@tonic-gate #define	klgrpset_isempty(klgrpset) \
420*0Sstevel@tonic-gate 	((klgrpset) == (klgrpset_t)0)
421*0Sstevel@tonic-gate 
422*0Sstevel@tonic-gate /* Macro to check if two lgrpsets intersect */
423*0Sstevel@tonic-gate #define	klgrpset_intersects(klgrpset1, klgrpset2) \
424*0Sstevel@tonic-gate 	((klgrpset1) & (klgrpset2))
425*0Sstevel@tonic-gate 
426*0Sstevel@tonic-gate /* Macro to count the number of members in an lgrpset */
427*0Sstevel@tonic-gate #define	klgrpset_nlgrps(klgrpset, count)				\
428*0Sstevel@tonic-gate {									\
429*0Sstevel@tonic-gate 	lgrp_id_t	lgrpid;						\
430*0Sstevel@tonic-gate 	for (lgrpid = 0, count = 0; lgrpid <= lgrp_alloc_max; lgrpid++) {\
431*0Sstevel@tonic-gate 		if (klgrpset_ismember(klgrpset, lgrpid))		\
432*0Sstevel@tonic-gate 			count++;					\
433*0Sstevel@tonic-gate 	}								\
434*0Sstevel@tonic-gate }
435*0Sstevel@tonic-gate 
436*0Sstevel@tonic-gate /* Macro to get total memory size (in bytes) of a given set of lgroups */
437*0Sstevel@tonic-gate #define	klgrpset_totalsize(klgrpset, size)				\
438*0Sstevel@tonic-gate {									\
439*0Sstevel@tonic-gate 	lgrp_handle_t	hand;						\
440*0Sstevel@tonic-gate 	lgrp_id_t	lgrpid;						\
441*0Sstevel@tonic-gate 									\
442*0Sstevel@tonic-gate 	for (lgrpid = 0, size = 0; lgrpid <= lgrp_alloc_max; lgrpid++) {\
443*0Sstevel@tonic-gate 		if (klgrpset_ismember(klgrpset, lgrpid) &&		\
444*0Sstevel@tonic-gate 		    lgrp_table[lgrpid])	{				\
445*0Sstevel@tonic-gate 			hand = lgrp_table[lgrpid]->lgrp_plathand;	\
446*0Sstevel@tonic-gate 			size += lgrp_plat_mem_size(hand,		\
447*0Sstevel@tonic-gate 			    LGRP_MEM_SIZE_AVAIL) * PAGESIZE;		\
448*0Sstevel@tonic-gate 		}							\
449*0Sstevel@tonic-gate 	}								\
450*0Sstevel@tonic-gate }
451*0Sstevel@tonic-gate 
452*0Sstevel@tonic-gate /*
453*0Sstevel@tonic-gate  * Does this lgroup exist?
454*0Sstevel@tonic-gate  */
455*0Sstevel@tonic-gate #define	LGRP_EXISTS(lgrp)	\
456*0Sstevel@tonic-gate 	(lgrp != NULL && lgrp->lgrp_id != LGRP_NONE)
457*0Sstevel@tonic-gate 
458*0Sstevel@tonic-gate /*
459*0Sstevel@tonic-gate  * Initialize an lgrp_mnode_cookie
460*0Sstevel@tonic-gate  */
461*0Sstevel@tonic-gate #define	LGRP_MNODE_COOKIE_INIT(c, lgrp, scope)	\
462*0Sstevel@tonic-gate {							\
463*0Sstevel@tonic-gate 	bzero(&(c), sizeof (lgrp_mnode_cookie_t));	\
464*0Sstevel@tonic-gate 	(&(c))->lmc_lgrp = lgrp;			\
465*0Sstevel@tonic-gate 	(&(c))->lmc_nodes = lgrp->lgrp_mnodes;		\
466*0Sstevel@tonic-gate 	(&(c))->lmc_cnt = lgrp->lgrp_nmnodes;		\
467*0Sstevel@tonic-gate 	(&(c))->lmc_scope = scope;			\
468*0Sstevel@tonic-gate 	(&(c))->lmc_rand = (ushort_t)gethrtime_unscaled() >> 4;	\
469*0Sstevel@tonic-gate }
470*0Sstevel@tonic-gate 
471*0Sstevel@tonic-gate /*
472*0Sstevel@tonic-gate  * Upgrade cookie scope from LGRP_SRCH_LOCAL to LGRP_SRCH_HIER.
473*0Sstevel@tonic-gate  */
474*0Sstevel@tonic-gate #define	LGRP_MNODE_COOKIE_UPGRADE(c)	\
475*0Sstevel@tonic-gate {							\
476*0Sstevel@tonic-gate 	ASSERT((&(c))->lmc_scope == LGRP_SRCH_LOCAL);	\
477*0Sstevel@tonic-gate 	(&(c))->lmc_scope = LGRP_SRCH_HIER;		\
478*0Sstevel@tonic-gate }
479*0Sstevel@tonic-gate 
480*0Sstevel@tonic-gate /*
481*0Sstevel@tonic-gate  * Macro to see whether memory allocation policy can be reapplied
482*0Sstevel@tonic-gate  */
483*0Sstevel@tonic-gate #define	LGRP_MEM_POLICY_REAPPLICABLE(p) \
484*0Sstevel@tonic-gate 	(p == LGRP_MEM_POLICY_NEXT)
485*0Sstevel@tonic-gate 
486*0Sstevel@tonic-gate /*
487*0Sstevel@tonic-gate  * Return true if lgrp has CPU resources in the cpupart
488*0Sstevel@tonic-gate  */
489*0Sstevel@tonic-gate #define	LGRP_CPUS_IN_PART(lgrpid, cpupart) \
490*0Sstevel@tonic-gate 	(cpupart->cp_lgrploads[lgrpid].lpl_ncpu > 0)
491*0Sstevel@tonic-gate 
492*0Sstevel@tonic-gate extern int	lgrp_alloc_max;
493*0Sstevel@tonic-gate extern lgrp_t	*lgrp_table[NLGRPS_MAX];	/* indexed by lgrp_id */
494*0Sstevel@tonic-gate extern int		nlgrps;		/* number of lgroups in machine */
495*0Sstevel@tonic-gate extern int		nlgrpsmax;	/* max number of lgroups on platform */
496*0Sstevel@tonic-gate extern lgrp_gen_t	lgrp_gen;	/* generation of lgroup hierarchy */
497*0Sstevel@tonic-gate extern int		lgrp_initialized; /* single-CPU initialization done */
498*0Sstevel@tonic-gate extern int		lgrp_topo_initialized; /* lgrp topology constructed */
499*0Sstevel@tonic-gate extern lgrp_t		*lgrp_root;	/* root lgroup */
500*0Sstevel@tonic-gate extern unsigned int	lgrp_topo_levels;
501*0Sstevel@tonic-gate extern lpl_t		*lpl_bootstrap;	/* bootstrap lpl for non-active CPUs */
502*0Sstevel@tonic-gate 
503*0Sstevel@tonic-gate 
504*0Sstevel@tonic-gate /* generic interfaces */
505*0Sstevel@tonic-gate 
506*0Sstevel@tonic-gate /*
507*0Sstevel@tonic-gate  * lgroup management
508*0Sstevel@tonic-gate  */
509*0Sstevel@tonic-gate int	lgrp_optimizations(void);
510*0Sstevel@tonic-gate void	lgrp_init(void);
511*0Sstevel@tonic-gate void	lgrp_setup(void);
512*0Sstevel@tonic-gate lgrp_t	*lgrp_create(void);
513*0Sstevel@tonic-gate void	lgrp_destroy(lgrp_t *);
514*0Sstevel@tonic-gate void	lgrp_config(lgrp_config_flag_t, uintptr_t, uintptr_t);
515*0Sstevel@tonic-gate lgrp_t	*lgrp_hand_to_lgrp(lgrp_handle_t);
516*0Sstevel@tonic-gate 
517*0Sstevel@tonic-gate /*
518*0Sstevel@tonic-gate  * lgroup stats
519*0Sstevel@tonic-gate  */
520*0Sstevel@tonic-gate void	lgrp_kstat_create(struct cpu *);
521*0Sstevel@tonic-gate void	lgrp_kstat_destroy(struct cpu *);
522*0Sstevel@tonic-gate void	lgrp_stat_add(lgrp_id_t, lgrp_stat_t, int64_t);
523*0Sstevel@tonic-gate int64_t lgrp_stat_read(lgrp_id_t, lgrp_stat_t);
524*0Sstevel@tonic-gate 
525*0Sstevel@tonic-gate /*
526*0Sstevel@tonic-gate  * lgroup memory
527*0Sstevel@tonic-gate  */
528*0Sstevel@tonic-gate lgrp_mem_policy_t	lgrp_madv_to_policy(uchar_t, size_t, int);
529*0Sstevel@tonic-gate pgcnt_t	lgrp_mem_size(lgrp_id_t, lgrp_mem_query_t);
530*0Sstevel@tonic-gate lgrp_t	*lgrp_mem_choose(struct seg *, caddr_t, size_t);
531*0Sstevel@tonic-gate int	lgrp_memnode_choose(lgrp_mnode_cookie_t *);
532*0Sstevel@tonic-gate lgrp_mem_policy_t	lgrp_mem_policy_default(size_t, int);
533*0Sstevel@tonic-gate int	lgrp_mnode_update(klgrpset_t, klgrpset_t *);
534*0Sstevel@tonic-gate lgrp_t	*lgrp_pfn_to_lgrp(pfn_t);
535*0Sstevel@tonic-gate lgrp_t	*lgrp_phys_to_lgrp(u_longlong_t);	/* used by numat driver */
536*0Sstevel@tonic-gate int	lgrp_privm_policy_set(lgrp_mem_policy_t, lgrp_mem_policy_info_t *,
537*0Sstevel@tonic-gate     size_t);
538*0Sstevel@tonic-gate void	lgrp_shm_policy_init(struct anon_map *, vnode_t *);
539*0Sstevel@tonic-gate void	lgrp_shm_policy_fini(struct anon_map *, vnode_t *);
540*0Sstevel@tonic-gate lgrp_mem_policy_info_t	*lgrp_shm_policy_get(struct anon_map *, ulong_t,
541*0Sstevel@tonic-gate     vnode_t *, u_offset_t);
542*0Sstevel@tonic-gate int	lgrp_shm_policy_set(lgrp_mem_policy_t, struct anon_map *, ulong_t,
543*0Sstevel@tonic-gate     vnode_t *, u_offset_t, size_t);
544*0Sstevel@tonic-gate 
545*0Sstevel@tonic-gate /*
546*0Sstevel@tonic-gate  * Used by numat driver
547*0Sstevel@tonic-gate  */
548*0Sstevel@tonic-gate int	lgrp_query_cpu(processorid_t, lgrp_id_t *);
549*0Sstevel@tonic-gate int	lgrp_query_load(processorid_t, lgrp_load_t *);
550*0Sstevel@tonic-gate 
551*0Sstevel@tonic-gate /*
552*0Sstevel@tonic-gate  * lgroup thread placement
553*0Sstevel@tonic-gate  */
554*0Sstevel@tonic-gate lpl_t	*lgrp_affinity_best(kthread_t *, struct cpupart *, lgrp_id_t);
555*0Sstevel@tonic-gate void	lgrp_affinity_init(lgrp_affinity_t **);
556*0Sstevel@tonic-gate void	lgrp_affinity_free(lgrp_affinity_t **);
557*0Sstevel@tonic-gate lpl_t	*lgrp_choose(kthread_t *t, struct cpupart *);
558*0Sstevel@tonic-gate lgrp_t	*lgrp_home_lgrp(void);
559*0Sstevel@tonic-gate lgrp_id_t	lgrp_home_id(kthread_t *);
560*0Sstevel@tonic-gate void	lgrp_loadavg(lpl_t *, uint_t, int);
561*0Sstevel@tonic-gate void	lgrp_move_thread(kthread_t *, lpl_t *, int);
562*0Sstevel@tonic-gate 
563*0Sstevel@tonic-gate /*
564*0Sstevel@tonic-gate  * lgroup topology
565*0Sstevel@tonic-gate  */
566*0Sstevel@tonic-gate int	lgrp_leaf_add(lgrp_t *, lgrp_t **, int, klgrpset_t *);
567*0Sstevel@tonic-gate int	lgrp_leaf_delete(lgrp_t *, lgrp_t **, int, klgrpset_t *);
568*0Sstevel@tonic-gate int	lgrp_rsets_empty(klgrpset_t *);
569*0Sstevel@tonic-gate int	lgrp_rsets_member(klgrpset_t *, lgrp_id_t);
570*0Sstevel@tonic-gate int	lgrp_topo_flatten(int, lgrp_t **, int, klgrpset_t *);
571*0Sstevel@tonic-gate int	lgrp_topo_ht_limit(void);
572*0Sstevel@tonic-gate int	lgrp_topo_ht_limit_default(void);
573*0Sstevel@tonic-gate int	lgrp_topo_ht_limit_set(int);
574*0Sstevel@tonic-gate int	lgrp_topo_update(lgrp_t **, int, klgrpset_t *);
575*0Sstevel@tonic-gate 
576*0Sstevel@tonic-gate /*
577*0Sstevel@tonic-gate  * lpl topology
578*0Sstevel@tonic-gate  */
579*0Sstevel@tonic-gate void	lpl_topo_bootstrap(lpl_t *, int);
580*0Sstevel@tonic-gate int	lpl_topo_flatten(int);
581*0Sstevel@tonic-gate int	lpl_topo_verify(struct cpupart *);
582*0Sstevel@tonic-gate 
583*0Sstevel@tonic-gate 
584*0Sstevel@tonic-gate /* platform interfaces */
585*0Sstevel@tonic-gate void	lgrp_plat_init(void);
586*0Sstevel@tonic-gate void	lgrp_plat_main_init(void);
587*0Sstevel@tonic-gate lgrp_t	*lgrp_plat_alloc(lgrp_id_t lgrpid);
588*0Sstevel@tonic-gate void	lgrp_plat_config(lgrp_config_flag_t, uintptr_t);
589*0Sstevel@tonic-gate lgrp_handle_t	lgrp_plat_cpu_to_hand(processorid_t);
590*0Sstevel@tonic-gate lgrp_handle_t	lgrp_plat_pfn_to_hand(pfn_t);
591*0Sstevel@tonic-gate int	lgrp_plat_max_lgrps(void);
592*0Sstevel@tonic-gate pgcnt_t	lgrp_plat_mem_size(lgrp_handle_t, lgrp_mem_query_t);
593*0Sstevel@tonic-gate int	lgrp_plat_latency(lgrp_handle_t, lgrp_handle_t);
594*0Sstevel@tonic-gate lgrp_handle_t	lgrp_plat_root_hand(void);
595*0Sstevel@tonic-gate void	lgrp_plat_probe(void);
596*0Sstevel@tonic-gate void	lgrp_plat_build_topo(void);
597*0Sstevel@tonic-gate 
598*0Sstevel@tonic-gate #endif	/* _KERNEL && _KMEMUSER */
599*0Sstevel@tonic-gate 
600*0Sstevel@tonic-gate #ifdef	__cplusplus
601*0Sstevel@tonic-gate }
602*0Sstevel@tonic-gate #endif
603*0Sstevel@tonic-gate 
604*0Sstevel@tonic-gate #endif /* _LGRP_H */
605