#ifndef _VM_DEP_H
#define _VM_DEP_H
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/clock.h>
#include <vm/hat_pte.h>
#include <sys/param.h>
#include <sys/memnode.h>
#define GETTICK() tsc_read()
extern u_longlong_t randtick();
extern uint_t page_create_update_flags_x86(uint_t);
extern size_t plcnt_sz(size_t);
#define PLCNT_SZ(ctrs_sz) (ctrs_sz = plcnt_sz(ctrs_sz))
extern caddr_t plcnt_init(caddr_t);
#define PLCNT_INIT(addr) (addr = plcnt_init(addr))
extern void plcnt_inc_dec(page_t *, int, int, long, int);
#define PLCNT_INCR(pp, mnode, mtype, szc, flags) \
plcnt_inc_dec(pp, mtype, szc, 1l << PAGE_BSZS_SHIFT(szc), flags)
#define PLCNT_DECR(pp, mnode, mtype, szc, flags) \
plcnt_inc_dec(pp, mtype, szc, \
(long)(ULONG_MAX << PAGE_BSZS_SHIFT(szc)), flags)
#define PLCNT_XFER_NORELOC(pp)
#define PLCNT_MODIFY_MAX(pfn, cnt) mtype_modify_max(pfn, cnt)
extern int memrange_num(pfn_t);
extern int pfn_2_mtype(pfn_t);
extern int mtype_func(int, int, uint_t);
extern void mtype_modify_max(pfn_t, long);
extern int mnode_pgcnt(int);
extern int mnode_range_cnt(int);
#define NUM_MEM_RANGES 4
#define MAX_MNODE_MRANGES NUM_MEM_RANGES
#define MNODE_RANGE_CNT(mnode) mnode_range_cnt(mnode)
#define MNODE_MAX_MRANGE(mnode) memrange_num(mem_node_config[mnode].physbase)
extern int mtype_2_mrange(int);
#define MTYPE_2_MRANGE(mnode, mtype) \
(mnode_maxmrange[mnode] - mtype_2_mrange(mtype))
extern page_t ****page_freelists;
#define PAGE_FREELISTS(mnode, szc, color, mtype) \
(*(page_freelists[mtype][szc] + (color)))
extern page_t ***page_cachelists;
#define PAGE_CACHELISTS(mnode, color, mtype) \
(*(page_cachelists[mtype] + (color)))
#define NPC_MUTEX 16
extern kmutex_t *fpc_mutex[NPC_MUTEX];
extern kmutex_t *cpc_mutex[NPC_MUTEX];
extern page_t *page_get_mnode_freelist(int, uint_t, int, uchar_t, uint_t);
extern page_t *page_get_mnode_cachelist(uint_t, uint_t, int, int);
#define MEM_NODE_ITERATOR_DECL(it)
#define MEM_NODE_ITERATOR_INIT(pfn, mnode, szc, it)
#define HPM_COUNTERS_LIMITS(mnode, physbase, physmax, first) \
{ \
(physbase) = mem_node_config[(mnode)].physbase; \
(physmax) = mem_node_config[(mnode)].physmax; \
(first) = (mnode); \
}
#define PAGE_CTRS_WRITE_LOCK(mnode) \
{ \
rw_enter(&page_ctrs_rwlock[(mnode)], RW_WRITER);\
page_freelist_lock(mnode); \
}
#define PAGE_CTRS_WRITE_UNLOCK(mnode) \
{ \
page_freelist_unlock(mnode); \
rw_exit(&page_ctrs_rwlock[(mnode)]); \
}
#define PAGE_CTRS_ADJUST(pfn, cnt, rv) { \
spgcnt_t _cnt = (spgcnt_t)(cnt); \
int _mn; \
pgcnt_t _np; \
pfn_t _pfn = (pfn); \
pfn_t _endpfn = _pfn + _cnt; \
rv = 0; \
while (_pfn < _endpfn) { \
_mn = PFN_2_MEM_NODE(_pfn); \
_np = MIN(_endpfn, mem_node_config[_mn].physmax + 1) - _pfn; \
_pfn += _np; \
if ((rv = page_ctrs_adjust(_mn)) != 0) \
break; \
} \
}
#define PAGE_GET_COLOR_SHIFT(szc, nszc) \
(hw_page_array[(nszc)].hp_shift - hw_page_array[(szc)].hp_shift)
#define PAGE_CONVERT_COLOR(ncolor, szc, nszc) \
((ncolor) << PAGE_GET_COLOR_SHIFT((szc), (nszc)))
#define PFN_2_COLOR(pfn, szc, it) \
(((pfn) & page_colors_mask) >> \
(hw_page_array[szc].hp_shift - hw_page_array[0].hp_shift))
#define PNUM_SIZE(szc) \
(hw_page_array[(szc)].hp_pgcnt)
#define PNUM_SHIFT(szc) \
(hw_page_array[(szc)].hp_shift - hw_page_array[0].hp_shift)
#define PAGE_GET_SHIFT(szc) \
(hw_page_array[(szc)].hp_shift)
#define PAGE_GET_PAGECOLORS(szc) \
(hw_page_array[(szc)].hp_colors)
#define PAGE_NEXT_PFN_FOR_COLOR(pfn, szc, color, ceq_mask, color_mask, it) \
{ \
uint_t pfn_shift = PAGE_BSZS_SHIFT(szc); \
pfn_t spfn = pfn >> pfn_shift; \
pfn_t stride = (ceq_mask) + 1; \
ASSERT(((color) & ~(ceq_mask)) == 0); \
ASSERT((((ceq_mask) + 1) & (ceq_mask)) == 0); \
if (((spfn ^ (color)) & (ceq_mask)) == 0) { \
pfn += stride << pfn_shift; \
} else { \
pfn = (spfn & ~(pfn_t)(ceq_mask)) | (color); \
pfn = (pfn > spfn ? pfn : pfn + stride) << pfn_shift; \
} \
}
#define PAGE_GET_NSZ_MASK(szc, mask) \
((mask) >> (PAGE_GET_SHIFT((szc) + 1) - PAGE_GET_SHIFT(szc)))
#define PAGE_GET_NSZ_COLOR(szc, color) \
((color) >> (PAGE_GET_SHIFT((szc) + 1) - PAGE_GET_SHIFT(szc)))
#define PP_2_BIN_SZC(pp, szc) (PFN_2_COLOR(pp->p_pagenum, szc, NULL))
#define PP_2_BIN(pp) (PP_2_BIN_SZC(pp, pp->p_szc))
#define PP_2_MEM_NODE(pp) (PFN_2_MEM_NODE(pp->p_pagenum))
#define PP_2_MTYPE(pp) (pfn_2_mtype(pp->p_pagenum))
#define PP_2_SZC(pp) (pp->p_szc)
#define SZCPAGES(szc) (1 << PAGE_BSZS_SHIFT(szc))
#define PFN_BASE(pfnum, szc) (pfnum & ~(SZCPAGES(szc) - 1))
typedef struct page_list_walker {
uint_t plw_colors;
uint_t plw_color_mask;
uint_t plw_bin_step;
uint_t plw_count;
uint_t plw_bin0;
uint_t plw_bin_marker;
uint_t plw_bin_split_prev;
uint_t plw_do_split;
uint_t plw_split_next;
uint_t plw_ceq_dif;
uint_t plw_ceq_mask[MMU_PAGE_SIZES + 1];
uint_t plw_bins[MMU_PAGE_SIZES + 1];
} page_list_walker_t;
void page_list_walk_init(uchar_t szc, uint_t flags, uint_t bin,
int can_split, int use_ceq, page_list_walker_t *plw);
uint_t page_list_walk_next_bin(uchar_t szc, uint_t bin,
page_list_walker_t *plw);
extern struct cpu cpus[];
#define CPU0 cpus
extern int mtype_init(vnode_t *, caddr_t, uint_t *, size_t);
#define MTYPE_INIT(mtype, vp, vaddr, flags, pgsz) \
(mtype = mtype_init(vp, vaddr, &(flags), pgsz))
#define MTYPE_START(mnode, mtype, flags) \
(mtype = mtype_func(mnode, mtype, flags))
#define MTYPE_NEXT(mnode, mtype, flags) { \
if (flags & PGI_MT_RANGE) { \
mtype = mtype_func(mnode, mtype, flags | PGI_MT_NEXT); \
} else { \
mtype = -1; \
} \
}
extern int mtype_pgr_init(int *, page_t *, pgcnt_t);
#define MTYPE_PGR_INIT(mtype, flags, pp, pgcnt) \
(mtype = mtype_pgr_init(&flags, pp, pgcnt))
#define MNODE_PGCNT(mnode) mnode_pgcnt(mnode)
extern void mnodetype_2_pfn(int, int, pfn_t *, pfn_t *);
#define MNODETYPE_2_PFN(mnode, mtype, pfnlo, pfnhi) \
mnodetype_2_pfn(mnode, mtype, &pfnlo, &pfnhi)
#define PC_BIN_MUTEX(mnode, bin, flags) ((flags & PG_FREE_LIST) ? \
&fpc_mutex[(bin) & (NPC_MUTEX - 1)][mnode] : \
&cpc_mutex[(bin) & (NPC_MUTEX - 1)][mnode])
#define FPC_MUTEX(mnode, i) (&fpc_mutex[i][mnode])
#define CPC_MUTEX(mnode, i) (&cpc_mutex[i][mnode])
#ifdef DEBUG
#define CHK_LPG(pp, szc) chk_lpg(pp, szc)
extern void chk_lpg(page_t *, uchar_t);
#else
#define CHK_LPG(pp, szc)
#endif
#define FULL_REGION_CNT(rg_szc) \
(LEVEL_SIZE(rg_szc) >> LEVEL_SHIFT(rg_szc - 1))
#define PP_GROUPLEADER(pp, szc) \
(&(pp)[-(int)((pp)->p_pagenum & (SZCPAGES(szc)-1))])
#define PP_PAGEROOT(pp) ((pp)->p_szc == 0 ? (pp) : \
PP_GROUPLEADER((pp), (pp)->p_szc))
#define PC_BASE_ALIGN ((pfn_t)1 << PAGE_BSZS_SHIFT(MMU_PAGE_SIZES-1))
#define PC_BASE_ALIGN_MASK (PC_BASE_ALIGN - 1)
extern uint_t mmu_page_sizes;
extern uint_t mmu_exported_page_sizes;
extern uint_t mmu_legacy_page_sizes;
#define USERSZC_2_SZC(userszc) (userszc)
#define SZC_2_USERSZC(szc) (szc)
typedef short hpmctr_t;
extern int l2cache_sz, l2cache_linesz, l2cache_assoc;
#define L2CACHE_ALIGN l2cache_linesz
#define L2CACHE_ALIGN_MAX 64
#define CPUSETSIZE() \
(l2cache_assoc ? (l2cache_sz / l2cache_assoc) : MMU_PAGESIZE)
#define PAGE_BSZS_SHIFT(szc) (LEVEL_SHIFT(szc) - MMU_PAGESHIFT)
#define PGI_RELOCONLY 0x010000
#define PGI_NOCAGE 0x020000
#define PGI_PGCPHIPRI 0x040000
#define PGI_PGCPSZC0 0x080000
#define PGI_MT_RANGE0 0x1000000
#define PGI_MT_RANGE16M 0x2000000
#define PGI_MT_RANGE4G 0x4000000
#define PGI_MT_NEXT 0x8000000
#define PGI_MT_RANGE (PGI_MT_RANGE0 | PGI_MT_RANGE16M | PGI_MT_RANGE4G)
extern size_t max_uheap_lpsize;
extern size_t default_uheap_lpsize;
extern size_t max_ustack_lpsize;
extern size_t default_ustack_lpsize;
extern size_t max_privmap_lpsize;
extern size_t max_uidata_lpsize;
extern size_t max_utext_lpsize;
extern size_t max_shm_lpsize;
extern size_t mcntl0_lpsize;
extern pgcnt_t privm_lpg_min_physmem;
extern pgcnt_t shm_lpg_min_physmem;
#define AS_2_BIN(as, seg, vp, addr, bin, szc) \
bin = (((((uintptr_t)(addr) >> PAGESHIFT) + ((uintptr_t)(as) >> 4)) \
& page_colors_mask) >> \
(hw_page_array[szc].hp_shift - hw_page_array[0].hp_shift))
typedef struct {
struct memseg *vc_pnum_memseg;
struct memseg *vc_pnext_memseg;
void *vc_kmptr;
size_t vc_kmsize;
} vm_cpu_data_t;
#define VM_CPU_DATA_PADSIZE \
(P2ROUNDUP(sizeof (vm_cpu_data_t), L2CACHE_ALIGN_MAX))
#define BIN_STEP 19
#ifdef VM_STATS
struct vmm_vmstats_str {
ulong_t pgf_alloc[MMU_PAGE_SIZES];
ulong_t pgf_allocok[MMU_PAGE_SIZES];
ulong_t pgf_allocokrem[MMU_PAGE_SIZES];
ulong_t pgf_allocfailed[MMU_PAGE_SIZES];
ulong_t pgf_allocdeferred;
ulong_t pgf_allocretry[MMU_PAGE_SIZES];
ulong_t pgc_alloc;
ulong_t pgc_allocok;
ulong_t pgc_allocokrem;
ulong_t pgc_allocokdeferred;
ulong_t pgc_allocfailed;
ulong_t pgcp_alloc[MMU_PAGE_SIZES];
ulong_t pgcp_allocfailed[MMU_PAGE_SIZES];
ulong_t pgcp_allocempty[MMU_PAGE_SIZES];
ulong_t pgcp_allocok[MMU_PAGE_SIZES];
ulong_t ptcp[MMU_PAGE_SIZES];
ulong_t ptcpfreethresh[MMU_PAGE_SIZES];
ulong_t ptcpfailexcl[MMU_PAGE_SIZES];
ulong_t ptcpfailszc[MMU_PAGE_SIZES];
ulong_t ptcpfailcage[MMU_PAGE_SIZES];
ulong_t ptcpok[MMU_PAGE_SIZES];
ulong_t pgmf_alloc[MMU_PAGE_SIZES];
ulong_t pgmf_allocfailed[MMU_PAGE_SIZES];
ulong_t pgmf_allocempty[MMU_PAGE_SIZES];
ulong_t pgmf_allocok[MMU_PAGE_SIZES];
ulong_t pgmc_alloc;
ulong_t pgmc_allocfailed;
ulong_t pgmc_allocempty;
ulong_t pgmc_allocok;
ulong_t pladd_free[MMU_PAGE_SIZES];
ulong_t plsub_free[MMU_PAGE_SIZES];
ulong_t pladd_cache;
ulong_t plsub_cache;
ulong_t plsubpages_szcbig;
ulong_t plsubpages_szc0;
ulong_t pfs_req[MMU_PAGE_SIZES];
ulong_t pfs_demote[MMU_PAGE_SIZES];
ulong_t pfc_coalok[MMU_PAGE_SIZES][MAX_MNODE_MRANGES];
ulong_t ppr_reloc[MMU_PAGE_SIZES];
ulong_t ppr_relocnoroot[MMU_PAGE_SIZES];
ulong_t ppr_reloc_replnoroot[MMU_PAGE_SIZES];
ulong_t ppr_relocnolock[MMU_PAGE_SIZES];
ulong_t ppr_relocnomem[MMU_PAGE_SIZES];
ulong_t ppr_relocok[MMU_PAGE_SIZES];
ulong_t ppr_copyfail;
ulong_t page_ctrs_coalesce[MMU_PAGE_SIZES][MAX_MNODE_MRANGES];
ulong_t page_ctrs_cands_skip[MMU_PAGE_SIZES][MAX_MNODE_MRANGES];
ulong_t page_ctrs_changed[MMU_PAGE_SIZES][MAX_MNODE_MRANGES];
ulong_t page_ctrs_failed[MMU_PAGE_SIZES][MAX_MNODE_MRANGES];
ulong_t page_ctrs_coalesce_all;
ulong_t page_ctrs_cands_skip_all;
ulong_t restrict4gcnt;
ulong_t unrestrict16mcnt;
ulong_t pgpanicalloc;
ulong_t pcf_deny[MMU_PAGE_SIZES];
ulong_t pcf_allow[MMU_PAGE_SIZES];
};
extern struct vmm_vmstats_str vmm_vmstats;
#endif
extern size_t page_ctrs_sz(void);
extern caddr_t page_ctrs_alloc(caddr_t);
extern void page_ctr_sub(int, int, page_t *, int);
extern page_t *page_freelist_split(uchar_t,
uint_t, int, int, pfn_t, pfn_t, page_list_walker_t *);
extern page_t *page_freelist_coalesce(int, uchar_t, uint_t, uint_t, int,
pfn_t);
extern void page_freelist_coalesce_all(int);
extern uint_t page_get_pagecolors(uint_t);
extern void pfnzero(pfn_t, uint_t, uint_t);
#ifdef __cplusplus
}
#endif
#endif