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