59
60 /*
61 * segspt_minfree is the memory left for system after ISM
62 * locked its pages; it is set up to 5% of availrmem in
63 * sptcreate when ISM is created. ISM should not use more
64 * than ~90% of availrmem; if it does, then the performance
65 * of the system may decrease. Machines with large memories may
66 * be able to use up more memory for ISM so we set the default
67 * segspt_minfree to 5% (which gives ISM max 95% of availrmem.
68 * If somebody wants even more memory for ISM (risking hanging
69 * the system) they can patch the segspt_minfree to smaller number.
70 */
71 pgcnt_t segspt_minfree = 0;
72
73 static int segspt_create(struct seg *seg, caddr_t argsp);
74 static int segspt_unmap(struct seg *seg, caddr_t raddr, size_t ssize);
75 static void segspt_free(struct seg *seg);
76 static void segspt_free_pages(struct seg *seg, caddr_t addr, size_t len);
77 static lgrp_mem_policy_info_t *segspt_getpolicy(struct seg *seg, caddr_t addr);
78
79 static void
80 segspt_badop()
81 {
82 panic("segspt_badop called");
83 /*NOTREACHED*/
84 }
85
86 #define SEGSPT_BADOP(t) (t(*)())segspt_badop
87
88 struct seg_ops segspt_ops = {
89 SEGSPT_BADOP(int), /* dup */
90 segspt_unmap,
91 segspt_free,
92 SEGSPT_BADOP(int), /* fault */
93 SEGSPT_BADOP(faultcode_t), /* faulta */
94 SEGSPT_BADOP(int), /* setprot */
95 SEGSPT_BADOP(int), /* checkprot */
96 SEGSPT_BADOP(int), /* kluster */
97 SEGSPT_BADOP(size_t), /* swapout */
98 SEGSPT_BADOP(int), /* sync */
99 SEGSPT_BADOP(size_t), /* incore */
100 SEGSPT_BADOP(int), /* lockop */
101 SEGSPT_BADOP(int), /* getprot */
102 SEGSPT_BADOP(u_offset_t), /* getoffset */
103 SEGSPT_BADOP(int), /* gettype */
104 SEGSPT_BADOP(int), /* getvp */
105 SEGSPT_BADOP(int), /* advise */
106 SEGSPT_BADOP(void), /* dump */
107 SEGSPT_BADOP(int), /* pagelock */
108 SEGSPT_BADOP(int), /* setpgsz */
109 SEGSPT_BADOP(int), /* getmemid */
110 segspt_getpolicy, /* getpolicy */
111 SEGSPT_BADOP(int), /* capable */
112 seg_inherit_notsup /* inherit */
113 };
114
115 static int segspt_shmdup(struct seg *seg, struct seg *newseg);
116 static int segspt_shmunmap(struct seg *seg, caddr_t raddr, size_t ssize);
117 static void segspt_shmfree(struct seg *seg);
118 static faultcode_t segspt_shmfault(struct hat *hat, struct seg *seg,
119 caddr_t addr, size_t len, enum fault_type type, enum seg_rw rw);
120 static faultcode_t segspt_shmfaulta(struct seg *seg, caddr_t addr);
121 static int segspt_shmsetprot(register struct seg *seg, register caddr_t addr,
122 register size_t len, register uint_t prot);
123 static int segspt_shmcheckprot(struct seg *seg, caddr_t addr, size_t size,
124 uint_t prot);
125 static int segspt_shmkluster(struct seg *seg, caddr_t addr, ssize_t delta);
126 static size_t segspt_shmswapout(struct seg *seg);
127 static size_t segspt_shmincore(struct seg *seg, caddr_t addr, size_t len,
128 register char *vec);
129 static int segspt_shmsync(struct seg *seg, register caddr_t addr, size_t len,
130 int attr, uint_t flags);
131 static int segspt_shmlockop(struct seg *seg, caddr_t addr, size_t len,
132 int attr, int op, ulong_t *lockmap, size_t pos);
133 static int segspt_shmgetprot(struct seg *seg, caddr_t addr, size_t len,
134 uint_t *protv);
135 static u_offset_t segspt_shmgetoffset(struct seg *seg, caddr_t addr);
136 static int segspt_shmgettype(struct seg *seg, caddr_t addr);
137 static int segspt_shmgetvp(struct seg *seg, caddr_t addr, struct vnode **vpp);
138 static int segspt_shmadvise(struct seg *seg, caddr_t addr, size_t len,
139 uint_t behav);
140 static void segspt_shmdump(struct seg *seg);
141 static int segspt_shmpagelock(struct seg *, caddr_t, size_t,
142 struct page ***, enum lock_type, enum seg_rw);
143 static int segspt_shmsetpgsz(struct seg *, caddr_t, size_t, uint_t);
144 static int segspt_shmgetmemid(struct seg *, caddr_t, memid_t *);
145 static lgrp_mem_policy_info_t *segspt_shmgetpolicy(struct seg *, caddr_t);
146 static int segspt_shmcapable(struct seg *, segcapability_t);
147
148 struct seg_ops segspt_shmops = {
149 segspt_shmdup,
150 segspt_shmunmap,
151 segspt_shmfree,
152 segspt_shmfault,
153 segspt_shmfaulta,
154 segspt_shmsetprot,
155 segspt_shmcheckprot,
156 segspt_shmkluster,
157 segspt_shmswapout,
158 segspt_shmsync,
159 segspt_shmincore,
160 segspt_shmlockop,
161 segspt_shmgetprot,
162 segspt_shmgetoffset,
163 segspt_shmgettype,
164 segspt_shmgetvp,
165 segspt_shmadvise, /* advise */
166 segspt_shmdump,
167 segspt_shmpagelock,
168 segspt_shmsetpgsz,
169 segspt_shmgetmemid,
170 segspt_shmgetpolicy,
171 segspt_shmcapable,
172 seg_inherit_notsup
173 };
174
175 static void segspt_purge(struct seg *seg);
176 static int segspt_reclaim(void *, caddr_t, size_t, struct page **,
177 enum seg_rw, int);
178 static int spt_anon_getpages(struct seg *seg, caddr_t addr, size_t len,
179 page_t **ppa);
180
181
182
183 /*ARGSUSED*/
184 int
185 sptcreate(size_t size, struct seg **sptseg, struct anon_map *amp,
186 uint_t prot, uint_t flags, uint_t share_szc)
187 {
188 int err;
189 struct as *newas;
190 struct segspt_crargs sptcargs;
191
192 #ifdef DEBUG
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);
2229 return (0);
2247 cmn_err(CE_WARN, "segspt_shmfault default type?");
2248 #endif
2249 return (FC_NOMAP);
2250 }
2251 }
2252
2253 /*ARGSUSED*/
2254 static faultcode_t
2255 segspt_shmfaulta(struct seg *seg, caddr_t addr)
2256 {
2257 return (0);
2258 }
2259
2260 /*ARGSUSED*/
2261 static int
2262 segspt_shmkluster(struct seg *seg, caddr_t addr, ssize_t delta)
2263 {
2264 return (0);
2265 }
2266
2267 /*ARGSUSED*/
2268 static size_t
2269 segspt_shmswapout(struct seg *seg)
2270 {
2271 return (0);
2272 }
2273
2274 /*
2275 * duplicate the shared page tables
2276 */
2277 int
2278 segspt_shmdup(struct seg *seg, struct seg *newseg)
2279 {
2280 struct shm_data *shmd = (struct shm_data *)seg->s_data;
2281 struct anon_map *amp = shmd->shm_amp;
2282 struct shm_data *shmd_new;
2283 struct seg *spt_seg = shmd->shm_sptseg;
2284 struct spt_data *sptd = spt_seg->s_data;
2285 int error = 0;
2286
2287 ASSERT(seg->s_as && AS_WRITE_HELD(seg->s_as, &seg->s_as->a_lock));
2288
2289 shmd_new = kmem_zalloc((sizeof (*shmd_new)), KM_SLEEP);
2290 newseg->s_data = (void *)shmd_new;
2291 shmd_new->shm_sptas = shmd->shm_sptas;
2292 shmd_new->shm_amp = amp;
2293 shmd_new->shm_sptseg = shmd->shm_sptseg;
2997 * don't bother reapplying it.
2998 */
2999 if (already_set && !LGRP_MEM_POLICY_REAPPLICABLE(policy))
3000 return (0);
3001
3002 /*
3003 * Mark any existing pages in the given range for
3004 * migration, flushing the I/O page cache, and using
3005 * underlying segment to calculate anon index and get
3006 * anonmap and vnode pointer from
3007 */
3008 if (shmd->shm_softlockcnt > 0)
3009 segspt_purge(seg);
3010
3011 page_mark_migrate(seg, shm_addr, size, amp, 0, NULL, 0, 0);
3012 }
3013
3014 return (0);
3015 }
3016
3017 /*ARGSUSED*/
3018 void
3019 segspt_shmdump(struct seg *seg)
3020 {
3021 /* no-op for ISM segment */
3022 }
3023
3024 /*ARGSUSED*/
3025 static faultcode_t
3026 segspt_shmsetpgsz(struct seg *seg, caddr_t addr, size_t len, uint_t szc)
3027 {
3028 return (ENOTSUP);
3029 }
3030
3031 /*
3032 * get a memory ID for an addr in a given segment
3033 */
3034 static int
3035 segspt_shmgetmemid(struct seg *seg, caddr_t addr, memid_t *memidp)
3036 {
3037 struct shm_data *shmd = (struct shm_data *)seg->s_data;
3038 struct anon *ap;
3039 size_t anon_index;
3040 struct anon_map *amp = shmd->shm_amp;
3041 struct spt_data *sptd = shmd->shm_sptseg->s_data;
3042 struct seg *sptseg = shmd->shm_sptseg;
3043 anon_sync_obj_t cookie;
3044
3045 anon_index = seg_page(seg, addr);
3046
3047 if (addr > (seg->s_base + sptd->spt_realsize)) {
3048 return (EFAULT);
3049 }
3050
3090 * Assume that no lock needs to be held on anon_map, since
3091 * it should be protected by its reference count which must be
3092 * nonzero for an existing segment
3093 * Need to grab readers lock on policy tree though
3094 */
3095 shm_data = (struct shm_data *)seg->s_data;
3096 if (shm_data == NULL)
3097 return (NULL);
3098 amp = shm_data->shm_amp;
3099 ASSERT(amp->refcnt != 0);
3100
3101 /*
3102 * Get policy info
3103 *
3104 * Assume starting anon index of 0
3105 */
3106 anon_index = seg_page(seg, addr);
3107 policy_info = lgrp_shm_policy_get(amp, anon_index, NULL, 0);
3108
3109 return (policy_info);
3110 }
3111
3112 /*ARGSUSED*/
3113 static int
3114 segspt_shmcapable(struct seg *seg, segcapability_t capability)
3115 {
3116 return (0);
3117 }
|
59
60 /*
61 * segspt_minfree is the memory left for system after ISM
62 * locked its pages; it is set up to 5% of availrmem in
63 * sptcreate when ISM is created. ISM should not use more
64 * than ~90% of availrmem; if it does, then the performance
65 * of the system may decrease. Machines with large memories may
66 * be able to use up more memory for ISM so we set the default
67 * segspt_minfree to 5% (which gives ISM max 95% of availrmem.
68 * If somebody wants even more memory for ISM (risking hanging
69 * the system) they can patch the segspt_minfree to smaller number.
70 */
71 pgcnt_t segspt_minfree = 0;
72
73 static int segspt_create(struct seg *seg, caddr_t argsp);
74 static int segspt_unmap(struct seg *seg, caddr_t raddr, size_t ssize);
75 static void segspt_free(struct seg *seg);
76 static void segspt_free_pages(struct seg *seg, caddr_t addr, size_t len);
77 static lgrp_mem_policy_info_t *segspt_getpolicy(struct seg *seg, caddr_t addr);
78
79 static const struct seg_ops segspt_ops = {
80 .unmap = segspt_unmap,
81 .free = segspt_free,
82 .getpolicy = segspt_getpolicy,
83 };
84
85 static int segspt_shmdup(struct seg *seg, struct seg *newseg);
86 static int segspt_shmunmap(struct seg *seg, caddr_t raddr, size_t ssize);
87 static void segspt_shmfree(struct seg *seg);
88 static faultcode_t segspt_shmfault(struct hat *hat, struct seg *seg,
89 caddr_t addr, size_t len, enum fault_type type, enum seg_rw rw);
90 static faultcode_t segspt_shmfaulta(struct seg *seg, caddr_t addr);
91 static int segspt_shmsetprot(register struct seg *seg, register caddr_t addr,
92 register size_t len, register uint_t prot);
93 static int segspt_shmcheckprot(struct seg *seg, caddr_t addr, size_t size,
94 uint_t prot);
95 static int segspt_shmkluster(struct seg *seg, caddr_t addr, ssize_t delta);
96 static size_t segspt_shmincore(struct seg *seg, caddr_t addr, size_t len,
97 register char *vec);
98 static int segspt_shmsync(struct seg *seg, register caddr_t addr, size_t len,
99 int attr, uint_t flags);
100 static int segspt_shmlockop(struct seg *seg, caddr_t addr, size_t len,
101 int attr, int op, ulong_t *lockmap, size_t pos);
102 static int segspt_shmgetprot(struct seg *seg, caddr_t addr, size_t len,
103 uint_t *protv);
104 static u_offset_t segspt_shmgetoffset(struct seg *seg, caddr_t addr);
105 static int segspt_shmgettype(struct seg *seg, caddr_t addr);
106 static int segspt_shmgetvp(struct seg *seg, caddr_t addr, struct vnode **vpp);
107 static int segspt_shmadvise(struct seg *seg, caddr_t addr, size_t len,
108 uint_t behav);
109 static int segspt_shmpagelock(struct seg *, caddr_t, size_t,
110 struct page ***, enum lock_type, enum seg_rw);
111 static int segspt_shmgetmemid(struct seg *, caddr_t, memid_t *);
112 static lgrp_mem_policy_info_t *segspt_shmgetpolicy(struct seg *, caddr_t);
113
114 const struct seg_ops segspt_shmops = {
115 .dup = segspt_shmdup,
116 .unmap = segspt_shmunmap,
117 .free = segspt_shmfree,
118 .fault = segspt_shmfault,
119 .faulta = segspt_shmfaulta,
120 .setprot = segspt_shmsetprot,
121 .checkprot = segspt_shmcheckprot,
122 .kluster = segspt_shmkluster,
123 .sync = segspt_shmsync,
124 .incore = segspt_shmincore,
125 .lockop = segspt_shmlockop,
126 .getprot = segspt_shmgetprot,
127 .getoffset = segspt_shmgetoffset,
128 .gettype = segspt_shmgettype,
129 .getvp = segspt_shmgetvp,
130 .advise = segspt_shmadvise,
131 .pagelock = segspt_shmpagelock,
132 .getmemid = segspt_shmgetmemid,
133 .getpolicy = segspt_shmgetpolicy,
134 };
135
136 static void segspt_purge(struct seg *seg);
137 static int segspt_reclaim(void *, caddr_t, size_t, struct page **,
138 enum seg_rw, int);
139 static int spt_anon_getpages(struct seg *seg, caddr_t addr, size_t len,
140 page_t **ppa);
141
142
143
144 /*ARGSUSED*/
145 int
146 sptcreate(size_t size, struct seg **sptseg, struct anon_map *amp,
147 uint_t prot, uint_t flags, uint_t share_szc)
148 {
149 int err;
150 struct as *newas;
151 struct segspt_crargs sptcargs;
152
153 #ifdef DEBUG
1868 atomic_add_long((ulong_t *)(
1869 &(shmd->shm_softlockcnt)), -npages);
1870 }
1871 goto dism_err;
1872 }
1873 AS_LOCK_ENTER(sptseg->s_as, &sptseg->s_as->a_lock, RW_READER);
1874 a = segspt_addr;
1875 pidx = 0;
1876 if (type == F_SOFTLOCK) {
1877
1878 /*
1879 * Load up the translation keeping it
1880 * locked and don't unlock the page.
1881 */
1882 for (; pidx < npages; a += pgsz, pidx += pgcnt) {
1883 hat_memload_array(sptseg->s_as->a_hat,
1884 a, pgsz, &ppa[pidx], sptd->spt_prot,
1885 HAT_LOAD_LOCK | HAT_LOAD_SHARE);
1886 }
1887 } else {
1888 /*
1889 * Migrate pages marked for migration
1890 */
1891 if (lgrp_optimizations())
1892 page_migrate(seg, shm_addr, ppa, npages);
1893
1894 for (; pidx < npages; a += pgsz, pidx += pgcnt) {
1895 hat_memload_array(sptseg->s_as->a_hat,
1896 a, pgsz, &ppa[pidx],
1897 sptd->spt_prot,
1898 HAT_LOAD_SHARE);
1899 }
1900
1901 /*
1902 * And now drop the SE_SHARED lock(s).
1903 */
1904 if (dyn_ism_unmap) {
1905 for (i = 0; i < npages; i++) {
1906 page_unlock(ppa[i]);
1907 }
1908 }
1909 }
1910
1911 if (!dyn_ism_unmap) {
1912 if (hat_share(seg->s_as->a_hat, shm_addr,
1913 curspt->a_hat, segspt_addr, ptob(npages),
1914 seg->s_szc) != 0) {
1915 panic("hat_share err in DISM fault");
1916 /* NOTREACHED */
1917 }
1918 if (type == F_INVAL) {
1919 for (i = 0; i < npages; i++) {
2118 * We are already holding the as->a_lock on the user's
2119 * real segment, but we need to hold the a_lock on the
2120 * underlying dummy as. This is mostly to satisfy the
2121 * underlying HAT layer.
2122 */
2123 AS_LOCK_ENTER(sptseg->s_as, &sptseg->s_as->a_lock, RW_READER);
2124 a = sptseg_addr;
2125 pidx = 0;
2126 if (type == F_SOFTLOCK) {
2127 /*
2128 * Load up the translation keeping it
2129 * locked and don't unlock the page.
2130 */
2131 for (; pidx < npages; a += pgsz, pidx += pgcnt) {
2132 sz = MIN(pgsz, ptob(npages - pidx));
2133 hat_memload_array(sptseg->s_as->a_hat, a,
2134 sz, &ppa[pidx], sptd->spt_prot,
2135 HAT_LOAD_LOCK | HAT_LOAD_SHARE);
2136 }
2137 } else {
2138 /*
2139 * Migrate pages marked for migration.
2140 */
2141 if (lgrp_optimizations())
2142 page_migrate(seg, shm_addr, ppa, npages);
2143
2144 for (; pidx < npages; a += pgsz, pidx += pgcnt) {
2145 sz = MIN(pgsz, ptob(npages - pidx));
2146 hat_memload_array(sptseg->s_as->a_hat,
2147 a, sz, &ppa[pidx],
2148 sptd->spt_prot, HAT_LOAD_SHARE);
2149 }
2150
2151 /*
2152 * And now drop the SE_SHARED lock(s).
2153 */
2154 for (i = 0; i < npages; i++)
2155 page_unlock(ppa[i]);
2156 }
2157 AS_LOCK_EXIT(sptseg->s_as, &sptseg->s_as->a_lock);
2158
2159 kmem_free(ppa, sizeof (page_t *) * npages);
2160 return (0);
2161 case F_SOFTUNLOCK:
2162
2163 /*
2164 * This is a bit ugly, we pass in the real seg pointer,
2165 * but the sptseg_addr is the virtual address within the
2166 * dummy seg.
2167 */
2168 segspt_softunlock(seg, sptseg_addr, ptob(npages), rw);
2169 return (0);
2187 cmn_err(CE_WARN, "segspt_shmfault default type?");
2188 #endif
2189 return (FC_NOMAP);
2190 }
2191 }
2192
2193 /*ARGSUSED*/
2194 static faultcode_t
2195 segspt_shmfaulta(struct seg *seg, caddr_t addr)
2196 {
2197 return (0);
2198 }
2199
2200 /*ARGSUSED*/
2201 static int
2202 segspt_shmkluster(struct seg *seg, caddr_t addr, ssize_t delta)
2203 {
2204 return (0);
2205 }
2206
2207 /*
2208 * duplicate the shared page tables
2209 */
2210 int
2211 segspt_shmdup(struct seg *seg, struct seg *newseg)
2212 {
2213 struct shm_data *shmd = (struct shm_data *)seg->s_data;
2214 struct anon_map *amp = shmd->shm_amp;
2215 struct shm_data *shmd_new;
2216 struct seg *spt_seg = shmd->shm_sptseg;
2217 struct spt_data *sptd = spt_seg->s_data;
2218 int error = 0;
2219
2220 ASSERT(seg->s_as && AS_WRITE_HELD(seg->s_as, &seg->s_as->a_lock));
2221
2222 shmd_new = kmem_zalloc((sizeof (*shmd_new)), KM_SLEEP);
2223 newseg->s_data = (void *)shmd_new;
2224 shmd_new->shm_sptas = shmd->shm_sptas;
2225 shmd_new->shm_amp = amp;
2226 shmd_new->shm_sptseg = shmd->shm_sptseg;
2930 * don't bother reapplying it.
2931 */
2932 if (already_set && !LGRP_MEM_POLICY_REAPPLICABLE(policy))
2933 return (0);
2934
2935 /*
2936 * Mark any existing pages in the given range for
2937 * migration, flushing the I/O page cache, and using
2938 * underlying segment to calculate anon index and get
2939 * anonmap and vnode pointer from
2940 */
2941 if (shmd->shm_softlockcnt > 0)
2942 segspt_purge(seg);
2943
2944 page_mark_migrate(seg, shm_addr, size, amp, 0, NULL, 0, 0);
2945 }
2946
2947 return (0);
2948 }
2949
2950 /*
2951 * get a memory ID for an addr in a given segment
2952 */
2953 static int
2954 segspt_shmgetmemid(struct seg *seg, caddr_t addr, memid_t *memidp)
2955 {
2956 struct shm_data *shmd = (struct shm_data *)seg->s_data;
2957 struct anon *ap;
2958 size_t anon_index;
2959 struct anon_map *amp = shmd->shm_amp;
2960 struct spt_data *sptd = shmd->shm_sptseg->s_data;
2961 struct seg *sptseg = shmd->shm_sptseg;
2962 anon_sync_obj_t cookie;
2963
2964 anon_index = seg_page(seg, addr);
2965
2966 if (addr > (seg->s_base + sptd->spt_realsize)) {
2967 return (EFAULT);
2968 }
2969
3009 * Assume that no lock needs to be held on anon_map, since
3010 * it should be protected by its reference count which must be
3011 * nonzero for an existing segment
3012 * Need to grab readers lock on policy tree though
3013 */
3014 shm_data = (struct shm_data *)seg->s_data;
3015 if (shm_data == NULL)
3016 return (NULL);
3017 amp = shm_data->shm_amp;
3018 ASSERT(amp->refcnt != 0);
3019
3020 /*
3021 * Get policy info
3022 *
3023 * Assume starting anon index of 0
3024 */
3025 anon_index = seg_page(seg, addr);
3026 policy_info = lgrp_shm_policy_get(amp, anon_index, NULL, 0);
3027
3028 return (policy_info);
3029 }
|