#ifndef _VM_SEG_H
#define _VM_SEG_H
#include <sys/vnode.h>
#include <sys/avl.h>
#include <vm/seg_enum.h>
#include <vm/faultcode.h>
#include <vm/hat.h>
#ifdef __cplusplus
extern "C" {
#endif
struct anon_map;
typedef struct {
kstat_named_t MADV_FREE_hit;
kstat_named_t MADV_FREE_miss;
} segadvstat_t;
typedef struct memid { u_longlong_t val[2]; } memid_t;
typedef struct pcache_link {
struct pcache_link *p_lnext;
struct pcache_link *p_lprev;
} pcache_link_t;
typedef struct seg {
caddr_t s_base;
size_t s_size;
uint_t s_szc;
uint_t s_flags;
struct as *s_as;
avl_node_t s_tree;
struct seg_ops *s_ops;
void *s_data;
kmutex_t s_pmtx;
pcache_link_t s_phead;
} seg_t;
#define S_PURGE (0x01)
#define S_HOLE (0x02)
struct seg_ops {
int (*dup)(struct seg *, struct seg *);
int (*unmap)(struct seg *, caddr_t, size_t);
void (*free)(struct seg *);
faultcode_t (*fault)(struct hat *, struct seg *, caddr_t, size_t,
enum fault_type, enum seg_rw);
faultcode_t (*faulta)(struct seg *, caddr_t);
int (*setprot)(struct seg *, caddr_t, size_t, uint_t);
int (*checkprot)(struct seg *, caddr_t, size_t, uint_t);
int (*kluster)(struct seg *, caddr_t, ssize_t);
size_t (*swapout)(struct seg *);
int (*sync)(struct seg *, caddr_t, size_t, int, uint_t);
size_t (*incore)(struct seg *, caddr_t, size_t, char *);
int (*lockop)(struct seg *, caddr_t, size_t, int, int, ulong_t *,
size_t);
int (*getprot)(struct seg *, caddr_t, size_t, uint_t *);
u_offset_t (*getoffset)(struct seg *, caddr_t);
int (*gettype)(struct seg *, caddr_t);
int (*getvp)(struct seg *, caddr_t, struct vnode **);
int (*advise)(struct seg *, caddr_t, size_t, uint_t);
void (*dump)(struct seg *);
int (*pagelock)(struct seg *, caddr_t, size_t, struct page ***,
enum lock_type, enum seg_rw);
int (*setpagesize)(struct seg *, caddr_t, size_t, uint_t);
int (*getmemid)(struct seg *, caddr_t, memid_t *);
struct lgrp_mem_policy_info *(*getpolicy)(struct seg *, caddr_t);
int (*capable)(struct seg *, segcapability_t);
int (*inherit)(struct seg *, caddr_t, size_t, uint_t);
};
#ifdef _KERNEL
extern void seg_init(void);
extern struct seg *seg_alloc(struct as *as, caddr_t base, size_t size);
extern int seg_attach(struct as *as, caddr_t base, size_t size,
struct seg *seg);
extern void seg_unmap(struct seg *seg);
extern void seg_free(struct seg *seg);
typedef int (*seg_preclaim_cbfunc_t)(void *, caddr_t, size_t,
struct page **, enum seg_rw, int);
extern struct page **seg_plookup(struct seg *seg, struct anon_map *amp,
caddr_t addr, size_t len, enum seg_rw rw, uint_t flags);
extern void seg_pinactive(struct seg *seg, struct anon_map *amp,
caddr_t addr, size_t len, struct page **pp, enum seg_rw rw,
uint_t flags, seg_preclaim_cbfunc_t callback);
extern void seg_ppurge(struct seg *seg, struct anon_map *amp,
uint_t flags);
extern void seg_ppurge_wiredpp(struct page **pp);
extern int seg_pinsert_check(struct seg *seg, struct anon_map *amp,
caddr_t addr, size_t len, uint_t flags);
extern int seg_pinsert(struct seg *seg, struct anon_map *amp,
caddr_t addr, size_t len, size_t wlen, struct page **pp, enum seg_rw rw,
uint_t flags, seg_preclaim_cbfunc_t callback);
extern void seg_pasync_thread(void);
extern void seg_preap(void);
extern int seg_p_disable(void);
extern void seg_p_enable(void);
extern segadvstat_t segadvstat;
#define SEGP_FORCE_WIRED 0x1
#define SEGP_AMP 0x2
#define SEGP_PSHIFT 0x4
#define SEGP_SUCCESS 0
#define SEGP_FAIL 1
#define SEG_PAGE_INCORE 0x01
#define SEG_PAGE_LOCKED 0x02
#define SEG_PAGE_HASCOW 0x04
#define SEG_PAGE_SOFTLOCK 0x08
#define SEG_PAGE_VNODEBACKED 0x10
#define SEG_PAGE_ANON 0x20
#define SEG_PAGE_VNODE 0x40
#define SEGOP_DUP(s, n) (*(s)->s_ops->dup)((s), (n))
#define SEGOP_UNMAP(s, a, l) (*(s)->s_ops->unmap)((s), (a), (l))
#define SEGOP_FREE(s) (*(s)->s_ops->free)((s))
#define SEGOP_FAULT(h, s, a, l, t, rw) \
(*(s)->s_ops->fault)((h), (s), (a), (l), (t), (rw))
#define SEGOP_FAULTA(s, a) (*(s)->s_ops->faulta)((s), (a))
#define SEGOP_SETPROT(s, a, l, p) (*(s)->s_ops->setprot)((s), (a), (l), (p))
#define SEGOP_CHECKPROT(s, a, l, p) (*(s)->s_ops->checkprot)((s), (a), (l), (p))
#define SEGOP_KLUSTER(s, a, d) (*(s)->s_ops->kluster)((s), (a), (d))
#define SEGOP_SWAPOUT(s) (*(s)->s_ops->swapout)((s))
#define SEGOP_SYNC(s, a, l, atr, f) \
(*(s)->s_ops->sync)((s), (a), (l), (atr), (f))
#define SEGOP_INCORE(s, a, l, v) (*(s)->s_ops->incore)((s), (a), (l), (v))
#define SEGOP_LOCKOP(s, a, l, atr, op, b, p) \
(*(s)->s_ops->lockop)((s), (a), (l), (atr), (op), (b), (p))
#define SEGOP_GETPROT(s, a, l, p) (*(s)->s_ops->getprot)((s), (a), (l), (p))
#define SEGOP_GETOFFSET(s, a) (*(s)->s_ops->getoffset)((s), (a))
#define SEGOP_GETTYPE(s, a) (*(s)->s_ops->gettype)((s), (a))
#define SEGOP_GETVP(s, a, vpp) (*(s)->s_ops->getvp)((s), (a), (vpp))
#define SEGOP_ADVISE(s, a, l, b) (*(s)->s_ops->advise)((s), (a), (l), (b))
#define SEGOP_DUMP(s) (*(s)->s_ops->dump)((s))
#define SEGOP_PAGELOCK(s, a, l, p, t, rw) \
(*(s)->s_ops->pagelock)((s), (a), (l), (p), (t), (rw))
#define SEGOP_SETPAGESIZE(s, a, l, szc) \
(*(s)->s_ops->setpagesize)((s), (a), (l), (szc))
#define SEGOP_GETMEMID(s, a, mp) (*(s)->s_ops->getmemid)((s), (a), (mp))
#define SEGOP_GETPOLICY(s, a) (*(s)->s_ops->getpolicy)((s), (a))
#define SEGOP_CAPABLE(s, c) (*(s)->s_ops->capable)((s), (c))
#define SEGOP_INHERIT(s, a, l, b) (*(s)->s_ops->inherit)((s), (a), (l), (b))
#define seg_page(seg, addr) \
(((uintptr_t)((addr) - (seg)->s_base)) >> PAGESHIFT)
#define seg_pages(seg) \
(((uintptr_t)((seg)->s_size + PAGEOFFSET)) >> PAGESHIFT)
#define IE_NOMEM -1
#define IE_RETRY -2
#define IE_REATTACH -3
#define SEGP_INH_ZERO 0x01
int seg_inherit_notsup(struct seg *, caddr_t, size_t, uint_t);
#define SEGP_PREDEL_DELAY_FACTOR 4
#define SEGP_STALL_SECONDS 25
#define SEGP_STALL_THRESHOLD \
(SEGP_STALL_SECONDS * SEGP_PREDEL_DELAY_FACTOR)
#ifdef VMDEBUG
uint_t seg_page(struct seg *, caddr_t);
uint_t seg_pages(struct seg *);
#endif
boolean_t seg_can_change_zones(struct seg *);
size_t seg_swresv(struct seg *);
#endif
#ifdef __cplusplus
}
#endif
#endif