17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5d5d7cf4eSJonathan Chew * Common Development and Distribution License (the "License").
6d5d7cf4eSJonathan Chew * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
21d5d7cf4eSJonathan Chew
227c478bd9Sstevel@tonic-gate /*
23*56f33205SJonathan Adams * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
247c478bd9Sstevel@tonic-gate * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate */
267c478bd9Sstevel@tonic-gate
277c478bd9Sstevel@tonic-gate #include <sys/cpuvar.h>
287c478bd9Sstevel@tonic-gate #include <sys/lgrp.h>
297c478bd9Sstevel@tonic-gate #include <sys/memnode.h>
307c478bd9Sstevel@tonic-gate #include <sys/mman.h>
317c478bd9Sstevel@tonic-gate #include <sys/param.h>
327c478bd9Sstevel@tonic-gate #include <sys/systm.h>
337c478bd9Sstevel@tonic-gate #include <sys/types.h>
347c478bd9Sstevel@tonic-gate #include <vm/seg_spt.h>
357c478bd9Sstevel@tonic-gate #include <vm/seg_vn.h>
36affbd3ccSkchow #include <vm/vm_dep.h>
377c478bd9Sstevel@tonic-gate
387c478bd9Sstevel@tonic-gate #include <sys/errno.h>
397c478bd9Sstevel@tonic-gate #include <sys/kstat.h>
407c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h>
417c478bd9Sstevel@tonic-gate #include <sys/memlist.h>
427c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h>
437c478bd9Sstevel@tonic-gate
447c478bd9Sstevel@tonic-gate /*
457c478bd9Sstevel@tonic-gate * Platform-specific support for lgroups common to sun4 based platforms.
467c478bd9Sstevel@tonic-gate *
477c478bd9Sstevel@tonic-gate * Those sun4 platforms wanting default lgroup behavior build with
487c478bd9Sstevel@tonic-gate * MAX_MEM_NODES = 1. Those sun4 platforms wanting other than default
497c478bd9Sstevel@tonic-gate * lgroup behavior build with MAX_MEM_NODES > 1 and provide unique
507c478bd9Sstevel@tonic-gate * definitions to replace the #pragma weak interfaces.
517c478bd9Sstevel@tonic-gate */
527c478bd9Sstevel@tonic-gate
537c478bd9Sstevel@tonic-gate /*
547c478bd9Sstevel@tonic-gate * For now, there are 0 or 1 memnodes per lgroup on sun4 based platforms,
557c478bd9Sstevel@tonic-gate * plus the root lgroup.
567c478bd9Sstevel@tonic-gate */
577c478bd9Sstevel@tonic-gate #define NLGRP (MAX_MEM_NODES + 1)
587c478bd9Sstevel@tonic-gate
597c478bd9Sstevel@tonic-gate /*
607c478bd9Sstevel@tonic-gate * Allocate lgrp and lgrp stat arrays statically.
617c478bd9Sstevel@tonic-gate */
627c478bd9Sstevel@tonic-gate struct lgrp_stats lgrp_stats[NLGRP];
637c478bd9Sstevel@tonic-gate
647c478bd9Sstevel@tonic-gate static int nlgrps_alloc;
657c478bd9Sstevel@tonic-gate static lgrp_t lgrp_space[NLGRP];
667c478bd9Sstevel@tonic-gate
677c478bd9Sstevel@tonic-gate /*
687c478bd9Sstevel@tonic-gate * Arrays mapping lgroup handles to memnodes and vice versa. This helps
697c478bd9Sstevel@tonic-gate * manage a copy-rename operation during DR, which moves memory from one
707c478bd9Sstevel@tonic-gate * board to another without changing addresses/pfns or memnodes.
717c478bd9Sstevel@tonic-gate */
727c478bd9Sstevel@tonic-gate int lgrphand_to_memnode[MAX_MEM_NODES];
737c478bd9Sstevel@tonic-gate int memnode_to_lgrphand[MAX_MEM_NODES];
747c478bd9Sstevel@tonic-gate
757c478bd9Sstevel@tonic-gate static pgcnt_t lgrp_plat_mem_size_default(lgrp_handle_t, lgrp_mem_query_t);
767c478bd9Sstevel@tonic-gate int plat_lgrphand_to_mem_node(lgrp_handle_t);
777c478bd9Sstevel@tonic-gate lgrp_handle_t plat_mem_node_to_lgrphand(int);
787c478bd9Sstevel@tonic-gate void plat_assign_lgrphand_to_mem_node(lgrp_handle_t, int);
797c478bd9Sstevel@tonic-gate
807c478bd9Sstevel@tonic-gate /*
817c478bd9Sstevel@tonic-gate * Default sun4 lgroup interfaces which should be overriden
827c478bd9Sstevel@tonic-gate * by platform module.
837c478bd9Sstevel@tonic-gate */
847c478bd9Sstevel@tonic-gate extern void plat_lgrp_init(void);
857c478bd9Sstevel@tonic-gate extern void plat_lgrp_config(lgrp_config_flag_t, uintptr_t);
867c478bd9Sstevel@tonic-gate extern lgrp_handle_t plat_lgrp_cpu_to_hand(processorid_t);
877c478bd9Sstevel@tonic-gate extern int plat_lgrp_latency(lgrp_handle_t, lgrp_handle_t);
887c478bd9Sstevel@tonic-gate extern lgrp_handle_t plat_lgrp_root_hand(void);
897c478bd9Sstevel@tonic-gate
907c478bd9Sstevel@tonic-gate #pragma weak plat_lgrp_init
917c478bd9Sstevel@tonic-gate #pragma weak plat_lgrp_config
927c478bd9Sstevel@tonic-gate #pragma weak plat_lgrp_cpu_to_hand
937c478bd9Sstevel@tonic-gate #pragma weak plat_lgrp_latency
947c478bd9Sstevel@tonic-gate #pragma weak plat_lgrp_root_hand
957c478bd9Sstevel@tonic-gate
967c478bd9Sstevel@tonic-gate int mpo_disabled = 0;
977c478bd9Sstevel@tonic-gate lgrp_handle_t lgrp_default_handle = LGRP_DEFAULT_HANDLE;
987c478bd9Sstevel@tonic-gate
997c478bd9Sstevel@tonic-gate void
lgrp_plat_init(lgrp_init_stages_t stage)100d5d7cf4eSJonathan Chew lgrp_plat_init(lgrp_init_stages_t stage)
1017c478bd9Sstevel@tonic-gate {
1027c478bd9Sstevel@tonic-gate int i;
1037c478bd9Sstevel@tonic-gate
104d5d7cf4eSJonathan Chew switch (stage) {
105d5d7cf4eSJonathan Chew case LGRP_INIT_STAGE1:
1067c478bd9Sstevel@tonic-gate /*
1077c478bd9Sstevel@tonic-gate * Initialize lookup tables to invalid values so we catch
1087c478bd9Sstevel@tonic-gate * any illegal use of them.
1097c478bd9Sstevel@tonic-gate */
1107c478bd9Sstevel@tonic-gate for (i = 0; i < MAX_MEM_NODES; i++) {
1117c478bd9Sstevel@tonic-gate memnode_to_lgrphand[i] = -1;
1127c478bd9Sstevel@tonic-gate lgrphand_to_memnode[i] = -1;
1137c478bd9Sstevel@tonic-gate }
1147c478bd9Sstevel@tonic-gate
1157c478bd9Sstevel@tonic-gate if (lgrp_topo_ht_limit() == 1) {
1167c478bd9Sstevel@tonic-gate max_mem_nodes = 1;
1177c478bd9Sstevel@tonic-gate return;
1187c478bd9Sstevel@tonic-gate }
1197c478bd9Sstevel@tonic-gate
1207c478bd9Sstevel@tonic-gate if (&plat_lgrp_cpu_to_hand)
1217c478bd9Sstevel@tonic-gate max_mem_nodes = MAX_MEM_NODES;
1227c478bd9Sstevel@tonic-gate
1237c478bd9Sstevel@tonic-gate if (&plat_lgrp_init)
1247c478bd9Sstevel@tonic-gate plat_lgrp_init();
125d5d7cf4eSJonathan Chew break;
126d5d7cf4eSJonathan Chew default:
127d5d7cf4eSJonathan Chew break;
1287c478bd9Sstevel@tonic-gate }
1297c478bd9Sstevel@tonic-gate }
1307c478bd9Sstevel@tonic-gate
1317c478bd9Sstevel@tonic-gate /* ARGSUSED */
1327c478bd9Sstevel@tonic-gate void
lgrp_plat_config(lgrp_config_flag_t flag,uintptr_t arg)1337c478bd9Sstevel@tonic-gate lgrp_plat_config(lgrp_config_flag_t flag, uintptr_t arg)
1347c478bd9Sstevel@tonic-gate {
1357c478bd9Sstevel@tonic-gate if (max_mem_nodes == 1)
1367c478bd9Sstevel@tonic-gate return;
1377c478bd9Sstevel@tonic-gate
1387c478bd9Sstevel@tonic-gate if (&plat_lgrp_config) {
1397c478bd9Sstevel@tonic-gate plat_lgrp_config(flag, arg);
1407c478bd9Sstevel@tonic-gate }
1417c478bd9Sstevel@tonic-gate }
1427c478bd9Sstevel@tonic-gate
1437c478bd9Sstevel@tonic-gate lgrp_handle_t
lgrp_plat_cpu_to_hand(processorid_t id)1447c478bd9Sstevel@tonic-gate lgrp_plat_cpu_to_hand(processorid_t id)
1457c478bd9Sstevel@tonic-gate {
1467c478bd9Sstevel@tonic-gate if (lgrp_topo_ht_limit() > 1 && &plat_lgrp_cpu_to_hand)
1477c478bd9Sstevel@tonic-gate return (plat_lgrp_cpu_to_hand(id));
1487c478bd9Sstevel@tonic-gate else
1497c478bd9Sstevel@tonic-gate return (LGRP_DEFAULT_HANDLE);
1507c478bd9Sstevel@tonic-gate }
1517c478bd9Sstevel@tonic-gate
1527c478bd9Sstevel@tonic-gate /*
1537c478bd9Sstevel@tonic-gate * Lgroup interfaces common to all sun4 platforms.
1547c478bd9Sstevel@tonic-gate */
1557c478bd9Sstevel@tonic-gate
1567c478bd9Sstevel@tonic-gate /*
1577c478bd9Sstevel@tonic-gate * Return the platform handle of the lgroup that contains the physical memory
1587c478bd9Sstevel@tonic-gate * corresponding to the given page frame number
1597c478bd9Sstevel@tonic-gate */
1607c478bd9Sstevel@tonic-gate lgrp_handle_t
lgrp_plat_pfn_to_hand(pfn_t pfn)1617c478bd9Sstevel@tonic-gate lgrp_plat_pfn_to_hand(pfn_t pfn)
1627c478bd9Sstevel@tonic-gate {
1637c478bd9Sstevel@tonic-gate int mnode;
1647c478bd9Sstevel@tonic-gate
1657c478bd9Sstevel@tonic-gate if (lgrp_topo_ht_limit() == 1 || max_mem_nodes == 1)
1667c478bd9Sstevel@tonic-gate return (LGRP_DEFAULT_HANDLE);
1677c478bd9Sstevel@tonic-gate
1687c478bd9Sstevel@tonic-gate if (pfn > physmax)
1697c478bd9Sstevel@tonic-gate return (LGRP_NULL_HANDLE);
1707c478bd9Sstevel@tonic-gate
1717c478bd9Sstevel@tonic-gate mnode = PFN_2_MEM_NODE(pfn);
17213bb8906Slm66018 if (mnode < 0)
17313bb8906Slm66018 return (LGRP_NULL_HANDLE);
17413bb8906Slm66018
1757c478bd9Sstevel@tonic-gate return (MEM_NODE_2_LGRPHAND(mnode));
1767c478bd9Sstevel@tonic-gate }
1777c478bd9Sstevel@tonic-gate
1787c478bd9Sstevel@tonic-gate /*
1797c478bd9Sstevel@tonic-gate * Return the maximum number of supported lgroups
1807c478bd9Sstevel@tonic-gate */
1817c478bd9Sstevel@tonic-gate int
lgrp_plat_max_lgrps(void)1827c478bd9Sstevel@tonic-gate lgrp_plat_max_lgrps(void)
1837c478bd9Sstevel@tonic-gate {
1847c478bd9Sstevel@tonic-gate return (NLGRP);
1857c478bd9Sstevel@tonic-gate }
1867c478bd9Sstevel@tonic-gate
1877c478bd9Sstevel@tonic-gate /*
1887c478bd9Sstevel@tonic-gate * Return the number of free pages in an lgroup.
1897c478bd9Sstevel@tonic-gate *
1907c478bd9Sstevel@tonic-gate * For query of LGRP_MEM_SIZE_FREE, return the number of base pagesize
1917c478bd9Sstevel@tonic-gate * pages on freelists. For query of LGRP_MEM_SIZE_AVAIL, return the
1927c478bd9Sstevel@tonic-gate * number of allocatable base pagesize pages corresponding to the
1937c478bd9Sstevel@tonic-gate * lgroup (e.g. do not include page_t's, BOP_ALLOC()'ed memory, ..)
1947c478bd9Sstevel@tonic-gate * For query of LGRP_MEM_SIZE_INSTALL, return the amount of physical
1957c478bd9Sstevel@tonic-gate * memory installed, regardless of whether or not it's usable.
1967c478bd9Sstevel@tonic-gate */
1977c478bd9Sstevel@tonic-gate pgcnt_t
lgrp_plat_mem_size(lgrp_handle_t plathand,lgrp_mem_query_t query)1987c478bd9Sstevel@tonic-gate lgrp_plat_mem_size(lgrp_handle_t plathand, lgrp_mem_query_t query)
1997c478bd9Sstevel@tonic-gate {
2007c478bd9Sstevel@tonic-gate int mnode;
2017c478bd9Sstevel@tonic-gate pgcnt_t npgs = (pgcnt_t)0;
2027c478bd9Sstevel@tonic-gate extern struct memlist *phys_avail;
2037c478bd9Sstevel@tonic-gate extern struct memlist *phys_install;
2047c478bd9Sstevel@tonic-gate
2057c478bd9Sstevel@tonic-gate
2067c478bd9Sstevel@tonic-gate if (lgrp_topo_ht_limit() == 1 || max_mem_nodes == 1 || mpo_disabled ||
2077c478bd9Sstevel@tonic-gate plathand == LGRP_DEFAULT_HANDLE)
2087c478bd9Sstevel@tonic-gate return (lgrp_plat_mem_size_default(plathand, query));
2097c478bd9Sstevel@tonic-gate
2107c478bd9Sstevel@tonic-gate if (plathand != LGRP_NULL_HANDLE) {
2117c478bd9Sstevel@tonic-gate mnode = plat_lgrphand_to_mem_node(plathand);
2127c478bd9Sstevel@tonic-gate if (mnode >= 0 && mem_node_config[mnode].exists) {
2137c478bd9Sstevel@tonic-gate switch (query) {
2147c478bd9Sstevel@tonic-gate case LGRP_MEM_SIZE_FREE:
215affbd3ccSkchow npgs = MNODE_PGCNT(mnode);
2167c478bd9Sstevel@tonic-gate break;
2177c478bd9Sstevel@tonic-gate case LGRP_MEM_SIZE_AVAIL:
2187c478bd9Sstevel@tonic-gate npgs = mem_node_memlist_pages(mnode,
2197c478bd9Sstevel@tonic-gate phys_avail);
2207c478bd9Sstevel@tonic-gate break;
2217c478bd9Sstevel@tonic-gate case LGRP_MEM_SIZE_INSTALL:
2227c478bd9Sstevel@tonic-gate npgs = mem_node_memlist_pages(mnode,
2237c478bd9Sstevel@tonic-gate phys_install);
2247c478bd9Sstevel@tonic-gate break;
2257c478bd9Sstevel@tonic-gate default:
2267c478bd9Sstevel@tonic-gate break;
2277c478bd9Sstevel@tonic-gate }
2287c478bd9Sstevel@tonic-gate }
2297c478bd9Sstevel@tonic-gate }
2307c478bd9Sstevel@tonic-gate return (npgs);
2317c478bd9Sstevel@tonic-gate }
2327c478bd9Sstevel@tonic-gate
2337c478bd9Sstevel@tonic-gate /*
2347c478bd9Sstevel@tonic-gate * Return latency between "from" and "to" lgroups
2357c478bd9Sstevel@tonic-gate * If "from" or "to" is LGRP_NONE, then just return latency within other
2367c478bd9Sstevel@tonic-gate * lgroup. This latency number can only be used for relative comparison
2377c478bd9Sstevel@tonic-gate * between lgroups on the running system, cannot be used across platforms,
2387c478bd9Sstevel@tonic-gate * and may not reflect the actual latency. It is platform and implementation
2397c478bd9Sstevel@tonic-gate * specific, so platform gets to decide its value.
2407c478bd9Sstevel@tonic-gate */
2417c478bd9Sstevel@tonic-gate int
lgrp_plat_latency(lgrp_handle_t from,lgrp_handle_t to)2427c478bd9Sstevel@tonic-gate lgrp_plat_latency(lgrp_handle_t from, lgrp_handle_t to)
2437c478bd9Sstevel@tonic-gate {
2447c478bd9Sstevel@tonic-gate if (lgrp_topo_ht_limit() > 1 && &plat_lgrp_latency)
2457c478bd9Sstevel@tonic-gate return (plat_lgrp_latency(from, to));
2467c478bd9Sstevel@tonic-gate else
2477c478bd9Sstevel@tonic-gate return (0);
2487c478bd9Sstevel@tonic-gate }
2497c478bd9Sstevel@tonic-gate
2507c478bd9Sstevel@tonic-gate /*
2517c478bd9Sstevel@tonic-gate * Return platform handle for root lgroup
2527c478bd9Sstevel@tonic-gate */
2537c478bd9Sstevel@tonic-gate lgrp_handle_t
lgrp_plat_root_hand(void)2547c478bd9Sstevel@tonic-gate lgrp_plat_root_hand(void)
2557c478bd9Sstevel@tonic-gate {
2567c478bd9Sstevel@tonic-gate if (&plat_lgrp_root_hand)
2577c478bd9Sstevel@tonic-gate return (plat_lgrp_root_hand());
2587c478bd9Sstevel@tonic-gate else
2597c478bd9Sstevel@tonic-gate return (LGRP_DEFAULT_HANDLE);
2607c478bd9Sstevel@tonic-gate }
2617c478bd9Sstevel@tonic-gate
2627c478bd9Sstevel@tonic-gate /* Internal interfaces */
2637c478bd9Sstevel@tonic-gate /*
2647c478bd9Sstevel@tonic-gate * Return the number of free, allocatable, or installed
2657c478bd9Sstevel@tonic-gate * pages in an lgroup
2667c478bd9Sstevel@tonic-gate * This is a copy of the MAX_MEM_NODES == 1 version of the routine
2677c478bd9Sstevel@tonic-gate * used when MPO is disabled (i.e. single lgroup)
2687c478bd9Sstevel@tonic-gate */
2697c478bd9Sstevel@tonic-gate /* ARGSUSED */
2707c478bd9Sstevel@tonic-gate static pgcnt_t
lgrp_plat_mem_size_default(lgrp_handle_t lgrphand,lgrp_mem_query_t query)2717c478bd9Sstevel@tonic-gate lgrp_plat_mem_size_default(lgrp_handle_t lgrphand, lgrp_mem_query_t query)
2727c478bd9Sstevel@tonic-gate {
2737c478bd9Sstevel@tonic-gate extern struct memlist *phys_install;
2747c478bd9Sstevel@tonic-gate extern struct memlist *phys_avail;
2757c478bd9Sstevel@tonic-gate struct memlist *mlist;
2767c478bd9Sstevel@tonic-gate pgcnt_t npgs = 0;
2777c478bd9Sstevel@tonic-gate
2787c478bd9Sstevel@tonic-gate switch (query) {
2797c478bd9Sstevel@tonic-gate case LGRP_MEM_SIZE_FREE:
2807c478bd9Sstevel@tonic-gate return ((pgcnt_t)freemem);
2817c478bd9Sstevel@tonic-gate case LGRP_MEM_SIZE_AVAIL:
2827c478bd9Sstevel@tonic-gate memlist_read_lock();
283*56f33205SJonathan Adams for (mlist = phys_avail; mlist; mlist = mlist->ml_next)
284*56f33205SJonathan Adams npgs += btop(mlist->ml_size);
2857c478bd9Sstevel@tonic-gate memlist_read_unlock();
2867c478bd9Sstevel@tonic-gate return (npgs);
2877c478bd9Sstevel@tonic-gate case LGRP_MEM_SIZE_INSTALL:
2887c478bd9Sstevel@tonic-gate memlist_read_lock();
289*56f33205SJonathan Adams for (mlist = phys_install; mlist; mlist = mlist->ml_next)
290*56f33205SJonathan Adams npgs += btop(mlist->ml_size);
2917c478bd9Sstevel@tonic-gate memlist_read_unlock();
2927c478bd9Sstevel@tonic-gate return (npgs);
2937c478bd9Sstevel@tonic-gate default:
2947c478bd9Sstevel@tonic-gate return ((pgcnt_t)0);
2957c478bd9Sstevel@tonic-gate }
2967c478bd9Sstevel@tonic-gate }
2977c478bd9Sstevel@tonic-gate
2987c478bd9Sstevel@tonic-gate /*
2997c478bd9Sstevel@tonic-gate * Return the memnode associated with the specified lgroup handle
3007c478bd9Sstevel@tonic-gate */
3017c478bd9Sstevel@tonic-gate int
plat_lgrphand_to_mem_node(lgrp_handle_t plathand)3027c478bd9Sstevel@tonic-gate plat_lgrphand_to_mem_node(lgrp_handle_t plathand)
3037c478bd9Sstevel@tonic-gate {
3047c478bd9Sstevel@tonic-gate int mnode;
3057c478bd9Sstevel@tonic-gate
3067c478bd9Sstevel@tonic-gate if (lgrp_topo_ht_limit() == 1 || mpo_disabled || max_mem_nodes == 1)
3077c478bd9Sstevel@tonic-gate return (-1);
3087c478bd9Sstevel@tonic-gate
3097c478bd9Sstevel@tonic-gate /*
3107c478bd9Sstevel@tonic-gate * We should always receive a valid pointer to a platform
3117c478bd9Sstevel@tonic-gate * handle, as we can not choose the allocation policy in
3127c478bd9Sstevel@tonic-gate * this layer.
3137c478bd9Sstevel@tonic-gate */
3147c478bd9Sstevel@tonic-gate ASSERT((int)plathand >= 0 && (int)plathand < max_mem_nodes);
3157c478bd9Sstevel@tonic-gate
3167c478bd9Sstevel@tonic-gate mnode = lgrphand_to_memnode[(int)plathand];
3177c478bd9Sstevel@tonic-gate return (mnode);
3187c478bd9Sstevel@tonic-gate }
3197c478bd9Sstevel@tonic-gate
3207c478bd9Sstevel@tonic-gate lgrp_handle_t
plat_mem_node_to_lgrphand(int mnode)3217c478bd9Sstevel@tonic-gate plat_mem_node_to_lgrphand(int mnode)
3227c478bd9Sstevel@tonic-gate {
3237c478bd9Sstevel@tonic-gate if (lgrp_topo_ht_limit() == 1 || mpo_disabled || max_mem_nodes == 1)
3247c478bd9Sstevel@tonic-gate return (lgrp_default_handle);
3257c478bd9Sstevel@tonic-gate
3267c478bd9Sstevel@tonic-gate ASSERT(mnode >= 0 && mnode < max_mem_nodes);
3277c478bd9Sstevel@tonic-gate return (memnode_to_lgrphand[mnode]);
3287c478bd9Sstevel@tonic-gate }
3297c478bd9Sstevel@tonic-gate
3307c478bd9Sstevel@tonic-gate void
plat_assign_lgrphand_to_mem_node(lgrp_handle_t plathand,int mnode)3317c478bd9Sstevel@tonic-gate plat_assign_lgrphand_to_mem_node(lgrp_handle_t plathand, int mnode)
3327c478bd9Sstevel@tonic-gate {
3337c478bd9Sstevel@tonic-gate if (lgrp_topo_ht_limit() == 1 || mpo_disabled || max_mem_nodes == 1)
3347c478bd9Sstevel@tonic-gate return;
3357c478bd9Sstevel@tonic-gate
3367c478bd9Sstevel@tonic-gate ASSERT(plathand < max_mem_nodes);
3377c478bd9Sstevel@tonic-gate ASSERT(mnode >= 0 && mnode < max_mem_nodes);
3387c478bd9Sstevel@tonic-gate
3397c478bd9Sstevel@tonic-gate lgrphand_to_memnode[plathand] = mnode;
3407c478bd9Sstevel@tonic-gate memnode_to_lgrphand[mnode] = plathand;
3417c478bd9Sstevel@tonic-gate }
3427c478bd9Sstevel@tonic-gate
3437c478bd9Sstevel@tonic-gate lgrp_t *
lgrp_plat_alloc(lgrp_id_t lgrpid)3447c478bd9Sstevel@tonic-gate lgrp_plat_alloc(lgrp_id_t lgrpid)
3457c478bd9Sstevel@tonic-gate {
3467c478bd9Sstevel@tonic-gate lgrp_t *lgrp;
3477c478bd9Sstevel@tonic-gate
3487c478bd9Sstevel@tonic-gate lgrp = &lgrp_space[nlgrps_alloc++];
3497c478bd9Sstevel@tonic-gate if (lgrpid >= NLGRP || nlgrps_alloc > NLGRP)
3507c478bd9Sstevel@tonic-gate return (NULL);
3517c478bd9Sstevel@tonic-gate return (lgrp);
3527c478bd9Sstevel@tonic-gate }
353