summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authordv142724 <none@none>2008-06-16 06:29:27 -0700
committerdv142724 <none@none>2008-06-16 06:29:27 -0700
commit06fb6a368cb1af862cff62b9a1fd89171e9ac63a (patch)
treef04b72bca55a432f2214c38ff61de9225dd979cc /usr/src
parent59f081ed215eb7d3fbf19cce3474b2987eaf3225 (diff)
downloadillumos-joyent-06fb6a368cb1af862cff62b9a1fd89171e9ac63a.tar.gz
6658818 The macro PCF_INDEX is incorrect
6666035 Lock contention for pcf_buckets impacting ISM creation times 6666045 The data structures pcc_info_t and hw_page_map_t need to be cached aligned.
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/os/cpu.c1
-rw-r--r--usr/src/uts/common/sys/cpuvar.h1
-rw-r--r--usr/src/uts/common/vm/page.h6
-rw-r--r--usr/src/uts/common/vm/vm_page.c390
-rw-r--r--usr/src/uts/common/vm/vm_pagelist.c4
-rw-r--r--usr/src/uts/i86pc/os/mlsetup.c1
-rw-r--r--usr/src/uts/i86pc/os/startup.c8
-rw-r--r--usr/src/uts/i86pc/vm/vm_dep.h6
-rw-r--r--usr/src/uts/intel/ia32/ml/i86_subr.s27
-rw-r--r--usr/src/uts/sun4/os/startup.c7
-rw-r--r--usr/src/uts/sun4/vm/vm_dep.h6
-rw-r--r--usr/src/uts/sun4u/os/fillsysinfo.c4
-rw-r--r--usr/src/uts/sun4v/os/fillsysinfo.c2
13 files changed, 255 insertions, 208 deletions
diff --git a/usr/src/uts/common/os/cpu.c b/usr/src/uts/common/os/cpu.c
index a06b5fb189..4d332ea042 100644
--- a/usr/src/uts/common/os/cpu.c
+++ b/usr/src/uts/common/os/cpu.c
@@ -123,6 +123,7 @@ int max_ncpus = NCPU;
* at device tree scan time during boot.
*/
int boot_max_ncpus = -1;
+int boot_ncpus = -1;
/*
* Maximum possible CPU id. This can never be >= NCPU since NCPU is
* used to size arrays that are indexed by CPU id.
diff --git a/usr/src/uts/common/sys/cpuvar.h b/usr/src/uts/common/sys/cpuvar.h
index cd0d027866..5884d72789 100644
--- a/usr/src/uts/common/sys/cpuvar.h
+++ b/usr/src/uts/common/sys/cpuvar.h
@@ -524,6 +524,7 @@ extern int ncpus; /* number of CPUs present */
extern int ncpus_online; /* number of CPUs not quiesced */
extern int max_ncpus; /* max present before ncpus is known */
extern int boot_max_ncpus; /* like max_ncpus but for real */
+extern int boot_ncpus; /* # cpus present @ boot */
extern processorid_t max_cpuid; /* maximum CPU number */
extern struct cpu *cpu_inmotion; /* offline or partition move target */
extern cpu_t *clock_cpu_list;
diff --git a/usr/src/uts/common/vm/page.h b/usr/src/uts/common/vm/page.h
index 2b138dc71b..28ba33cedf 100644
--- a/usr/src/uts/common/vm/page.h
+++ b/usr/src/uts/common/vm/page.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -675,8 +675,8 @@ page_t *page_create_va_large(vnode_t *vp, u_offset_t off, size_t bytes,
uint_t flags, struct seg *seg, caddr_t vaddr, void *arg);
page_t *page_create_va(struct vnode *, u_offset_t, size_t, uint_t,
struct seg *, caddr_t);
-int page_create_wait(size_t npages, uint_t flags);
-void page_create_putback(ssize_t npages);
+int page_create_wait(pgcnt_t npages, uint_t flags);
+void page_create_putback(spgcnt_t npages);
void page_free(page_t *, int);
void page_free_at_startup(page_t *);
void page_free_pages(page_t *);
diff --git a/usr/src/uts/common/vm/vm_page.c b/usr/src/uts/common/vm/vm_page.c
index 0890319e28..12e137b351 100644
--- a/usr/src/uts/common/vm/vm_page.c
+++ b/usr/src/uts/common/vm/vm_page.c
@@ -167,19 +167,9 @@ static kcondvar_t freemem_cv;
* of clearning pcf_block, doing the wakeups, etc.
*/
-#if NCPU <= 4
-#define PAD 2
-#define PCF_FANOUT 4
-static uint_t pcf_mask = PCF_FANOUT - 1;
-#else
-#define PAD 10
-#ifdef sun4v
-#define PCF_FANOUT 32
-#else
-#define PCF_FANOUT 128
-#endif
-static uint_t pcf_mask = PCF_FANOUT - 1;
-#endif
+#define MAX_PCF_FANOUT NCPU
+static uint_t pcf_fanout = 1; /* Will get changed at boot time */
+static uint_t pcf_fanout_mask = 0;
struct pcf {
kmutex_t pcf_lock; /* protects the structure */
@@ -187,11 +177,25 @@ struct pcf {
uint_t pcf_wait; /* number of waiters */
uint_t pcf_block; /* pcgs flag to page_free() */
uint_t pcf_reserve; /* pages freed after pcf_block set */
- uint_t pcf_fill[PAD]; /* to line up on the caches */
+ uint_t pcf_fill[10]; /* to line up on the caches */
};
-static struct pcf pcf[PCF_FANOUT];
-#define PCF_INDEX() ((CPU->cpu_id) & (pcf_mask))
+/*
+ * PCF_INDEX hash needs to be dynamic (every so often the hash changes where
+ * it will hash the cpu to). This is done to prevent a drain condition
+ * from happening. This drain condition will occur when pcf_count decrement
+ * occurs on cpu A and the increment of pcf_count always occurs on cpu B. An
+ * example of this shows up with device interrupts. The dma buffer is allocated
+ * by the cpu requesting the IO thus the pcf_count is decremented based on that.
+ * When the memory is returned by the interrupt thread, the pcf_count will be
+ * incremented based on the cpu servicing the interrupt.
+ */
+static struct pcf pcf[MAX_PCF_FANOUT];
+#define PCF_INDEX() ((int)(((long)CPU->cpu_seqid) + \
+ (randtick() >> 24)) & (pcf_fanout_mask))
+
+static int pcf_decrement_bucket(pgcnt_t);
+static int pcf_decrement_multiple(pgcnt_t *, pgcnt_t, int);
kmutex_t pcgs_lock; /* serializes page_create_get_ */
kmutex_t pcgs_cagelock; /* serializes NOSLEEP cage allocs */
@@ -349,6 +353,39 @@ int page_capture_take_action(page_t *, uint_t, void *);
static void page_demote_vp_pages(page_t *);
+
+void
+pcf_init(void)
+
+{
+ int i;
+
+ if (boot_ncpus != -1) {
+ pcf_fanout = boot_ncpus;
+ } else {
+ pcf_fanout = max_ncpus;
+ }
+#ifdef sun4v
+ /*
+ * Force at least 4 buckets if possible for sun4v.
+ */
+ pcf_fanout = MAX(pcf_fanout, 4);
+#endif /* sun4v */
+
+ /*
+ * Round up to the nearest power of 2.
+ */
+ pcf_fanout = MIN(pcf_fanout, MAX_PCF_FANOUT);
+ if (!ISP2(pcf_fanout)) {
+ pcf_fanout = 1 << highbit(pcf_fanout);
+
+ if (pcf_fanout > MAX_PCF_FANOUT) {
+ pcf_fanout = 1 << (highbit(MAX_PCF_FANOUT) - 1);
+ }
+ }
+ pcf_fanout_mask = pcf_fanout - 1;
+}
+
/*
* vm subsystem related initialization
*/
@@ -492,7 +529,7 @@ page_free_large_ctr(pgcnt_t npages)
freemem += npages;
- lump = roundup(npages, PCF_FANOUT) / PCF_FANOUT;
+ lump = roundup(npages, pcf_fanout) / pcf_fanout;
while (npages > 0) {
@@ -508,7 +545,7 @@ page_free_large_ctr(pgcnt_t npages)
ASSERT(!p->pcf_wait);
- if (++p > &pcf[PCF_FANOUT - 1])
+ if (++p > &pcf[pcf_fanout - 1])
p = pcf;
}
@@ -1316,7 +1353,7 @@ set_freemem()
t = 0;
p = pcf;
- for (i = 0; i < PCF_FANOUT; i++) {
+ for (i = 0; i < pcf_fanout; i++) {
t += p->pcf_count;
p++;
}
@@ -1340,7 +1377,7 @@ get_freemem()
t = 0;
p = pcf;
- for (i = 0; i < PCF_FANOUT; i++) {
+ for (i = 0; i < pcf_fanout; i++) {
t += p->pcf_count;
p++;
}
@@ -1361,7 +1398,7 @@ pcf_acquire_all()
uint_t i;
p = pcf;
- for (i = 0; i < PCF_FANOUT; i++) {
+ for (i = 0; i < pcf_fanout; i++) {
mutex_enter(&p->pcf_lock);
p++;
}
@@ -1377,7 +1414,7 @@ pcf_release_all()
uint_t i;
p = pcf;
- for (i = 0; i < PCF_FANOUT; i++) {
+ for (i = 0; i < pcf_fanout; i++) {
mutex_exit(&p->pcf_lock);
p++;
}
@@ -1462,7 +1499,7 @@ page_create_throttle(pgcnt_t npages, int flags)
fm = 0;
pcf_acquire_all();
mutex_enter(&new_freemem_lock);
- for (i = 0; i < PCF_FANOUT; i++) {
+ for (i = 0; i < pcf_fanout; i++) {
fm += pcf[i].pcf_count;
pcf[i].pcf_wait++;
mutex_exit(&pcf[i].pcf_lock);
@@ -1490,7 +1527,7 @@ page_create_throttle(pgcnt_t npages, int flags)
* Sadly, this is called from platform/vm/vm_machdep.c
*/
int
-page_create_wait(size_t npages, uint_t flags)
+page_create_wait(pgcnt_t npages, uint_t flags)
{
pgcnt_t total;
uint_t i;
@@ -1514,44 +1551,9 @@ checkagain:
if (!page_create_throttle(npages, flags))
return (0);
- /*
- * Since page_create_va() looked at every
- * bucket, assume we are going to have to wait.
- * Get all of the pcf locks.
- */
- total = 0;
- p = pcf;
- for (i = 0; i < PCF_FANOUT; i++) {
- mutex_enter(&p->pcf_lock);
- total += p->pcf_count;
- if (total >= npages) {
- /*
- * Wow! There are enough pages laying around
- * to satisfy the request. Do the accounting,
- * drop the locks we acquired, and go back.
- *
- * freemem is not protected by any lock. So,
- * we cannot have any assertion containing
- * freemem.
- */
- freemem -= npages;
-
- while (p >= pcf) {
- if (p->pcf_count <= npages) {
- npages -= p->pcf_count;
- p->pcf_count = 0;
- } else {
- p->pcf_count -= (uint_t)npages;
- npages = 0;
- }
- mutex_exit(&p->pcf_lock);
- p--;
- }
- ASSERT(npages == 0);
- return (1);
- }
- p++;
- }
+ if (pcf_decrement_bucket(npages) ||
+ pcf_decrement_multiple(&total, npages, 0))
+ return (1);
/*
* All of the pcf locks are held, there are not enough pages
@@ -1593,7 +1595,7 @@ checkagain:
mutex_enter(&new_freemem_lock);
p = pcf;
- for (i = 0; i < PCF_FANOUT; i++) {
+ for (i = 0; i < pcf_fanout; i++) {
p->pcf_wait++;
mutex_exit(&p->pcf_lock);
p++;
@@ -1616,7 +1618,6 @@ checkagain:
VM_STAT_ADD(page_create_not_enough_again);
goto checkagain;
}
-
/*
* A routine to do the opposite of page_create_wait().
*/
@@ -1632,10 +1633,10 @@ page_create_putback(spgcnt_t npages)
* deal with lots of pages (min 64) so lets spread
* the wealth around.
*/
- lump = roundup(npages, PCF_FANOUT) / PCF_FANOUT;
+ lump = roundup(npages, pcf_fanout) / pcf_fanout;
freemem += npages;
- for (p = pcf; (npages > 0) && (p < &pcf[PCF_FANOUT]); p++) {
+ for (p = pcf; (npages > 0) && (p < &pcf[pcf_fanout]); p++) {
which = &p->pcf_count;
mutex_enter(&p->pcf_lock);
@@ -1695,7 +1696,7 @@ pcgs_unblock(void)
/* Update freemem while we're here. */
freemem = 0;
p = pcf;
- for (i = 0; i < PCF_FANOUT; i++) {
+ for (i = 0; i < pcf_fanout; i++) {
mutex_enter(&p->pcf_lock);
ASSERT(p->pcf_count == 0);
p->pcf_count = p->pcf_reserve;
@@ -1861,7 +1862,7 @@ page_create_get_something(vnode_t *vp, u_offset_t off, struct seg *seg,
VM_STAT_ADD(pcgs_locked);
locked = 1;
p = pcf;
- for (i = 0; i < PCF_FANOUT; i++) {
+ for (i = 0; i < pcf_fanout; i++) {
mutex_enter(&p->pcf_lock);
ASSERT(p->pcf_block == 0);
p->pcf_block = 1;
@@ -2127,15 +2128,10 @@ page_t *
page_create_va_large(vnode_t *vp, u_offset_t off, size_t bytes, uint_t flags,
struct seg *seg, caddr_t vaddr, void *arg)
{
- pgcnt_t npages, pcftotal;
+ pgcnt_t npages;
page_t *pp;
page_t *rootpp;
lgrp_t *lgrp;
- uint_t enough;
- uint_t pcf_index;
- uint_t i;
- struct pcf *p;
- struct pcf *q;
lgrp_id_t *lgrpid = (lgrp_id_t *)arg;
ASSERT(vp != NULL);
@@ -2184,84 +2180,10 @@ page_create_va_large(vnode_t *vp, u_offset_t off, size_t bytes, uint_t flags,
}
}
- enough = 0;
- pcf_index = PCF_INDEX();
- p = &pcf[pcf_index];
- q = &pcf[PCF_FANOUT];
- for (pcftotal = 0, i = 0; i < PCF_FANOUT; i++) {
- if (p->pcf_count > npages) {
- /*
- * a good one to try.
- */
- mutex_enter(&p->pcf_lock);
- if (p->pcf_count > npages) {
- p->pcf_count -= (uint_t)npages;
- /*
- * freemem is not protected by any lock.
- * Thus, we cannot have any assertion
- * containing freemem here.
- */
- freemem -= npages;
- enough = 1;
- mutex_exit(&p->pcf_lock);
- break;
- }
- mutex_exit(&p->pcf_lock);
- }
- pcftotal += p->pcf_count;
- p++;
- if (p >= q) {
- p = pcf;
- }
- }
-
- if (!enough) {
- /* If there isn't enough memory available, give up. */
- if (pcftotal < npages) {
- VM_STAT_ADD(page_create_large_cnt[3]);
- return (NULL);
- }
-
- /* try to collect pages from several pcf bins */
- for (p = pcf, pcftotal = 0, i = 0; i < PCF_FANOUT; i++) {
- mutex_enter(&p->pcf_lock);
- pcftotal += p->pcf_count;
- if (pcftotal >= npages) {
- /*
- * Wow! There are enough pages laying around
- * to satisfy the request. Do the accounting,
- * drop the locks we acquired, and go back.
- *
- * freemem is not protected by any lock. So,
- * we cannot have any assertion containing
- * freemem.
- */
- pgcnt_t tpages = npages;
- freemem -= npages;
- while (p >= pcf) {
- if (p->pcf_count <= tpages) {
- tpages -= p->pcf_count;
- p->pcf_count = 0;
- } else {
- p->pcf_count -= (uint_t)tpages;
- tpages = 0;
- }
- mutex_exit(&p->pcf_lock);
- p--;
- }
- ASSERT(tpages == 0);
- break;
- }
- p++;
- }
- if (i == PCF_FANOUT) {
- /* failed to collect pages - release the locks */
- while (--p >= pcf) {
- mutex_exit(&p->pcf_lock);
- }
- VM_STAT_ADD(page_create_large_cnt[4]);
- return (NULL);
- }
+ if (!pcf_decrement_bucket(npages) &&
+ !pcf_decrement_multiple(NULL, npages, 1)) {
+ VM_STAT_ADD(page_create_large_cnt[4]);
+ return (NULL);
}
/*
@@ -2336,11 +2258,7 @@ page_create_va(vnode_t *vp, u_offset_t off, size_t bytes, uint_t flags,
pgcnt_t found_on_free = 0;
pgcnt_t pages_req;
page_t *npp = NULL;
- uint_t enough;
- uint_t i;
- uint_t pcf_index;
struct pcf *p;
- struct pcf *q;
lgrp_t *lgrp;
TRACE_4(TR_FAC_VM, TR_PAGE_CREATE_START,
@@ -2410,38 +2328,7 @@ page_create_va(vnode_t *vp, u_offset_t off, size_t bytes, uint_t flags,
VM_STAT_ADD(page_create_cnt[0]);
- enough = 0;
- pcf_index = PCF_INDEX();
-
- p = &pcf[pcf_index];
- q = &pcf[PCF_FANOUT];
- for (i = 0; i < PCF_FANOUT; i++) {
- if (p->pcf_count > npages) {
- /*
- * a good one to try.
- */
- mutex_enter(&p->pcf_lock);
- if (p->pcf_count > npages) {
- p->pcf_count -= (uint_t)npages;
- /*
- * freemem is not protected by any lock.
- * Thus, we cannot have any assertion
- * containing freemem here.
- */
- freemem -= npages;
- enough = 1;
- mutex_exit(&p->pcf_lock);
- break;
- }
- mutex_exit(&p->pcf_lock);
- }
- p++;
- if (p >= q) {
- p = pcf;
- }
- }
-
- if (!enough) {
+ if (!pcf_decrement_bucket(npages)) {
/*
* Have to look harder. If npages is greater than
* one, then we might have to coalesce the counters.
@@ -2668,7 +2555,7 @@ fail:
if (overshoot) {
VM_STAT_ADD(page_create_overshoot);
- p = &pcf[pcf_index];
+ p = &pcf[PCF_INDEX()];
mutex_enter(&p->pcf_lock);
if (p->pcf_block) {
p->pcf_reserve += overshoot;
@@ -3006,7 +2893,6 @@ int
page_reclaim(page_t *pp, kmutex_t *lock)
{
struct pcf *p;
- uint_t pcf_index;
struct cpu *cpup;
int enough;
uint_t i;
@@ -3042,15 +2928,7 @@ page_reclaim(page_t *pp, kmutex_t *lock)
goto page_reclaim_nomem;
}
- enough = 0;
- pcf_index = PCF_INDEX();
- p = &pcf[pcf_index];
- mutex_enter(&p->pcf_lock);
- if (p->pcf_count >= 1) {
- enough = 1;
- p->pcf_count--;
- }
- mutex_exit(&p->pcf_lock);
+ enough = pcf_decrement_bucket(1);
if (!enough) {
VM_STAT_ADD(page_reclaim_zero);
@@ -3061,7 +2939,7 @@ page_reclaim(page_t *pp, kmutex_t *lock)
* until we find a page.
*/
p = pcf;
- for (i = 0; i < PCF_FANOUT; i++) {
+ for (i = 0; i < pcf_fanout; i++) {
mutex_enter(&p->pcf_lock);
if (p->pcf_count >= 1) {
p->pcf_count -= 1;
@@ -3095,7 +2973,7 @@ page_reclaim_nomem:
mutex_enter(&new_freemem_lock);
p = pcf;
- for (i = 0; i < PCF_FANOUT; i++) {
+ for (i = 0; i < pcf_fanout; i++) {
p->pcf_wait++;
mutex_exit(&p->pcf_lock);
p++;
@@ -7428,3 +7306,113 @@ page_capture_thread(void)
}
/*NOTREACHED*/
}
+/*
+ * Attempt to locate a bucket that has enough pages to satisfy the request.
+ * The initial check is done without the lock to avoid unneeded contention.
+ * The function returns 1 if enough pages were found, else 0 if it could not
+ * find enough pages in a bucket.
+ */
+static int
+pcf_decrement_bucket(pgcnt_t npages)
+{
+ struct pcf *p;
+ struct pcf *q;
+ int i;
+
+ p = &pcf[PCF_INDEX()];
+ q = &pcf[pcf_fanout];
+ for (i = 0; i < pcf_fanout; i++) {
+ if (p->pcf_count > npages) {
+ /*
+ * a good one to try.
+ */
+ mutex_enter(&p->pcf_lock);
+ if (p->pcf_count > npages) {
+ p->pcf_count -= (uint_t)npages;
+ /*
+ * freemem is not protected by any lock.
+ * Thus, we cannot have any assertion
+ * containing freemem here.
+ */
+ freemem -= npages;
+ mutex_exit(&p->pcf_lock);
+ return (1);
+ }
+ mutex_exit(&p->pcf_lock);
+ }
+ p++;
+ if (p >= q) {
+ p = pcf;
+ }
+ }
+ return (0);
+}
+
+/*
+ * Arguments:
+ * pcftotal_ret: If the value is not NULL and we have walked all the
+ * buckets but did not find enough pages then it will
+ * be set to the total number of pages in all the pcf
+ * buckets.
+ * npages: Is the number of pages we have been requested to
+ * find.
+ * unlock: If set to 0 we will leave the buckets locked if the
+ * requested number of pages are not found.
+ *
+ * Go and try to satisfy the page request from any number of buckets.
+ * This can be a very expensive operation as we have to lock the buckets
+ * we are checking (and keep them locked), starting at bucket 0.
+ *
+ * The function returns 1 if enough pages were found, else 0 if it could not
+ * find enough pages in the buckets.
+ *
+ */
+static int
+pcf_decrement_multiple(pgcnt_t *pcftotal_ret, pgcnt_t npages, int unlock)
+{
+ struct pcf *p;
+ pgcnt_t pcftotal;
+ int i;
+
+ p = pcf;
+ /* try to collect pages from several pcf bins */
+ for (pcftotal = 0, i = 0; i < pcf_fanout; i++) {
+ mutex_enter(&p->pcf_lock);
+ pcftotal += p->pcf_count;
+ if (pcftotal >= npages) {
+ /*
+ * Wow! There are enough pages laying around
+ * to satisfy the request. Do the accounting,
+ * drop the locks we acquired, and go back.
+ *
+ * freemem is not protected by any lock. So,
+ * we cannot have any assertion containing
+ * freemem.
+ */
+ freemem -= npages;
+ while (p >= pcf) {
+ if (p->pcf_count <= npages) {
+ npages -= p->pcf_count;
+ p->pcf_count = 0;
+ } else {
+ p->pcf_count -= (uint_t)npages;
+ npages = 0;
+ }
+ mutex_exit(&p->pcf_lock);
+ p--;
+ }
+ ASSERT(npages == 0);
+ return (1);
+ }
+ p++;
+ }
+ if (unlock) {
+ /* failed to collect pages - release the locks */
+ while (--p >= pcf) {
+ mutex_exit(&p->pcf_lock);
+ }
+ }
+ if (pcftotal_ret != NULL)
+ *pcftotal_ret = pcftotal;
+ return (0);
+}
diff --git a/usr/src/uts/common/vm/vm_pagelist.c b/usr/src/uts/common/vm/vm_pagelist.c
index cf3c9afa21..200216189f 100644
--- a/usr/src/uts/common/vm/vm_pagelist.c
+++ b/usr/src/uts/common/vm/vm_pagelist.c
@@ -164,6 +164,7 @@ int pg_lpgcreate_nocage = LPGCREATE;
typedef struct pcc_info {
pgcnt_t pcc_pages_free;
pgcnt_t *pcc_color_free;
+ uint_t pad[12];
} pcc_info_t;
/*
@@ -288,6 +289,9 @@ typedef struct hw_page_map {
int hpm_shift;
pfn_t hpm_base;
size_t *hpm_color_current[MAX_MNODE_MRANGES];
+#if defined(__sparc)
+ uint_t pad[4];
+#endif
} hw_page_map_t;
/*
diff --git a/usr/src/uts/i86pc/os/mlsetup.c b/usr/src/uts/i86pc/os/mlsetup.c
index e150ebc8b9..6302a75ea4 100644
--- a/usr/src/uts/i86pc/os/mlsetup.c
+++ b/usr/src/uts/i86pc/os/mlsetup.c
@@ -104,7 +104,6 @@ mlsetup(struct regs *rp)
extern struct classfuncs sys_classfuncs;
extern disp_t cpu0_disp;
extern char t0stack[];
- int boot_ncpus;
#if !defined(__xpv)
extern int xpv_is_hvm;
#endif
diff --git a/usr/src/uts/i86pc/os/startup.c b/usr/src/uts/i86pc/os/startup.c
index 489925e92c..b7f304ec77 100644
--- a/usr/src/uts/i86pc/os/startup.c
+++ b/usr/src/uts/i86pc/os/startup.c
@@ -136,6 +136,7 @@ struct xen_evt_data cpu0_evt_data;
extern void progressbar_init(void);
extern void progressbar_start(void);
extern void brand_init(void);
+extern void pcf_init(void);
extern int size_pse_array(pgcnt_t, int);
@@ -1154,6 +1155,13 @@ startup_memlist(void)
(void) page_ctrs_alloc(page_ctrs_mem);
/*
+ * Size the pcf array based on the number of cpus in the box at
+ * boot time.
+ */
+
+ pcf_init();
+
+ /*
* Initialize the page structures from the memory lists.
*/
availrmem_initial = availrmem = freemem = 0;
diff --git a/usr/src/uts/i86pc/vm/vm_dep.h b/usr/src/uts/i86pc/vm/vm_dep.h
index bc6ae7f9fd..622371e41c 100644
--- a/usr/src/uts/i86pc/vm/vm_dep.h
+++ b/usr/src/uts/i86pc/vm/vm_dep.h
@@ -46,7 +46,13 @@ extern "C" {
*/
#define GETTICK() tsc_read()
+/*
+ * Do not use this function for obtaining clock tick. This
+ * is called by callers who do not need to have a guarenteed
+ * correct tick value. The proper routine to use is tsc_read().
+ */
+extern hrtime_t randtick();
extern uint_t page_create_update_flags_x86(uint_t);
extern size_t plcnt_sz(size_t);
diff --git a/usr/src/uts/intel/ia32/ml/i86_subr.s b/usr/src/uts/intel/ia32/ml/i86_subr.s
index 76e47fcf6a..9f1a625a34 100644
--- a/usr/src/uts/intel/ia32/ml/i86_subr.s
+++ b/usr/src/uts/intel/ia32/ml/i86_subr.s
@@ -862,8 +862,35 @@ _tsc_lfence_end:
#endif /* __lint */
+
#endif /* __xpv */
+#ifdef __lint
+/*
+ * Do not use this function for obtaining clock tick. This
+ * is called by callers who do not need to have a guarenteed
+ * correct tick value. The proper routine to use is tsc_read().
+ */
+hrtime_t
+randtick(void)
+{
+ return (0);
+}
+#else
+#if defined(__amd64)
+ ENTRY_NP(randtick)
+ rdtsc
+ shlq $32, %rdx
+ orq %rdx, %rax
+ ret
+ SET_SIZE(randtick)
+#else
+ ENTRY_NP(randtick)
+ rdtsc
+ ret
+ SET_SIZE(randtick)
+#endif /* __i386 */
+#endif /* __lint */
/*
* Insert entryp after predp in a doubly linked list.
*/
diff --git a/usr/src/uts/sun4/os/startup.c b/usr/src/uts/sun4/os/startup.c
index d90157a937..429a4303c0 100644
--- a/usr/src/uts/sun4/os/startup.c
+++ b/usr/src/uts/sun4/os/startup.c
@@ -94,6 +94,7 @@ extern void mem_config_init(void);
extern void memseg_remap_init(void);
extern void mach_kpm_init(void);
+extern void pcf_init();
extern int size_pse_array(pgcnt_t, int);
/*
@@ -1337,6 +1338,12 @@ startup_memlist(void)
prom_panic("memlist overflow");
/*
+ * Size the pcf array based on the number of cpus in the box at
+ * boot time.
+ */
+ pcf_init();
+
+ /*
* Initialize the page structures from the memory lists.
*/
kphysm_init();
diff --git a/usr/src/uts/sun4/vm/vm_dep.h b/usr/src/uts/sun4/vm/vm_dep.h
index 56d56c4cc6..567e57677b 100644
--- a/usr/src/uts/sun4/vm/vm_dep.h
+++ b/usr/src/uts/sun4/vm/vm_dep.h
@@ -41,6 +41,12 @@ extern "C" {
#include <sys/memnode.h>
#define GETTICK() gettick()
+/*
+ * Do not use this function for obtaining clock tick. This
+ * is called by callers who do not need to have a guarenteed
+ * correct tick value. The proper routine to use is tsc_read().
+ */
+#define randtick() gettick()
/*
* Per page size free lists. Allocated dynamically.
diff --git a/usr/src/uts/sun4u/os/fillsysinfo.c b/usr/src/uts/sun4u/os/fillsysinfo.c
index 4a9c9895d2..561ad9ef05 100644
--- a/usr/src/uts/sun4u/os/fillsysinfo.c
+++ b/usr/src/uts/sun4u/os/fillsysinfo.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -1027,7 +1027,7 @@ check_cpus_set(void)
max_ncpus = set_max_ncpus();
if (max_ncpus < ncpunode)
max_ncpus = ncpunode;
- boot_max_ncpus = ncpunode;
+ boot_ncpus = boot_max_ncpus = ncpunode;
} else {
max_ncpus = ncpunode;
}
diff --git a/usr/src/uts/sun4v/os/fillsysinfo.c b/usr/src/uts/sun4v/os/fillsysinfo.c
index 9c10d6713e..522a29575d 100644
--- a/usr/src/uts/sun4v/os/fillsysinfo.c
+++ b/usr/src/uts/sun4v/os/fillsysinfo.c
@@ -373,7 +373,7 @@ cpu_setup_common(char **cpu_module_isa_set)
if ((mdp = md_get_handle()) == NULL)
cmn_err(CE_PANIC, "Unable to initialize machine description");
- nocpus = md_alloc_scan_dag(mdp,
+ boot_ncpus = nocpus = md_alloc_scan_dag(mdp,
md_root_node(mdp), "cpu", "fwd", &cpulist);
if (nocpus < 1) {
cmn_err(CE_PANIC, "cpu_common_setup: cpulist allocation "