1907 atomic_add_long((ulong_t *)(
1908 &(shmd->shm_softlockcnt)), -npages);
1909 }
1910 goto dism_err;
1911 }
1912 AS_LOCK_ENTER(sptseg->s_as, &sptseg->s_as->a_lock, RW_READER);
1913 a = segspt_addr;
1914 pidx = 0;
1915 if (type == F_SOFTLOCK) {
1916
1917 /*
1918 * Load up the translation keeping it
1919 * locked and don't unlock the page.
1920 */
1921 for (; pidx < npages; a += pgsz, pidx += pgcnt) {
1922 hat_memload_array(sptseg->s_as->a_hat,
1923 a, pgsz, &ppa[pidx], sptd->spt_prot,
1924 HAT_LOAD_LOCK | HAT_LOAD_SHARE);
1925 }
1926 } else {
1927 if (hat == seg->s_as->a_hat) {
1928
1929 /*
1930 * Migrate pages marked for migration
1931 */
1932 if (lgrp_optimizations())
1933 page_migrate(seg, shm_addr, ppa,
1934 npages);
1935
1936 /* CPU HAT */
1937 for (; pidx < npages;
1938 a += pgsz, pidx += pgcnt) {
1939 hat_memload_array(sptseg->s_as->a_hat,
1940 a, pgsz, &ppa[pidx],
1941 sptd->spt_prot,
1942 HAT_LOAD_SHARE);
1943 }
1944 } else {
1945 /* XHAT. Pass real address */
1946 hat_memload_array(hat, shm_addr,
1947 size, ppa, sptd->spt_prot, HAT_LOAD_SHARE);
1948 }
1949
1950 /*
1951 * And now drop the SE_SHARED lock(s).
1952 */
1953 if (dyn_ism_unmap) {
1954 for (i = 0; i < npages; i++) {
1955 page_unlock(ppa[i]);
1956 }
1957 }
1958 }
1959
1960 if (!dyn_ism_unmap) {
1961 if (hat_share(seg->s_as->a_hat, shm_addr,
1962 curspt->a_hat, segspt_addr, ptob(npages),
1963 seg->s_szc) != 0) {
1964 panic("hat_share err in DISM fault");
1965 /* NOTREACHED */
1966 }
1967 if (type == F_INVAL) {
1968 for (i = 0; i < npages; i++) {
2167 * We are already holding the as->a_lock on the user's
2168 * real segment, but we need to hold the a_lock on the
2169 * underlying dummy as. This is mostly to satisfy the
2170 * underlying HAT layer.
2171 */
2172 AS_LOCK_ENTER(sptseg->s_as, &sptseg->s_as->a_lock, RW_READER);
2173 a = sptseg_addr;
2174 pidx = 0;
2175 if (type == F_SOFTLOCK) {
2176 /*
2177 * Load up the translation keeping it
2178 * locked and don't unlock the page.
2179 */
2180 for (; pidx < npages; a += pgsz, pidx += pgcnt) {
2181 sz = MIN(pgsz, ptob(npages - pidx));
2182 hat_memload_array(sptseg->s_as->a_hat, a,
2183 sz, &ppa[pidx], sptd->spt_prot,
2184 HAT_LOAD_LOCK | HAT_LOAD_SHARE);
2185 }
2186 } else {
2187 if (hat == seg->s_as->a_hat) {
2188
2189 /*
2190 * Migrate pages marked for migration.
2191 */
2192 if (lgrp_optimizations())
2193 page_migrate(seg, shm_addr, ppa,
2194 npages);
2195
2196 /* CPU HAT */
2197 for (; pidx < npages;
2198 a += pgsz, pidx += pgcnt) {
2199 sz = MIN(pgsz, ptob(npages - pidx));
2200 hat_memload_array(sptseg->s_as->a_hat,
2201 a, sz, &ppa[pidx],
2202 sptd->spt_prot, HAT_LOAD_SHARE);
2203 }
2204 } else {
2205 /* XHAT. Pass real address */
2206 hat_memload_array(hat, shm_addr,
2207 ptob(npages), ppa, sptd->spt_prot,
2208 HAT_LOAD_SHARE);
2209 }
2210
2211 /*
2212 * And now drop the SE_SHARED lock(s).
2213 */
2214 for (i = 0; i < npages; i++)
2215 page_unlock(ppa[i]);
2216 }
2217 AS_LOCK_EXIT(sptseg->s_as, &sptseg->s_as->a_lock);
2218
2219 kmem_free(ppa, sizeof (page_t *) * npages);
2220 return (0);
2221 case F_SOFTUNLOCK:
2222
2223 /*
2224 * This is a bit ugly, we pass in the real seg pointer,
2225 * but the sptseg_addr is the virtual address within the
2226 * dummy seg.
2227 */
2228 segspt_softunlock(seg, sptseg_addr, ptob(npages), rw);
|
1907 atomic_add_long((ulong_t *)(
1908 &(shmd->shm_softlockcnt)), -npages);
1909 }
1910 goto dism_err;
1911 }
1912 AS_LOCK_ENTER(sptseg->s_as, &sptseg->s_as->a_lock, RW_READER);
1913 a = segspt_addr;
1914 pidx = 0;
1915 if (type == F_SOFTLOCK) {
1916
1917 /*
1918 * Load up the translation keeping it
1919 * locked and don't unlock the page.
1920 */
1921 for (; pidx < npages; a += pgsz, pidx += pgcnt) {
1922 hat_memload_array(sptseg->s_as->a_hat,
1923 a, pgsz, &ppa[pidx], sptd->spt_prot,
1924 HAT_LOAD_LOCK | HAT_LOAD_SHARE);
1925 }
1926 } else {
1927 /*
1928 * Migrate pages marked for migration
1929 */
1930 if (lgrp_optimizations())
1931 page_migrate(seg, shm_addr, ppa, npages);
1932
1933 for (; pidx < npages; a += pgsz, pidx += pgcnt) {
1934 hat_memload_array(sptseg->s_as->a_hat,
1935 a, pgsz, &ppa[pidx],
1936 sptd->spt_prot,
1937 HAT_LOAD_SHARE);
1938 }
1939
1940 /*
1941 * And now drop the SE_SHARED lock(s).
1942 */
1943 if (dyn_ism_unmap) {
1944 for (i = 0; i < npages; i++) {
1945 page_unlock(ppa[i]);
1946 }
1947 }
1948 }
1949
1950 if (!dyn_ism_unmap) {
1951 if (hat_share(seg->s_as->a_hat, shm_addr,
1952 curspt->a_hat, segspt_addr, ptob(npages),
1953 seg->s_szc) != 0) {
1954 panic("hat_share err in DISM fault");
1955 /* NOTREACHED */
1956 }
1957 if (type == F_INVAL) {
1958 for (i = 0; i < npages; i++) {
2157 * We are already holding the as->a_lock on the user's
2158 * real segment, but we need to hold the a_lock on the
2159 * underlying dummy as. This is mostly to satisfy the
2160 * underlying HAT layer.
2161 */
2162 AS_LOCK_ENTER(sptseg->s_as, &sptseg->s_as->a_lock, RW_READER);
2163 a = sptseg_addr;
2164 pidx = 0;
2165 if (type == F_SOFTLOCK) {
2166 /*
2167 * Load up the translation keeping it
2168 * locked and don't unlock the page.
2169 */
2170 for (; pidx < npages; a += pgsz, pidx += pgcnt) {
2171 sz = MIN(pgsz, ptob(npages - pidx));
2172 hat_memload_array(sptseg->s_as->a_hat, a,
2173 sz, &ppa[pidx], sptd->spt_prot,
2174 HAT_LOAD_LOCK | HAT_LOAD_SHARE);
2175 }
2176 } else {
2177 /*
2178 * Migrate pages marked for migration.
2179 */
2180 if (lgrp_optimizations())
2181 page_migrate(seg, shm_addr, ppa, npages);
2182
2183 for (; pidx < npages; a += pgsz, pidx += pgcnt) {
2184 sz = MIN(pgsz, ptob(npages - pidx));
2185 hat_memload_array(sptseg->s_as->a_hat,
2186 a, sz, &ppa[pidx],
2187 sptd->spt_prot, HAT_LOAD_SHARE);
2188 }
2189
2190 /*
2191 * And now drop the SE_SHARED lock(s).
2192 */
2193 for (i = 0; i < npages; i++)
2194 page_unlock(ppa[i]);
2195 }
2196 AS_LOCK_EXIT(sptseg->s_as, &sptseg->s_as->a_lock);
2197
2198 kmem_free(ppa, sizeof (page_t *) * npages);
2199 return (0);
2200 case F_SOFTUNLOCK:
2201
2202 /*
2203 * This is a bit ugly, we pass in the real seg pointer,
2204 * but the sptseg_addr is the virtual address within the
2205 * dummy seg.
2206 */
2207 segspt_softunlock(seg, sptseg_addr, ptob(npages), rw);
|