summaryrefslogtreecommitdiff
path: root/usr/src/uts/sun4/os/memnode.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/sun4/os/memnode.c')
-rw-r--r--usr/src/uts/sun4/os/memnode.c70
1 files changed, 56 insertions, 14 deletions
diff --git a/usr/src/uts/sun4/os/memnode.c b/usr/src/uts/sun4/os/memnode.c
index 849bec22c8..cb21287ebd 100644
--- a/usr/src/uts/sun4/os/memnode.c
+++ b/usr/src/uts/sun4/os/memnode.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * 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.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -83,7 +82,7 @@ mem_node_add_slice(pfn_t start, pfn_t end)
end = roundup(end, btop(mem_node_physalign)) - 1;
}
- if (&plat_slice_add)
+ if (&plat_slice_add != NULL)
plat_slice_add(start, end);
mnode = PFN_2_MEM_NODE(start);
@@ -148,7 +147,7 @@ mem_node_post_del_slice(pfn_t start, pfn_t end, int cancelled)
if (!cancelled) {
delta_pgcnt = end - start;
node_size = mem_node_config[mnode].physmax -
- mem_node_config[mnode].physbase;
+ mem_node_config[mnode].physbase;
if (node_size > delta_pgcnt) {
/*
@@ -180,7 +179,7 @@ mem_node_post_del_slice(pfn_t start, pfn_t end, int cancelled)
mem_node_config[mnode].exists = 0;
}
- if (&plat_slice_del)
+ if (&plat_slice_del != NULL)
plat_slice_del(start, end);
}
}
@@ -195,7 +194,7 @@ startup_build_mem_nodes(u_longlong_t *list, size_t nelems)
/* LINTED: ASSERT will always true or false */
ASSERT(NBBY * sizeof (mnodeset_t) >= max_mem_nodes);
- if (&plat_build_mem_nodes) {
+ if (&plat_build_mem_nodes != NULL) {
plat_build_mem_nodes(list, nelems);
} else {
/*
@@ -226,7 +225,7 @@ mem_node_alloc()
*/
for (mnode = 0; mnode < max_mem_nodes; mnode++)
if (cas32((uint32_t *)&mem_node_config[mnode].exists,
- 0, 1) == 0)
+ 0, 1) == 0)
break;
if (mnode >= max_mem_nodes)
@@ -247,27 +246,39 @@ mem_node_alloc()
* Find the intersection between a memnode and a memlist
* and returns the number of pages that overlap.
*
- * Assumes the list is protected from DR operations by
- * the memlist lock.
+ * Grab the memlist lock to protect the list from DR operations.
*/
pgcnt_t
mem_node_memlist_pages(int mnode, struct memlist *mlist)
{
pfn_t base, end;
pfn_t cur_base, cur_end;
- pgcnt_t npgs;
+ pgcnt_t npgs = 0;
+ pgcnt_t pages;
struct memlist *pmem;
+ if (&plat_mem_node_intersect_range != NULL) {
+ memlist_read_lock();
+
+ for (pmem = mlist; pmem; pmem = pmem->next) {
+ plat_mem_node_intersect_range(btop(pmem->address),
+ btop(pmem->size), mnode, &pages);
+ npgs += pages;
+ }
+
+ memlist_read_unlock();
+ return (npgs);
+ }
+
base = mem_node_config[mnode].physbase;
end = mem_node_config[mnode].physmax;
- npgs = 0;
memlist_read_lock();
for (pmem = mlist; pmem; pmem = pmem->next) {
cur_base = btop(pmem->address);
cur_end = cur_base + btop(pmem->size) - 1;
- if (end <= cur_base || base >= cur_end)
+ if (end < cur_base || base > cur_end)
continue;
npgs = npgs + (MIN(cur_end, end) -
MAX(cur_base, base)) + 1;
@@ -277,3 +288,34 @@ mem_node_memlist_pages(int mnode, struct memlist *mlist)
return (npgs);
}
+
+/*
+ * Find MIN(physbase) and MAX(physmax) over all mnodes
+ *
+ * Called during startup and DR to find hpm_counters limits when
+ * interleaved_mnodes is set.
+ * NOTE: there is a race condition with DR if it tries to change more than
+ * one mnode in parallel. Sizing shared hpm_counters depends on finding the
+ * min(physbase) and max(physmax) across all mnodes. Therefore, the caller of
+ * page_ctrs_adjust must ensure that mem_node_config does not change while it
+ * is running.
+ */
+void
+mem_node_max_range(pfn_t *basep, pfn_t *maxp)
+{
+ int mnode;
+ pfn_t max = 0;
+ pfn_t base = (pfn_t)-1;
+
+ for (mnode = 0; mnode < max_mem_nodes; mnode++) {
+ if (mem_node_config[mnode].exists == 0)
+ continue;
+ if (max < mem_node_config[mnode].physmax)
+ max = mem_node_config[mnode].physmax;
+ if (base > mem_node_config[mnode].physbase)
+ base = mem_node_config[mnode].physbase;
+ }
+ ASSERT(base != (pfn_t)-1 && max != 0);
+ *basep = base;
+ *maxp = max;
+}