2033 }
2034
2035 seg = AS_SEGNEXT(as, seg);
2036
2037 if (seg != NULL)
2038 addr = seg->s_base;
2039 }
2040
2041 *basep = addr;
2042
2043 if (segend > eaddr)
2044 *lenp = eaddr - addr;
2045 else
2046 *lenp = segend - addr;
2047
2048 AS_LOCK_EXIT(as);
2049 return (0);
2050 }
2051
2052 /*
2053 * Swap the pages associated with the address space as out to
2054 * secondary storage, returning the number of bytes actually
2055 * swapped.
2056 *
2057 * The value returned is intended to correlate well with the process's
2058 * memory requirements. Its usefulness for this purpose depends on
2059 * how well the segment-level routines do at returning accurate
2060 * information.
2061 */
2062 size_t
2063 as_swapout(struct as *as)
2064 {
2065 struct seg *seg;
2066 size_t swpcnt = 0;
2067
2068 /*
2069 * Kernel-only processes have given up their address
2070 * spaces. Of course, we shouldn't be attempting to
2071 * swap out such processes in the first place...
2072 */
2073 if (as == NULL)
2074 return (0);
2075
2076 AS_LOCK_ENTER(as, RW_READER);
2077
2078 /*
2079 * Free all mapping resources associated with the address
2080 * space. The segment-level swapout routines capitalize
2081 * on this unmapping by scavanging pages that have become
2082 * unmapped here.
2083 */
2084 hat_swapout(as->a_hat);
2085
2086 /*
2087 * Call the swapout routines of all segments in the address
2088 * space to do the actual work, accumulating the amount of
2089 * space reclaimed.
2090 */
2091 for (seg = AS_SEGFIRST(as); seg != NULL; seg = AS_SEGNEXT(as, seg)) {
2092 struct seg_ops *ov = seg->s_ops;
2093
2094 /*
2095 * We have to check to see if the seg has
2096 * an ops vector because the seg may have
2097 * been in the middle of being set up when
2098 * the process was picked for swapout.
2099 */
2100 if ((ov != NULL) && (ov->swapout != NULL))
2101 swpcnt += SEGOP_SWAPOUT(seg);
2102 }
2103 AS_LOCK_EXIT(as);
2104 return (swpcnt);
2105 }
2106
2107 /*
2108 * Determine whether data from the mappings in interval [addr, addr + size)
2109 * are in the primary memory (core) cache.
2110 */
2111 int
2112 as_incore(struct as *as, caddr_t addr,
2113 size_t size, char *vec, size_t *sizep)
2114 {
2115 struct seg *seg;
2116 size_t ssize;
2117 caddr_t raddr; /* rounded down addr */
2118 size_t rsize; /* rounded up size */
2119 size_t isize; /* iteration size */
2120 int error = 0; /* result, assume success */
2121
2122 *sizep = 0;
2123 raddr = (caddr_t)((uintptr_t)addr & (uintptr_t)PAGEMASK);
2124 rsize = ((((size_t)addr + size) + PAGEOFFSET) & PAGEMASK) -
2125 (size_t)raddr;
2126
2127 if (raddr + rsize < raddr) /* check for wraparound */
|
2033 }
2034
2035 seg = AS_SEGNEXT(as, seg);
2036
2037 if (seg != NULL)
2038 addr = seg->s_base;
2039 }
2040
2041 *basep = addr;
2042
2043 if (segend > eaddr)
2044 *lenp = eaddr - addr;
2045 else
2046 *lenp = segend - addr;
2047
2048 AS_LOCK_EXIT(as);
2049 return (0);
2050 }
2051
2052 /*
2053 * Determine whether data from the mappings in interval [addr, addr + size)
2054 * are in the primary memory (core) cache.
2055 */
2056 int
2057 as_incore(struct as *as, caddr_t addr,
2058 size_t size, char *vec, size_t *sizep)
2059 {
2060 struct seg *seg;
2061 size_t ssize;
2062 caddr_t raddr; /* rounded down addr */
2063 size_t rsize; /* rounded up size */
2064 size_t isize; /* iteration size */
2065 int error = 0; /* result, assume success */
2066
2067 *sizep = 0;
2068 raddr = (caddr_t)((uintptr_t)addr & (uintptr_t)PAGEMASK);
2069 rsize = ((((size_t)addr + size) + PAGEOFFSET) & PAGEMASK) -
2070 (size_t)raddr;
2071
2072 if (raddr + rsize < raddr) /* check for wraparound */
|