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