Lines Matching defs:as

62 #include <vm/as.h>
75 static void as_setwatchprot(struct as *, caddr_t, size_t, uint_t);
76 static void as_clearwatchprot(struct as *, caddr_t, size_t);
77 int as_map_locked(struct as *, caddr_t, size_t, int ((*)()), void *);
92 * Link the entry on the as->a_callbacks list. A callback entry for the
96 * the specified as, the caller must guarantee persistence of the specified as
97 * for the duration of this function (eg. pages being locked within the as
101 as_add_callback(struct as *as, void (*cb_func)(), void *arg, uint_t events,
113 if (as == &kas)
146 mutex_enter(&as->a_contents);
147 current_head = as->a_callbacks;
148 as->a_callbacks = cb;
157 if ((cb->ascb_events & AS_UNMAPWAIT_EVENT) && AS_ISUNMAPWAIT(as)) {
158 AS_CLRUNMAPWAIT(as);
159 cv_broadcast(&as->a_cv);
162 mutex_exit(&as->a_contents);
182 * the specified as, the caller must guarantee persistence of the specified as
183 * for the duration of this function (eg. pages being locked within the as
187 as_delete_callback(struct as *as, void *arg)
189 struct as_callback **prevcb = &as->a_callbacks;
193 mutex_enter(&as->a_contents);
194 for (cb = as->a_callbacks; cb; prevcb = &cb->ascb_next, cb = *prevcb) {
211 cv_broadcast(&as->a_cv);
219 mutex_exit(&as->a_contents);
224 * Searches the as callback list for a matching entry.
233 as_find_callback(struct as *as, uint_t events, caddr_t event_addr,
238 ASSERT(MUTEX_HELD(&as->a_contents));
239 for (cb = as->a_callbacks; cb != NULL; cb = cb->ascb_next) {
265 as_execute_callback(struct as *as, struct as_callback *cb,
271 ASSERT(MUTEX_HELD(&as->a_contents) && (cb->ascb_events & events));
273 mutex_exit(&as->a_contents);
274 (*cb->ascb_func)(as, cb->ascb_arg, events);
275 mutex_enter(&as->a_contents);
285 cv_wait(&as->a_cv, &as->a_contents);
297 prevcb = &as->a_callbacks;
298 for (cb = as->a_callbacks; cb != NULL;
333 as_do_callbacks(struct as *as, uint_t events, caddr_t event_addr,
338 if ((cb = as_find_callback(as, events, event_addr, event_len))) {
339 as_execute_callback(as, cb, events);
357 as_findseg(struct as *as, caddr_t addr, int tail)
359 struct seg *seg = as->a_seglast;
362 ASSERT(AS_LOCK_HELD(as));
369 seg = avl_find(&as->a_segtree, &addr, &where);
371 return (as->a_seglast = seg);
373 seg = avl_nearest(&as->a_segtree, where, AVL_AFTER);
375 seg = avl_last(&as->a_segtree);
376 return (as->a_seglast = seg);
384 as_verify(struct as *as)
392 seglast = as->a_seglast;
394 for (seg = AS_SEGFIRST(as); seg != NULL; seg = AS_SEGNEXT(as, seg)) {
395 ASSERT(seg->s_as == as);
396 p = AS_SEGPREV(as, seg);
397 n = AS_SEGNEXT(as, seg);
398 ASSERT(p == NULL || p->s_as == as);
401 ASSERT(n != NULL || seg == avl_last(&as->a_segtree));
407 ASSERT(avl_numnodes(&as->a_segtree) == nsegs);
414 * in as_gap() as an insertion point.
417 as_addseg(struct as *as, struct seg *newseg)
424 ASSERT(AS_WRITE_HELD(as));
426 as->a_updatedir = 1; /* inform /proc */
427 gethrestime(&as->a_updatetime);
429 if (as->a_lastgaphl != NULL) {
433 if (as->a_lastgaphl->s_base > newseg->s_base) {
434 hseg = as->a_lastgaphl;
435 lseg = AVL_PREV(&as->a_segtree, hseg);
437 lseg = as->a_lastgaphl;
438 hseg = AVL_NEXT(&as->a_segtree, lseg);
443 avl_insert_here(&as->a_segtree, newseg, lseg,
445 as->a_lastgaphl = NULL;
446 as->a_seglast = newseg;
449 as->a_lastgaphl = NULL;
456 seg = avl_find(&as->a_segtree, &addr, &where);
459 seg = avl_nearest(&as->a_segtree, where, AVL_AFTER);
462 seg = avl_last(&as->a_segtree);
492 as->a_seglast = newseg;
493 avl_insert(&as->a_segtree, newseg, where);
496 as_verify(as);
502 as_removeseg(struct as *as, struct seg *seg)
506 ASSERT(AS_WRITE_HELD(as));
508 as->a_updatedir = 1; /* inform /proc */
509 gethrestime(&as->a_updatetime);
514 t = &as->a_segtree;
515 if (as->a_seglast == seg)
516 as->a_seglast = NULL;
517 as->a_lastgaphl = NULL;
523 if (as->a_lastgap &&
524 (seg == as->a_lastgap || seg->s_base > as->a_lastgap->s_base))
525 as->a_lastgap = AVL_NEXT(t, seg);
533 as_verify(as);
542 as_segat(struct as *as, caddr_t addr)
544 struct seg *seg = as->a_seglast;
546 ASSERT(AS_LOCK_HELD(as));
552 seg = avl_find(&as->a_segtree, &addr, NULL);
563 as_rangelock(struct as *as)
565 mutex_enter(&as->a_contents);
566 while (AS_ISCLAIMGAP(as))
567 cv_wait(&as->a_cv, &as->a_contents);
568 AS_SETCLAIMGAP(as);
569 mutex_exit(&as->a_contents);
576 as_rangeunlock(struct as *as)
578 mutex_enter(&as->a_contents);
579 AS_CLRCLAIMGAP(as);
580 cv_signal(&as->a_cv);
581 mutex_exit(&as->a_contents);
602 as_avlinit(struct as *as)
604 avl_create(&as->a_segtree, as_segcompar, sizeof (struct seg),
606 avl_create(&as->a_wpage, wp_compare, sizeof (struct watched_page),
614 struct as *as = buf;
616 mutex_init(&as->a_contents, NULL, MUTEX_DEFAULT, NULL);
617 cv_init(&as->a_cv, NULL, CV_DEFAULT, NULL);
618 rw_init(&as->a_lock, NULL, RW_DEFAULT, NULL);
619 as_avlinit(as);
627 struct as *as = buf;
629 avl_destroy(&as->a_segtree);
630 mutex_destroy(&as->a_contents);
631 cv_destroy(&as->a_cv);
632 rw_destroy(&as->a_lock);
638 as_cache = kmem_cache_create("as_cache", sizeof (struct as), 0,
647 struct as *
650 struct as *as;
652 as = kmem_cache_alloc(as_cache, KM_SLEEP);
654 as->a_flags = 0;
655 as->a_vbits = 0;
656 as->a_hrm = NULL;
657 as->a_seglast = NULL;
658 as->a_size = 0;
659 as->a_resvsize = 0;
660 as->a_updatedir = 0;
661 gethrestime(&as->a_updatetime);
662 as->a_objectdir = NULL;
663 as->a_sizedir = 0;
664 as->a_userlimit = (caddr_t)USERLIMIT;
665 as->a_lastgap = NULL;
666 as->a_lastgaphl = NULL;
667 as->a_callbacks = NULL;
669 AS_LOCK_ENTER(as, RW_WRITER);
670 as->a_hat = hat_alloc(as); /* create hat for default system mmu */
671 AS_LOCK_EXIT(as);
673 return (as);
679 * all the segments on this as and finally
680 * the space for the as struct itself.
683 as_free(struct as *as)
685 struct hat *hat = as->a_hat;
695 mutex_enter(&as->a_contents);
696 while (as->a_callbacks && as_do_callbacks(as, AS_ALL_EVENT, 0, 0))
699 mutex_exit(&as->a_contents);
700 AS_LOCK_ENTER(as, RW_WRITER);
706 for (seg = AS_SEGFIRST(as); seg != NULL; seg = next) {
709 next = AS_SEGNEXT(as, seg);
713 mutex_enter(&as->a_contents);
714 if (as->a_callbacks) {
715 AS_LOCK_EXIT(as);
716 } else if (!AS_ISNOUNMAPWAIT(as)) {
722 if (AS_ISUNMAPWAIT(as) == 0)
723 cv_broadcast(&as->a_cv);
724 AS_SETUNMAPWAIT(as);
725 AS_LOCK_EXIT(as);
726 while (AS_ISUNMAPWAIT(as))
727 cv_wait(&as->a_cv, &as->a_contents);
734 * 0. We don't drop as writer lock so our
739 AS_CLRNOUNMAPWAIT(as);
740 mutex_exit(&as->a_contents);
743 mutex_exit(&as->a_contents);
754 AS_LOCK_EXIT(as);
757 ASSERT(avl_numnodes(&as->a_wpage) == 0);
758 if (as->a_objectdir) {
759 kmem_free(as->a_objectdir, as->a_sizedir * sizeof (vnode_t *));
760 as->a_objectdir = NULL;
761 as->a_sizedir = 0;
765 * Free the struct as back to kmem. Assert it has no segments.
767 ASSERT(avl_numnodes(&as->a_segtree) == 0);
768 kmem_cache_free(as_cache, as);
772 as_dup(struct as *as, struct proc *forkedproc)
774 struct as *newas;
779 AS_LOCK_ENTER(as, RW_WRITER);
780 as_clearwatch(as);
782 newas->a_userlimit = as->a_userlimit;
787 (void) hat_dup(as->a_hat, newas->a_hat, NULL, 0, HAT_DUP_SRD);
789 for (seg = AS_SEGFIRST(as); seg != NULL; seg = AS_SEGNEXT(as, seg)) {
799 as_setwatch(as);
800 AS_LOCK_EXIT(as);
810 as_setwatch(as);
811 AS_LOCK_EXIT(as);
819 newas->a_resvsize = as->a_resvsize - purgesize;
821 error = hat_dup(as->a_hat, newas->a_hat, NULL, 0, HAT_DUP_ALL);
825 as_setwatch(as);
826 AS_LOCK_EXIT(as);
839 as_fault(struct hat *hat, struct as *as, caddr_t addr, size_t size,
885 if (as == &kas)
902 * XXX -- Don't grab the as lock for segkmap. We should grab it for
906 * as exec'ing requires the write lock on the as.
908 if (as == &kas && segkmap && segkmap->s_base <= raddr &&
913 AS_LOCK_ENTER(as, RW_READER);
915 seg = as_segat(as, raddr);
917 AS_LOCK_EXIT(as);
931 seg = AS_SEGNEXT(as, seg);
956 seg = AS_SEGNEXT(as, seg);
972 AS_LOCK_EXIT(as);
999 as_faulta(struct as *as, caddr_t addr, size_t size)
1020 AS_LOCK_ENTER(as, RW_READER);
1021 seg = as_segat(as, raddr);
1023 AS_LOCK_EXIT(as);
1031 seg = AS_SEGNEXT(as, seg);
1041 AS_LOCK_EXIT(as);
1063 * in address space `as' to have the specified protection.
1065 * as long as they are contiguous.
1068 as_setprot(struct as *as, caddr_t addr, size_t size, uint_t prot)
1091 * Normally we only lock the as as a reader. But
1094 * the as lock as a writer so the segment driver can change
1097 * locking as a writer. Since these opeartions should be rare
1098 * want to only lock as a writer when necessary.
1100 if (writer || avl_numnodes(&as->a_wpage) != 0) {
1101 AS_LOCK_ENTER(as, RW_WRITER);
1103 AS_LOCK_ENTER(as, RW_READER);
1106 as_clearwatchprot(as, raddr, rsize);
1107 seg = as_segat(as, raddr);
1109 as_setwatch(as);
1110 AS_LOCK_EXIT(as);
1116 seg = AS_SEGNEXT(as, seg);
1135 AS_LOCK_EXIT(as);
1142 * Make sure we have a_lock as writer.
1145 AS_LOCK_EXIT(as);
1182 mutex_enter(&as->a_contents);
1183 if (as->a_callbacks &&
1184 (cb = as_find_callback(as, AS_SETPROT_EVENT,
1186 AS_LOCK_EXIT(as);
1187 as_execute_callback(as, cb, AS_SETPROT_EVENT);
1188 } else if (!AS_ISNOUNMAPWAIT(as)) {
1189 if (AS_ISUNMAPWAIT(as) == 0)
1190 cv_broadcast(&as->a_cv);
1191 AS_SETUNMAPWAIT(as);
1192 AS_LOCK_EXIT(as);
1193 while (AS_ISUNMAPWAIT(as))
1194 cv_wait(&as->a_cv, &as->a_contents);
1201 * 0. We don't drop as writer lock so our
1206 AS_CLRNOUNMAPWAIT(as);
1207 mutex_exit(&as->a_contents);
1210 mutex_exit(&as->a_contents);
1216 as_setwatch(as);
1218 as_setwatchprot(as, saveraddr, saversize, prot);
1220 AS_LOCK_EXIT(as);
1226 * in address space `as' has at least the specified protection.
1227 * It is ok for the range to cross over several segments, as long
1228 * as they are contiguous.
1231 as_checkprot(struct as *as, caddr_t addr, size_t size, uint_t prot)
1247 * This is ugly as sin...
1253 if (avl_numnodes(&as->a_wpage) != 0)
1254 AS_LOCK_ENTER(as, RW_WRITER);
1256 AS_LOCK_ENTER(as, RW_READER);
1257 as_clearwatchprot(as, raddr, rsize);
1258 seg = as_segat(as, raddr);
1260 as_setwatch(as);
1261 AS_LOCK_EXIT(as);
1267 seg = AS_SEGNEXT(as, seg);
1282 as_setwatch(as);
1283 AS_LOCK_EXIT(as);
1288 as_unmap(struct as *as, caddr_t addr, size_t size)
1301 AS_LOCK_ENTER(as, RW_WRITER);
1303 as->a_updatedir = 1; /* inform /proc */
1304 gethrestime(&as->a_updatetime);
1310 as_clearwatchprot(as, raddr, eaddr - raddr);
1312 for (seg = as_findseg(as, raddr, 0); seg != NULL; seg = seg_next) {
1331 seg_next = AS_SEGNEXT(as, seg);
1378 mutex_enter(&as->a_contents);
1379 if (as->a_callbacks &&
1380 (cb = as_find_callback(as, AS_UNMAP_EVENT,
1382 AS_LOCK_EXIT(as);
1383 as_execute_callback(as, cb, AS_UNMAP_EVENT);
1384 } else if (!AS_ISNOUNMAPWAIT(as)) {
1385 if (AS_ISUNMAPWAIT(as) == 0)
1386 cv_broadcast(&as->a_cv);
1387 AS_SETUNMAPWAIT(as);
1388 AS_LOCK_EXIT(as);
1389 while (AS_ISUNMAPWAIT(as))
1390 cv_wait(&as->a_cv, &as->a_contents);
1397 * 0. We don't drop as writer lock so our
1402 AS_CLRNOUNMAPWAIT(as);
1403 mutex_exit(&as->a_contents);
1406 mutex_exit(&as->a_contents);
1409 AS_LOCK_EXIT(as);
1412 as_setwatch(as);
1413 AS_LOCK_EXIT(as);
1417 as->a_size -= ssize;
1419 as->a_resvsize -= rsize;
1422 AS_LOCK_EXIT(as);
1427 as_map_segvn_segs(struct as *as, caddr_t addr, size_t size, uint_t szcvec,
1441 ASSERT(AS_WRITE_HELD(as));
1450 seg = seg_alloc(as, addr, size);
1459 as->a_size += size;
1460 as->a_resvsize += size;
1482 seg = seg_alloc(as, addr, segsize);
1492 as->a_size += segsize;
1493 as->a_resvsize += segsize;
1511 seg = seg_alloc(as, addr, segsize);
1521 as->a_size += segsize;
1522 as->a_resvsize += segsize;
1541 as_map_vnsegs(struct as *as, caddr_t addr, size_t size,
1555 ASSERT(AS_WRITE_HELD(as));
1563 seg = seg_alloc(as, addr, size);
1572 as->a_size += size;
1573 as->a_resvsize += size;
1604 error = as_map_segvn_segs(as, addr, size, szcvec, crfp, vn_a,
1623 as_map_ansegs(struct as *as, caddr_t addr, size_t size,
1644 ASSERT(AS_WRITE_HELD(as));
1649 return (as_map_segvn_segs(as, addr, size, szcvec,
1654 as_map(struct as *as, caddr_t addr, size_t size, int (*crfp)(), void *argsp)
1656 AS_LOCK_ENTER(as, RW_WRITER);
1657 return (as_map_locked(as, addr, size, crfp, argsp));
1661 as_map_locked(struct as *as, caddr_t addr, size_t size, int (*crfp)(),
1679 if ((raddr + rsize < raddr) || (as->a_size > (ULONG_MAX - size))) {
1680 AS_LOCK_EXIT(as);
1684 as->a_updatedir = 1; /* inform /proc */
1685 gethrestime(&as->a_updatetime);
1687 if (as != &kas && as->a_size + rsize > (size_t)p->p_vmem_ctl) {
1688 AS_LOCK_EXIT(as);
1698 error = as_map_vnsegs(as, raddr, rsize, crfp, &crargs, &unmap);
1700 AS_LOCK_EXIT(as);
1702 (void) as_unmap(as, addr, size);
1708 error = as_map_ansegs(as, raddr, rsize, crfp, &crargs, &unmap);
1710 AS_LOCK_EXIT(as);
1712 (void) as_unmap(as, addr, size);
1717 seg = seg_alloc(as, addr, size);
1719 AS_LOCK_EXIT(as);
1726 AS_LOCK_EXIT(as);
1732 as->a_size += rsize;
1733 as->a_resvsize += rsize;
1736 as_setwatch(as);
1742 mutex_enter(&as->a_contents);
1743 if (AS_ISPGLCK(as)) {
1744 mutex_exit(&as->a_contents);
1745 AS_LOCK_EXIT(as);
1746 error = as_ctl(as, addr, size, MC_LOCK, 0, 0, NULL, 0);
1748 (void) as_unmap(as, addr, size);
1750 mutex_exit(&as->a_contents);
1751 AS_LOCK_EXIT(as);
1760 * These segments are deleted as a first step before calls to as_gap(), so
1764 as_purge(struct as *as)
1773 if ((as->a_flags & AS_NEEDSPURGE) == 0)
1776 AS_LOCK_ENTER(as, RW_WRITER);
1778 seg = AS_SEGFIRST(as);
1780 next_seg = AS_SEGNEXT(as, seg);
1785 AS_LOCK_EXIT(as);
1787 mutex_enter(&as->a_contents);
1788 as->a_flags &= ~AS_NEEDSPURGE;
1789 mutex_exit(&as->a_contents);
1801 * in the range. We use the as->a_lastgap field to figure out where to
1814 as_gap_aligned(struct as *as, size_t minlen, caddr_t *basep, size_t *lenp,
1848 AS_LOCK_ENTER(as, RW_READER);
1849 if (AS_SEGFIRST(as) == NULL) {
1852 AS_LOCK_EXIT(as);
1855 AS_LOCK_EXIT(as);
1871 hseg = as_findseg(as, lobound, 1);
1872 lseg = AS_SEGPREV(as, hseg);
1876 * If allocating at least as much as the last allocation,
1877 * use a_lastgap's base as a better estimate of hibound.
1879 if (as->a_lastgap &&
1880 minlen >= as->a_lastgap->s_size &&
1881 hibound >= as->a_lastgap->s_base)
1882 hibound = as->a_lastgap->s_base;
1884 hseg = as_findseg(as, hibound, 1);
1889 lseg = AS_SEGPREV(as, hseg);
1931 as->a_lastgap = hseg;
1933 as->a_lastgaphl = hseg;
1935 as->a_lastgaphl = lseg;
1936 AS_LOCK_EXIT(as);
1947 hseg = AS_SEGNEXT(as, hseg);
1952 lseg = AS_SEGPREV(as, lseg);
1963 AS_LOCK_EXIT(as);
1971 * in the range. We use the as->a_lastgap field to figure out where to
1985 as_gap(struct as *as, size_t minlen, caddr_t *basep, size_t *lenp, uint_t flags,
1989 return (as_gap_aligned(as, minlen, basep, lenp, flags, addr, 0, 0, 0));
1998 as_memory(struct as *as, caddr_t *basep, size_t *lenp)
2005 AS_LOCK_ENTER(as, RW_READER);
2010 seg = as_findseg(as, addr, 0);
2016 AS_LOCK_EXIT(as);
2035 seg = AS_SEGNEXT(as, seg);
2048 AS_LOCK_EXIT(as);
2053 * Swap the pages associated with the address space as out to
2063 as_swapout(struct as *as)
2073 if (as == NULL)
2076 AS_LOCK_ENTER(as, RW_READER);
2084 hat_swapout(as->a_hat);
2091 for (seg = AS_SEGFIRST(as); seg != NULL; seg = AS_SEGNEXT(as, seg)) {
2103 AS_LOCK_EXIT(as);
2112 as_incore(struct as *as, caddr_t addr,
2130 AS_LOCK_ENTER(as, RW_READER);
2131 seg = as_segat(as, raddr);
2133 AS_LOCK_EXIT(as);
2139 seg = AS_SEGNEXT(as, seg);
2156 AS_LOCK_EXIT(as);
2182 as_unlockerr(struct as *as, int attr, ulong_t *mlock_map,
2185 struct seg *seg = as_segat(as, raddr);
2190 seg = AS_SEGNEXT(as, seg);
2206 * address space "as".
2210 as_ctl(struct as *as, caddr_t addr, size_t size, int func, int attr,
2226 AS_LOCK_ENTER(as, RW_WRITER);
2228 AS_LOCK_ENTER(as, RW_READER);
2232 * all segments in the address space, as appropriate.
2236 size_t rlen = 0; /* rounded as length */
2241 mutex_enter(&as->a_contents);
2242 AS_SETPGLCK(as);
2243 mutex_exit(&as->a_contents);
2246 AS_LOCK_EXIT(as);
2250 seg = AS_SEGFIRST(as);
2252 AS_LOCK_EXIT(as);
2261 } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
2266 AS_LOCK_EXIT(as);
2270 for (seg = AS_SEGFIRST(as); seg; seg = AS_SEGNEXT(as, seg)) {
2279 for (seg = AS_SEGFIRST(as); seg != NULL;
2280 seg = AS_SEGNEXT(as, seg)) {
2292 AS_LOCK_EXIT(as);
2295 mutex_enter(&as->a_contents);
2296 AS_CLRPGLCK(as);
2297 mutex_exit(&as->a_contents);
2299 for (seg = AS_SEGFIRST(as); seg; seg = AS_SEGNEXT(as, seg)) {
2306 AS_LOCK_EXIT(as);
2318 AS_LOCK_EXIT(as);
2325 if ((seg = as_segat(as, raddr)) == NULL) {
2326 AS_LOCK_EXIT(as);
2334 AS_LOCK_EXIT(as);
2351 seg = AS_SEGNEXT(as, seg);
2354 as_unlockerr(as, attr, mlock_map,
2359 AS_LOCK_EXIT(as);
2380 AS_LOCK_EXIT(as);
2391 as_unlockerr(as, attr, mlock_map, initraddr,
2395 AS_LOCK_EXIT(as);
2424 AS_LOCK_EXIT(as);
2432 seg = as_segat(as, raddr);
2434 AS_LOCK_EXIT(as);
2441 AS_LOCK_EXIT(as);
2455 AS_LOCK_EXIT(as);
2474 AS_LOCK_EXIT(as);
2517 * as expected by the caller. Save pointers to per segment shadow lists at
2521 as_pagelock_segs(struct as *as, struct seg *seg, struct page ***ppp,
2539 ASSERT(AS_LOCK_HELD(as));
2554 seg = AS_SEGNEXT(as, seg);
2556 AS_LOCK_EXIT(as);
2568 AS_LOCK_EXIT(as);
2572 AS_LOCK_EXIT(as);
2593 seg = AS_SEGNEXT(as, seg);
2617 AS_LOCK_EXIT(as);
2635 seg = AS_SEGNEXT(as, seg);
2651 AS_LOCK_EXIT(as);
2666 fault_err = as_fault(as->a_hat, as, sv_addr, sv_size, F_SOFTLOCK, rw);
2680 as_pagelock(struct as *as, struct page ***ppp, caddr_t addr,
2700 AS_LOCK_ENTER(as, RW_READER);
2702 seg = as_segat(as, raddr);
2704 AS_LOCK_EXIT(as);
2709 return (as_pagelock_segs(as, seg, ppp, raddr, rsize, rw));
2712 AS_LOCK_EXIT(as);
2726 AS_LOCK_EXIT(as);
2739 fault_err = as_fault(as->a_hat, as, addr, size, F_SOFTLOCK, rw);
2752 * Drop as lock and free plist.
2755 as_pageunlock_segs(struct as *as, struct seg *seg, caddr_t addr, size_t size,
2764 ASSERT(AS_LOCK_HELD(as));
2774 seg = AS_SEGNEXT(as, seg);
2789 AS_LOCK_EXIT(as);
2799 as_pageunlock(struct as *as, struct page **pp, caddr_t addr, size_t size,
2814 (void) as_fault(as->a_hat, as, addr, size, F_SOFTUNLOCK, rw);
2822 AS_LOCK_ENTER(as, RW_READER);
2823 seg = as_segat(as, raddr);
2833 as_pageunlock_segs(as, seg, raddr, rsize, pp, rw);
2836 AS_LOCK_EXIT(as);
2841 as_setpagesize(struct as *as, caddr_t addr, size_t size, uint_t szc,
2862 AS_LOCK_ENTER(as, RW_WRITER);
2863 as_clearwatchprot(as, raddr, rsize);
2864 seg = as_segat(as, raddr);
2866 as_setwatch(as);
2867 AS_LOCK_EXIT(as);
2873 seg = AS_SEGNEXT(as, seg);
2894 AS_LOCK_EXIT(as);
2925 * there's no need to trigger as callbacks like
2928 mutex_enter(&as->a_contents);
2929 if (!AS_ISNOUNMAPWAIT(as)) {
2930 if (AS_ISUNMAPWAIT(as) == 0) {
2931 cv_broadcast(&as->a_cv);
2933 AS_SETUNMAPWAIT(as);
2934 AS_LOCK_EXIT(as);
2935 while (AS_ISUNMAPWAIT(as)) {
2936 cv_wait(&as->a_cv, &as->a_contents);
2944 * 0. We don't drop as writer lock so our
2949 AS_CLRNOUNMAPWAIT(as);
2950 mutex_exit(&as->a_contents);
2953 mutex_exit(&as->a_contents);
2959 as_setwatch(as);
2960 AS_LOCK_EXIT(as);
2969 as_iset3_default_lpsize(struct as *as, caddr_t raddr, size_t rsize, uint_t szc,
2976 ASSERT(AS_WRITE_HELD(as));
2978 seg = as_segat(as, raddr);
2985 seg = AS_SEGNEXT(as, seg);
2987 panic("as_iset3_default_lpsize: as changed");
3027 as_iset2_default_lpsize(struct as *as, caddr_t addr, size_t size, uint_t szc,
3033 ASSERT(AS_WRITE_HELD(as));
3036 error = as_iset3_default_lpsize(as, addr, size, szc, &retry);
3055 as_iset1_default_lpsize(struct as *as, caddr_t raddr, size_t rsize, uint_t szc,
3065 ASSERT(AS_WRITE_HELD(as));
3067 seg = as_segat(as, raddr);
3079 seg = AS_SEGNEXT(as, seg);
3081 panic("as_iset1_default_lpsize: as changed");
3085 error = as_iset2_default_lpsize(as,
3106 error = as_iset2_default_lpsize(as, setaddr, setsize,
3118 as_iset_default_lpsize(struct as *as, caddr_t addr, size_t size, int flags,
3133 ASSERT(AS_WRITE_HELD(as));
3165 error = as_iset1_default_lpsize(as, addr, segsize, szc,
3184 error = as_iset1_default_lpsize(as, addr, segsize, szc,
3209 as_set_default_lpsize(struct as *as, caddr_t addr, size_t size)
3225 AS_LOCK_ENTER(as, RW_WRITER);
3234 AS_LOCK_EXIT(as);
3237 as_clearwatchprot(as, raddr, rsize);
3238 seg = as_segat(as, raddr);
3240 as_setwatch(as);
3241 AS_LOCK_EXIT(as);
3257 seg = AS_SEGNEXT(as, seg);
3273 error = as_iset_default_lpsize(as,
3292 error = as_iset_default_lpsize(as,
3309 error = as_iset_default_lpsize(as, setaddr, setsize,
3320 mutex_enter(&as->a_contents);
3321 if (!AS_ISNOUNMAPWAIT(as)) {
3322 if (AS_ISUNMAPWAIT(as) == 0) {
3323 cv_broadcast(&as->a_cv);
3325 AS_SETUNMAPWAIT(as);
3326 AS_LOCK_EXIT(as);
3327 while (AS_ISUNMAPWAIT(as)) {
3328 cv_wait(&as->a_cv, &as->a_contents);
3330 mutex_exit(&as->a_contents);
3331 AS_LOCK_ENTER(as, RW_WRITER);
3337 * in this segment may be already 0. We don't drop as
3342 AS_CLRNOUNMAPWAIT(as);
3343 mutex_exit(&as->a_contents);
3348 as_setwatch(as);
3349 AS_LOCK_EXIT(as);
3357 as_setwatch(struct as *as)
3365 if (avl_numnodes(&as->a_wpage) == 0)
3368 ASSERT(AS_WRITE_HELD(as));
3370 for (pwp = avl_first(&as->a_wpage); pwp != NULL;
3371 pwp = AVL_NEXT(&as->a_wpage, pwp)) {
3376 (seg = as_segat(as, vaddr)) == NULL ||
3404 as_clearwatch(struct as *as)
3412 if (avl_numnodes(&as->a_wpage) == 0)
3415 ASSERT(AS_WRITE_HELD(as));
3417 for (pwp = avl_first(&as->a_wpage); pwp != NULL;
3418 pwp = AVL_NEXT(&as->a_wpage, pwp)) {
3423 (seg = as_segat(as, vaddr)) == NULL)
3443 as_setwatchprot(struct as *as, caddr_t addr, size_t size, uint_t prot)
3454 if (avl_numnodes(&as->a_wpage) == 0)
3457 ASSERT(AS_WRITE_HELD(as));
3460 if ((pwp = avl_find(&as->a_wpage, &tpw, &where)) == NULL)
3461 pwp = avl_nearest(&as->a_wpage, where, AVL_AFTER);
3476 seg = as_segat(as, vaddr);
3491 pwp = AVL_NEXT(&as->a_wpage, pwp);
3499 as_clearwatchprot(struct as *as, caddr_t addr, size_t size)
3509 if (avl_numnodes(&as->a_wpage) == 0)
3513 if ((pwp = avl_find(&as->a_wpage, &tpw, &where)) == NULL)
3514 pwp = avl_nearest(&as->a_wpage, where, AVL_AFTER);
3516 ASSERT(AS_WRITE_HELD(as));
3525 seg = as_segat(as, pwp->wp_vaddr);
3541 pwp = AVL_NEXT(&as->a_wpage, pwp);
3546 as_signal_proc(struct as *as, k_siginfo_t *siginfo)
3552 if (p->p_as == as) {
3554 if (p->p_as == as)
3566 as_getmemid(struct as *as, caddr_t addr, memid_t *memidp)
3571 AS_LOCK_ENTER(as, RW_READER);
3572 seg = as_segat(as, addr);
3574 AS_LOCK_EXIT(as);
3581 AS_LOCK_EXIT(as);
3587 AS_LOCK_EXIT(as);