summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorSean McEnroe <Sean.McEnroe@Sun.COM>2009-11-23 22:42:23 -0800
committerSean McEnroe <Sean.McEnroe@Sun.COM>2009-11-23 22:42:23 -0800
commitaf4c679f647cf088543c762e33d41a3ac52cfa14 (patch)
tree4311b62e5c03300652116b78f6474c8f020ca7e8 /usr/src
parent37b285d61e57561b538d999834714df1f5c2db53 (diff)
downloadillumos-joyent-af4c679f647cf088543c762e33d41a3ac52cfa14.tar.gz
6887924 PP_ISKAS needs to be defined in terms of VN_ISKAS for vnodes
6871169 kphysm_add_memory_dynamic panics testing vmstress + DR 6877160 guest domain panic at platsvc:mdeg_notify_client+10c 6874763 memseg_alloc_meta() incorrectly maps page_t pages 6873569 multiple calls to memlist_read_lock() can cause deadlock hazard 6886354 DR failure with "memory span duplication" error 6886782 panic after pagefault in seg_kpm after LDom add-mem on primary 6887644 domain hang/deadlock during ldom mem DR when trying to grab a write lock
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/mdb/common/modules/genunix/genunix.c8
-rw-r--r--usr/src/cmd/mdb/common/modules/genunix/memory.c22
-rw-r--r--usr/src/uts/common/avs/ns/sdbc/sd_bio.c7
-rw-r--r--usr/src/uts/common/cpr/cpr_dump.c13
-rw-r--r--usr/src/uts/common/fs/autofs/auto_vfsops.c14
-rw-r--r--usr/src/uts/common/fs/zfs/sys/zfs_vfsops.h2
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_ioctl.c20
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_vfsops.c6
-rw-r--r--usr/src/uts/common/io/ib/clients/rds/rds_ioctl.c10
-rw-r--r--usr/src/uts/common/io/ib/mgt/ibcm/ibcm_arp.c10
-rw-r--r--usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_subr.c8
-rw-r--r--usr/src/uts/common/os/dumpsubr.c6
-rw-r--r--usr/src/uts/common/os/kstat_fr.c2
-rw-r--r--usr/src/uts/common/os/mem_cage.c5
-rw-r--r--usr/src/uts/common/os/mem_config.c8
-rw-r--r--usr/src/uts/common/os/space.c5
-rw-r--r--usr/src/uts/common/rpc/rpcib.c10
-rw-r--r--usr/src/uts/common/sys/fs/lofs_node.h11
-rw-r--r--usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_proto.h2
-rw-r--r--usr/src/uts/common/sys/vnode.h19
-rw-r--r--usr/src/uts/common/vm/page.h4
-rw-r--r--usr/src/uts/common/vm/page_lock.c13
-rw-r--r--usr/src/uts/common/vm/page_retire.c3
-rw-r--r--usr/src/uts/common/vm/seg_kmem.c2
-rw-r--r--usr/src/uts/common/vm/seg_kmem.h15
-rw-r--r--usr/src/uts/common/vm/seg_vn.c2
-rw-r--r--usr/src/uts/common/vm/vm_page.c15
-rw-r--r--usr/src/uts/common/vm/vm_pagelist.c44
-rw-r--r--usr/src/uts/sun4/os/memlist.c9
-rw-r--r--usr/src/uts/sun4/os/startup.c6
-rw-r--r--usr/src/uts/sun4u/os/cpr_impl.c11
-rw-r--r--usr/src/uts/sun4v/io/dr_mem.c103
-rw-r--r--usr/src/uts/sun4v/io/drctl.c52
-rw-r--r--usr/src/uts/sun4v/io/vlds.c6
-rw-r--r--usr/src/uts/sun4v/os/memseg.c134
-rw-r--r--usr/src/uts/sun4v/promif/promif_emul.c5
-rw-r--r--usr/src/uts/sun4v/sys/drctl.h7
-rw-r--r--usr/src/uts/sun4v/vm/mach_kpm.c24
38 files changed, 283 insertions, 360 deletions
diff --git a/usr/src/cmd/mdb/common/modules/genunix/genunix.c b/usr/src/cmd/mdb/common/modules/genunix/genunix.c
index 513fc33860..6aac7c533b 100644
--- a/usr/src/cmd/mdb/common/modules/genunix/genunix.c
+++ b/usr/src/cmd/mdb/common/modules/genunix/genunix.c
@@ -2211,7 +2211,7 @@ typedef struct kmastat_args {
static int
kmastat_cache(uintptr_t addr, const kmem_cache_t *cp, kmastat_args_t *kap)
{
- kmastat_vmem_t **kvp = kap->ka_kvpp;
+ kmastat_vmem_t **kvpp = kap->ka_kvpp;
kmastat_vmem_t *kv;
datafmt_t *dfp = kmemfmt;
int magsize;
@@ -2234,15 +2234,15 @@ kmastat_cache(uintptr_t addr, const kmem_cache_t *cp, kmastat_args_t *kap)
(void) mdb_pwalk("kmem_cpu_cache", cpu_avail, &avail, addr);
(void) mdb_pwalk("kmem_slab_partial", slab_avail, &avail, addr);
- for (kv = *kvp; kv != NULL; kv = kv->kv_next) {
+ for (kv = *kvpp; kv != NULL; kv = kv->kv_next) {
if (kv->kv_addr == (uintptr_t)cp->cache_arena)
goto out;
}
kv = mdb_zalloc(sizeof (kmastat_vmem_t), UM_SLEEP | UM_GC);
- kv->kv_next = *kvp;
+ kv->kv_next = *kvpp;
kv->kv_addr = (uintptr_t)cp->cache_arena;
- *kvp = kv;
+ *kvpp = kv;
out:
kv->kv_meminuse += meminuse;
kv->kv_alloc += alloc;
diff --git a/usr/src/cmd/mdb/common/modules/genunix/memory.c b/usr/src/cmd/mdb/common/modules/genunix/memory.c
index 09dc83f731..a6e8e8b1c4 100644
--- a/usr/src/cmd/mdb/common/modules/genunix/memory.c
+++ b/usr/src/cmd/mdb/common/modules/genunix/memory.c
@@ -29,6 +29,7 @@
#include <sys/thread.h>
#include <sys/swap.h>
#include <sys/memlist.h>
+#include <sys/vnode.h>
#if defined(__i386) || defined(__amd64)
#include <sys/balloon_impl.h>
#endif
@@ -490,6 +491,7 @@ memstat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
memstat_t stats;
GElf_Sym sym;
vn_htable_t ht;
+ struct vnode *kvps;
uintptr_t vn_size = 0;
#if defined(__i386) || defined(__amd64)
bln_stats_t bln_stats;
@@ -533,25 +535,19 @@ memstat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
return (DCMD_ERR);
}
- /* read kernel vnode pointer */
- if (mdb_lookup_by_obj(MDB_OBJ_EXEC, "kvp",
+ /* read kernel vnode array pointer */
+ if (mdb_lookup_by_obj(MDB_OBJ_EXEC, "kvps",
(GElf_Sym *)&sym) == -1) {
- mdb_warn("unable to read kvp");
+ mdb_warn("unable to read kvps");
return (DCMD_ERR);
}
-
- stats.ms_kvp = (struct vnode *)(uintptr_t)sym.st_value;
+ kvps = (struct vnode *)(uintptr_t)sym.st_value;
+ stats.ms_kvp = &kvps[KV_KVP];
/*
- * Read the zio vnode pointer. It may not exist on all kernels, so it
- * it isn't found, it's not a fatal error.
+ * Read the zio vnode pointer.
*/
- if (mdb_lookup_by_obj(MDB_OBJ_EXEC, "zvp",
- (GElf_Sym *)&sym) == -1) {
- stats.ms_zvp = NULL;
- } else {
- stats.ms_zvp = (struct vnode *)(uintptr_t)sym.st_value;
- }
+ stats.ms_zvp = &kvps[KV_ZVP];
/*
* If physmem != total_pages, then the administrator has limited the
diff --git a/usr/src/uts/common/avs/ns/sdbc/sd_bio.c b/usr/src/uts/common/avs/ns/sdbc/sd_bio.c
index ff1656fb42..46bb16ddc7 100644
--- a/usr/src/uts/common/avs/ns/sdbc/sd_bio.c
+++ b/usr/src/uts/common/avs/ns/sdbc/sd_bio.c
@@ -41,6 +41,7 @@
#include <sys/sdt.h> /* dtrace is S10 or later */
+#include <vm/seg_kmem.h>
#include "sd_bcache.h"
#include "sd_trace.h"
#include "sd_io.h"
@@ -54,12 +55,6 @@
extern uintptr_t kobj_getsymvalue(char *, int); /* DDI violation */
#endif
-/*
- * Shouldn't really use an extern here but no .h file provides this
- * so we have no choice (other than not using it)
- */
-extern struct vnode kvp; /* the vnode for seg_kmem memory */
-
#define DO_PAGE_LIST sdbc_do_page /* enable pagelist code */
int sdbc_do_page = 0;
diff --git a/usr/src/uts/common/cpr/cpr_dump.c b/usr/src/uts/common/cpr/cpr_dump.c
index 753ebf07e8..3f264b53d2 100644
--- a/usr/src/uts/common/cpr/cpr_dump.c
+++ b/usr/src/uts/common/cpr/cpr_dump.c
@@ -19,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Fill in and write out the cpr state file
* 1. Allocate and write headers, ELF and cpr dump header
@@ -811,15 +809,8 @@ cpr_count_upages(int mapflag, bitfunc_t bitfunc)
page0 = pp = page_first();
do {
-#if defined(__sparc)
- extern struct vnode prom_ppages;
- if (pp->p_vnode == NULL || PP_ISKAS(pp) ||
- pp->p_vnode == &prom_ppages ||
- PP_ISFREE(pp) && PP_ISAGED(pp))
-#else
if (pp->p_vnode == NULL || PP_ISKAS(pp) ||
PP_ISFREE(pp) && PP_ISAGED(pp))
-#endif /* __sparc */
continue;
pfn = page_pptonum(pp);
@@ -835,7 +826,7 @@ cpr_count_upages(int mapflag, bitfunc_t bitfunc)
dcnt, tcnt);
CPR_DEBUG(CPR_DEBUG7, "cpr_count_upages: %ld pages, 0x%lx bytes\n",
dcnt, mmu_ptob(dcnt));
-
+ page0 = NULL; /* for Lint */
return (dcnt);
}
diff --git a/usr/src/uts/common/fs/autofs/auto_vfsops.c b/usr/src/uts/common/fs/autofs/auto_vfsops.c
index ae5a6efac0..388b7d9c29 100644
--- a/usr/src/uts/common/fs/autofs/auto_vfsops.c
+++ b/usr/src/uts/common/fs/autofs/auto_vfsops.c
@@ -19,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/param.h>
#include <sys/errno.h>
#include <sys/proc.h>
@@ -360,7 +358,7 @@ auto_mount(vfs_t *vfsp, vnode_t *vp, struct mounta *uap, cred_t *cr)
char datalen = uap->datalen;
dev_t autofs_dev;
char strbuff[MAXPATHLEN + 1];
- vnode_t *kvp;
+ vnode_t *kkvp;
struct autofs_globals *fngp;
zone_t *zone = curproc->p_zone;
@@ -622,15 +620,15 @@ auto_mount(vfs_t *vfsp, vnode_t *vp, struct mounta *uap, cred_t *cr)
* happens when the daemon gets restarted?
*/
if ((error = lookupname("/dev/ticotsord", UIO_SYSSPACE, FOLLOW,
- NULLVPP, &kvp)) != 0) {
+ NULLVPP, &kkvp)) != 0) {
cmn_err(CE_WARN, "autofs: lookupname: %d", error);
goto errout;
}
- fnip->fi_knconf.knc_rdev = kvp->v_rdev;
+ fnip->fi_knconf.knc_rdev = kkvp->v_rdev;
fnip->fi_knconf.knc_protofmly = NC_LOOPBACK;
fnip->fi_knconf.knc_semantics = NC_TPI_COTS_ORD;
- VN_RELE(kvp);
+ VN_RELE(kkvp);
/*
* Make the root vnode
@@ -701,7 +699,7 @@ auto_unmount(vfs_t *vfsp, int flag, cred_t *cr)
fnip = vfstofni(vfsp);
AUTOFS_DPRINT((4, "auto_unmount vfsp %p fnip %p\n", (void *)vfsp,
- (void *)fnip));
+ (void *)fnip));
if (secpolicy_fs_unmount(cr, vfsp) != 0)
return (EPERM);
diff --git a/usr/src/uts/common/fs/zfs/sys/zfs_vfsops.h b/usr/src/uts/common/fs/zfs/sys/zfs_vfsops.h
index 2ae99c80c2..e961b75610 100644
--- a/usr/src/uts/common/fs/zfs/sys/zfs_vfsops.h
+++ b/usr/src/uts/common/fs/zfs/sys/zfs_vfsops.h
@@ -143,7 +143,7 @@ extern int zfs_set_userquota(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type,
extern boolean_t zfs_usergroup_overquota(zfsvfs_t *zfsvfs,
boolean_t isgroup, uint64_t fuid);
extern int zfs_set_version(zfsvfs_t *zfsvfs, uint64_t newvers);
-extern int zfsvfs_create(const char *name, zfsvfs_t **zvp);
+extern int zfsvfs_create(const char *name, zfsvfs_t **zfvp);
extern void zfsvfs_free(zfsvfs_t *zfsvfs);
extern int zfs_check_global_label(const char *dsname, const char *hexsl);
diff --git a/usr/src/uts/common/fs/zfs/zfs_ioctl.c b/usr/src/uts/common/fs/zfs/zfs_ioctl.c
index 16733b3423..a4838d060e 100644
--- a/usr/src/uts/common/fs/zfs/zfs_ioctl.c
+++ b/usr/src/uts/common/fs/zfs/zfs_ioctl.c
@@ -954,7 +954,7 @@ put_nvlist(zfs_cmd_t *zc, nvlist_t *nvl)
}
static int
-getzfsvfs(const char *dsname, zfsvfs_t **zvp)
+getzfsvfs(const char *dsname, zfsvfs_t **zfvp)
{
objset_t *os;
int error;
@@ -968,9 +968,9 @@ getzfsvfs(const char *dsname, zfsvfs_t **zvp)
}
mutex_enter(&os->os_user_ptr_lock);
- *zvp = dmu_objset_get_user(os);
- if (*zvp) {
- VFS_HOLD((*zvp)->z_vfs);
+ *zfvp = dmu_objset_get_user(os);
+ if (*zfvp) {
+ VFS_HOLD((*zfvp)->z_vfs);
} else {
error = ESRCH;
}
@@ -984,21 +984,21 @@ getzfsvfs(const char *dsname, zfsvfs_t **zvp)
* case its z_vfs will be NULL, and it will be opened as the owner.
*/
static int
-zfsvfs_hold(const char *name, void *tag, zfsvfs_t **zvp)
+zfsvfs_hold(const char *name, void *tag, zfsvfs_t **zfvp)
{
int error = 0;
- if (getzfsvfs(name, zvp) != 0)
- error = zfsvfs_create(name, zvp);
+ if (getzfsvfs(name, zfvp) != 0)
+ error = zfsvfs_create(name, zfvp);
if (error == 0) {
- rrw_enter(&(*zvp)->z_teardown_lock, RW_READER, tag);
- if ((*zvp)->z_unmounted) {
+ rrw_enter(&(*zfvp)->z_teardown_lock, RW_READER, tag);
+ if ((*zfvp)->z_unmounted) {
/*
* XXX we could probably try again, since the unmounting
* thread should be just about to disassociate the
* objset from the zfsvfs.
*/
- rrw_exit(&(*zvp)->z_teardown_lock, tag);
+ rrw_exit(&(*zfvp)->z_teardown_lock, tag);
return (EBUSY);
}
}
diff --git a/usr/src/uts/common/fs/zfs/zfs_vfsops.c b/usr/src/uts/common/fs/zfs/zfs_vfsops.c
index ec9d8334ff..0a262cbe21 100644
--- a/usr/src/uts/common/fs/zfs/zfs_vfsops.c
+++ b/usr/src/uts/common/fs/zfs/zfs_vfsops.c
@@ -816,7 +816,7 @@ zfs_usergroup_overquota(zfsvfs_t *zfsvfs, boolean_t isgroup, uint64_t fuid)
}
int
-zfsvfs_create(const char *osname, zfsvfs_t **zvp)
+zfsvfs_create(const char *osname, zfsvfs_t **zfvp)
{
objset_t *os;
zfsvfs_t *zfsvfs;
@@ -923,12 +923,12 @@ zfsvfs_create(const char *osname, zfsvfs_t **zvp)
for (i = 0; i != ZFS_OBJ_MTX_SZ; i++)
mutex_init(&zfsvfs->z_hold_mtx[i], NULL, MUTEX_DEFAULT, NULL);
- *zvp = zfsvfs;
+ *zfvp = zfsvfs;
return (0);
out:
dmu_objset_disown(os, zfsvfs);
- *zvp = NULL;
+ *zfvp = NULL;
kmem_free(zfsvfs, sizeof (zfsvfs_t));
return (error);
}
diff --git a/usr/src/uts/common/io/ib/clients/rds/rds_ioctl.c b/usr/src/uts/common/io/ib/clients/rds/rds_ioctl.c
index 03d82fbcab..130c51cc15 100644
--- a/usr/src/uts/common/io/ib/clients/rds/rds_ioctl.c
+++ b/usr/src/uts/common/io/ib/clients/rds/rds_ioctl.c
@@ -49,18 +49,18 @@ static sin_t sin_null; /* Zero address for quick clears */
int
rds_do_ip_ioctl(int cmd, int len, void *arg)
{
- vnode_t *kvp, *vp;
+ vnode_t *kkvp, *vp;
TIUSER *tiptr;
struct strioctl iocb;
k_sigset_t smask;
int err = 0;
- if (lookupname("/dev/udp", UIO_SYSSPACE, FOLLOW, NULLVPP, &kvp) == 0) {
- if (t_kopen((file_t *)NULL, kvp->v_rdev, FREAD|FWRITE,
+ if (lookupname("/dev/udp", UIO_SYSSPACE, FOLLOW, NULLVPP, &kkvp) == 0) {
+ if (t_kopen((file_t *)NULL, kkvp->v_rdev, FREAD|FWRITE,
&tiptr, CRED()) == 0) {
vp = tiptr->fp->f_vnode;
} else {
- VN_RELE(kvp);
+ VN_RELE(kkvp);
return (EPROTO);
}
} else {
@@ -75,7 +75,7 @@ rds_do_ip_ioctl(int cmd, int len, void *arg)
err = kstr_ioctl(vp, I_STR, (intptr_t)&iocb);
sigunintr(&smask);
(void) t_kclose(tiptr, 0);
- VN_RELE(kvp);
+ VN_RELE(kkvp);
return (err);
}
diff --git a/usr/src/uts/common/io/ib/mgt/ibcm/ibcm_arp.c b/usr/src/uts/common/io/ib/mgt/ibcm/ibcm_arp.c
index 3bb7d3a98c..f404db5a1e 100644
--- a/usr/src/uts/common/io/ib/mgt/ibcm/ibcm_arp.c
+++ b/usr/src/uts/common/io/ib/mgt/ibcm/ibcm_arp.c
@@ -284,16 +284,16 @@ ibcm_arp_get_ibd_insts(ibcm_arp_ibd_insts_t *ibds)
static int
ibcm_do_ip_ioctl(int cmd, int len, void *arg)
{
- vnode_t *kvp;
+ vnode_t *kkvp;
TIUSER *tiptr;
struct strioctl iocb;
int err = 0;
- if (lookupname("/dev/udp", UIO_SYSSPACE, FOLLOW, NULLVPP, &kvp) != 0)
+ if (lookupname("/dev/udp", UIO_SYSSPACE, FOLLOW, NULLVPP, &kkvp) != 0)
return (EPROTO);
- if (t_kopen(NULL, kvp->v_rdev, FREAD|FWRITE, &tiptr, CRED()) != 0) {
- VN_RELE(kvp);
+ if (t_kopen(NULL, kkvp->v_rdev, FREAD|FWRITE, &tiptr, CRED()) != 0) {
+ VN_RELE(kkvp);
return (EPROTO);
}
@@ -303,7 +303,7 @@ ibcm_do_ip_ioctl(int cmd, int len, void *arg)
iocb.ic_dp = (caddr_t)arg;
err = kstr_ioctl(tiptr->fp->f_vnode, I_STR, (intptr_t)&iocb);
(void) t_kclose(tiptr, 0);
- VN_RELE(kvp);
+ VN_RELE(kkvp);
return (err);
}
diff --git a/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_subr.c b/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_subr.c
index 2be7e09eca..6c5a1e549e 100644
--- a/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_subr.c
+++ b/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_subr.c
@@ -6601,12 +6601,12 @@ pmcs_smp_function_result(pmcs_hw_t *pwp, smp_response_frame_t *srf)
* acch: ddi_acc_handle_t to use for the mapping
* dmah: ddi_dma_handle_t to use
* length: Amount of memory for mapping
- * kvp: Pointer filled in with kernel virtual address on successful return
+ * kvap: Pointer filled in with kernel virtual address on successful return
* dma_addr: Pointer filled in with DMA address on successful return
*/
boolean_t
pmcs_dma_setup(pmcs_hw_t *pwp, ddi_dma_attr_t *dma_attr, ddi_acc_handle_t *acch,
- ddi_dma_handle_t *dmah, size_t length, caddr_t *kvp, uint64_t *dma_addr)
+ ddi_dma_handle_t *dmah, size_t length, caddr_t *kvap, uint64_t *dma_addr)
{
dev_info_t *dip = pwp->dip;
ddi_dma_cookie_t cookie;
@@ -6632,7 +6632,7 @@ pmcs_dma_setup(pmcs_hw_t *pwp, ddi_dma_attr_t *dma_attr, ddi_acc_handle_t *acch,
}
if (ddi_dma_mem_alloc(*dmah, length, &mattr, ddma_flag, DDI_DMA_SLEEP,
- NULL, kvp, &real_length, acch) != DDI_SUCCESS) {
+ NULL, kvap, &real_length, acch) != DDI_SUCCESS) {
pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
"Failed to allocate DMA mem");
ddi_dma_free_handle(dmah);
@@ -6640,7 +6640,7 @@ pmcs_dma_setup(pmcs_hw_t *pwp, ddi_dma_attr_t *dma_attr, ddi_acc_handle_t *acch,
return (B_FALSE);
}
- if (ddi_dma_addr_bind_handle(*dmah, NULL, *kvp, real_length,
+ if (ddi_dma_addr_bind_handle(*dmah, NULL, *kvap, real_length,
ddabh_flag, DDI_DMA_SLEEP, NULL, &cookie, &cookie_cnt)
!= DDI_DMA_MAPPED) {
pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, "Failed to bind DMA");
diff --git a/usr/src/uts/common/os/dumpsubr.c b/usr/src/uts/common/os/dumpsubr.c
index 8687f7f356..292ec165d4 100644
--- a/usr/src/uts/common/os/dumpsubr.c
+++ b/usr/src/uts/common/os/dumpsubr.c
@@ -817,13 +817,9 @@ static inline int
dump_pfn_check(pfn_t pfn)
{
page_t *pp = page_numtopp_nolock(pfn);
-#if defined(__sparc)
- extern struct vnode prom_ppages;
-#endif
-
if (pp == NULL || pp->p_pagenum != pfn ||
#if defined(__sparc)
- pp->p_vnode == &prom_ppages ||
+ pp->p_vnode == &promvp ||
#else
PP_ISBOOTPAGES(pp) ||
#endif
diff --git a/usr/src/uts/common/os/kstat_fr.c b/usr/src/uts/common/os/kstat_fr.c
index 308fa30837..2ea5eb459f 100644
--- a/usr/src/uts/common/os/kstat_fr.c
+++ b/usr/src/uts/common/os/kstat_fr.c
@@ -876,8 +876,6 @@ extern caddr_t econtig32;
extern caddr_t econtig;
#endif /* __sparc */
-extern struct vnode kvp;
-
/* ARGSUSED */
static int
system_pages_kstat_update(kstat_t *ksp, int rw)
diff --git a/usr/src/uts/common/os/mem_cage.c b/usr/src/uts/common/os/mem_cage.c
index cab8f0a487..590819f088 100644
--- a/usr/src/uts/common/os/mem_cage.c
+++ b/usr/src/uts/common/os/mem_cage.c
@@ -911,7 +911,6 @@ kcage_init(pgcnt_t preferred_size)
page_t *pp;
kstat_t *ksp;
- extern struct vnode kvp;
extern void page_list_noreloc_startup(page_t *);
ASSERT(!kcage_on);
@@ -1618,10 +1617,8 @@ kcage_invalidate_page(page_t *pp, pgcnt_t *nfreedp)
int result;
#if defined(__sparc)
- extern struct vnode prom_ppages;
- ASSERT(pp->p_vnode != &prom_ppages);
+ ASSERT(pp->p_vnode != &promvp);
#endif /* __sparc */
-
ASSERT(!PP_ISFREE(pp));
ASSERT(PAGE_EXCL(pp));
diff --git a/usr/src/uts/common/os/mem_config.c b/usr/src/uts/common/os/mem_config.c
index b2ff63eec5..6e280a9af5 100644
--- a/usr/src/uts/common/os/mem_config.c
+++ b/usr/src/uts/common/os/mem_config.c
@@ -63,6 +63,7 @@ extern void mem_node_add(pfn_t, pfn_t);
extern void mem_node_del(pfn_t, pfn_t);
extern uint_t page_ctrs_adjust(int);
+void page_ctrs_cleanup(void);
static void kphysm_setup_post_add(pgcnt_t);
static int kphysm_setup_pre_del(pgcnt_t);
static void kphysm_setup_post_del(pgcnt_t, int);
@@ -101,7 +102,7 @@ extern pfn_t memseg_get_metapfn(void *, pgcnt_t);
extern void memseg_remap_meta(struct memseg *);
static int memseg_is_dynamic(struct memseg *);
static int memseg_includes_meta(struct memseg *);
-static pfn_t memseg_get_start(struct memseg *);
+pfn_t memseg_get_start(struct memseg *);
static void memseg_cpu_vm_flush(void);
int meta_alloc_enable;
@@ -354,6 +355,9 @@ mapalloc:
mem_node_del_range(pt_base, pnum);
+ /* cleanup the page counters */
+ page_ctrs_cleanup();
+
hat_unload(kas.a_hat, (caddr_t)pp, ptob(metapgs),
HAT_UNLOAD_UNMAP|HAT_UNLOAD_UNLOCK);
@@ -2384,6 +2388,8 @@ refused:
mem_node_del_range(mdsp->mds_base,
mdsp->mds_base + mdsp->mds_npgs - 1);
}
+ /* cleanup the page counters */
+ page_ctrs_cleanup();
comp_code = KPHYSM_OK;
diff --git a/usr/src/uts/common/os/space.c b/usr/src/uts/common/os/space.c
index 255759587c..6b6bff8b41 100644
--- a/usr/src/uts/common/os/space.c
+++ b/usr/src/uts/common/os/space.c
@@ -101,6 +101,11 @@ struct var v;
#include <sys/bootconf.h>
/*
+ * Data for segkmem pages that should be resident
+ */
+struct vnode kvps[KV_MAX];
+
+/*
* Data from swapgeneric.c that must be resident.
*/
struct vnode *rootvp; /* vnode of the root device */
diff --git a/usr/src/uts/common/rpc/rpcib.c b/usr/src/uts/common/rpc/rpcib.c
index 3d3635f001..cf3d7283c9 100644
--- a/usr/src/uts/common/rpc/rpcib.c
+++ b/usr/src/uts/common/rpc/rpcib.c
@@ -5170,18 +5170,18 @@ rpcib_rdma_capable_interface(struct lifreq *lifrp)
static int
rpcib_do_ip_ioctl(int cmd, int len, void *arg)
{
- vnode_t *kvp, *vp;
+ vnode_t *kkvp, *vp;
TIUSER *tiptr;
struct strioctl iocb;
k_sigset_t smask;
int err = 0;
- if (lookupname("/dev/udp", UIO_SYSSPACE, FOLLOW, NULLVPP, &kvp) == 0) {
- if (t_kopen(NULL, kvp->v_rdev, FREAD|FWRITE,
+ if (lookupname("/dev/udp", UIO_SYSSPACE, FOLLOW, NULLVPP, &kkvp) == 0) {
+ if (t_kopen(NULL, kkvp->v_rdev, FREAD|FWRITE,
&tiptr, CRED()) == 0) {
vp = tiptr->fp->f_vnode;
} else {
- VN_RELE(kvp);
+ VN_RELE(kkvp);
return (EPROTO);
}
} else {
@@ -5196,7 +5196,7 @@ rpcib_do_ip_ioctl(int cmd, int len, void *arg)
err = kstr_ioctl(vp, I_STR, (intptr_t)&iocb);
sigunintr(&smask);
(void) t_kclose(tiptr, 0);
- VN_RELE(kvp);
+ VN_RELE(kkvp);
return (err);
}
diff --git a/usr/src/uts/common/sys/fs/lofs_node.h b/usr/src/uts/common/sys/fs/lofs_node.h
index 3ea00237d8..fb30cfb44b 100644
--- a/usr/src/uts/common/sys/fs/lofs_node.h
+++ b/usr/src/uts/common/sys/fs/lofs_node.h
@@ -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 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -31,8 +30,6 @@
#ifndef _SYS_FS_LOFS_NODE_H
#define _SYS_FS_LOFS_NODE_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/fs/lofs_info.h>
#ifdef __cplusplus
@@ -72,8 +69,6 @@ typedef struct lnode {
#ifdef _KERNEL
extern vnode_t *makelonode(vnode_t *, struct loinfo *, int);
extern void freelonode(lnode_t *);
-
-extern struct vnode kvp;
#endif /* _KERNEL */
#ifdef __cplusplus
diff --git a/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_proto.h b/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_proto.h
index 272095a62f..882ce06044 100644
--- a/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_proto.h
+++ b/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_proto.h
@@ -291,7 +291,7 @@ int pmcs_sata_identify(pmcs_hw_t *, pmcs_phy_t *);
void pmcs_sata_work(pmcs_hw_t *);
boolean_t pmcs_dma_setup(pmcs_hw_t *pwp, ddi_dma_attr_t *dma_attr,
ddi_acc_handle_t *acch, ddi_dma_handle_t *dmah, size_t length,
- caddr_t *kvp, uint64_t *dma_addr);
+ caddr_t *kvap, uint64_t *dma_addr);
void pmcs_fm_ereport(pmcs_hw_t *pwp, char *detail);
int pmcs_check_dma_handle(ddi_dma_handle_t handle);
int pmcs_check_acc_handle(ddi_acc_handle_t handle);
diff --git a/usr/src/uts/common/sys/vnode.h b/usr/src/uts/common/sys/vnode.h
index a060c30434..cdf4fe9b68 100644
--- a/usr/src/uts/common/sys/vnode.h
+++ b/usr/src/uts/common/sys/vnode.h
@@ -1318,10 +1318,22 @@ extern uint_t pvn_vmodsort_supported;
((VP1) && (VP2) && (vn_getops(VP1) == vn_getops(VP2)) ? \
VOP_CMP(VP1, VP2, NULL) : 0))
-extern struct vnode kvp;
-extern struct vnode zvp;
+/*
+ * Some well-known global vnodes used by the VM system to name pages.
+ */
+extern struct vnode kvps[];
+
+typedef enum {
+ KV_KVP, /* vnode for all segkmem pages */
+ KV_ZVP, /* vnode for all ZFS pages */
+#if defined(__sparc)
+ KV_MPVP, /* vnode for all page_t meta-pages */
+ KV_PROMVP, /* vnode for all PROM pages */
+#endif /* __sparc */
+ KV_MAX /* total number of vnodes in kvps[] */
+} kvps_index_t;
-#define VN_ISKAS(vp) ((vp) == &kvp || (vp) == &zvp)
+#define VN_ISKAS(vp) ((vp) >= &kvps[0] && (vp) < &kvps[KV_MAX])
#endif /* _KERNEL */
@@ -1367,7 +1379,6 @@ struct async_reqs {
* be necessary to ensure the page was freed.
*/
#define VN_DISPOSE(pp, flag, dn, cr) { \
- extern struct vnode kvp; \
if ((pp)->p_vnode != NULL && !VN_ISKAS((pp)->p_vnode)) \
VOP_DISPOSE((pp)->p_vnode, (pp), (flag), (dn), (cr), NULL); \
else if ((flag) == B_FREE) \
diff --git a/usr/src/uts/common/vm/page.h b/usr/src/uts/common/vm/page.h
index ceccab3d32..8739e8a366 100644
--- a/usr/src/uts/common/vm/page.h
+++ b/usr/src/uts/common/vm/page.h
@@ -898,8 +898,7 @@ int page_szc_user_filtered(size_t);
#define PP_ISAGED(pp) (((pp)->p_state & P_FREE) && \
((pp)->p_vnode == NULL))
#define PP_ISNORELOC(pp) ((pp)->p_state & P_NORELOC)
-#define PP_ISKAS(pp) (((pp)->p_vnode == &kvp) || \
- ((pp)->p_vnode == &zvp))
+#define PP_ISKAS(pp) (VN_ISKAS((pp)->p_vnode))
#define PP_ISNORELOCKERNEL(pp) (PP_ISNORELOC(pp) && PP_ISKAS(pp))
#define PP_ISMIGRATE(pp) ((pp)->p_state & P_MIGRATE)
#define PP_ISSWAP(pp) ((pp)->p_state & P_SWAP)
@@ -1177,6 +1176,7 @@ int page_trycapture(page_t *pp, uint_t szc, uint_t flags, void *datap);
void page_unlock_capture(page_t *pp);
int page_capture_unretire_pp(page_t *);
+extern int memsegs_trylock(int);
extern void memsegs_lock(int);
extern void memsegs_unlock(int);
extern int memsegs_lock_held(void);
diff --git a/usr/src/uts/common/vm/page_lock.c b/usr/src/uts/common/vm/page_lock.c
index 7696178019..8003884652 100644
--- a/usr/src/uts/common/vm/page_lock.c
+++ b/usr/src/uts/common/vm/page_lock.c
@@ -19,11 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* VM - page locking primitives
@@ -33,7 +32,6 @@
#include <sys/vtrace.h>
#include <sys/debug.h>
#include <sys/cmn_err.h>
-#include <sys/vnode.h>
#include <sys/bitmap.h>
#include <sys/lockstat.h>
#include <sys/sysmacros.h>
@@ -41,6 +39,7 @@
#include <vm/page.h>
#include <vm/seg_enum.h>
#include <vm/vm_dep.h>
+#include <vm/seg_kmem.h>
/*
* This global mutex is for logical page locking.
@@ -145,8 +144,6 @@ static pad_mutex_t pszc_mutex[PSZC_MTX_TABLE_SIZE];
((uintptr_t)(vp) >> 12)) \
& (VPH_TABLE_SIZE - 1))
-extern struct vnode kvp;
-
/*
* Two slots after VPH_TABLE_SIZE are reserved in vph_mutex for kernel vnodes.
* The lock for kvp is VPH_TABLE_SIZE + 0, and the lock for zvp is
@@ -1025,6 +1022,12 @@ static krwlock_t memsegslock;
*/
static krwlock_t memlists_lock;
+int
+memsegs_trylock(int writer)
+{
+ return (rw_tryenter(&memsegslock, writer ? RW_WRITER : RW_READER));
+}
+
void
memsegs_lock(int writer)
{
diff --git a/usr/src/uts/common/vm/page_retire.c b/usr/src/uts/common/vm/page_retire.c
index 8908807a4d..1d6512f1b2 100644
--- a/usr/src/uts/common/vm/page_retire.c
+++ b/usr/src/uts/common/vm/page_retire.c
@@ -142,6 +142,7 @@
#include <vm/vm_dep.h>
#include <vm/as.h>
#include <vm/hat.h>
+#include <vm/seg_kmem.h>
/*
* vnode for all pages which are retired from the VM system;
@@ -273,8 +274,6 @@ int page_retire_first_ue = 1;
*/
static int pr_enable = 0;
-extern struct vnode kvp;
-
#ifdef DEBUG
struct page_retire_debug {
int prd_dup1;
diff --git a/usr/src/uts/common/vm/seg_kmem.c b/usr/src/uts/common/vm/seg_kmem.c
index 3a8bfdd268..1b2f34dd0b 100644
--- a/usr/src/uts/common/vm/seg_kmem.c
+++ b/usr/src/uts/common/vm/seg_kmem.c
@@ -111,8 +111,6 @@ struct seg kvseg32; /* 32-bit kernel heap segment */
vmem_t *heap32_arena; /* 32-bit kernel heap arena */
vmem_t *heaptext_arena; /* heaptext arena */
struct as kas; /* kernel address space */
-struct vnode kvp; /* vnode for all segkmem pages */
-struct vnode zvp; /* vnode for zfs pages */
int segkmem_reloc; /* enable/disable relocatable segkmem pages */
vmem_t *static_arena; /* arena for caches to import static memory */
vmem_t *static_alloc_arena; /* arena for allocating static memory */
diff --git a/usr/src/uts/common/vm/seg_kmem.h b/usr/src/uts/common/vm/seg_kmem.h
index 70e941a848..2a4ed3b2aa 100644
--- a/usr/src/uts/common/vm/seg_kmem.h
+++ b/usr/src/uts/common/vm/seg_kmem.h
@@ -19,14 +19,13 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _VM_SEG_KMEM_H
#define _VM_SEG_KMEM_H
-#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
@@ -59,13 +58,21 @@ extern struct seg kvseg32; /* 32-bit kernel heap segment */
extern vmem_t *heap32_arena; /* 32-bit kernel heap arena */
extern vmem_t *heaptext_arena; /* kernel text arena, from heap */
extern struct as kas; /* kernel address space */
-extern struct vnode kvp; /* vnode for all segkmem pages */
-extern struct vnode zvp; /* vnode for all segkmem pages for zfs */
extern int segkmem_reloc; /* enable/disable segkmem relocatable pages */
extern vmem_t *static_arena; /* arena for caches to import static memory */
extern vmem_t *static_alloc_arena; /* arena for allocating static memory */
extern vmem_t *zio_arena; /* arena for zio caches */
extern vmem_t *zio_alloc_arena; /* arena for zio caches */
+extern struct vnode kvps[];
+/*
+ * segkmem page vnodes
+ */
+#define kvp (kvps[KV_KVP])
+#define zvp (kvps[KV_ZVP])
+#if defined(__sparc)
+#define mpvp (kvps[KV_MPVP])
+#define promvp (kvps[KV_PROMVP])
+#endif /* __sparc */
extern int segkmem_create(struct seg *);
extern page_t *segkmem_page_create(void *, size_t, int, void *);
diff --git a/usr/src/uts/common/vm/seg_vn.c b/usr/src/uts/common/vm/seg_vn.c
index 9ba274a2eb..3649a8da21 100644
--- a/usr/src/uts/common/vm/seg_vn.c
+++ b/usr/src/uts/common/vm/seg_vn.c
@@ -566,7 +566,6 @@ segvn_create(struct seg *seg, void *argsp)
!IS_P2ALIGNED(seg->s_size, pgsz)) {
a->szc = 0;
} else if (a->vp != NULL) {
- extern struct vnode kvp;
if (IS_SWAPFSVP(a->vp) || VN_ISKAS(a->vp)) {
/*
* paranoid check.
@@ -6017,7 +6016,6 @@ segvn_setpagesize(struct seg *seg, caddr_t addr, size_t len, uint_t szc)
pgcnt_t pgcnt = page_get_pagecnt(szc);
int err;
u_offset_t off = svd->offset + (uintptr_t)(addr - seg->s_base);
- extern struct vnode kvp;
ASSERT(seg->s_as && AS_WRITE_HELD(seg->s_as, &seg->s_as->a_lock));
ASSERT(addr >= seg->s_base && eaddr <= seg->s_base + seg->s_size);
diff --git a/usr/src/uts/common/vm/vm_page.c b/usr/src/uts/common/vm/vm_page.c
index fbf616bd4a..61ff0c16c0 100644
--- a/usr/src/uts/common/vm/vm_page.c
+++ b/usr/src/uts/common/vm/vm_page.c
@@ -4365,10 +4365,6 @@ page_invalidate_pages()
pgcnt_t nbusypages;
int retry = 0;
const int MAXRETRIES = 4;
-#if defined(__sparc)
- extern struct vnode prom_ppages;
-#endif /* __sparc */
-
top:
/*
* Flush dirty pages and destroy the clean ones.
@@ -4385,12 +4381,7 @@ top:
* skip the page if it has no vnode or the page associated
* with the kernel vnode or prom allocated kernel mem.
*/
-#if defined(__sparc)
- if ((vp = pp->p_vnode) == NULL || VN_ISKAS(vp) ||
- vp == &prom_ppages)
-#else /* x86 doesn't have prom or prom_ppage */
if ((vp = pp->p_vnode) == NULL || VN_ISKAS(vp))
-#endif /* __sparc */
continue;
/*
@@ -6726,14 +6717,10 @@ cleanup:
int
page_capture_pre_checks(page_t *pp, uint_t flags)
{
-#if defined(__sparc)
- extern struct vnode prom_ppages;
-#endif /* __sparc */
-
ASSERT(pp != NULL);
#if defined(__sparc)
- if (pp->p_vnode == &prom_ppages) {
+ if (pp->p_vnode == &promvp) {
return (EPERM);
}
diff --git a/usr/src/uts/common/vm/vm_pagelist.c b/usr/src/uts/common/vm/vm_pagelist.c
index 59b4e079c5..7b761da108 100644
--- a/usr/src/uts/common/vm/vm_pagelist.c
+++ b/usr/src/uts/common/vm/vm_pagelist.c
@@ -1117,13 +1117,12 @@ page_ctrs_adjust(int mnode)
/* update shared hpm_counters in other mnodes */
if (interleaved_mnodes) {
for (i = 0; i < max_mem_nodes; i++) {
- if (i == mnode)
+ if ((i == mnode) ||
+ (mem_node_config[i].exists == 0))
continue;
ASSERT(
PAGE_COUNTERS_COUNTERS(i, r) == old_ctr ||
PAGE_COUNTERS_COUNTERS(i, r) == NULL);
- if (mem_node_config[i].exists == 0)
- continue;
PAGE_COUNTERS_COUNTERS(i, r) = new_ctr;
PAGE_COUNTERS_ENTRIES(i, r) = pcsz;
PAGE_COUNTERS_BASE(i, r) = newbase;
@@ -1277,6 +1276,33 @@ cleanup:
return (rc);
}
+/*
+ * Cleanup the hpm_counters field in the page counters
+ * array.
+ */
+void
+page_ctrs_cleanup(void)
+{
+ int r; /* region size */
+ int i; /* mnode index */
+
+ /*
+ * Get the page counters write lock while we are
+ * setting the page hpm_counters field to NULL
+ * for non-existent mnodes.
+ */
+ for (i = 0; i < max_mem_nodes; i++) {
+ PAGE_CTRS_WRITE_LOCK(i);
+ if (mem_node_config[i].exists) {
+ PAGE_CTRS_WRITE_UNLOCK(i);
+ continue;
+ }
+ for (r = 1; r < mmu_page_sizes; r++) {
+ PAGE_COUNTERS_COUNTERS(i, r) = NULL;
+ }
+ PAGE_CTRS_WRITE_UNLOCK(i);
+ }
+}
#ifdef DEBUG
@@ -3449,7 +3475,17 @@ page_geti_contig_pages(int mnode, uint_t bin, uchar_t szc, int flags,
pfnhi = pfnlo + (slotlen * szcpgcnt) - 1;
}
- memsegs_lock(0);
+ /*
+ * This routine is can be called recursively so we shouldn't
+ * acquire a reader lock if a write request is pending. This
+ * could lead to a deadlock with the DR thread.
+ *
+ * Returning NULL informs the caller that we could not get
+ * a contig page with the required characteristics.
+ */
+
+ if (!memsegs_trylock(0))
+ return (NULL);
/*
* loop through memsegs to look for contig page candidates
diff --git a/usr/src/uts/sun4/os/memlist.c b/usr/src/uts/sun4/os/memlist.c
index 1fb663b31c..013b56bc14 100644
--- a/usr/src/uts/sun4/os/memlist.c
+++ b/usr/src/uts/sun4/os/memlist.c
@@ -19,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <sys/param.h>
#include <sys/sysmacros.h>
@@ -177,9 +175,6 @@ get_max_phys_size(
}
-
-struct vnode prom_ppages;
-
static void
more_pages(uint64_t base, uint64_t len)
{
@@ -226,7 +221,7 @@ less_pages(uint64_t base, uint64_t len)
* are page numbers (gack) for >32 bit
* physical memory machines.
*/
- (void) page_hashin(pp, &prom_ppages,
+ (void) page_hashin(pp, &promvp,
(offset_t)pfnum, NULL);
if (kcage_on) {
diff --git a/usr/src/uts/sun4/os/startup.c b/usr/src/uts/sun4/os/startup.c
index 0508bcf788..ebb336f6d9 100644
--- a/usr/src/uts/sun4/os/startup.c
+++ b/usr/src/uts/sun4/os/startup.c
@@ -2561,8 +2561,6 @@ memseg_find(pfn_t base, pfn_t *next)
return (NULL);
}
-extern struct vnode prom_ppages;
-
/*
* Put page allocated by OBP on prom_ppages
*/
@@ -2604,7 +2602,7 @@ kphysm_erase(uint64_t addr, uint64_t len)
add_physmem_cb(pp, base);
if (page_trylock(pp, SE_EXCL) == 0)
cmn_err(CE_PANIC, "prom page locked");
- (void) page_hashin(pp, &prom_ppages,
+ (void) page_hashin(pp, &promvp,
(offset_t)base, NULL);
(void) page_pp_lock(pp, 0, 1);
pp++, base++, num--;
@@ -2700,7 +2698,7 @@ kphysm_add(uint64_t addr, uint64_t len, int reclaim)
* unhash and unlock it
*/
while (rpp < lpp) {
- ASSERT(PAGE_EXCL(rpp) && rpp->p_vnode == &prom_ppages);
+ ASSERT(PAGE_EXCL(rpp) && rpp->p_vnode == &promvp);
ASSERT(PP_ISNORELOC(rpp));
PP_CLRNORELOC(rpp);
page_pp_unlock(rpp, 0, 1);
diff --git a/usr/src/uts/sun4u/os/cpr_impl.c b/usr/src/uts/sun4u/os/cpr_impl.c
index 0cc9640c11..bbf1051c1d 100644
--- a/usr/src/uts/sun4u/os/cpr_impl.c
+++ b/usr/src/uts/sun4u/os/cpr_impl.c
@@ -19,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Platform specific implementation code
*/
@@ -1505,7 +1503,6 @@ i_cpr_reusable_supported(void)
static int
i_cpr_find_ppages(void)
{
- extern struct vnode prom_ppages;
struct page *pp;
struct memlist *pmem;
pgcnt_t npages, pcnt, scnt, vcnt;
@@ -1539,15 +1536,15 @@ i_cpr_find_ppages(void)
scnt = cpr_count_seg_pages(mapflag, cpr_clrbit);
/*
- * set bits for phys pages referenced by the prom_ppages vnode;
+ * set bits for phys pages referenced by the promvp vnode;
* these pages are mostly comprised of forthdebug words
*/
vcnt = 0;
- for (pp = prom_ppages.v_pages; pp; ) {
+ for (pp = promvp.v_pages; pp; ) {
if (cpr_setbit(pp->p_offset, mapflag) == 0)
vcnt++;
pp = pp->p_vpnext;
- if (pp == prom_ppages.v_pages)
+ if (pp == promvp.v_pages)
break;
}
diff --git a/usr/src/uts/sun4v/io/dr_mem.c b/usr/src/uts/sun4v/io/dr_mem.c
index 2b346a6d48..a32b0af792 100644
--- a/usr/src/uts/sun4v/io/dr_mem.c
+++ b/usr/src/uts/sun4v/io/dr_mem.c
@@ -203,10 +203,6 @@ static mde_cookie_t dr_mem_find_node_md(dr_mem_blk_t *, md_t *, mde_cookie_t *);
static int mem_add(pfn_t, pgcnt_t);
static int mem_del(pfn_t, pgcnt_t);
-static size_t rsvaddsz;
-extern void i_dr_mem_init(uint64_t *);
-extern void i_dr_mem_fini();
-extern void i_dr_mem_update();
extern int kphysm_add_memory_dynamic(pfn_t, pgcnt_t);
int
@@ -261,8 +257,6 @@ dr_mem_init(void)
return (rv);
}
- i_dr_mem_init(&rsvaddsz);
-
return (0);
}
@@ -271,8 +265,6 @@ dr_mem_fini(void)
{
int rv;
- i_dr_mem_fini();
-
if ((rv = ds_cap_fini(&dr_mem_cap)) != 0) {
cmn_err(CE_NOTE, "dr_mem: ds_cap_fini failed: %d", rv);
}
@@ -720,6 +712,8 @@ dr_mem_list_query(dr_mem_hdr_t *req, dr_mem_hdr_t **resp, int *resp_len)
dr_mem_hdr_t *rp;
dr_mem_query_t *stat;
+ drctl_block();
+
/* the incoming array of req_mblks to configure */
req_mblks = DR_MEM_CMD_MBLKS(req);
@@ -764,6 +758,8 @@ dr_mem_list_query(dr_mem_hdr_t *req, dr_mem_hdr_t **resp, int *resp_len)
*resp = rp;
*resp_len = rlen;
+ drctl_unblock();
+
return (0);
}
@@ -832,7 +828,7 @@ static int
dr_mem_configure(dr_mem_blk_t *mbp, int *status)
{
int rv;
- uint64_t addr, size, addsz;
+ uint64_t addr, size;
rv = 0;
addr = mbp->addr;
@@ -854,64 +850,10 @@ dr_mem_configure(dr_mem_blk_t *mbp, int *status)
*status = DR_MEM_STAT_UNCONFIGURED;
rv = DR_MEM_RES_FAILURE;
}
- } else if (rsvaddsz) {
- addr += size;
-
- /*
- * Add up to the first <rsvaddsz> portion of mblock
- * first since that portion has reserved meta pages.
- * This will likely guarantee an additional amount of
- * free pages from which we may have to allocate the
- * rest of the meta pages.
- *
- * Break up the request in descending order (if needed)
- * in order to ensure that cage grows from the high end
- * of the original request.
- */
- for (addsz = MIN(size, rsvaddsz); addsz > 0; addsz = size) {
- ASSERT(addr >= mbp->addr);
- DR_DBG_MEM("addsz=0x%lx size=0x%lx\n", addsz, size);
- if (rv = mem_add(btop(addr - addsz), btop(addsz))) {
- DR_DBG_MEM("failed to configure span"
- " 0x%lx.0x%lx (%d)\n", addr, addsz, rv);
- break;
- } else {
- size -= addsz;
- addr -= addsz;
- }
- }
-
- /*
- * Mark the mblock configured if any span
- * in that mblock was successfully added.
- *
- * In case of partial success:
- *
- * rv != DR_MEM_RES_OK
- * status == DR_MEM_STAT_CONFIGURED
- *
- * mark span actually configured.
- */
- if (size == mbp->size && rv != KPHYSM_ESPAN) {
- *status = DR_MEM_STAT_UNCONFIGURED;
- } else {
- DR_DBG_MEM("failed (partial) to configure span"
- " 0x%lx.0x%lx (%d)\n", addr, addsz, rv);
- *status = DR_MEM_STAT_CONFIGURED;
- mbp->addr = addr;
- mbp->size -= size;
- }
-
- rv = cvt_err(rv);
- i_dr_mem_update();
} else {
- /*
- * The reserved feature is disabled, add whole mblock.
- */
rv = mem_add(btop(addr), btop(size));
DR_DBG_MEM("addr=0x%lx size=0x%lx rv=%d\n", addr, size, rv);
if (rv) {
- rv = cvt_err(rv);
*status = DR_MEM_STAT_UNCONFIGURED;
} else {
*status = DR_MEM_STAT_CONFIGURED;
@@ -934,7 +876,6 @@ dr_mem_unconfigure(dr_mem_blk_t *mbp, int *status)
*status = DR_MEM_STAT_CONFIGURED;
rv = DR_MEM_RES_EINVAL;
} else if (rv = mem_del(btop(mbp->addr), btop(mbp->size))) {
- rv = cvt_err(rv);
*status = DR_MEM_STAT_CONFIGURED;
} else {
*status = DR_MEM_STAT_UNCONFIGURED;
@@ -1117,15 +1058,16 @@ mem_add(pfn_t base, pgcnt_t npgs)
DR_DBG_MEM("%s: begin base=0x%lx npgs=0x%lx\n", __func__, base, npgs);
if (npgs == 0)
- return (0);
+ return (DR_MEM_RES_OK);
rv = kphysm_add_memory_dynamic(base, npgs);
DR_DBG_MEM("%s: kphysm_add(0x%lx, 0x%lx) = %d", __func__, base, npgs,
rv);
- if (!rv) {
+ if (rv == KPHYSM_OK) {
if (rc = kcage_range_add(base, npgs, KCAGE_DOWN))
cmn_err(CE_WARN, "kcage_range_add() = %d", rc);
}
+ rv = cvt_err(rv);
return (rv);
}
@@ -1145,6 +1087,7 @@ static int
mem_del(pfn_t base, pgcnt_t npgs)
{
int rv, err, del_range = 0;
+ int convert = 1;
mem_sync_t ms;
memquery_t mq;
memhandle_t mh;
@@ -1154,10 +1097,11 @@ mem_del(pfn_t base, pgcnt_t npgs)
DR_DBG_MEM("%s: begin base=0x%lx npgs=0x%lx\n", __func__, base, npgs);
if (npgs == 0)
- return (0);
+ return (DR_MEM_RES_OK);
if ((rv = kphysm_del_gethandle(&mh)) != KPHYSM_OK) {
cmn_err(CE_WARN, "%s: del_gethandle() = %d", __func__, rv);
+ rv = cvt_err(rv);
return (rv);
}
if ((rv = kphysm_del_span_query(base, npgs, &mq))
@@ -1168,10 +1112,19 @@ mem_del(pfn_t base, pgcnt_t npgs)
if (mq.nonrelocatable) {
DR_DBG_MEM("%s: non-reloc pages = %ld",
__func__, mq.nonrelocatable);
- rv = KPHYSM_ENONRELOC;
+ rv = KPHYSM_ENONRELOC;
goto done;
}
if (rv = kcage_range_delete(base, npgs)) {
+ switch (rv) {
+ case EBUSY:
+ rv = DR_MEM_RES_ENOTVIABLE;
+ break;
+ default:
+ rv = DR_MEM_RES_FAILURE;
+ break;
+ }
+ convert = 0; /* conversion done */
cmn_err(CE_WARN, "%s: del_range() = %d", __func__, rv);
goto done;
} else {
@@ -1183,6 +1136,18 @@ mem_del(pfn_t base, pgcnt_t npgs)
}
if ((rv = memlist_add_span(ptob(base), ptob(npgs), &d_ml))
!= MEML_SPANOP_OK) {
+ switch (rv) {
+ case MEML_SPANOP_ESPAN:
+ rv = DR_MEM_RES_ESPAN;
+ break;
+ case MEML_SPANOP_EALLOC:
+ rv = DR_MEM_RES_ERESOURCE;
+ break;
+ default:
+ rv = DR_MEM_RES_FAILURE;
+ break;
+ }
+ convert = 0; /* conversion done */
cmn_err(CE_WARN, "%s: add_span() = %d", __func__, rv);
goto done;
}
@@ -1245,6 +1210,8 @@ done:
if ((err = kphysm_del_release(mh)) != KPHYSM_OK)
cmn_err(CE_WARN, "%s: del_release() = %d", __func__, err);
+ if (convert)
+ rv = cvt_err(rv);
DR_DBG_MEM("%s: rv=%d", __func__, rv);
diff --git a/usr/src/uts/sun4v/io/drctl.c b/usr/src/uts/sun4v/io/drctl.c
index 5061b1228c..4ca542716f 100644
--- a/usr/src/uts/sun4v/io/drctl.c
+++ b/usr/src/uts/sun4v/io/drctl.c
@@ -156,6 +156,7 @@ _init(void)
drctlp->drc_inst = -1;
mutex_init(&drctlp->drc_lock, NULL, MUTEX_DRIVER, NULL);
+ cv_init(&drctlp->drc_busy_cv, NULL, CV_DRIVER, NULL);
if ((rv = mod_install(&modlinkage)) != 0)
mutex_destroy(&drctlp->drc_lock);
@@ -171,7 +172,7 @@ _fini(void)
if ((rv = mod_remove(&modlinkage)) != 0)
return (rv);
-
+ cv_destroy(&drctlp->drc_busy_cv);
mutex_destroy(&drctlp->drc_lock);
return (0);
}
@@ -376,7 +377,6 @@ verify_response(int cmd,
return (0);
}
-
static int
drctl_config_common(int cmd, int flags, drctl_rsrc_t *res,
int count, drctl_resp_t **rbuf, size_t *rsize, size_t *rq_size)
@@ -460,7 +460,6 @@ drctl_config_init(int cmd, int flags, drctl_rsrc_t *res,
}
mutex_enter(&drctlp->drc_lock);
-
if (drctlp->drc_busy != NULL) {
mutex_exit(&drctlp->drc_lock);
*rbuf = drctl_generate_err_resp(busy_msg, rsize);
@@ -488,6 +487,7 @@ drctl_config_init(int cmd, int flags, drctl_rsrc_t *res,
kmem_free(*rbuf, *rsize);
*rbuf = drctl_generate_err_resp(rsp_msg, rsize);
drctlp->drc_busy = NULL;
+ cv_broadcast(&drctlp->drc_busy_cv);
} else { /* message format is valid */
drctlp->drc_busy = ck;
drctlp->drc_cmd = cmd;
@@ -511,8 +511,8 @@ drctl_config_init(int cmd, int flags, drctl_rsrc_t *res,
drctlp->drc_cmd = -1;
drctlp->drc_flags = 0;
drctlp->drc_busy = NULL;
+ cv_broadcast(&drctlp->drc_busy_cv);
}
-
return (rv);
}
@@ -528,12 +528,10 @@ drctl_config_fini(drctl_cookie_t ck, drctl_rsrc_t *res, int count)
size_t rq_size;
mutex_enter(&drctlp->drc_lock);
-
if (drctlp->drc_busy != ck) {
mutex_exit(&drctlp->drc_lock);
return (EBUSY);
}
-
mutex_exit(&drctlp->drc_lock);
flags = drctlp->drc_flags;
@@ -579,11 +577,11 @@ drctl_config_fini(drctl_cookie_t ck, drctl_rsrc_t *res, int count)
flags, res, count, NULL, 0, &rq_size);
done:
- drctlp->drc_cmd = -1;
- drctlp->drc_flags = 0;
- drctlp->drc_busy = NULL;
-
- return (rv);
+ drctlp->drc_cmd = -1;
+ drctlp->drc_flags = 0;
+ drctlp->drc_busy = NULL;
+ cv_broadcast(&drctlp->drc_busy_cv);
+ return (rv);
}
static int
@@ -697,3 +695,35 @@ pack_message(int cmd,
return (msgp);
}
+
+/*
+ * Block DR operations
+ */
+void
+drctl_block(void)
+{
+ /* Wait for any in progress DR operation to complete */
+ mutex_enter(&drctlp->drc_lock);
+ while (drctlp->drc_busy != NULL)
+ (void) cv_wait_sig(&drctlp->drc_busy_cv, &drctlp->drc_lock);
+ /* Mark the link busy */
+ drctlp->drc_busy = (drctl_cookie_t)-1;
+ drctlp->drc_cmd = DRCTL_DRC_BLOCK;
+ drctlp->drc_flags = 0;
+ mutex_exit(&drctlp->drc_lock);
+}
+
+/*
+ * Unblock DR operations
+ */
+void
+drctl_unblock(void)
+{
+ /* Mark the link free */
+ mutex_enter(&drctlp->drc_lock);
+ drctlp->drc_cmd = -1;
+ drctlp->drc_flags = 0;
+ drctlp->drc_busy = NULL;
+ cv_broadcast(&drctlp->drc_busy_cv);
+ mutex_exit(&drctlp->drc_lock);
+}
diff --git a/usr/src/uts/sun4v/io/vlds.c b/usr/src/uts/sun4v/io/vlds.c
index 4eedeee56b..a33978680e 100644
--- a/usr/src/uts/sun4v/io/vlds.c
+++ b/usr/src/uts/sun4v/io/vlds.c
@@ -278,7 +278,6 @@ _init(void)
}
vlds_mdeg_init();
- (void) vlds_mdeg_register();
return (s);
}
@@ -293,8 +292,6 @@ _fini(void)
ddi_soft_state_fini(&vlds_statep);
- (void) vlds_mdeg_unregister();
-
return (s);
}
@@ -338,6 +335,8 @@ vlds_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
vlds_minor_init();
+ (void) vlds_mdeg_register();
+
return (DDI_SUCCESS);
}
@@ -352,6 +351,7 @@ vlds_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
vlds_minor_free(vlds_minor_bitmap);
ddi_remove_minor_node(devi, NULL);
+ (void) vlds_mdeg_unregister();
return (DDI_SUCCESS);
}
diff --git a/usr/src/uts/sun4v/os/memseg.c b/usr/src/uts/sun4v/os/memseg.c
index d562905eec..359588150a 100644
--- a/usr/src/uts/sun4v/os/memseg.c
+++ b/usr/src/uts/sun4v/os/memseg.c
@@ -44,9 +44,6 @@ extern struct memseg *memseg_alloc();
extern page_t *ppvm_base;
extern pgcnt_t ppvm_size;
-static vnode_t pp_vn, rsv_vn;
-static pgcnt_t rsv_metapgs;
-static int meta_rsv_enable;
static int sun4v_memseg_debug;
extern struct memseg *memseg_reuse(pgcnt_t);
@@ -77,12 +74,11 @@ extern void remap_to_dummy(caddr_t, pgcnt_t);
int
memseg_alloc_meta(pfn_t base, pgcnt_t npgs, void **ptp, pgcnt_t *metap)
{
- page_t *pp, *opp, *epp, *pgpp;
+ page_t *pp, *opp, *epp;
pgcnt_t metapgs;
- int i, rsv;
+ int i;
struct seg kseg;
caddr_t vaddr;
- u_offset_t off;
/*
* Verify incoming memory is within supported DR range.
@@ -95,7 +91,7 @@ memseg_alloc_meta(pfn_t base, pgcnt_t npgs, void **ptp, pgcnt_t *metap)
metapgs = btopr(npgs * sizeof (page_t));
if (!IS_P2ALIGNED((uint64_t)pp, PAGESIZE) &&
- page_find(&pp_vn, (u_offset_t)pp)) {
+ page_find(&mpvp, (u_offset_t)pp)) {
/*
* Another memseg has page_t's in the same
* page which 'pp' resides. This would happen
@@ -120,7 +116,7 @@ memseg_alloc_meta(pfn_t base, pgcnt_t npgs, void **ptp, pgcnt_t *metap)
}
if (!IS_P2ALIGNED((uint64_t)epp, PAGESIZE) &&
- page_find(&pp_vn, (u_offset_t)epp)) {
+ page_find(&mpvp, (u_offset_t)epp)) {
/*
* Another memseg has page_t's in the same
* page which 'epp' resides. This would happen
@@ -144,59 +140,20 @@ memseg_alloc_meta(pfn_t base, pgcnt_t npgs, void **ptp, pgcnt_t *metap)
vaddr = (caddr_t)pp;
for (i = 0; i < metapgs; i++)
- if (page_find(&pp_vn, (u_offset_t)(vaddr + i * PAGESIZE)))
+ if (page_find(&mpvp, (u_offset_t)(vaddr + i * PAGESIZE)))
panic("page_find(0x%p, %p)\n",
- (void *)&pp_vn, (void *)(vaddr + i * PAGESIZE));
+ (void *)&mpvp, (void *)(vaddr + i * PAGESIZE));
/*
* Allocate the metadata pages; these are the pages that will
* contain the page_t's for the incoming memory.
- *
- * If a normal allocation fails, use the reserved metapgs for
- * a small allocation; otherwise retry with PG_WAIT.
*/
- rsv = off = 0;
- if (metapgs <= rsv_metapgs) {
- MEMSEG_DEBUG("memseg_get: use rsv 0x%lx metapgs", metapgs);
- ASSERT(meta_rsv_enable);
- rsv = 1;
- } else if ((pgpp = page_create_va(&pp_vn, (u_offset_t)pp, ptob(metapgs),
+ if ((page_create_va(&mpvp, (u_offset_t)pp, ptob(metapgs),
PG_NORELOC | PG_EXCL, &kseg, vaddr)) == NULL) {
- cmn_err(CE_WARN, "memseg_get: can't get 0x%ld metapgs",
+ MEMSEG_DEBUG("memseg_alloc_meta: can't get 0x%ld metapgs",
metapgs);
return (KPHYSM_ERESOURCE);
}
- if (rsv) {
- /*
- * The reseve pages must be hashed out of the reserve vnode
- * and rehashed by <pp_vn,vaddr>. The resreved pages also
- * must be replenished immedidately at the end of the add
- * processing.
- */
- for (i = 0; i < metapgs; i++) {
- pgpp = page_find(&rsv_vn, off);
- ASSERT(pgpp);
- page_hashout(pgpp, 0);
- hat_devload(kas.a_hat, vaddr, PAGESIZE,
- page_pptonum(pgpp), PROT_READ | PROT_WRITE,
- HAT_LOAD | HAT_LOAD_REMAP | HAT_LOAD_NOCONSIST);
- ASSERT(!page_find(&pp_vn, (u_offset_t)vaddr));
- if (!page_hashin(pgpp, &pp_vn, (u_offset_t)vaddr, 0))
- panic("memseg_get: page_hashin(0x%p, 0x%p)",
- (void *)pgpp, (void *)vaddr);
- off += PAGESIZE;
- vaddr += PAGESIZE;
- rsv_metapgs--;
- }
- } else {
- for (i = 0; i < metapgs; i++) {
- hat_devload(kas.a_hat, vaddr, PAGESIZE,
- page_pptonum(pgpp), PROT_READ | PROT_WRITE,
- HAT_LOAD | HAT_LOAD_REMAP | HAT_LOAD_NOCONSIST);
- pgpp = pgpp->p_next;
- vaddr += PAGESIZE;
- }
- }
ASSERT(ptp);
ASSERT(metap);
@@ -228,7 +185,7 @@ memseg_free_meta(void *ptp, pgcnt_t metapgs)
* Free pages allocated during add.
*/
for (i = 0; i < metapgs; i++) {
- pp = page_find(&pp_vn, off);
+ pp = page_find(&mpvp, off);
ASSERT(pp);
ASSERT(pp->p_szc == 0);
page_io_unlock(pp);
@@ -248,7 +205,7 @@ memseg_get_metapfn(void *ptp, pgcnt_t metapg)
ASSERT(off);
ASSERT(IS_P2ALIGNED((uint64_t)off, PAGESIZE));
- pp = page_find(&pp_vn, off);
+ pp = page_find(&mpvp, off);
ASSERT(pp);
ASSERT(pp->p_szc == 0);
ASSERT(pp->p_pagenum != PFN_INVALID);
@@ -285,7 +242,7 @@ memseg_remap_meta(struct memseg *seg)
*/
if (!IS_P2ALIGNED((uint64_t)pp, PAGESIZE) &&
- page_find(&pp_vn, (u_offset_t)(pp - 1)) && !page_deleted(pp - 1)) {
+ page_find(&mpvp, (u_offset_t)(pp - 1)) && !page_deleted(pp - 1)) {
/*
* Another memseg has page_t's in the same
* page which 'pp' resides. This would happen
@@ -312,7 +269,7 @@ memseg_remap_meta(struct memseg *seg)
}
if (!IS_P2ALIGNED((uint64_t)epp, PAGESIZE) &&
- page_find(&pp_vn, (u_offset_t)epp) && !page_deleted(epp)) {
+ page_find(&mpvp, (u_offset_t)epp) && !page_deleted(epp)) {
/*
* Another memseg has page_t's in the same
* page which 'epp' resides. This would happen
@@ -333,13 +290,13 @@ memseg_remap_meta(struct memseg *seg)
off = (u_offset_t)pp;
- MEMSEG_DEBUG("memseg_remap: off=0x%lx metapgs=0x%lx\n", (uint64_t)off,
- metapgs);
+ MEMSEG_DEBUG("memseg_remap_meta: off=0x%lx metapgs=0x%lx\n",
+ (uint64_t)off, metapgs);
/*
* Free pages allocated during add.
*/
for (i = 0; i < metapgs; i++) {
- pp = page_find(&pp_vn, off);
+ pp = page_find(&mpvp, off);
ASSERT(pp);
ASSERT(pp->p_szc == 0);
page_io_unlock(pp);
@@ -347,64 +304,3 @@ memseg_remap_meta(struct memseg *seg)
off += PAGESIZE;
}
}
-
-static void
-rsv_alloc()
-{
- int i;
- page_t *pp;
- pgcnt_t metapgs;
- u_offset_t off;
- struct seg kseg;
-
- kseg.s_as = &kas;
-
- /*
- * Reserve enough page_t pages for an add request of
- * RSV_SIZE bytes.
- */
- metapgs = btopr(btop(RSV_SIZE) * sizeof (page_t)) - rsv_metapgs;
-
- for (i = off = 0; i < metapgs; i++, off += PAGESIZE) {
- (void) page_create_va(&rsv_vn, off, PAGESIZE,
- PG_NORELOC | PG_WAIT, &kseg, 0);
- pp = page_find(&rsv_vn, off);
- ASSERT(pp);
- ASSERT(PAGE_EXCL(pp));
- page_iolock_init(pp);
- rsv_metapgs++;
- }
-}
-
-void
-i_dr_mem_init(size_t *hint)
-{
- if (meta_rsv_enable) {
- rsv_alloc();
- if (hint)
- *hint = RSV_SIZE;
- }
-}
-
-void
-i_dr_mem_fini()
-{
- int i;
- page_t *pp;
- u_offset_t off;
-
- for (i = off = 0; i < rsv_metapgs; i++, off += PAGESIZE) {
- if (pp = page_find(&rsv_vn, off)) {
- ASSERT(PAGE_EXCL(pp));
- page_destroy(pp, 0);
- }
- ASSERT(!page_find(&rsv_vn, off));
- }
- rsv_metapgs = 0;
-}
-
-void
-i_dr_mem_update()
-{
- rsv_alloc();
-}
diff --git a/usr/src/uts/sun4v/promif/promif_emul.c b/usr/src/uts/sun4v/promif/promif_emul.c
index 143caa1f9d..1adf719ba6 100644
--- a/usr/src/uts/sun4v/promif/promif_emul.c
+++ b/usr/src/uts/sun4v/promif/promif_emul.c
@@ -36,6 +36,7 @@
#include <sys/mdesc.h>
#include <sys/mach_descrip.h>
#include <sys/cpu_module.h>
+#include <vm/seg_kmem.h>
#ifndef _KMDB
#include <sys/pte.h>
@@ -50,7 +51,7 @@ int cif_cpu_mp_ready;
int (*prom_cif_handler)(void *) = NULL;
extern struct memlist *phys_avail;
-extern struct vnode prom_ppages;
+extern struct vnode promvp;
extern void kdi_tlb_page_unlock(caddr_t, int);
#define COMBINE(hi, lo) (((uint64_t)(uint32_t)(hi) << 32) | (uint32_t)(lo))
@@ -309,7 +310,7 @@ unmap_prom_mappings(struct translation *transroot, size_t ntransroot)
ASSERT(PAGE_EXCL(pp));
ASSERT(PP_ISNORELOC(pp));
ASSERT(!PP_ISFREE(pp));
- ASSERT(page_find(&prom_ppages, pfn));
+ ASSERT(page_find(&promvp, pfn));
ASSERT(page_get_pagecnt(pp->p_szc) == 1);
if (pp->p_mapping) {
diff --git a/usr/src/uts/sun4v/sys/drctl.h b/usr/src/uts/sun4v/sys/drctl.h
index 75299f2c93..26b4970541 100644
--- a/usr/src/uts/sun4v/sys/drctl.h
+++ b/usr/src/uts/sun4v/sys/drctl.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -46,7 +46,8 @@ typedef enum {
DRCTL_IO_CONFIG_REQUEST,
DRCTL_IO_CONFIG_NOTIFY,
DRCTL_IO_UNCONFIG_REQUEST,
- DRCTL_IO_UNCONFIG_NOTIFY
+ DRCTL_IO_UNCONFIG_NOTIFY,
+ DRCTL_DRC_BLOCK
} drctl_cmds_t;
/*
@@ -135,6 +136,8 @@ typedef void *drctl_cookie_t;
extern int drctl_config_init(int, int,
drctl_rsrc_t *, int, drctl_resp_t **, size_t *, drctl_cookie_t);
extern int drctl_config_fini(drctl_cookie_t, drctl_rsrc_t *, int);
+extern void drctl_block(void);
+extern void drctl_unblock(void);
/*
* Values for the 2nd arg (flags) of drctl_config_init
diff --git a/usr/src/uts/sun4v/vm/mach_kpm.c b/usr/src/uts/sun4v/vm/mach_kpm.c
index f47e74e001..de3a53f7a4 100644
--- a/usr/src/uts/sun4v/vm/mach_kpm.c
+++ b/usr/src/uts/sun4v/vm/mach_kpm.c
@@ -35,11 +35,15 @@
#include <sys/machsystm.h>
#include <vm/seg_kpm.h>
#include <vm/mach_kpm.h>
+#include <vm/faultcode.h>
+
+extern pfn_t memseg_get_start(struct memseg *);
/*
* Kernel Physical Mapping (kpm) facility
*/
+
void
mach_kpm_init()
{
@@ -226,7 +230,15 @@ hat_kpm_addmem_mseg_update(struct memseg *msp, pgcnt_t nkpmpgs,
* if nkpmpgs needs to be used at some point.
*/
- base = msp->pages_base;
+ /*
+ * The meta (page_t) pages for dynamically added memory are allocated
+ * either from the incoming memory itself or from existing memory.
+ * In the former case the base of the incoming pages will be different
+ * than the base of the dynamic segment so call memseg_get_start() to
+ * get the actual base of the incoming memory for each case.
+ */
+
+ base = memseg_get_start(msp);
end = msp->pages_end;
hat_devload(kas.a_hat, kpm_vbase + mmu_ptob(base),
@@ -259,7 +271,15 @@ hat_kpm_delmem_mseg_update(struct memseg *msp, struct memseg **mspp)
{
pfn_t base, end;
- base = msp->pages_base;
+ /*
+ * The meta (page_t) pages for dynamically added memory are allocated
+ * either from the incoming memory itself or from existing memory.
+ * In the former case the base of the incoming pages will be different
+ * than the base of the dynamic segment so call memseg_get_start() to
+ * get the actual base of the incoming memory for each case.
+ */
+
+ base = memseg_get_start(msp);
end = msp->pages_end;
hat_unload(kas.a_hat, kpm_vbase + mmu_ptob(base), mmu_ptob(end - base),