Lines Matching refs:as
63 #include <vm/as.h>
76 static void as_setwatchprot(struct as *, caddr_t, size_t, uint_t);
77 static void as_clearwatchprot(struct as *, caddr_t, size_t);
78 int as_map_locked(struct as *, caddr_t, size_t, int ((*)()), void *);
93 * Link the entry on the as->a_callbacks list. A callback entry for the
97 * the specified as, the caller must guarantee persistence of the specified as
98 * for the duration of this function (eg. pages being locked within the as
102 as_add_callback(struct as *as, void (*cb_func)(), void *arg, uint_t events,
114 if (as == &kas)
147 mutex_enter(&as->a_contents);
148 current_head = as->a_callbacks;
149 as->a_callbacks = cb;
158 if ((cb->ascb_events & AS_UNMAPWAIT_EVENT) && AS_ISUNMAPWAIT(as)) {
159 AS_CLRUNMAPWAIT(as);
160 cv_broadcast(&as->a_cv);
163 mutex_exit(&as->a_contents);
183 * the specified as, the caller must guarantee persistence of the specified as
184 * for the duration of this function (eg. pages being locked within the as
188 as_delete_callback(struct as *as, void *arg)
190 struct as_callback **prevcb = &as->a_callbacks;
194 mutex_enter(&as->a_contents);
195 for (cb = as->a_callbacks; cb; prevcb = &cb->ascb_next, cb = *prevcb) {
212 cv_broadcast(&as->a_cv);
220 mutex_exit(&as->a_contents);
225 * Searches the as callback list for a matching entry.
234 as_find_callback(struct as *as, uint_t events, caddr_t event_addr,
239 ASSERT(MUTEX_HELD(&as->a_contents));
240 for (cb = as->a_callbacks; cb != NULL; cb = cb->ascb_next) {
266 as_execute_callback(struct as *as, struct as_callback *cb,
272 ASSERT(MUTEX_HELD(&as->a_contents) && (cb->ascb_events & events));
274 mutex_exit(&as->a_contents);
275 (*cb->ascb_func)(as, cb->ascb_arg, events);
276 mutex_enter(&as->a_contents);
286 cv_wait(&as->a_cv, &as->a_contents);
298 prevcb = &as->a_callbacks;
299 for (cb = as->a_callbacks; cb != NULL;
334 as_do_callbacks(struct as *as, uint_t events, caddr_t event_addr,
339 if ((cb = as_find_callback(as, events, event_addr, event_len))) {
340 as_execute_callback(as, cb, events);
358 as_findseg(struct as *as, caddr_t addr, int tail)
360 struct seg *seg = as->a_seglast;
363 ASSERT(AS_LOCK_HELD(as));
370 seg = avl_find(&as->a_segtree, &addr, &where);
372 return (as->a_seglast = seg);
374 seg = avl_nearest(&as->a_segtree, where, AVL_AFTER);
376 seg = avl_last(&as->a_segtree);
377 return (as->a_seglast = seg);
385 as_verify(struct as *as)
393 seglast = as->a_seglast;
395 for (seg = AS_SEGFIRST(as); seg != NULL; seg = AS_SEGNEXT(as, seg)) {
396 ASSERT(seg->s_as == as);
397 p = AS_SEGPREV(as, seg);
398 n = AS_SEGNEXT(as, seg);
399 ASSERT(p == NULL || p->s_as == as);
402 ASSERT(n != NULL || seg == avl_last(&as->a_segtree));
408 ASSERT(avl_numnodes(&as->a_segtree) == nsegs);
415 * in as_gap() as an insertion point.
418 as_addseg(struct as *as, struct seg *newseg)
425 ASSERT(AS_WRITE_HELD(as));
427 as->a_updatedir = 1; /* inform /proc */
428 gethrestime(&as->a_updatetime);
430 if (as->a_lastgaphl != NULL) {
434 if (as->a_lastgaphl->s_base > newseg->s_base) {
435 hseg = as->a_lastgaphl;
436 lseg = AVL_PREV(&as->a_segtree, hseg);
438 lseg = as->a_lastgaphl;
439 hseg = AVL_NEXT(&as->a_segtree, lseg);
444 avl_insert_here(&as->a_segtree, newseg, lseg,
446 as->a_lastgaphl = NULL;
447 as->a_seglast = newseg;
450 as->a_lastgaphl = NULL;
457 seg = avl_find(&as->a_segtree, &addr, &where);
460 seg = avl_nearest(&as->a_segtree, where, AVL_AFTER);
463 seg = avl_last(&as->a_segtree);
493 as->a_seglast = newseg;
494 avl_insert(&as->a_segtree, newseg, where);
497 as_verify(as);
503 as_removeseg(struct as *as, struct seg *seg)
507 ASSERT(AS_WRITE_HELD(as));
509 as->a_updatedir = 1; /* inform /proc */
510 gethrestime(&as->a_updatetime);
515 t = &as->a_segtree;
516 if (as->a_seglast == seg)
517 as->a_seglast = NULL;
518 as->a_lastgaphl = NULL;
524 if (as->a_lastgap &&
525 (seg == as->a_lastgap || seg->s_base > as->a_lastgap->s_base))
526 as->a_lastgap = AVL_NEXT(t, seg);
534 as_verify(as);
543 as_segat(struct as *as, caddr_t addr)
545 struct seg *seg = as->a_seglast;
547 ASSERT(AS_LOCK_HELD(as));
553 seg = avl_find(&as->a_segtree, &addr, NULL);
564 as_rangelock(struct as *as)
566 mutex_enter(&as->a_contents);
567 while (AS_ISCLAIMGAP(as))
568 cv_wait(&as->a_cv, &as->a_contents);
569 AS_SETCLAIMGAP(as);
570 mutex_exit(&as->a_contents);
577 as_rangeunlock(struct as *as)
579 mutex_enter(&as->a_contents);
580 AS_CLRCLAIMGAP(as);
581 cv_signal(&as->a_cv);
582 mutex_exit(&as->a_contents);
603 as_avlinit(struct as *as)
605 avl_create(&as->a_segtree, as_segcompar, sizeof (struct seg),
607 avl_create(&as->a_wpage, wp_compare, sizeof (struct watched_page),
615 struct as *as = buf;
617 mutex_init(&as->a_contents, NULL, MUTEX_DEFAULT, NULL);
618 cv_init(&as->a_cv, NULL, CV_DEFAULT, NULL);
619 rw_init(&as->a_lock, NULL, RW_DEFAULT, NULL);
620 as_avlinit(as);
628 struct as *as = buf;
630 avl_destroy(&as->a_segtree);
631 mutex_destroy(&as->a_contents);
632 cv_destroy(&as->a_cv);
633 rw_destroy(&as->a_lock);
639 as_cache = kmem_cache_create("as_cache", sizeof (struct as), 0,
648 struct as *
651 struct as *as;
653 as = kmem_cache_alloc(as_cache, KM_SLEEP);
655 as->a_flags = 0;
656 as->a_vbits = 0;
657 as->a_hrm = NULL;
658 as->a_seglast = NULL;
659 as->a_size = 0;
660 as->a_resvsize = 0;
661 as->a_updatedir = 0;
662 gethrestime(&as->a_updatetime);
663 as->a_objectdir = NULL;
664 as->a_sizedir = 0;
665 as->a_userlimit = (caddr_t)USERLIMIT;
666 as->a_lastgap = NULL;
667 as->a_lastgaphl = NULL;
668 as->a_callbacks = NULL;
669 as->a_proc = NULL;
671 AS_LOCK_ENTER(as, RW_WRITER);
672 as->a_hat = hat_alloc(as); /* create hat for default system mmu */
673 AS_LOCK_EXIT(as);
675 return (as);
681 * all the segments on this as and finally
682 * the space for the as struct itself.
685 as_free(struct as *as)
687 struct hat *hat = as->a_hat;
697 mutex_enter(&as->a_contents);
698 while (as->a_callbacks && as_do_callbacks(as, AS_ALL_EVENT, 0, 0))
701 mutex_exit(&as->a_contents);
702 AS_LOCK_ENTER(as, RW_WRITER);
708 for (seg = AS_SEGFIRST(as); seg != NULL; seg = next) {
711 next = AS_SEGNEXT(as, seg);
715 mutex_enter(&as->a_contents);
716 if (as->a_callbacks) {
717 AS_LOCK_EXIT(as);
718 } else if (!AS_ISNOUNMAPWAIT(as)) {
724 if (AS_ISUNMAPWAIT(as) == 0)
725 cv_broadcast(&as->a_cv);
726 AS_SETUNMAPWAIT(as);
727 AS_LOCK_EXIT(as);
728 while (AS_ISUNMAPWAIT(as))
729 cv_wait(&as->a_cv, &as->a_contents);
736 * 0. We don't drop as writer lock so our
741 AS_CLRNOUNMAPWAIT(as);
742 mutex_exit(&as->a_contents);
745 mutex_exit(&as->a_contents);
756 AS_LOCK_EXIT(as);
759 ASSERT(avl_numnodes(&as->a_wpage) == 0);
760 if (as->a_objectdir) {
761 kmem_free(as->a_objectdir, as->a_sizedir * sizeof (vnode_t *));
762 as->a_objectdir = NULL;
763 as->a_sizedir = 0;
767 * Free the struct as back to kmem. Assert it has no segments.
769 ASSERT(avl_numnodes(&as->a_segtree) == 0);
770 kmem_cache_free(as_cache, as);
774 as_dup(struct as *as, struct proc *forkedproc)
776 struct as *newas;
781 AS_LOCK_ENTER(as, RW_WRITER);
782 as_clearwatch(as);
784 newas->a_userlimit = as->a_userlimit;
789 (void) hat_dup(as->a_hat, newas->a_hat, NULL, 0, HAT_DUP_SRD);
791 for (seg = AS_SEGFIRST(as); seg != NULL; seg = AS_SEGNEXT(as, seg)) {
801 as_setwatch(as);
802 AS_LOCK_EXIT(as);
812 as_setwatch(as);
813 AS_LOCK_EXIT(as);
821 newas->a_resvsize = as->a_resvsize - purgesize;
823 error = hat_dup(as->a_hat, newas->a_hat, NULL, 0, HAT_DUP_ALL);
827 as_setwatch(as);
828 AS_LOCK_EXIT(as);
841 as_fault(struct hat *hat, struct as *as, caddr_t addr, size_t size,
887 if (as == &kas)
904 * XXX -- Don't grab the as lock for segkmap. We should grab it for
908 * as exec'ing requires the write lock on the as.
910 if (as == &kas && segkmap && segkmap->s_base <= raddr &&
915 AS_LOCK_ENTER(as, RW_READER);
917 seg = as_segat(as, raddr);
919 AS_LOCK_EXIT(as);
933 seg = AS_SEGNEXT(as, seg);
958 seg = AS_SEGNEXT(as, seg);
974 AS_LOCK_EXIT(as);
1001 as_faulta(struct as *as, caddr_t addr, size_t size)
1022 AS_LOCK_ENTER(as, RW_READER);
1023 seg = as_segat(as, raddr);
1025 AS_LOCK_EXIT(as);
1033 seg = AS_SEGNEXT(as, seg);
1043 AS_LOCK_EXIT(as);
1065 * in address space `as' to have the specified protection.
1067 * as long as they are contiguous.
1070 as_setprot(struct as *as, caddr_t addr, size_t size, uint_t prot)
1093 * Normally we only lock the as as a reader. But
1096 * the as lock as a writer so the segment driver can change
1099 * locking as a writer. Since these opeartions should be rare
1100 * want to only lock as a writer when necessary.
1102 if (writer || avl_numnodes(&as->a_wpage) != 0) {
1103 AS_LOCK_ENTER(as, RW_WRITER);
1105 AS_LOCK_ENTER(as, RW_READER);
1108 as_clearwatchprot(as, raddr, rsize);
1109 seg = as_segat(as, raddr);
1111 as_setwatch(as);
1112 AS_LOCK_EXIT(as);
1118 seg = AS_SEGNEXT(as, seg);
1137 AS_LOCK_EXIT(as);
1144 * Make sure we have a_lock as writer.
1147 AS_LOCK_EXIT(as);
1184 mutex_enter(&as->a_contents);
1185 if (as->a_callbacks &&
1186 (cb = as_find_callback(as, AS_SETPROT_EVENT,
1188 AS_LOCK_EXIT(as);
1189 as_execute_callback(as, cb, AS_SETPROT_EVENT);
1190 } else if (!AS_ISNOUNMAPWAIT(as)) {
1191 if (AS_ISUNMAPWAIT(as) == 0)
1192 cv_broadcast(&as->a_cv);
1193 AS_SETUNMAPWAIT(as);
1194 AS_LOCK_EXIT(as);
1195 while (AS_ISUNMAPWAIT(as))
1196 cv_wait(&as->a_cv, &as->a_contents);
1203 * 0. We don't drop as writer lock so our
1208 AS_CLRNOUNMAPWAIT(as);
1209 mutex_exit(&as->a_contents);
1212 mutex_exit(&as->a_contents);
1218 as_setwatch(as);
1220 as_setwatchprot(as, saveraddr, saversize, prot);
1222 AS_LOCK_EXIT(as);
1228 * in address space `as' has at least the specified protection.
1229 * It is ok for the range to cross over several segments, as long
1230 * as they are contiguous.
1233 as_checkprot(struct as *as, caddr_t addr, size_t size, uint_t prot)
1249 * This is ugly as sin...
1255 if (avl_numnodes(&as->a_wpage) != 0)
1256 AS_LOCK_ENTER(as, RW_WRITER);
1258 AS_LOCK_ENTER(as, RW_READER);
1259 as_clearwatchprot(as, raddr, rsize);
1260 seg = as_segat(as, raddr);
1262 as_setwatch(as);
1263 AS_LOCK_EXIT(as);
1269 seg = AS_SEGNEXT(as, seg);
1284 as_setwatch(as);
1285 AS_LOCK_EXIT(as);
1290 as_unmap(struct as *as, caddr_t addr, size_t size)
1303 AS_LOCK_ENTER(as, RW_WRITER);
1305 as->a_updatedir = 1; /* inform /proc */
1306 gethrestime(&as->a_updatetime);
1312 as_clearwatchprot(as, raddr, eaddr - raddr);
1314 for (seg = as_findseg(as, raddr, 0); seg != NULL; seg = seg_next) {
1333 seg_next = AS_SEGNEXT(as, seg);
1380 mutex_enter(&as->a_contents);
1381 if (as->a_callbacks &&
1382 (cb = as_find_callback(as, AS_UNMAP_EVENT,
1384 AS_LOCK_EXIT(as);
1385 as_execute_callback(as, cb, AS_UNMAP_EVENT);
1386 } else if (!AS_ISNOUNMAPWAIT(as)) {
1387 if (AS_ISUNMAPWAIT(as) == 0)
1388 cv_broadcast(&as->a_cv);
1389 AS_SETUNMAPWAIT(as);
1390 AS_LOCK_EXIT(as);
1391 while (AS_ISUNMAPWAIT(as))
1392 cv_wait(&as->a_cv, &as->a_contents);
1399 * 0. We don't drop as writer lock so our
1404 AS_CLRNOUNMAPWAIT(as);
1405 mutex_exit(&as->a_contents);
1408 mutex_exit(&as->a_contents);
1411 AS_LOCK_EXIT(as);
1414 as_setwatch(as);
1415 AS_LOCK_EXIT(as);
1419 as->a_size -= ssize;
1421 as->a_resvsize -= rsize;
1424 AS_LOCK_EXIT(as);
1429 as_map_segvn_segs(struct as *as, caddr_t addr, size_t size, uint_t szcvec,
1443 ASSERT(AS_WRITE_HELD(as));
1452 seg = seg_alloc(as, addr, size);
1461 as->a_size += size;
1462 as->a_resvsize += size;
1484 seg = seg_alloc(as, addr, segsize);
1494 as->a_size += segsize;
1495 as->a_resvsize += segsize;
1513 seg = seg_alloc(as, addr, segsize);
1523 as->a_size += segsize;
1524 as->a_resvsize += segsize;
1543 as_map_vnsegs(struct as *as, caddr_t addr, size_t size,
1557 ASSERT(AS_WRITE_HELD(as));
1565 seg = seg_alloc(as, addr, size);
1574 as->a_size += size;
1575 as->a_resvsize += size;
1606 error = as_map_segvn_segs(as, addr, size, szcvec, crfp, vn_a,
1625 as_map_ansegs(struct as *as, caddr_t addr, size_t size,
1646 ASSERT(AS_WRITE_HELD(as));
1651 return (as_map_segvn_segs(as, addr, size, szcvec,
1656 as_map(struct as *as, caddr_t addr, size_t size, int (*crfp)(), void *argsp)
1658 AS_LOCK_ENTER(as, RW_WRITER);
1659 return (as_map_locked(as, addr, size, crfp, argsp));
1663 as_map_locked(struct as *as, caddr_t addr, size_t size, int (*crfp)(),
1678 struct proc *p = (as->a_proc == NULL) ? curproc : as->a_proc;
1688 if ((raddr + rsize < raddr) || (as->a_size > (ULONG_MAX - size))) {
1689 AS_LOCK_EXIT(as);
1693 as->a_updatedir = 1; /* inform /proc */
1694 gethrestime(&as->a_updatetime);
1696 if (as != &kas && as->a_size + rsize > (size_t)p->p_vmem_ctl) {
1697 AS_LOCK_EXIT(as);
1707 error = as_map_vnsegs(as, raddr, rsize, crfp, &crargs, &unmap);
1709 AS_LOCK_EXIT(as);
1711 (void) as_unmap(as, addr, size);
1717 error = as_map_ansegs(as, raddr, rsize, crfp, &crargs, &unmap);
1719 AS_LOCK_EXIT(as);
1721 (void) as_unmap(as, addr, size);
1726 seg = seg_alloc(as, addr, size);
1728 AS_LOCK_EXIT(as);
1735 AS_LOCK_EXIT(as);
1741 as->a_size += rsize;
1742 as->a_resvsize += rsize;
1745 as_setwatch(as);
1751 mutex_enter(&as->a_contents);
1752 if (AS_ISPGLCK(as)) {
1753 mutex_exit(&as->a_contents);
1754 AS_LOCK_EXIT(as);
1755 error = as_ctl(as, addr, size, MC_LOCK, 0, 0, NULL, 0);
1757 (void) as_unmap(as, addr, size);
1759 mutex_exit(&as->a_contents);
1760 AS_LOCK_EXIT(as);
1769 * These segments are deleted as a first step before calls to as_gap(), so
1773 as_purge(struct as *as)
1782 if ((as->a_flags & AS_NEEDSPURGE) == 0)
1785 AS_LOCK_ENTER(as, RW_WRITER);
1787 seg = AS_SEGFIRST(as);
1789 next_seg = AS_SEGNEXT(as, seg);
1794 AS_LOCK_EXIT(as);
1796 mutex_enter(&as->a_contents);
1797 as->a_flags &= ~AS_NEEDSPURGE;
1798 mutex_exit(&as->a_contents);
1810 * in the range. We use the as->a_lastgap field to figure out where to
1823 as_gap_aligned(struct as *as, size_t minlen, caddr_t *basep, size_t *lenp,
1857 AS_LOCK_ENTER(as, RW_READER);
1858 if (AS_SEGFIRST(as) == NULL) {
1861 AS_LOCK_EXIT(as);
1864 AS_LOCK_EXIT(as);
1880 hseg = as_findseg(as, lobound, 1);
1881 lseg = AS_SEGPREV(as, hseg);
1885 * If allocating at least as much as the last allocation,
1886 * use a_lastgap's base as a better estimate of hibound.
1888 if (as->a_lastgap &&
1889 minlen >= as->a_lastgap->s_size &&
1890 hibound >= as->a_lastgap->s_base)
1891 hibound = as->a_lastgap->s_base;
1893 hseg = as_findseg(as, hibound, 1);
1898 lseg = AS_SEGPREV(as, hseg);
1940 as->a_lastgap = hseg;
1942 as->a_lastgaphl = hseg;
1944 as->a_lastgaphl = lseg;
1945 AS_LOCK_EXIT(as);
1956 hseg = AS_SEGNEXT(as, hseg);
1961 lseg = AS_SEGPREV(as, lseg);
1972 AS_LOCK_EXIT(as);
1980 * in the range. We use the as->a_lastgap field to figure out where to
1994 as_gap(struct as *as, size_t minlen, caddr_t *basep, size_t *lenp, uint_t flags,
1998 return (as_gap_aligned(as, minlen, basep, lenp, flags, addr, 0, 0, 0));
2007 as_memory(struct as *as, caddr_t *basep, size_t *lenp)
2014 AS_LOCK_ENTER(as, RW_READER);
2019 seg = as_findseg(as, addr, 0);
2025 AS_LOCK_EXIT(as);
2044 seg = AS_SEGNEXT(as, seg);
2057 AS_LOCK_EXIT(as);
2062 * Swap the pages associated with the address space as out to
2072 as_swapout(struct as *as)
2082 if (as == NULL)
2085 AS_LOCK_ENTER(as, RW_READER);
2093 hat_swapout(as->a_hat);
2100 for (seg = AS_SEGFIRST(as); seg != NULL; seg = AS_SEGNEXT(as, seg)) {
2112 AS_LOCK_EXIT(as);
2121 as_incore(struct as *as, caddr_t addr,
2139 AS_LOCK_ENTER(as, RW_READER);
2140 seg = as_segat(as, raddr);
2142 AS_LOCK_EXIT(as);
2148 seg = AS_SEGNEXT(as, seg);
2165 AS_LOCK_EXIT(as);
2191 as_unlockerr(struct as *as, int attr, ulong_t *mlock_map,
2194 struct seg *seg = as_segat(as, raddr);
2199 seg = AS_SEGNEXT(as, seg);
2215 * address space "as".
2219 as_ctl(struct as *as, caddr_t addr, size_t size, int func, int attr,
2235 AS_LOCK_ENTER(as, RW_WRITER);
2237 AS_LOCK_ENTER(as, RW_READER);
2241 * all segments in the address space, as appropriate.
2245 size_t rlen = 0; /* rounded as length */
2250 mutex_enter(&as->a_contents);
2251 AS_SETPGLCK(as);
2252 mutex_exit(&as->a_contents);
2255 AS_LOCK_EXIT(as);
2259 seg = AS_SEGFIRST(as);
2261 AS_LOCK_EXIT(as);
2270 } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
2275 AS_LOCK_EXIT(as);
2279 for (seg = AS_SEGFIRST(as); seg; seg = AS_SEGNEXT(as, seg)) {
2288 for (seg = AS_SEGFIRST(as); seg != NULL;
2289 seg = AS_SEGNEXT(as, seg)) {
2301 AS_LOCK_EXIT(as);
2304 mutex_enter(&as->a_contents);
2305 AS_CLRPGLCK(as);
2306 mutex_exit(&as->a_contents);
2308 for (seg = AS_SEGFIRST(as); seg; seg = AS_SEGNEXT(as, seg)) {
2315 AS_LOCK_EXIT(as);
2327 AS_LOCK_EXIT(as);
2334 if ((seg = as_segat(as, raddr)) == NULL) {
2335 AS_LOCK_EXIT(as);
2343 AS_LOCK_EXIT(as);
2360 seg = AS_SEGNEXT(as, seg);
2363 as_unlockerr(as, attr, mlock_map,
2368 AS_LOCK_EXIT(as);
2389 AS_LOCK_EXIT(as);
2400 as_unlockerr(as, attr, mlock_map, initraddr,
2404 AS_LOCK_EXIT(as);
2433 AS_LOCK_EXIT(as);
2441 seg = as_segat(as, raddr);
2443 AS_LOCK_EXIT(as);
2450 AS_LOCK_EXIT(as);
2464 AS_LOCK_EXIT(as);
2483 AS_LOCK_EXIT(as);
2526 * as expected by the caller. Save pointers to per segment shadow lists at
2530 as_pagelock_segs(struct as *as, struct seg *seg, struct page ***ppp,
2548 ASSERT(AS_LOCK_HELD(as));
2563 seg = AS_SEGNEXT(as, seg);
2565 AS_LOCK_EXIT(as);
2577 AS_LOCK_EXIT(as);
2581 AS_LOCK_EXIT(as);
2602 seg = AS_SEGNEXT(as, seg);
2626 AS_LOCK_EXIT(as);
2644 seg = AS_SEGNEXT(as, seg);
2660 AS_LOCK_EXIT(as);
2675 fault_err = as_fault(as->a_hat, as, sv_addr, sv_size, F_SOFTLOCK, rw);
2689 as_pagelock(struct as *as, struct page ***ppp, caddr_t addr,
2709 AS_LOCK_ENTER(as, RW_READER);
2711 seg = as_segat(as, raddr);
2713 AS_LOCK_EXIT(as);
2718 return (as_pagelock_segs(as, seg, ppp, raddr, rsize, rw));
2721 AS_LOCK_EXIT(as);
2735 AS_LOCK_EXIT(as);
2748 fault_err = as_fault(as->a_hat, as, addr, size, F_SOFTLOCK, rw);
2761 * Drop as lock and free plist.
2764 as_pageunlock_segs(struct as *as, struct seg *seg, caddr_t addr, size_t size,
2773 ASSERT(AS_LOCK_HELD(as));
2783 seg = AS_SEGNEXT(as, seg);
2798 AS_LOCK_EXIT(as);
2808 as_pageunlock(struct as *as, struct page **pp, caddr_t addr, size_t size,
2823 (void) as_fault(as->a_hat, as, addr, size, F_SOFTUNLOCK, rw);
2831 AS_LOCK_ENTER(as, RW_READER);
2832 seg = as_segat(as, raddr);
2842 as_pageunlock_segs(as, seg, raddr, rsize, pp, rw);
2845 AS_LOCK_EXIT(as);
2850 as_setpagesize(struct as *as, caddr_t addr, size_t size, uint_t szc,
2871 AS_LOCK_ENTER(as, RW_WRITER);
2872 as_clearwatchprot(as, raddr, rsize);
2873 seg = as_segat(as, raddr);
2875 as_setwatch(as);
2876 AS_LOCK_EXIT(as);
2882 seg = AS_SEGNEXT(as, seg);
2903 AS_LOCK_EXIT(as);
2934 * there's no need to trigger as callbacks like
2937 mutex_enter(&as->a_contents);
2938 if (!AS_ISNOUNMAPWAIT(as)) {
2939 if (AS_ISUNMAPWAIT(as) == 0) {
2940 cv_broadcast(&as->a_cv);
2942 AS_SETUNMAPWAIT(as);
2943 AS_LOCK_EXIT(as);
2944 while (AS_ISUNMAPWAIT(as)) {
2945 cv_wait(&as->a_cv, &as->a_contents);
2953 * 0. We don't drop as writer lock so our
2958 AS_CLRNOUNMAPWAIT(as);
2959 mutex_exit(&as->a_contents);
2962 mutex_exit(&as->a_contents);
2968 as_setwatch(as);
2969 AS_LOCK_EXIT(as);
2978 as_iset3_default_lpsize(struct as *as, caddr_t raddr, size_t rsize, uint_t szc,
2985 ASSERT(AS_WRITE_HELD(as));
2987 seg = as_segat(as, raddr);
2994 seg = AS_SEGNEXT(as, seg);
2996 panic("as_iset3_default_lpsize: as changed");
3036 as_iset2_default_lpsize(struct as *as, caddr_t addr, size_t size, uint_t szc,
3042 ASSERT(AS_WRITE_HELD(as));
3045 error = as_iset3_default_lpsize(as, addr, size, szc, &retry);
3064 as_iset1_default_lpsize(struct as *as, caddr_t raddr, size_t rsize, uint_t szc,
3074 ASSERT(AS_WRITE_HELD(as));
3076 seg = as_segat(as, raddr);
3088 seg = AS_SEGNEXT(as, seg);
3090 panic("as_iset1_default_lpsize: as changed");
3094 error = as_iset2_default_lpsize(as,
3115 error = as_iset2_default_lpsize(as, setaddr, setsize,
3127 as_iset_default_lpsize(struct as *as, caddr_t addr, size_t size, int flags,
3142 ASSERT(AS_WRITE_HELD(as));
3174 error = as_iset1_default_lpsize(as, addr, segsize, szc,
3193 error = as_iset1_default_lpsize(as, addr, segsize, szc,
3218 as_set_default_lpsize(struct as *as, caddr_t addr, size_t size)
3234 AS_LOCK_ENTER(as, RW_WRITER);
3243 AS_LOCK_EXIT(as);
3246 as_clearwatchprot(as, raddr, rsize);
3247 seg = as_segat(as, raddr);
3249 as_setwatch(as);
3250 AS_LOCK_EXIT(as);
3266 seg = AS_SEGNEXT(as, seg);
3282 error = as_iset_default_lpsize(as,
3301 error = as_iset_default_lpsize(as,
3318 error = as_iset_default_lpsize(as, setaddr, setsize,
3329 mutex_enter(&as->a_contents);
3330 if (!AS_ISNOUNMAPWAIT(as)) {
3331 if (AS_ISUNMAPWAIT(as) == 0) {
3332 cv_broadcast(&as->a_cv);
3334 AS_SETUNMAPWAIT(as);
3335 AS_LOCK_EXIT(as);
3336 while (AS_ISUNMAPWAIT(as)) {
3337 cv_wait(&as->a_cv, &as->a_contents);
3339 mutex_exit(&as->a_contents);
3340 AS_LOCK_ENTER(as, RW_WRITER);
3346 * in this segment may be already 0. We don't drop as
3351 AS_CLRNOUNMAPWAIT(as);
3352 mutex_exit(&as->a_contents);
3357 as_setwatch(as);
3358 AS_LOCK_EXIT(as);
3366 as_setwatch(struct as *as)
3374 if (avl_numnodes(&as->a_wpage) == 0)
3377 ASSERT(AS_WRITE_HELD(as));
3379 for (pwp = avl_first(&as->a_wpage); pwp != NULL;
3380 pwp = AVL_NEXT(&as->a_wpage, pwp)) {
3385 (seg = as_segat(as, vaddr)) == NULL ||
3413 as_clearwatch(struct as *as)
3421 if (avl_numnodes(&as->a_wpage) == 0)
3424 ASSERT(AS_WRITE_HELD(as));
3426 for (pwp = avl_first(&as->a_wpage); pwp != NULL;
3427 pwp = AVL_NEXT(&as->a_wpage, pwp)) {
3432 (seg = as_segat(as, vaddr)) == NULL)
3452 as_setwatchprot(struct as *as, caddr_t addr, size_t size, uint_t prot)
3463 if (avl_numnodes(&as->a_wpage) == 0)
3466 ASSERT(AS_WRITE_HELD(as));
3469 if ((pwp = avl_find(&as->a_wpage, &tpw, &where)) == NULL)
3470 pwp = avl_nearest(&as->a_wpage, where, AVL_AFTER);
3485 seg = as_segat(as, vaddr);
3500 pwp = AVL_NEXT(&as->a_wpage, pwp);
3508 as_clearwatchprot(struct as *as, caddr_t addr, size_t size)
3518 if (avl_numnodes(&as->a_wpage) == 0)
3522 if ((pwp = avl_find(&as->a_wpage, &tpw, &where)) == NULL)
3523 pwp = avl_nearest(&as->a_wpage, where, AVL_AFTER);
3525 ASSERT(AS_WRITE_HELD(as));
3534 seg = as_segat(as, pwp->wp_vaddr);
3550 pwp = AVL_NEXT(&as->a_wpage, pwp);
3555 as_signal_proc(struct as *as, k_siginfo_t *siginfo)
3561 if (p->p_as == as) {
3563 if (p->p_as == as)
3575 as_getmemid(struct as *as, caddr_t addr, memid_t *memidp)
3580 AS_LOCK_ENTER(as, RW_READER);
3581 seg = as_segat(as, addr);
3583 AS_LOCK_EXIT(as);
3590 AS_LOCK_EXIT(as);
3596 AS_LOCK_EXIT(as);