Lines Matching refs:seg

67 #include <vm/seg.h>
100 * Private seg op routines.
102 static int segvn_dup(struct seg *seg, struct seg *newseg);
103 static int segvn_unmap(struct seg *seg, caddr_t addr, size_t len);
104 static void segvn_free(struct seg *seg);
105 static faultcode_t segvn_fault(struct hat *hat, struct seg *seg,
108 static faultcode_t segvn_faulta(struct seg *seg, caddr_t addr);
109 static int segvn_setprot(struct seg *seg, caddr_t addr,
111 static int segvn_checkprot(struct seg *seg, caddr_t addr,
113 static int segvn_kluster(struct seg *seg, caddr_t addr, ssize_t delta);
114 static size_t segvn_swapout(struct seg *seg);
115 static int segvn_sync(struct seg *seg, caddr_t addr, size_t len,
117 static size_t segvn_incore(struct seg *seg, caddr_t addr, size_t len,
119 static int segvn_lockop(struct seg *seg, caddr_t addr, size_t len,
121 static int segvn_getprot(struct seg *seg, caddr_t addr, size_t len,
123 static u_offset_t segvn_getoffset(struct seg *seg, caddr_t addr);
124 static int segvn_gettype(struct seg *seg, caddr_t addr);
125 static int segvn_getvp(struct seg *seg, caddr_t addr,
127 static int segvn_advise(struct seg *seg, caddr_t addr, size_t len,
129 static void segvn_dump(struct seg *seg);
130 static int segvn_pagelock(struct seg *seg, caddr_t addr, size_t len,
132 static int segvn_setpagesize(struct seg *seg, caddr_t addr, size_t len,
134 static int segvn_getmemid(struct seg *seg, caddr_t addr,
136 static lgrp_mem_policy_info_t *segvn_getpolicy(struct seg *, caddr_t);
137 static int segvn_capable(struct seg *seg, segcapability_t capable);
138 static int segvn_inherit(struct seg *, caddr_t, size_t, uint_t);
192 static int segvn_concat(struct seg *, struct seg *, int);
193 static int segvn_extend_prev(struct seg *, struct seg *,
195 static int segvn_extend_next(struct seg *, struct seg *,
197 static void segvn_softunlock(struct seg *, caddr_t, size_t, enum seg_rw);
204 static faultcode_t segvn_fault_vnodepages(struct hat *, struct seg *, caddr_t,
206 static faultcode_t segvn_fault_anonpages(struct hat *, struct seg *, caddr_t,
208 static faultcode_t segvn_faultpage(struct hat *, struct seg *, caddr_t,
211 static void segvn_vpage(struct seg *);
212 static size_t segvn_count_swap_by_vpages(struct seg *);
214 static void segvn_purge(struct seg *seg);
220 static int sameprot(struct seg *, caddr_t, size_t);
222 static int segvn_demote_range(struct seg *, caddr_t, size_t, int, uint_t);
223 static int segvn_clrszc(struct seg *);
224 static struct seg *segvn_split_seg(struct seg *, caddr_t);
225 static int segvn_claim_pages(struct seg *, struct vpage *, u_offset_t,
249 #define CALC_LPG_REGION(pgsz, seg, addr, len, lpgaddr, lpgeaddr) { \
252 ASSERT(lpgaddr >= (seg)->s_base); \
256 ASSERT(lpgeaddr <= (seg)->s_base + (seg)->s_size); \
397 static void segvn_textrepl(struct seg *);
398 static void segvn_textunrepl(struct seg *, int);
403 static void segvn_trupdate_seg(struct seg *, segvn_data_t *, svntr_t *,
541 segvn_create(struct seg *seg, void *argsp)
554 ASSERT(seg->s_as && AS_WRITE_HELD(seg->s_as));
583 (a->flags & MAP_NORESERVE) || seg->s_as == &kas) {
589 if (!IS_P2ALIGNED(seg->s_base, pgsz) ||
590 !IS_P2ALIGNED(seg->s_size, pgsz)) {
600 } else if (map_addr_vacalign_check(seg->s_base,
619 if (anon_resv_zone(seg->s_size,
620 seg->s_as->a_proc->p_zone) == 0)
622 swresv = seg->s_size;
624 seg, swresv, 1);
634 hat_map(seg->s_as->a_hat, seg->s_base, seg->s_size, HAT_MAP);
647 seg->s_as, seg->s_base, seg->s_size, a->prot,
652 seg->s_as->a_proc->p_zone);
654 "anon proc:%p %lu %u", seg, swresv, 0);
658 hat_unload(seg->s_as->a_hat, seg->s_base,
659 seg->s_size, HAT_UNLOAD_UNMAP);
667 (seg->s_size > textrepl_size_thresh ||
672 seg->s_as != &kas && a->vp->v_type == VREG);
683 seg->s_as->a_resvsize -= seg->s_size;
693 struct seg *pseg, *nseg;
704 !(a->flags & MAP_NORESERVE) && (seg->s_as != &kas)) {
710 mpolicy = lgrp_mem_policy_default(seg->s_size, a->type);
716 pseg = AS_SEGPREV(seg->s_as, seg);
718 pseg->s_base + pseg->s_size == seg->s_base &&
736 pseg->s_size + seg->s_size,
742 (pseg->s_size + seg->s_size <=
744 segvn_extend_prev(pseg, seg, a, swresv) == 0) {
747 * with following seg
766 * Failed, so try to concatenate with following seg
768 nseg = AS_SEGNEXT(seg->s_as, seg);
770 seg->s_base + seg->s_size == nseg->s_base &&
788 nseg->s_size + seg->s_size,
794 segvn_extend_next(seg, nseg, a, swresv) == 0) {
812 seg->s_ops = &segvn_ops;
813 seg->s_data = (void *)svd;
814 seg->s_szc = a->szc;
816 svd->seg = seg;
860 svd->amp = anonmap_alloc(seg->s_size, swresv,
862 svd->amp->a_szc = seg->s_szc;
884 if ((amp->size - a->offset) < seg->s_size) {
923 svd->amp = anonmap_alloc(seg->s_size, 0, ANON_SLEEP);
924 svd->amp->a_szc = seg->s_szc;
933 eaddr = seg->s_base + seg->s_size;
935 for (anon_idx = anon_num, addr = seg->s_base;
948 pp = anon_zero(seg, addr, &ap, cred);
963 ASSERT(seg->s_szc == 0);
967 hat_memload(seg->s_as->a_hat, addr, pp,
972 ASSERT(seg->s_szc == 0);
974 0, seg->s_size);
985 (void) lgrp_privm_policy_set(mpolicy, &svd->policy_info, seg->s_size);
989 svd->vp, svd->offset, seg->s_size);
994 svd->rcookie = hat_join_region(seg->s_as->a_hat, seg->s_base,
995 seg->s_size, (void *)svd->vp, svd->offset, svd->prot,
996 (uchar_t)seg->s_szc, segvn_hat_rgn_unload_callback,
1013 segvn_concat(struct seg *seg1, struct seg *seg2, int amp_cat)
1079 * If either seg has vpages, create a new merged vpage array.
1257 struct seg *seg1, *seg2;
1377 struct seg *seg1,
1378 struct seg *seg2,
1499 segvn_dup_pages(struct seg *seg, struct seg *newseg)
1508 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
1513 i = btopr(seg->s_size);
1514 addr = seg->s_base;
1525 vpp = &svd->vpage[seg_page(seg, addr)];
1546 PAGESIZE, seg, addr, S_READ, svd->cred);
1569 segvn_dup(struct seg *seg, struct seg *newseg)
1571 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
1573 pgcnt_t npages = seg_pages(seg);
1578 ASSERT(seg->s_as && AS_WRITE_HELD(seg->s_as));
1582 * If segment has anon reserved, reserve more for the new seg.
1594 seg, len, 0);
1601 newseg->s_szc = seg->s_szc;
1603 newsvd->seg = newseg;
1710 segvn_purge(seg);
1715 error = segvn_dup_pages(seg, newseg);
1721 if (seg->s_szc != 0) {
1731 0, seg->s_size, seg->s_szc,
1735 newsvd->amp->ahp, 0, seg->s_size);
1738 hat_clrattr(seg->s_as->a_hat, seg->s_base,
1739 seg->s_size, PROT_WRITE);
1815 struct seg *seg = cb->hcb_data;
1816 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
1822 ASSERT(cb->hcb_start_addr >= seg->s_base);
1825 off = cb->hcb_start_addr - seg->s_base;
1835 segvn_count_swap_by_vpages(struct seg *seg)
1837 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
1844 evp = &svd->vpage[seg_page(seg, seg->s_base + seg->s_size)];
1855 segvn_unmap(struct seg *seg, caddr_t addr, size_t len)
1857 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
1859 struct seg *nseg;
1875 ASSERT(seg->s_as && AS_WRITE_HELD(seg->s_as));
1899 segvn_purge(seg);
1909 if (addr < seg->s_base || addr + len > seg->s_base + seg->s_size ||
1915 if (seg->s_szc != 0) {
1916 size_t pgsz = page_get_pagesize(seg->s_szc);
1919 ASSERT(seg->s_base != addr || seg->s_size != len);
1923 hat_leave_region(seg->s_as->a_hat,
1936 segvn_textunrepl(seg, 1);
1941 err = segvn_demote_range(seg, addr, len, SDR_END, 0);
1954 (offset_t)svd->offset + (uintptr_t)(addr - seg->s_base),
1955 seg->s_as, addr, len, svd->prot, svd->maxprot,
1968 (void) segvn_lockop(seg, addr, len, 0, MC_UNLOCK, NULL, 0);
1975 hat_leave_region(seg->s_as->a_hat, svd->rcookie,
1981 segvn_textunrepl(seg, 1);
1993 callback.hcb_data = seg;
1997 hat_unload_callback(seg->s_as->a_hat, addr, len,
2010 if (addr == seg->s_base && len == seg->s_size) {
2011 seg_free(seg);
2015 opages = seg_pages(seg);
2019 ASSERT(amp == NULL || amp->a_szc >= seg->s_szc);
2024 if (addr == seg->s_base) {
2054 if (amp->a_szc == seg->s_szc) {
2055 if (seg->s_szc != 0) {
2058 seg->s_szc);
2066 ASSERT(amp->a_szc > seg->s_szc);
2078 seg->s_as->a_proc->p_zone);
2088 seg->s_base += len;
2089 seg->s_size -= len;
2099 seg->s_as->a_proc->p_zone);
2100 if (SEG_IS_PARTIAL_RESV(seg))
2101 seg->s_as->a_resvsize -= oswresv -
2109 segvn_count_swap_by_vpages(seg);
2114 ASSERT(svd->swresv == seg->s_size);
2118 seg->s_as->a_proc->p_zone);
2121 seg, len, 0);
2130 if (addr + len == seg->s_base + seg->s_size) {
2164 if (amp->a_szc == seg->s_szc) {
2165 if (seg->s_szc != 0) {
2168 seg->s_szc);
2175 ASSERT(amp->a_szc > seg->s_szc);
2187 seg->s_as->a_proc->p_zone);
2194 seg->s_size -= len;
2203 seg->s_as->a_proc->p_zone);
2204 if (SEG_IS_PARTIAL_RESV(seg))
2205 seg->s_as->a_resvsize -= oswresv -
2213 segvn_count_swap_by_vpages(seg);
2218 ASSERT(svd->swresv == seg->s_size);
2222 seg->s_as->a_proc->p_zone);
2225 "anon proc:%p %lu %u", seg, len, 0);
2234 * the high end while seg is cut down at the low end.
2236 nbase = addr + len; /* new seg base */
2237 nsize = (seg->s_base + seg->s_size) - nbase; /* new seg size */
2238 seg->s_size = addr - seg->s_base; /* shrink old seg */
2239 nseg = seg_alloc(seg->s_as, nbase, nsize);
2244 nseg->s_ops = seg->s_ops;
2247 nseg->s_szc = seg->s_szc;
2249 nsvd->seg = nseg;
2250 nsvd->offset = svd->offset + (uintptr_t)(nseg->s_base - seg->s_base);
2274 npages = seg_pages(seg); /* seg has shrunk */
2299 opages = btop((uintptr_t)(addr - seg->s_base));
2318 if (amp->a_szc == seg->s_szc) {
2319 if (seg->s_szc != 0) {
2321 seg->s_szc);
2328 ASSERT(amp->a_szc > seg->s_szc);
2339 seg->s_as->a_proc->p_zone);
2344 btop((uintptr_t)(nseg->s_base - seg->s_base));
2353 nahp = anon_create(btop(seg->s_size), ANON_SLEEP);
2355 namp->a_szc = seg->s_szc;
2357 0, btop(seg->s_size), ANON_SLEEP);
2364 amp->size = seg->s_size;
2374 svd->anon_index, btop(seg->s_size)));
2379 seg->s_as->a_proc->p_zone);
2380 if (SEG_IS_PARTIAL_RESV(seg))
2381 seg->s_as->a_resvsize -= oswresv -
2388 svd->swresv = segvn_count_swap_by_vpages(seg);
2393 if (seg->s_size + nseg->s_size + len !=
2399 svd->swresv = seg->s_size;
2404 seg->s_as->a_proc->p_zone);
2407 seg, len, 0);
2414 segvn_free(struct seg *seg)
2416 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
2417 pgcnt_t npages = seg_pages(seg);
2425 ASSERT(seg->s_as && AS_WRITE_HELD(seg->s_as));
2434 (void) segvn_lockop(seg, seg->s_base, seg->s_size,
2451 ASSERT(amp->a_szc >= seg->s_szc);
2458 if (seg->s_szc != 0) {
2460 svd->anon_index, seg->s_size,
2461 seg->s_szc);
2464 seg->s_size);
2489 seg->s_as->a_proc->p_zone);
2491 "anon proc:%p %lu %u", seg, len, 0);
2503 if (seg->s_szc != 0) {
2505 seg->s_size, seg->s_szc);
2508 seg->s_size);
2521 seg->s_as->a_proc->p_zone);
2523 seg, len, 0);
2524 if (SEG_IS_PARTIAL_RESV(seg))
2525 seg->s_as->a_resvsize -= svd->swresv;
2553 seg->s_data = NULL;
2564 segvn_softunlock(struct seg *seg, caddr_t addr, size_t len, enum seg_rw rw)
2566 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
2575 ASSERT(seg->s_as && AS_LOCK_HELD(seg->s_as));
2576 ASSERT(SEGVN_LOCK_HELD(seg->s_as, &svd->lock));
2579 anon_index = svd->anon_index + seg_page(seg, addr);
2583 hat_unlock_region(seg->s_as->a_hat, addr, len, svd->rcookie);
2585 hat_unlock(seg->s_as->a_hat, addr, len);
2596 (uintptr_t)(adr - seg->s_base);
2602 (uintptr_t)(adr - seg->s_base);
2619 if (seg->s_as->a_vbits)
2620 hat_setstat(seg->s_as, adr, PAGESIZE,
2624 if (seg->s_as->a_vbits)
2625 hat_setstat(seg->s_as, adr, PAGESIZE, P_REF);
2640 if (AS_ISUNMAPWAIT(seg->s_as)) {
2641 mutex_enter(&seg->s_as->a_contents);
2642 if (AS_ISUNMAPWAIT(seg->s_as)) {
2643 AS_CLRUNMAPWAIT(seg->s_as);
2644 cv_broadcast(&seg->s_as->a_cv);
2646 mutex_exit(&seg->s_as->a_contents);
2702 struct seg *seg, /* seg_vn of interest */
2712 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
2733 ASSERT(SEGVN_READ_HELD(seg->s_as, &svd->lock));
2734 ASSERT(seg->s_szc == 0);
2778 anon_index = svd->anon_index + seg_page(seg, addr);
2791 seg->s_as->a_proc->p_zone)) {
2793 atomic_add_long(&seg->s_as->a_resvsize,
2800 if ((pp = anon_zero(seg, addr, &ap,
2818 page_migrate(seg, addr, &pp, 1);
2860 if (AS_ISPGLCK(seg->s_as) && vpage != NULL &&
2863 proc_t *p = seg->s_as->a_proc;
2898 seg, addr, rw, svd->cred);
2977 page_migrate(seg, addr, &opp, 1);
3038 hat_unload(seg->s_as->a_hat, addr, PAGESIZE,
3069 if (anon_resv_zone(ptob(1), seg->s_as->a_proc->p_zone)) {
3071 atomic_add_long(&seg->s_as->a_resvsize, ptob(1));
3079 pp = anon_private(&ap, seg, addr, prot, opp, pageflags, svd->cred);
3103 page_migrate(seg, addr, &pp, 1);
3824 segvn_fault_vnodepages(struct hat *hat, struct seg *seg, caddr_t lpgaddr,
3828 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
3831 uint_t szc = seg->s_szc;
3839 u_offset_t off = svd->offset + (uintptr_t)(a - seg->s_base);
3840 ulong_t aindx = svd->anon_index + seg_page(seg, a);
3842 &svd->vpage[seg_page(seg, a)] : NULL;
3875 ASSERT(SEGVN_LOCK_HELD(seg->s_as, &svd->lock));
3876 ASSERT(seg->s_szc < NBBY * sizeof (int));
3923 while (szc < seg->s_szc) {
3927 seg->s_szc;
3953 err = segvn_fault_anonpages(hat, seg,
3961 if (szc < seg->s_szc) {
3962 szc = seg->s_szc;
3982 ASSERT(sameprot(seg, a, maxpgsz));
4001 if (page_alloc_pages(vp, seg, a, &pplist, NULL,
4041 &vpprot, ppa, pgsz, seg, a, arw,
4129 if (szc < seg->s_szc) {
4147 pszc = seg->s_szc;
4164 ASSERT(szc == seg->s_szc);
4169 seg, a, prot, ppa, vpage, segvn_anypgsz,
4259 page_migrate(seg, a, ppa, pages);
4282 if (pszc > szc && szc < seg->s_szc &&
4283 (segvn_anypgsz_vnode || pszc >= seg->s_szc)) {
4285 uint_t pszc1 = MIN(pszc, seg->s_szc);
4450 page_alloc_pages(vp, seg, a, &pplist, NULL,
4526 ASSERT(ierr == -1 || szc < seg->s_szc);
4529 ASSERT(pszc > szc && pszc <= seg->s_szc);
4554 off = svd->offset + (uintptr_t)(a - seg->s_base);
4555 aindx = svd->anon_index + seg_page(seg, a);
4557 &svd->vpage[seg_page(seg, a)] : NULL;
4578 (uintptr_t)(a - seg->s_base);
4579 aindx = svd->anon_index + seg_page(seg, a);
4581 &svd->vpage[seg_page(seg, a)] : NULL;
4593 segvn_softunlock(seg, lpgaddr, a - lpgaddr, S_OTHER);
4610 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
4611 SEGVN_LOCK_ENTER(seg->s_as, &svd->lock, RW_WRITER);
4613 if (seg->s_szc != 0) {
4616 err = segvn_clrszc(seg);
4621 ASSERT(err || seg->s_szc == 0);
4622 SEGVN_LOCK_DOWNGRADE(seg->s_as, &svd->lock);
4633 segvn_fault_anonpages(struct hat *hat, struct seg *seg, caddr_t lpgaddr,
4637 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
4640 uint_t szc = seg->s_szc;
4646 ulong_t aindx = svd->anon_index + seg_page(seg, a);
4648 &svd->vpage[seg_page(seg, a)] : NULL;
4669 ASSERT(SEGVN_LOCK_HELD(seg->s_as, &svd->lock));
4709 ASSERT(sameprot(seg, a, maxpgsz));
4718 szc = seg->s_szc;
4731 ierr = anon_map_getpages(amp, aindx, szc, seg, a,
4761 page_migrate(seg, a, ppa, pages);
4807 ASSERT(ierr == -1 || szc < seg->s_szc);
4814 * than 0 or seg->s_szc. This could be due
4821 szc = (ierr == -1) ? 0 : seg->s_szc;
4823 ASSERT(ppa_szc <= seg->s_szc);
4854 aindx = svd->anon_index + seg_page(seg, a);
4856 &svd->vpage[seg_page(seg, a)] : NULL;
4877 aindx = svd->anon_index + seg_page(seg, a);
4879 &svd->vpage[seg_page(seg, a)] : NULL;
4893 segvn_softunlock(seg, lpgaddr, a - lpgaddr, S_OTHER);
4922 segvn_fault(struct hat *hat, struct seg *seg, caddr_t addr, size_t len,
4925 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
4943 ASSERT(seg->s_as && AS_LOCK_HELD(seg->s_as));
4952 ASSERT(AS_WRITE_HELD(seg->s_as));
4954 SEGVN_LOCK_ENTER(seg->s_as, &svd->lock, RW_READER);
4955 pgsz = (seg->s_szc == 0) ? PAGESIZE :
4956 page_get_pagesize(seg->s_szc);
4958 CALC_LPG_REGION(pgsz, seg, addr, len, lpgaddr, lpgeaddr);
4959 segvn_softunlock(seg, lpgaddr, lpgeaddr - lpgaddr, rw);
4960 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
4968 SEGVN_LOCK_ENTER(seg->s_as, &svd->lock, RW_WRITER);
4973 segvn_textrepl(seg);
4978 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
4981 SEGVN_LOCK_ENTER(seg->s_as, &svd->lock, RW_WRITER);
4985 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
4991 segvn_textunrepl(seg, 0);
4998 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
5002 SEGVN_LOCK_ENTER(seg->s_as, &svd->lock, RW_READER);
5030 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
5039 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
5040 SEGVN_LOCK_ENTER(seg->s_as, &svd->lock, RW_WRITER);
5047 hat_leave_region(seg->s_as->a_hat, svd->rcookie,
5051 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
5082 if (type == F_SOFTLOCK && svd->vp != NULL && seg->s_szc != 0) {
5089 pgsz = page_get_pagesize(seg->s_szc);
5090 CALC_LPG_REGION(pgsz, seg, addr, len, lpgaddr,
5097 ASSERT(demote || AS_WRITE_HELD(seg->s_as));
5100 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
5101 SEGVN_LOCK_ENTER(seg->s_as, &svd->lock, RW_WRITER);
5102 if (seg->s_szc != 0) {
5105 err = segvn_clrszc(seg);
5108 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
5112 ASSERT(seg->s_szc == 0);
5113 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
5128 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
5129 SEGVN_LOCK_ENTER(seg->s_as, &svd->lock, RW_WRITER);
5132 svd->amp = anonmap_alloc(seg->s_size, 0, ANON_SLEEP);
5133 svd->amp->a_szc = seg->s_szc;
5135 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
5151 ASSERT(AS_WRITE_HELD(seg->s_as));
5160 if (seg->s_szc != 0) {
5161 pgsz = page_get_pagesize(seg->s_szc);
5162 ASSERT(SEGVN_LOCK_HELD(seg->s_as, &svd->lock));
5163 CALC_LPG_REGION(pgsz, seg, addr, len, lpgaddr, lpgeaddr);
5165 err = segvn_fault_anonpages(hat, seg, lpgaddr,
5168 err = segvn_fault_vnodepages(hat, seg, lpgaddr,
5171 ASSERT(seg->s_szc == 0);
5172 ASSERT(SEGVN_READ_HELD(seg->s_as, &svd->lock));
5173 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
5177 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
5181 page = seg_page(seg, addr);
5211 hat_chgprot(seg->s_as->a_hat, addr, len, svd->prot);
5213 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
5224 off = svd->offset + (uintptr_t)(addr - seg->s_base);
5369 struct as *as = seg->s_as;
5384 (size_t)(seg->s_base + seg->s_size)) &&
5400 ((seg->s_base + seg->s_size) - addr));
5402 (seg->s_base + seg->s_size));
5424 "segvn_getpage:seg %p addr %p vp %p",
5425 seg, addr, vp);
5427 &vpprot, plp, plsz, seg, addr + (vp_off - off), arw,
5430 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
5485 err = segvn_faultpage(hat, seg, a, off, vpage, plp, vpprot,
5491 segvn_softunlock(seg, addr, (a - addr),
5494 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
5503 page = seg_page(seg, addr);
5546 pp->p_offset < svd->offset + seg->s_size) {
5590 seg->s_base + diff,
5603 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
5615 segvn_faulta(struct seg *seg, caddr_t addr)
5617 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
5622 ASSERT(seg->s_as && AS_LOCK_HELD(seg->s_as));
5624 SEGVN_LOCK_ENTER(seg->s_as, &svd->lock, RW_READER);
5635 svd->anon_index + seg_page(seg, addr))) != NULL) {
5638 0, seg, addr, S_READ, svd->cred);
5641 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
5650 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
5656 "segvn_getpage:seg %p addr %p vp %p", seg, addr, vp);
5658 (offset_t)(svd->offset + (uintptr_t)(addr - seg->s_base)),
5659 PAGESIZE, NULL, NULL, 0, seg, addr,
5662 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
5669 segvn_setprot(struct seg *seg, caddr_t addr, size_t len, uint_t prot)
5671 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
5679 ASSERT(seg->s_as && AS_LOCK_HELD(seg->s_as));
5684 SEGVN_LOCK_ENTER(seg->s_as, &svd->lock, RW_WRITER);
5688 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
5705 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
5711 * the cache with entries belonging to this seg during
5715 segvn_purge(seg);
5717 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
5725 hat_leave_region(seg->s_as->a_hat, svd->rcookie,
5733 segvn_textunrepl(seg, 0);
5743 if (seg->s_szc != 0) {
5745 pgsz = page_get_pagesize(seg->s_szc);
5749 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
5750 ASSERT(seg->s_base != addr || seg->s_size != len);
5756 if (AS_READ_HELD(seg->s_as))
5760 err = segvn_demote_range(seg, addr, len,
5763 uint_t szcvec = map_pgszcvec(seg->s_base,
5764 pgsz, (uintptr_t)seg->s_base,
5766 err = segvn_demote_range(seg, addr, len,
5800 if (addr == seg->s_base &&
5801 len == seg->s_size &&
5804 sz = seg->s_size;
5812 segvn_vpage(seg);
5814 SEGVN_LOCK_EXIT(seg->s_as,
5818 svp = &svd->vpage[seg_page(seg, addr)];
5819 evp = &svd->vpage[seg_page(seg,
5847 seg->s_as->a_proc->p_zone) == 0) {
5848 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
5856 if (svd->pageswap == 0 && sz == seg->s_size) {
5876 svd->amp == NULL && addr == seg->s_base &&
5877 len == seg->s_size && svd->pageprot == 0) {
5880 seg->s_as->a_proc->p_zone);
5883 "anon proc:%p %lu %u", seg, 0, 0);
5888 if (addr == seg->s_base && len == seg->s_size && svd->vpage == NULL) {
5890 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
5910 segvn_vpage(seg);
5912 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
5917 anon_idx = svd->anon_index + seg_page(seg, addr);
5918 ASSERT(seg->s_szc == 0 ||
5923 offset = svd->offset + (uintptr_t)(addr - seg->s_base);
5924 evp = &svd->vpage[seg_page(seg, addr + len)];
5930 for (svp = &svd->vpage[seg_page(seg, addr)]; svp < evp; svp++) {
5932 if (seg->s_szc != 0) {
5938 !segvn_claim_pages(seg, svp, offset,
5972 ASSERT(seg->s_szc == 0);
6005 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
6008 len = (svp - &svd->vpage[seg_page(seg, addr)]) *
6010 ASSERT(seg->s_szc == 0 || IS_P2ALIGNED(len, pgsz));
6012 hat_unload(seg->s_as->a_hat, addr,
6014 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
6018 segvn_vpage(seg);
6020 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
6024 evp = &svd->vpage[seg_page(seg, addr + len)];
6025 for (svp = &svd->vpage[seg_page(seg, addr)]; svp < evp; svp++) {
6031 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
6048 hat_unload(seg->s_as->a_hat, addr, len, HAT_UNLOAD);
6057 hat_chgattr(seg->s_as->a_hat, addr, len, prot);
6060 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
6067 * to determine if the seg is capable of mapping the requested szc.
6070 segvn_setpagesize(struct seg *seg, caddr_t addr, size_t len, uint_t szc)
6072 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
6075 struct seg *nseg;
6080 u_offset_t off = svd->offset + (uintptr_t)(addr - seg->s_base);
6082 ASSERT(seg->s_as && AS_WRITE_HELD(seg->s_as));
6083 ASSERT(addr >= seg->s_base && eaddr <= seg->s_base + seg->s_size);
6085 if (seg->s_szc == szc || segvn_lpg_disable != 0) {
6098 eaddr != seg->s_base + seg->s_size)) {
6105 ulong_t an_idx = svd->anon_index + seg_page(seg, addr);
6113 if ((svd->flags & MAP_NORESERVE) || seg->s_as == &kas ||
6124 if (seg->s_szc == 0 && svd->vp != NULL &&
6136 if (!sameprot(seg, a, eaddr - a)) {
6140 if (!sameprot(seg, a, pgsz)) {
6165 * the cache with entries belonging to this seg during
6169 segvn_purge(seg);
6178 hat_leave_region(seg->s_as->a_hat, svd->rcookie,
6185 segvn_textunrepl(seg, 1);
6193 if (addr != seg->s_base || eaddr != (seg->s_base + seg->s_size)) {
6194 if (szc < seg->s_szc) {
6196 err = segvn_demote_range(seg, addr, len, SDR_RANGE, 0);
6205 if (addr != seg->s_base) {
6206 nseg = segvn_split_seg(seg, addr);
6213 if (eaddr != (seg->s_base + seg->s_size)) {
6215 (void) segvn_split_seg(seg, eaddr);
6221 * Break any low level sharing and reset seg->s_szc to 0.
6223 if ((err = segvn_clrszc(seg)) != 0) {
6229 ASSERT(seg->s_szc == 0);
6236 nseg = AS_SEGNEXT(seg->s_as, seg);
6237 if (nseg == NULL || nseg == seg || eaddr != nseg->s_base) {
6265 err = segvn_concat(seg, nseg, 1);
6293 nahp, 0, btop(seg->s_size), ANON_NOSLEEP)) {
6308 eoffpage += seg->s_size;
6327 if ((err = anon_fill_cow_holes(seg, seg->s_base,
6329 seg->s_size, szc, svd->prot, svd->vpage,
6347 seg->s_szc = szc;
6353 segvn_clrszc(struct seg *seg)
6355 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
6360 caddr_t a = seg->s_base;
6361 caddr_t ea = a + seg->s_size;
6370 ASSERT(AS_WRITE_HELD(seg->s_as) ||
6371 SEGVN_WRITE_HELD(seg->s_as, &svd->lock));
6376 seg->s_szc = 0;
6383 hat_leave_region(seg->s_as->a_hat, svd->rcookie,
6388 segvn_textunrepl(seg, 1);
6402 hat_unload(seg->s_as->a_hat, seg->s_base, seg->s_size,
6407 seg->s_szc = 0;
6411 pgsz = page_get_pagesize(seg->s_szc);
6424 ASSERT(sameprot(seg, a, pgsz));
6428 if (seg->s_szc != 0) {
6432 seg, a, prot, vpage, svd->cred)) != 0) {
6440 anon_pl, PAGESIZE, seg, a, S_READ,
6444 if ((pp = anon_private(&ap, seg, a, prot,
6459 seg->s_szc = 0;
6467 struct seg *seg,
6473 pgcnt_t pgcnt = page_get_pagecnt(seg->s_szc);
6476 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
6480 + seg->s_base;
6491 ASSERT(seg->s_szc != 0);
6494 ASSERT(sameprot(seg, addr, pgcnt << PAGESHIFT));
6543 if (ppa[0]->p_szc == seg->s_szc) {
6574 static struct seg *
6575 segvn_split_seg(struct seg *seg, caddr_t addr)
6577 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
6578 struct seg *nseg;
6582 ASSERT(AS_WRITE_HELD(seg->s_as));
6585 ASSERT(addr >= seg->s_base);
6586 ASSERT(addr <= seg->s_base + seg->s_size);
6589 if (addr == seg->s_base || addr == seg->s_base + seg->s_size)
6590 return (seg);
6592 nsize = seg->s_base + seg->s_size - addr;
6593 seg->s_size = addr - seg->s_base;
6594 nseg = seg_alloc(seg->s_as, addr, nsize);
6596 nseg->s_ops = seg->s_ops;
6599 nseg->s_szc = seg->s_szc;
6602 nsvd->seg = nseg;
6608 (uintptr_t)(nseg->s_base - seg->s_base);
6632 size_t bytes = vpgtob(seg_pages(seg));
6639 bcopy(ovpage + seg_pages(seg), nsvd->vpage, nbytes);
6648 nahp = anon_create(btop(seg->s_size), ANON_SLEEP);
6650 nahp, 0, btop(seg->s_size), ANON_SLEEP);
6655 svd->anon_index + btop(seg->s_size),
6659 oamp->size = seg->s_size;
6665 pgcnt_t pgcnt = page_get_pagecnt(seg->s_szc);
6667 ASSERT(seg->s_szc <= svd->amp->a_szc);
6668 nsvd->anon_index = svd->anon_index + seg_pages(seg);
6690 svd->anon_index, btop(seg->s_size)));
6696 svd->swresv = segvn_count_swap_by_vpages(seg);
6700 ASSERT(svd->swresv == seg->s_size +
6702 svd->swresv = seg->s_size;
6720 struct seg *seg,
6728 struct seg *nseg;
6729 struct seg *badseg1 = NULL;
6730 struct seg *badseg2 = NULL;
6732 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
6734 uint_t szc = seg->s_szc;
6737 ASSERT(AS_WRITE_HELD(seg->s_as));
6741 ASSERT(seg->s_base != addr || seg->s_size != len);
6742 ASSERT(addr >= seg->s_base && eaddr <= seg->s_base + seg->s_size);
6747 CALC_LPG_REGION(pgsz, seg, addr, len, lpgaddr, lpgeaddr);
6751 badseg1 = nseg = segvn_split_seg(seg, lpgaddr);
6757 badseg1 = nseg = segvn_split_seg(seg, lpgaddr);
6779 badseg1 = nseg = segvn_split_seg(seg, lpgeaddr - pgsz);
6861 segvn_checkprot(struct seg *seg, caddr_t addr, size_t len, uint_t prot)
6863 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
6866 ASSERT(seg->s_as && AS_LOCK_HELD(seg->s_as));
6868 SEGVN_LOCK_ENTER(seg->s_as, &svd->lock, RW_READER);
6876 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
6883 evp = &svd->vpage[seg_page(seg, addr + len)];
6884 for (vp = &svd->vpage[seg_page(seg, addr)]; vp < evp; vp++) {
6886 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
6890 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
6895 segvn_getprot(struct seg *seg, caddr_t addr, size_t len, uint_t *protv)
6897 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
6898 size_t pgno = seg_page(seg, addr + len) - seg_page(seg, addr) + 1;
6900 ASSERT(seg->s_as && AS_LOCK_HELD(seg->s_as));
6903 SEGVN_LOCK_ENTER(seg->s_as, &svd->lock, RW_READER);
6909 size_t pgoff = seg_page(seg, addr);
6916 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
6922 segvn_getoffset(struct seg *seg, caddr_t addr)
6924 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
6926 ASSERT(seg->s_as && AS_LOCK_HELD(seg->s_as));
6928 return (svd->offset + (uintptr_t)(addr - seg->s_base));
6933 segvn_gettype(struct seg *seg, caddr_t addr)
6935 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
6937 ASSERT(seg->s_as && AS_LOCK_HELD(seg->s_as));
6945 segvn_getvp(struct seg *seg, caddr_t addr, struct vnode **vpp)
6947 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
6949 ASSERT(seg->s_as && AS_LOCK_HELD(seg->s_as));
6966 segvn_kluster(struct seg *seg, caddr_t addr, ssize_t delta)
6968 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
6976 ASSERT(seg->s_as && AS_LOCK_HELD(seg->s_as));
6977 ASSERT(AS_WRITE_HELD(seg->s_as) ||
6978 SEGVN_LOCK_HELD(seg->s_as, &svd->lock));
6980 if (addr + delta < seg->s_base ||
6981 addr + delta >= (seg->s_base + seg->s_size))
6985 page = seg_page(seg, addr);
7054 * Swap the pages of seg out to secondary storage, returning the
7073 segvn_swapout(struct seg *seg)
7075 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
7082 ASSERT(seg->s_as && AS_LOCK_HELD(seg->s_as));
7084 SEGVN_LOCK_ENTER(seg->s_as, &svd->lock, RW_READER);
7091 npages = seg->s_size >> PAGESHIFT;
7227 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
7242 segvn_sync(struct seg *seg, caddr_t addr, size_t len, int attr, uint_t flags)
7244 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
7261 ASSERT(seg->s_as && AS_LOCK_HELD(seg->s_as));
7263 SEGVN_LOCK_ENTER(seg->s_as, &svd->lock, RW_READER);
7271 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
7276 * flush all pages from seg cache
7289 segvn_purge(seg);
7291 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
7301 segvn_purge(seg);
7303 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
7309 offset = svd->offset + (uintptr_t)(addr - seg->s_base);
7323 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
7328 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
7333 vpp = &svd->vpage[seg_page(seg, addr)];
7344 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
7349 anon_index = svd->anon_index + seg_page(seg, addr);
7396 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
7459 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
7468 segvn_incore(struct seg *seg, caddr_t addr, size_t len, char *vec)
7470 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
7483 ASSERT(seg->s_as && AS_LOCK_HELD(seg->s_as));
7485 SEGVN_LOCK_ENTER(seg->s_as, &svd->lock, RW_READER);
7487 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
7492 p = seg_page(seg, addr);
7493 ep = seg_page(seg, addr + len);
7521 if ((hat_getattr(seg->s_as->a_hat, addr,
7541 offset = svd->offset + (uintptr_t)(addr - seg->s_base);
7577 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
7629 segvn_lockop(struct seg *seg, caddr_t addr, size_t len,
7632 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
7659 ASSERT(seg->s_as && AS_LOCK_HELD(seg->s_as));
7675 SEGVN_LOCK_ENTER(seg->s_as, &svd->lock, RW_WRITER);
7686 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
7690 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
7700 segvn_textunrepl(seg, 0);
7714 segvn_vpage(seg);
7716 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
7720 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
7732 svd->amp = anonmap_alloc(seg->s_size, 0, ANON_SLEEP);
7733 svd->amp->a_szc = seg->s_szc;
7737 anon_index = svd->anon_index + seg_page(seg, addr);
7740 offset = svd->offset + (uintptr_t)(addr - seg->s_base);
7741 evp = &svd->vpage[seg_page(seg, addr + len)];
7750 for (vpp = &svd->vpage[seg_page(seg, addr)]; vpp < evp;
7763 i_edx = svd->anon_index + seg_page(seg, addr + len);
7794 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
7803 for (vpp = &svd->vpage[seg_page(seg, addr)]; vpp < evp;
7825 pp = anon_zero(seg, addr, &ap,
7890 (uint_t *)NULL, pl, PAGESIZE, seg, addr,
8039 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
8063 segvn_advise(struct seg *seg, caddr_t addr, size_t len, uint_t behav)
8065 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
8071 struct seg *next;
8073 struct seg *prev;
8076 ASSERT(seg->s_as && AS_LOCK_HELD(seg->s_as));
8083 SEGVN_LOCK_ENTER(seg->s_as, &svd->lock, RW_WRITER);
8085 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
8089 SEGVN_LOCK_ENTER(seg->s_as, &svd->lock, RW_READER);
8101 (seg->s_szc != 0 || HAT_IS_REGION_COOKIE_VALID(svd->rcookie))) ||
8104 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
8123 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
8129 * belonging to this seg during the purge.
8134 segvn_purge(seg);
8142 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
8152 segvn_purge(seg);
8169 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
8180 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
8184 segvn_purge(seg);
8186 page = seg_page(seg, addr);
8202 anon_unresv_zone(bytes, seg->s_as->a_proc->p_zone);
8204 atomic_add_long(&seg->s_as->a_resvsize, -bytes);
8208 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
8224 if ((addr == seg->s_base) && (len == seg->s_size)) {
8242 if (AS_READ_HELD(seg->s_as)) {
8243 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
8263 page_mark_migrate(seg, addr, len, amp, svd->anon_index,
8280 prev = AS_SEGPREV(seg->s_as, seg);
8281 next = AS_SEGNEXT(seg->s_as, seg);
8285 (void) segvn_concat(seg, next, 1);
8295 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
8296 if (!segvn_concat(prev, seg, 1))
8308 ASSERT(seg->s_szc == 0);
8310 hat_unload(seg->s_as->a_hat, addr, len,
8328 struct seg *new_seg;
8333 page = seg_page(seg, addr);
8335 segvn_vpage(seg);
8337 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
8356 if (seg->s_szc != 0) {
8359 pgsz = page_get_pagesize(seg->s_szc);
8370 off = svd->offset + (uintptr_t)(addr - seg->s_base);
8393 AS_READ_HELD(seg->s_as)) {
8394 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
8402 page_mark_migrate(seg, addr, len, amp, svd->anon_index,
8417 hat_leave_region(seg->s_as->a_hat, svd->rcookie,
8428 oldeaddr = seg->s_base + seg->s_size;
8429 if (addr > seg->s_base) {
8435 segvn_purge(seg);
8441 new_seg = segvn_split_seg(seg, addr);
8480 segvn_purge(seg);
8487 if (new_seg != NULL && new_seg != seg) {
8505 (void) segvn_split_seg(seg, eaddr);
8509 &svd->policy_info, seg->s_size);
8516 if (addr == seg->s_base) {
8517 prev = AS_SEGPREV(seg->s_as,
8518 seg);
8531 seg->s_as,
8534 prev, seg, 1);
8542 ASSERT(seg->s_szc == 0);
8544 hat_unload(seg->s_as->a_hat, addr, len, HAT_UNLOAD);
8563 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
8573 segvn_inherit(struct seg *seg, caddr_t addr, size_t len, uint_t behav)
8575 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
8580 ASSERT(seg->s_as && AS_LOCK_HELD(seg->s_as));
8586 SEGVN_LOCK_ENTER(seg->s_as, &svd->lock, RW_WRITER);
8611 if ((addr == seg->s_base) && (len == seg->s_size)) {
8622 segvn_vpage(seg);
8630 page = seg_page(seg, addr);
8638 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
8643 * Create a vpage structure for this seg.
8646 segvn_vpage(struct seg *seg)
8648 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
8652 ASSERT(SEGVN_WRITE_HELD(seg->s_as, &svd->lock));
8674 ulong_t mem_needed = seg_pages(seg) * sizeof (struct vpage);
8685 evp = &svd->vpage[seg_page(seg, seg->s_base + seg->s_size)];
8697 segvn_dump(struct seg *seg)
8709 npages = seg_pages(seg);
8710 svd = (struct segvn_data *)seg->s_data;
8713 addr = seg->s_base;
8744 dump_addpage(seg->s_as, addr, pfn);
8806 segvn_pagelock(struct seg *seg, caddr_t addr, size_t len, struct page ***ppp,
8809 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
8847 "segvn_pagelock: start seg %p addr %p", seg, addr);
8849 ASSERT(seg->s_as && AS_LOCK_HELD(seg->s_as));
8852 SEGVN_LOCK_ENTER(seg->s_as, &svd->lock, RW_READER);
8882 if (seg->s_szc != 0) {
8907 pgsz = page_get_pagesize(seg->s_szc);
8908 CALC_LPG_REGION(pgsz, seg, addr, len, lpgaddr, lpgeaddr);
8948 if (lpgaddr < seg->s_base) {
8949 lpgaddr = seg->s_base;
8953 ulong_t aix = svd->anon_index + seg_page(seg, addr);
8956 lpgaddr = seg->s_base;
8960 ASSERT(lpgaddr >= seg->s_base);
8964 struct vpage *vp = &svd->vpage[seg_page(seg, lpgaddr)];
8965 struct vpage *evp = &svd->vpage[seg_page(seg, addr)];
8985 seg_page(seg, lpgeaddr);
8995 lpgeaddr > seg->s_base + seg->s_size) {
8996 lpgeaddr = seg->s_base + seg->s_size;
9004 vp = &svd->vpage[seg_page(seg, addr + len)];
9005 evp = &svd->vpage[seg_page(seg, lpgeaddr)];
9028 paddr = (caddr_t)((lpgaddr - seg->s_base) +
9046 if (seg->s_as->a_vbits) {
9049 hat_setstat(seg->s_as, a,
9052 hat_setstat(seg->s_as, a,
9072 paddr = (caddr_t)((addr - seg->s_base) +
9075 ptag = (void *)seg;
9084 seg_pinactive(seg, pamp, paddr, len,
9111 if (AS_ISUNMAPWAIT(seg->s_as)) {
9113 mutex_enter(&seg->s_as->a_contents);
9114 if (AS_ISUNMAPWAIT(seg->s_as)) {
9115 AS_CLRUNMAPWAIT(seg->s_as);
9116 cv_broadcast(&seg->s_as->a_cv);
9118 mutex_exit(&seg->s_as->a_contents);
9133 segvn_purge(seg);
9136 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
9138 "segvn_pagelock: unlock seg %p addr %p", seg, addr);
9164 if (seg->s_szc) {
9174 ASSERT(seg->s_szc == 0 ||
9175 sameprot(seg, a, pgsz));
9176 vp = &svd->vpage[seg_page(seg, a)];
9188 pplist = seg_plookup(seg, pamp, paddr, lpgeaddr - lpgaddr, rw, pflags);
9202 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
9205 "segvn_pagelock: cache hit seg %p addr %p", seg, addr);
9234 ASSERT(seg->s_szc == 0 ||
9235 sameprot(seg, a, pgsz));
9236 vp = &svd->vpage[seg_page(seg, a)];
9264 if (seg_pinsert_check(seg, pamp, paddr,
9291 page = seg_page(seg, addr);
9296 ASSERT(amp->a_szc >= seg->s_szc);
9330 if (seg->s_szc) {
9335 vpage = &svd->vpage[seg_page(seg, a)];
9343 error = segvn_faultpage(seg->s_as->a_hat, seg, a, 0,
9396 (void) seg_pinsert(seg, pamp, paddr, len, wlen, pl,
9399 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
9401 "segvn_pagelock: cache fill seg %p addr %p", seg, addr);
9415 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
9418 "segvn_pagelock: cache miss seg %p addr %p", seg, addr);
9426 segvn_purge(struct seg *seg)
9428 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
9444 seg_ppurge(seg, NULL, 0);
9447 seg_ppurge(seg, svd->amp, 0);
9461 struct seg *seg = (struct seg *)ptag;
9462 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
9471 ASSERT(async || AS_LOCK_HELD(seg->s_as));
9514 if (async || AS_ISUNMAPWAIT(seg->s_as)) {
9515 mutex_enter(&seg->s_as->a_contents);
9517 AS_SETNOUNMAPWAIT(seg->s_as);
9519 if (AS_ISUNMAPWAIT(seg->s_as)) {
9520 AS_CLRUNMAPWAIT(seg->s_as);
9521 cv_broadcast(&seg->s_as->a_cv);
9523 mutex_exit(&seg->s_as->a_contents);
9586 segvn_getmemid(struct seg *seg, caddr_t addr, memid_t *memidp)
9588 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
9595 memidp->val[0] = (uintptr_t)seg->s_as;
9604 (uintptr_t)(addr - seg->s_base);
9608 SEGVN_LOCK_ENTER(seg->s_as, &svd->lock, RW_READER);
9611 seg_page(seg, addr);
9613 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
9623 pp = anon_zero(seg, addr, &ap, svd->cred);
9648 sameprot(struct seg *seg, caddr_t a, size_t len)
9650 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
9660 vpage = &svd->vpage[seg_page(seg, a)];
9676 segvn_getpolicy(struct seg *seg, caddr_t addr)
9685 ASSERT(seg != NULL);
9687 svn_data = (struct segvn_data *)seg->s_data;
9704 anon_index = svn_data->anon_index + seg_page(seg, addr);
9706 vn_off = svn_data->offset + (uintptr_t)(addr - seg->s_base);
9715 segvn_capable(struct seg *seg, segcapability_t capability)
9732 segvn_textrepl(struct seg *seg)
9734 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
9737 size_t size = seg->s_size;
9739 uint_t szc = seg->s_szc;
9743 proc_t *p = seg->s_as->a_proc;
9749 ASSERT(AS_LOCK_HELD(seg->s_as));
9750 ASSERT(SEGVN_WRITE_HELD(seg->s_as, &svd->lock));
9759 ASSERT(seg->s_as != &kas);
10008 * Convert seg back to regular vnode mapping seg by unbinding it from its text
10016 segvn_textunrepl(struct seg *seg, int unload_unmap)
10018 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
10021 size_t size = seg->s_size;
10023 uint_t szc = seg->s_szc;
10030 ASSERT(AS_LOCK_HELD(seg->s_as));
10031 ASSERT(AS_WRITE_HELD(seg->s_as) ||
10032 SEGVN_WRITE_HELD(seg->s_as, &svd->lock));
10102 hat_unload_callback(seg->s_as->a_hat, seg->s_base, size,
10200 segvn_trupdate_seg(svd->seg, svd, svntrp,
10209 segvn_trupdate_seg(struct seg *seg,
10223 ASSERT(svd->offset + seg->s_size == svntrp->tr_eoff);
10224 ASSERT(seg != NULL);
10225 ASSERT(svd->seg == seg);
10226 ASSERT(seg->s_data == (void *)svd);
10227 ASSERT(seg->s_szc == svntrp->tr_szc);
10238 as = seg->s_as;
10253 * Use tryenter locking since we are locking as/seg and svntr hash
10263 if (!SEGVN_LOCK_TRYENTER(seg->s_as, &svd->lock, RW_WRITER)) {
10271 size = seg->s_size;
10275 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
10282 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
10290 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
10298 amp->a_szc = seg->s_szc;
10310 hat_unload_callback(as->a_hat, seg->s_base, size, 0, NULL);
10322 SEGVN_LOCK_EXIT(seg->s_as, &svd->lock);
10329 ASSERT(svd->seg == seg);