4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
38 #include <sys/bitmap.h>
40 #include <sys/types.h>
42 #include <sys/lgrp_user.h>
46 * Fast trap for getting home lgroup of current thread
48 extern lgrp_id_t
_lgrp_home_fast(void);
53 extern int _lgrpsys(int subcode
, long arg
, void *ap
);
55 static int lgrp_cpus_hier(lgrp_snapshot_header_t
*snap
, lgrp_id_t lgrp
,
56 processorid_t
**cpuids
, uint_t
*count
);
60 * Get generation ID of lgroup hierarchy given view
61 * which changes whenever the hierarchy changes (eg. DR or pset contents
62 * change for caller's view)
65 lgrp_generation(lgrp_view_t view
)
67 return (_lgrpsys(LGRP_SYS_GENERATION
, view
, NULL
));
72 * Get supported revision number of lgroup interface
75 lgrp_version(int version
)
77 return (_lgrpsys(LGRP_SYS_VERSION
, version
, NULL
));
82 * Get affinity for given lgroup
85 lgrp_affinity_get(idtype_t idtype
, id_t id
, lgrp_id_t lgrp
)
87 lgrp_affinity_args_t args
;
92 return (_lgrpsys(LGRP_SYS_AFFINITY_GET
, 0, (void *)&args
));
97 * Set affinity for given lgroup
100 lgrp_affinity_set(idtype_t idtype
, id_t id
, lgrp_id_t lgrp
,
103 lgrp_affinity_args_t args
;
105 args
.idtype
= idtype
;
109 return (_lgrpsys(LGRP_SYS_AFFINITY_SET
, 0, (void *)&args
));
114 * Get home lgroup for given process or thread
117 lgrp_home(idtype_t idtype
, id_t id
)
120 * Use fast trap to get home lgroup of current thread or process
121 * Otherwise, use system call for other process or thread
123 if (id
== P_MYID
&& (idtype
== P_LWPID
|| idtype
== P_PID
))
124 return (_lgrp_home_fast());
126 return (_lgrpsys(LGRP_SYS_HOME
, idtype
, (void *)(intptr_t)id
));
131 * Get a snapshot of the lgroup hierarchy
134 lgrp_snapshot(void *buf
, size_t bufsize
)
136 return (_lgrpsys(LGRP_SYS_SNAPSHOT
, bufsize
, buf
));
141 * Find any orphan lgroups without parents and make them be children of
145 parent_orphans(lgrp_snapshot_header_t
*snap
)
148 lgrp_info_t
*lgrp_info
;
154 if (snap
== NULL
|| snap
->ss_info
== NULL
||
155 snap
->ss_parents
== NULL
|| snap
->ss_root
< 0 ||
156 snap
->ss_root
>= snap
->ss_nlgrps_max
)
159 nlgrpsmax
= snap
->ss_nlgrps_max
;
160 root
= &snap
->ss_info
[snap
->ss_root
];
162 for (i
= 0; i
< nlgrpsmax
; i
++) {
168 if (i
== snap
->ss_root
)
171 lgrp_info
= &snap
->ss_info
[i
];
172 if (lgrp_info
== NULL
|| lgrp_info
->info_lgrpid
== LGRP_NONE
)
176 * Make sure parents bitmap is setup
178 if (lgrp_info
->info_parents
== NULL
)
179 lgrp_info
->info_parents
=
180 (ulong_t
*)((uintptr_t)snap
->ss_parents
+
181 (i
* BT_SIZEOFMAP(nlgrpsmax
)));
184 * Look for orphans (lgroups with no parents)
187 parents
= lgrp_info
->info_parents
;
188 for (j
= 0; j
< BT_BITOUL(nlgrpsmax
); j
++)
189 if (parents
[j
] != 0) {
195 * Make root be parent of any orphans
198 BT_SET(parents
, root
->info_lgrpid
);
199 if (root
->info_children
) {
200 BT_SET(root
->info_children
, i
);
210 * Remove given lgroup from parent lgroup(s)
213 prune_child(lgrp_snapshot_header_t
*snap
, lgrp_id_t lgrp
)
216 lgrp_info_t
*lgrp_info
;
219 if (snap
== NULL
|| lgrp
< 0 || lgrp
> snap
->ss_nlgrps_max
)
222 lgrp_info
= &snap
->ss_info
[lgrp
];
224 parents
= lgrp_info
->info_parents
;
229 * Update children of parents not to include given lgroup
231 for (i
= 0; i
< snap
->ss_nlgrps_max
; i
++) {
232 if (BT_TEST(parents
, i
)) {
233 lgrp_info
= &snap
->ss_info
[i
];
234 BT_CLEAR(lgrp_info
->info_children
, lgrp
);
240 * Prune any CPUs not in given array from specified lgroup
243 prune_cpus(lgrp_snapshot_header_t
*snap
, lgrp_id_t lgrp
, processorid_t
*cpus
,
250 lgrp_info_t
*lgrp_info
;
252 processorid_t
*lgrp_cpus
;
254 if (snap
== NULL
|| lgrp
< 0 || lgrp
> snap
->ss_nlgrps_max
)
257 lgrp_info
= &snap
->ss_info
[lgrp
];
262 if (ncpus
== 0 || lgrp_info
->info_ncpus
== 0)
266 * Remove all CPUs from lgroup
268 if (cpus
== NULL
&& ncpus
== -1) {
269 lgrp_info
->info_ncpus
= 0;
274 * Remove any CPUs from lgroup not in given list of CPUs
276 lgrp_cpus
= lgrp_info
->info_cpuids
;
277 lgrp_ncpus
= lgrp_info
->info_ncpus
;
279 for (count
= 0; count
< lgrp_ncpus
; count
++) {
281 * Look for CPU in list
283 for (j
= 0; j
< ncpus
; j
++)
284 if (lgrp_cpus
[i
] == cpus
[j
])
288 * Go to next CPU if found this one in list
296 * Remove this CPU and shift others into its place
297 * and decrement number of CPUs
299 for (k
= i
+ 1; k
< lgrp_info
->info_ncpus
; k
++)
300 lgrp_cpus
[k
- 1] = lgrp_cpus
[k
];
301 lgrp_cpus
[k
- 1] = -1;
302 lgrp_info
->info_ncpus
--;
308 * Prune lgroup hierarchy for caller's view
311 prune_tree(lgrp_snapshot_header_t
*snap
)
315 lgrp_info_t
*lgrp_info
;
316 lgrp_mem_size_t nbytes
;
320 if (snap
== NULL
|| snap
->ss_info
== NULL
)
324 * Get CPUs in caller's pset
326 if (pset_info(PS_MYID
, NULL
, &ncpus
, NULL
) == -1)
331 cpus
= malloc(ncpus
* sizeof (processorid_t
));
332 if (pset_info(PS_MYID
, NULL
, &ncpus
, cpus
) == -1) {
339 * Remove any CPUs not in caller's pset from lgroup hierarchy
341 nlgrps_max
= snap
->ss_nlgrps_max
;
342 for (i
= 0; i
< nlgrps_max
; i
++) {
343 lgrp_info
= &snap
->ss_info
[i
];
344 if (BT_TEST(snap
->ss_lgrpset
, i
))
345 prune_cpus(snap
, i
, cpus
, ncpus
);
346 else if (lgrp_info
->info_lgrpid
!= LGRP_NONE
)
347 prune_cpus(snap
, i
, NULL
, -1);
354 * Change lgroup bitmask from just reflecting lgroups overlapping
355 * caller's pset to all lgroups available to caller, starting by
356 * filling in all lgroups and then removing any empty ones below
358 for (i
= 0; i
< nlgrps_max
; i
++) {
359 lgrp_info
= &snap
->ss_info
[i
];
360 if (lgrp_info
->info_lgrpid
== LGRP_NONE
)
363 BT_SET(snap
->ss_lgrpset
, i
);
367 * Remove empty lgroups from lgroup hierarchy, removing it from its
368 * parents and decrementing nlgrps
370 for (i
= 0; i
< nlgrps_max
; i
++) {
371 lgrp_info
= &snap
->ss_info
[i
];
372 if (lgrp_info
->info_lgrpid
== LGRP_NONE
)
375 ncpus
= lgrp_cpus_hier(snap
, i
, NULL
, NULL
);
376 nbytes
= lgrp_mem_size((lgrp_cookie_t
)snap
, i
,
377 LGRP_MEM_SZ_INSTALLED
, LGRP_CONTENT_HIERARCHY
);
378 if (ncpus
== 0 && nbytes
== 0) {
379 BT_CLEAR(snap
->ss_lgrpset
, i
);
380 prune_child(snap
, i
);
390 * Initialize lgroup interface
393 lgrp_init(lgrp_view_t view
)
398 lgrp_snapshot_header_t
*snap
;
401 * Check for legal view
403 if (view
!= LGRP_VIEW_OS
&& view
!= LGRP_VIEW_CALLER
) {
405 return (LGRP_COOKIE_NONE
);
409 * Try to take a consistent snapshot of lgroup hierarchy
412 while (snap
== NULL
) {
414 * Get lgroup generation number before taking snapshot
416 gen
= lgrp_generation(view
);
419 * Get size of buffer needed for snapshot
421 bufsize
= lgrp_snapshot(NULL
, 0);
424 return (LGRP_COOKIE_NONE
);
433 snap
= malloc(bufsize
);
435 return (LGRP_COOKIE_NONE
);
436 bzero(snap
, bufsize
);
439 * Take snapshot of lgroup hierarchy
441 bufsize
= lgrp_snapshot(snap
, bufsize
);
445 return (LGRP_COOKIE_NONE
);
452 * See whether lgroup generation number changed
454 if (gen
== lgrp_generation(view
))
462 * Remember generation number and view of this snapshot
465 snap
->ss_view
= view
;
468 * Keep caller's pset ID for caller's view
471 if (view
== LGRP_VIEW_CALLER
) {
474 if (pset_bind(PS_QUERY
, P_LWPID
, P_MYID
, &pset
) == -1)
475 return ((uintptr_t)-1);
477 snap
->ss_pset
= pset
;
481 * Find any orphan lgroups without parents and make them be children
484 if (snap
->ss_levels
> 1)
485 (void) parent_orphans(snap
);
488 * Prune snapshot of lgroup hierarchy for caller's view
490 if (view
== LGRP_VIEW_CALLER
)
491 (void) prune_tree(snap
);
494 * Change lgroup bitmask from just reflecting lgroups
495 * overlapping caller's pset to all lgroups available
497 for (i
= 0; i
< snap
->ss_nlgrps_max
; i
++) {
498 lgrp_info_t
*lgrp_info
;
500 lgrp_info
= &snap
->ss_info
[i
];
501 if (lgrp_info
->info_lgrpid
== LGRP_NONE
)
504 BT_SET(snap
->ss_lgrpset
, i
);
508 return ((uintptr_t)snap
);
513 * Return whether given cookie is out-of-date (stale) or not
516 lgrp_cookie_stale(lgrp_cookie_t cookie
)
519 lgrp_snapshot_header_t
*snap
;
522 * Check for bad cookie
524 snap
= (lgrp_snapshot_header_t
*)cookie
;
525 if (snap
== NULL
|| snap
->ss_magic
!= cookie
) {
531 * Check generation number which changes when lgroup hierarchy changes
532 * or pset contents change for caller's view
534 if (snap
->ss_gen
!= lgrp_generation(snap
->ss_view
))
538 * See whether pset binding has changed for caller's view
540 if (snap
->ss_view
== LGRP_VIEW_CALLER
) {
541 if (pset_bind(PS_QUERY
, P_LWPID
, P_MYID
, &pset
) == -1)
543 if (snap
->ss_pset
!= pset
)
547 return (0); /* cookie isn't stale */
552 * Get view of lgroup hierarchy from snapshot represented by given cookie
555 lgrp_view(lgrp_cookie_t cookie
)
557 lgrp_snapshot_header_t
*snap
;
559 snap
= (lgrp_snapshot_header_t
*)cookie
;
560 if (snap
== NULL
|| snap
->ss_magic
!= cookie
) {
565 return (snap
->ss_view
);
570 * Get number of lgroups
573 lgrp_nlgrps(lgrp_cookie_t cookie
)
575 lgrp_snapshot_header_t
*snap
;
577 snap
= (lgrp_snapshot_header_t
*)cookie
;
579 if (snap
== NULL
|| snap
->ss_magic
!= cookie
) {
584 return (snap
->ss_nlgrps
);
589 * Return root lgroup ID
592 lgrp_root(lgrp_cookie_t cookie
)
594 lgrp_snapshot_header_t
*snap
;
596 snap
= (lgrp_snapshot_header_t
*)cookie
;
598 if (snap
== NULL
|| snap
->ss_magic
!= cookie
) {
603 return (snap
->ss_root
);
608 * Get parent lgroups of given lgroup
611 lgrp_parents(lgrp_cookie_t cookie
, lgrp_id_t lgrp
, lgrp_id_t
*parents
,
615 ulong_t
*lgrp_parents
;
616 lgrp_snapshot_header_t
*snap
;
620 snap
= (lgrp_snapshot_header_t
*)cookie
;
623 * Check for valid arguments
625 if (snap
== NULL
|| snap
->ss_magic
!= cookie
||
626 lgrp
< 0 || lgrp
== LGRP_NONE
) {
632 * See whether given lgroup exists
634 nlgrps_max
= snap
->ss_nlgrps_max
;
635 if (lgrp
>= nlgrps_max
|| !BT_TEST(snap
->ss_lgrpset
, lgrp
)) {
641 * No parents, since given lgroup is root lgroup or
642 * only one level in lgroup hierarchy (ie. SMP)
644 if (lgrp
== snap
->ss_root
|| snap
->ss_levels
== 1) {
645 if (parents
== NULL
|| count
< 1)
651 * Make sure that parents exist
653 if (snap
->ss_parents
== NULL
) {
659 * Given lgroup should have a parent
661 lgrp_parents
= &snap
->ss_parents
[lgrp
* BT_BITOUL(nlgrps_max
)];
662 if (lgrp_parents
== NULL
) {
668 * Check lgroup parents bitmask, fill in parents array, and return
672 for (i
= 0; i
< nlgrps_max
; i
++) {
673 if (BT_TEST(lgrp_parents
, i
)) {
674 if (parents
!= NULL
&& nparents
< count
) {
675 parents
[nparents
] = i
;
685 * Get children lgroups of given lgroup
688 lgrp_children(lgrp_cookie_t cookie
, lgrp_id_t lgrp
, lgrp_id_t
*children
,
692 ulong_t
*lgrp_children
;
695 lgrp_snapshot_header_t
*snap
;
697 snap
= (lgrp_snapshot_header_t
*)cookie
;
700 * Check for valid arguments
702 if (snap
== NULL
|| snap
->ss_magic
!= cookie
||
703 lgrp
< 0 || lgrp
== LGRP_NONE
) {
709 * See whether given lgroup exists
711 nlgrps_max
= snap
->ss_nlgrps_max
;
712 if (lgrp
>= nlgrps_max
|| !BT_TEST(snap
->ss_lgrpset
, lgrp
)) {
718 * No children, since only one level in lgroup hierarchy (ie. SMP)
720 if (snap
->ss_levels
== 1) {
721 if (children
== NULL
|| count
< 1)
727 * Make sure that children exist
729 if (snap
->ss_children
== NULL
) {
735 * Given lgroup may not have any children
737 lgrp_children
= &snap
->ss_children
[lgrp
* BT_BITOUL(nlgrps_max
)];
739 if (lgrp_children
== NULL
)
743 * Check lgroup children bitmask, fill in children array, and return
747 for (i
= 0; i
< nlgrps_max
; i
++) {
748 if (BT_TEST(lgrp_children
, i
)) {
749 if (children
!= NULL
&& nchildren
< count
)
750 children
[nchildren
] = i
;
759 * Get all CPUs within given lgroup (hierarchy)
762 lgrp_cpus_hier(lgrp_snapshot_header_t
*snap
, lgrp_id_t lgrp
,
763 processorid_t
**cpuids
, uint_t
*count
)
768 lgrp_info_t
*lgrp_info
;
777 lgrp_info
= &snap
->ss_info
[lgrp
];
779 if (lgrp_info
== NULL
) {
785 * Check whether given lgroup contains any lgroups with CPU resources
787 if (lgrp_info
->info_rset
== NULL
)
790 nlgrps_max
= snap
->ss_nlgrps_max
;
791 rset
= &lgrp_info
->info_rset
[LGRP_RSRC_CPU
* BT_BITOUL(nlgrps_max
)];
794 * Get all CPUs within this lgroup
797 for (i
= 0; i
< nlgrps_max
; i
++) {
798 if (!BT_TEST(rset
, i
))
801 lgrp_info
= &snap
->ss_info
[i
];
804 * Get all CPUs within lgroup
806 cpus
= lgrp_info
->info_cpuids
;
807 ncpus
= lgrp_info
->info_ncpus
;
811 * Copy as many CPU IDs into array that will fit
812 * and decrement count and increment array pointer
815 if (cpuids
&& *cpuids
&& count
) {
816 for (j
= 0; j
< ncpus
; j
++) {
831 * Get CPUs in given lgroup
834 lgrp_cpus(lgrp_cookie_t cookie
, lgrp_id_t lgrp
, processorid_t
*cpuids
,
835 uint_t count
, lgrp_content_t content
)
839 lgrp_info_t
*lgrp_info
;
841 lgrp_snapshot_header_t
*snap
;
843 snap
= (lgrp_snapshot_header_t
*)cookie
;
846 * Check for valid arguments
848 if (snap
== NULL
|| snap
->ss_magic
!= cookie
||
849 lgrp
< 0 || lgrp
== LGRP_NONE
||
850 (content
!= LGRP_CONTENT_DIRECT
&&
851 content
!= LGRP_CONTENT_HIERARCHY
)) {
857 * See whether given lgroup exists
859 if (lgrp
>= snap
->ss_nlgrps_max
|| snap
->ss_info
== NULL
||
860 !BT_TEST(snap
->ss_lgrpset
, lgrp
)) {
868 lgrp_info
= &snap
->ss_info
[lgrp
];
871 * Get contents of lgroup
874 case LGRP_CONTENT_DIRECT
:
876 * Get CPUs contained directly within given lgroup
878 cpus
= lgrp_info
->info_cpuids
;
879 ncpus
= lgrp_info
->info_ncpus
;
882 * No array to copy CPU IDs into,
883 * so just return number of CPUs.
889 * Copy as many CPU IDs into array that will fit
891 for (i
= 0; i
< ncpus
; i
++)
897 case LGRP_CONTENT_ALL
:
898 return (lgrp_cpus_hier(snap
, lgrp
, &cpuids
, &count
));
908 * Return physical memory size in pages for given lgroup
911 lgrp_mem_size(lgrp_cookie_t cookie
, lgrp_id_t lgrp
, lgrp_mem_size_flag_t type
,
912 lgrp_content_t content
)
915 lgrp_info_t
*lgrp_info
;
919 lgrp_mem_size_t size
;
920 lgrp_snapshot_header_t
*snap
;
922 snap
= (lgrp_snapshot_header_t
*)cookie
;
925 * Check for valid arguments
927 if (snap
== NULL
|| snap
->ss_magic
!= cookie
||
928 lgrp
< 0 || lgrp
== LGRP_NONE
) {
934 * See whether given lgroup exists
936 nlgrps_max
= snap
->ss_nlgrps_max
;
937 if (lgrp
>= nlgrps_max
|| snap
->ss_info
== NULL
||
938 !BT_TEST(snap
->ss_lgrpset
, lgrp
)) {
943 pgsz
= getpagesize();
948 lgrp_info
= &snap
->ss_info
[lgrp
];
951 case LGRP_CONTENT_DIRECT
:
953 * Get memory contained directly in this lgroup
956 case LGRP_MEM_SZ_FREE
:
957 size
= (lgrp_mem_size_t
)pgsz
*
958 lgrp_info
->info_mem_free
;
960 case LGRP_MEM_SZ_INSTALLED
:
961 size
= (lgrp_mem_size_t
)pgsz
*
962 lgrp_info
->info_mem_install
;
969 case LGRP_CONTENT_ALL
:
971 * Get memory contained within this lgroup (and its children)
974 * Check whether given lgroup contains any lgroups with CPU
977 if (lgrp_info
->info_rset
== NULL
)
980 rset
= &lgrp_info
->info_rset
[LGRP_RSRC_MEM
*
981 BT_BITOUL(nlgrps_max
)];
984 * Add up memory in lgroup resources
987 for (i
= 0; i
< nlgrps_max
; i
++) {
988 if (!BT_TEST(rset
, i
))
991 lgrp_info
= &snap
->ss_info
[i
];
993 case LGRP_MEM_SZ_FREE
:
994 size
+= (lgrp_mem_size_t
)pgsz
*
995 lgrp_info
->info_mem_free
;
997 case LGRP_MEM_SZ_INSTALLED
:
998 size
+= (lgrp_mem_size_t
)pgsz
*
999 lgrp_info
->info_mem_install
;
1018 * Get resources for a particuliar lgroup
1021 lgrp_resources(lgrp_cookie_t cookie
, lgrp_id_t lgrp
, lgrp_id_t
*lgrps
,
1022 uint_t count
, lgrp_rsrc_t type
)
1025 lgrp_info_t
*lgrp_info
;
1029 lgrp_snapshot_header_t
*snap
;
1031 snap
= (lgrp_snapshot_header_t
*)cookie
;
1034 * Check for valid arguments
1036 if (snap
== NULL
|| snap
->ss_magic
!= cookie
||
1037 lgrp
< 0 || lgrp
== LGRP_NONE
||
1038 (type
!= LGRP_RSRC_CPU
&& type
!= LGRP_RSRC_MEM
)) {
1044 * See whether given lgroup exists
1046 nlgrps_max
= snap
->ss_nlgrps_max
;
1047 if (lgrp
>= nlgrps_max
|| snap
->ss_info
== NULL
||
1048 !BT_TEST(snap
->ss_lgrpset
, lgrp
)) {
1056 lgrp_info
= &snap
->ss_info
[lgrp
];
1059 * Count number lgroups contained within this lgroup and
1060 * copy as many lgroup IDs into array that will fit
1062 rset
= &lgrp_info
->info_rset
[type
* BT_BITOUL(nlgrps_max
)];
1064 for (i
= 0; i
< snap
->ss_nlgrps_max
; i
++)
1065 if (BT_TEST(rset
, i
)) {
1066 if (lgrps
!= NULL
&& nlgrps
< count
)
1076 * Finish using lgroup interface
1079 lgrp_fini(lgrp_cookie_t cookie
)
1081 lgrp_snapshot_header_t
*snap
;
1083 snap
= (lgrp_snapshot_header_t
*)cookie
;
1085 if (snap
== NULL
|| snap
->ss_magic
!= cookie
) {
1090 bzero(snap
, snap
->ss_size
);
1099 * Return latency between "from" and "to" lgroups
1101 * This latency number can only be used for relative comparison
1102 * between lgroups on the running system, cannot be used across platforms,
1103 * and may not reflect the actual latency. It is platform and implementation
1104 * specific, so platform gets to decide its value. It would be nice if the
1105 * number was at least proportional to make comparisons more meaningful though.
1108 lgrp_latency(lgrp_id_t from
, lgrp_id_t to
)
1110 lgrp_cookie_t cookie
;
1113 cookie
= lgrp_init(LGRP_VIEW_OS
);
1114 latency
= lgrp_latency_cookie(cookie
, from
, to
, LGRP_LAT_CPU_TO_MEM
);
1115 (void) lgrp_fini(cookie
);
1122 * Return latency between "from" and "to" lgroups
1124 * This latency number can only be used for relative comparison
1125 * between lgroups on the running system, cannot be used across platforms,
1126 * and may not reflect the actual latency. It is platform and implementation
1127 * specific, so platform gets to decide its value. It would be nice if the
1128 * number was at least proportional to make comparisons more meaningful though.
1131 lgrp_latency_cookie(lgrp_cookie_t cookie
, lgrp_id_t from
, lgrp_id_t to
,
1132 lgrp_lat_between_t between
)
1134 lgrp_info_t
*lgrp_info
;
1135 lgrp_mem_size_t nbytes
;
1138 lgrp_snapshot_header_t
*snap
;
1140 snap
= (lgrp_snapshot_header_t
*)cookie
;
1143 * Check for valid snapshot, lgroup, and between flag
1145 if (snap
== NULL
|| snap
->ss_magic
!= cookie
|| from
< 0 || to
< 0 ||
1146 between
!= LGRP_LAT_CPU_TO_MEM
) {
1152 * Check whether lgroups exist
1154 nlgrps_max
= snap
->ss_nlgrps_max
;
1155 if (from
>= nlgrps_max
|| to
>= nlgrps_max
) {
1161 * Check whether "from" lgroup has any CPUs
1163 ncpus
= lgrp_cpus(cookie
, from
, NULL
, 0, LGRP_CONTENT_HIERARCHY
);
1171 * Check whether "to" lgroup has any memory
1173 nbytes
= lgrp_mem_size(cookie
, to
, LGRP_MEM_SZ_INSTALLED
,
1174 LGRP_CONTENT_HIERARCHY
);
1182 lgrp_info
= &snap
->ss_info
[from
];
1183 return (lgrp_info
->info_latency
);
1186 return (snap
->ss_latencies
[from
][to
]);