Deleted Added
full compact
vm_pager.c (8416) vm_pager.c (9507)
1/*
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * The Mach Operating System project at Carnegie-Mellon University.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 47 unchanged lines hidden (view full) ---

56 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
57 * School of Computer Science
58 * Carnegie Mellon University
59 * Pittsburgh PA 15213-3890
60 *
61 * any improvements or extensions that they make and grant Carnegie the
62 * rights to redistribute these changes.
63 *
1/*
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * The Mach Operating System project at Carnegie-Mellon University.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 47 unchanged lines hidden (view full) ---

56 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
57 * School of Computer Science
58 * Carnegie Mellon University
59 * Pittsburgh PA 15213-3890
60 *
61 * any improvements or extensions that they make and grant Carnegie the
62 * rights to redistribute these changes.
63 *
64 * $Id: vm_pager.c,v 1.14 1995/04/25 06:22:47 davidg Exp $
64 * $Id: vm_pager.c,v 1.15 1995/05/10 18:56:07 davidg Exp $
65 */
66
67/*
68 * Paging space routine stubs. Emulates a matchmaker-like interface
69 * for builtin pagers.
70 */
71
72#include <sys/param.h>
73#include <sys/systm.h>
74#include <sys/proc.h>
75#include <sys/malloc.h>
76#include <sys/buf.h>
77#include <sys/ucred.h>
78
79#include <vm/vm.h>
80#include <vm/vm_page.h>
81#include <vm/vm_kern.h>
65 */
66
67/*
68 * Paging space routine stubs. Emulates a matchmaker-like interface
69 * for builtin pagers.
70 */
71
72#include <sys/param.h>
73#include <sys/systm.h>
74#include <sys/proc.h>
75#include <sys/malloc.h>
76#include <sys/buf.h>
77#include <sys/ucred.h>
78
79#include <vm/vm.h>
80#include <vm/vm_page.h>
81#include <vm/vm_kern.h>
82#include <vm/vm_pager.h>
82
83
84extern struct pagerops defaultpagerops;
83extern struct pagerops swappagerops;
84extern struct pagerops vnodepagerops;
85extern struct pagerops devicepagerops;
86
87struct pagerops *pagertab[] = {
85extern struct pagerops swappagerops;
86extern struct pagerops vnodepagerops;
87extern struct pagerops devicepagerops;
88
89struct pagerops *pagertab[] = {
88 &swappagerops, /* PG_SWAP */
89 &vnodepagerops, /* PG_VNODE */
90 &devicepagerops, /* PG_DEV */
90 &defaultpagerops, /* OBJT_DEFAULT */
91 &swappagerops, /* OBJT_SWAP */
92 &vnodepagerops, /* OBJT_VNODE */
93 &devicepagerops, /* OBJT_DEVICE */
91};
92int npagers = sizeof(pagertab) / sizeof(pagertab[0]);
93
94};
95int npagers = sizeof(pagertab) / sizeof(pagertab[0]);
96
94struct pagerops *dfltpagerops = NULL; /* default pager */
95
96/*
97 * Kernel address space for mapping pages.
98 * Used by pagers where KVAs are needed for IO.
99 *
100 * XXX needs to be large enough to support the number of pending async
101 * cleaning requests (NPENDINGIO == 64) * the maximum swap cluster size
102 * (MAXPHYS == 64k) if you want to get the most efficiency.
103 */

--- 10 unchanged lines hidden (view full) ---

114vm_pager_init()
115{
116 struct pagerops **pgops;
117
118 /*
119 * Initialize known pagers
120 */
121 for (pgops = pagertab; pgops < &pagertab[npagers]; pgops++)
97/*
98 * Kernel address space for mapping pages.
99 * Used by pagers where KVAs are needed for IO.
100 *
101 * XXX needs to be large enough to support the number of pending async
102 * cleaning requests (NPENDINGIO == 64) * the maximum swap cluster size
103 * (MAXPHYS == 64k) if you want to get the most efficiency.
104 */

--- 10 unchanged lines hidden (view full) ---

115vm_pager_init()
116{
117 struct pagerops **pgops;
118
119 /*
120 * Initialize known pagers
121 */
122 for (pgops = pagertab; pgops < &pagertab[npagers]; pgops++)
122 if (pgops)
123 if (pgops && ((*pgops)->pgo_init != NULL))
123 (*(*pgops)->pgo_init) ();
124 (*(*pgops)->pgo_init) ();
124 if (dfltpagerops == NULL)
125 panic("no default pager");
126}
127
128void
129vm_pager_bufferinit()
130{
131 struct buf *bp;
132 int i;
133

--- 15 unchanged lines hidden (view full) ---

149 panic("Not enough pager_map VM space for physical buffers");
150}
151
152/*
153 * Allocate an instance of a pager of the given type.
154 * Size, protection and offset parameters are passed in for pagers that
155 * need to perform page-level validation (e.g. the device pager).
156 */
125}
126
127void
128vm_pager_bufferinit()
129{
130 struct buf *bp;
131 int i;
132

--- 15 unchanged lines hidden (view full) ---

148 panic("Not enough pager_map VM space for physical buffers");
149}
150
151/*
152 * Allocate an instance of a pager of the given type.
153 * Size, protection and offset parameters are passed in for pagers that
154 * need to perform page-level validation (e.g. the device pager).
155 */
157vm_pager_t
156vm_object_t
158vm_pager_allocate(type, handle, size, prot, off)
157vm_pager_allocate(type, handle, size, prot, off)
159 int type;
158 objtype_t type;
160 void *handle;
161 vm_size_t size;
162 vm_prot_t prot;
163 vm_offset_t off;
164{
165 struct pagerops *ops;
166
159 void *handle;
160 vm_size_t size;
161 vm_prot_t prot;
162 vm_offset_t off;
163{
164 struct pagerops *ops;
165
167 ops = (type == PG_DFLT) ? dfltpagerops : pagertab[type];
166 ops = pagertab[type];
168 if (ops)
169 return ((*ops->pgo_alloc) (handle, size, prot, off));
170 return (NULL);
171}
172
173void
167 if (ops)
168 return ((*ops->pgo_alloc) (handle, size, prot, off));
169 return (NULL);
170}
171
172void
174vm_pager_deallocate(pager)
175 vm_pager_t pager;
173vm_pager_deallocate(object)
174 vm_object_t object;
176{
175{
177 if (pager == NULL)
178 panic("vm_pager_deallocate: null pager");
179
180 (*pager->pg_ops->pgo_dealloc) (pager);
176 (*pagertab[object->type]->pgo_dealloc) (object);
181}
182
183
184int
177}
178
179
180int
185vm_pager_get_pages(pager, m, count, reqpage, sync)
186 vm_pager_t pager;
181vm_pager_get_pages(object, m, count, reqpage)
182 vm_object_t object;
187 vm_page_t *m;
188 int count;
189 int reqpage;
183 vm_page_t *m;
184 int count;
185 int reqpage;
190 boolean_t sync;
191{
186{
192 int i;
193
194 if (pager == NULL) {
195 for (i = 0; i < count; i++) {
196 if (i != reqpage) {
197 PAGE_WAKEUP(m[i]);
198 vm_page_free(m[i]);
199 }
200 }
201 vm_page_zero_fill(m[reqpage]);
202 return VM_PAGER_OK;
203 }
204 if (pager->pg_ops->pgo_getpages == 0) {
205 for (i = 0; i < count; i++) {
206 if (i != reqpage) {
207 PAGE_WAKEUP(m[i]);
208 vm_page_free(m[i]);
209 }
210 }
211 return (VM_PAGER_GET(pager, m[reqpage], sync));
212 } else {
213 return (VM_PAGER_GET_MULTI(pager, m, count, reqpage, sync));
214 }
187 return ((*pagertab[object->type]->pgo_getpages)(object, m, count, reqpage));
215}
216
217int
188}
189
190int
218vm_pager_put_pages(pager, m, count, sync, rtvals)
219 vm_pager_t pager;
191vm_pager_put_pages(object, m, count, sync, rtvals)
192 vm_object_t object;
220 vm_page_t *m;
221 int count;
222 boolean_t sync;
223 int *rtvals;
224{
193 vm_page_t *m;
194 int count;
195 boolean_t sync;
196 int *rtvals;
197{
225 int i;
226
227 if (pager->pg_ops->pgo_putpages)
228 return (VM_PAGER_PUT_MULTI(pager, m, count, sync, rtvals));
229 else {
230 for (i = 0; i < count; i++) {
231 rtvals[i] = VM_PAGER_PUT(pager, m[i], sync);
232 }
233 return rtvals[0];
234 }
198 return ((*pagertab[object->type]->pgo_putpages)(object, m, count, sync, rtvals));
235}
236
237boolean_t
199}
200
201boolean_t
238vm_pager_has_page(pager, offset)
239 vm_pager_t pager;
202vm_pager_has_page(object, offset, before, after)
203 vm_object_t object;
240 vm_offset_t offset;
204 vm_offset_t offset;
205 int *before;
206 int *after;
241{
207{
242 if (pager == NULL)
243 panic("vm_pager_has_page: null pager");
244 return ((*pager->pg_ops->pgo_haspage) (pager, offset));
208 return ((*pagertab[object->type]->pgo_haspage) (object, offset, before, after));
245}
246
247/*
248 * Called by pageout daemon before going back to sleep.
249 * Gives pagers a chance to clean up any completed async pageing operations.
250 */
251void
252vm_pager_sync()
253{
254 struct pagerops **pgops;
255
256 for (pgops = pagertab; pgops < &pagertab[npagers]; pgops++)
209}
210
211/*
212 * Called by pageout daemon before going back to sleep.
213 * Gives pagers a chance to clean up any completed async pageing operations.
214 */
215void
216vm_pager_sync()
217{
218 struct pagerops **pgops;
219
220 for (pgops = pagertab; pgops < &pagertab[npagers]; pgops++)
257 if (pgops)
258 (*(*pgops)->pgo_putpage) (NULL, NULL, 0);
221 if (pgops && ((*pgops)->pgo_sync != NULL))
222 (*(*pgops)->pgo_sync) ();
259}
260
223}
224
261#if 0
262void
263vm_pager_cluster(pager, offset, loff, hoff)
264 vm_pager_t pager;
265 vm_offset_t offset;
266 vm_offset_t *loff;
267 vm_offset_t *hoff;
268{
269 if (pager == NULL)
270 panic("vm_pager_cluster: null pager");
271 return ((*pager->pg_ops->pgo_cluster) (pager, offset, loff, hoff));
272}
273#endif
274
275vm_offset_t
276vm_pager_map_page(m)
277 vm_page_t m;
278{
279 vm_offset_t kva;
280
281 kva = kmem_alloc_wait(pager_map, PAGE_SIZE);
282 pmap_kenter(kva, VM_PAGE_TO_PHYS(m));

--- 15 unchanged lines hidden (view full) ---

298 vm_offset_t pa;
299
300 pa = pmap_kextract(kva);
301 if (pa == 0)
302 panic("vm_pager_atop");
303 return (PHYS_TO_VM_PAGE(pa));
304}
305
225vm_offset_t
226vm_pager_map_page(m)
227 vm_page_t m;
228{
229 vm_offset_t kva;
230
231 kva = kmem_alloc_wait(pager_map, PAGE_SIZE);
232 pmap_kenter(kva, VM_PAGE_TO_PHYS(m));

--- 15 unchanged lines hidden (view full) ---

248 vm_offset_t pa;
249
250 pa = pmap_kextract(kva);
251 if (pa == 0)
252 panic("vm_pager_atop");
253 return (PHYS_TO_VM_PAGE(pa));
254}
255
306vm_pager_t
307vm_pager_lookup(pglist, handle)
308 register struct pagerlst *pglist;
309 caddr_t handle;
256vm_object_t
257vm_pager_object_lookup(pg_list, handle)
258 register struct pagerlst *pg_list;
259 void *handle;
310{
260{
311 register vm_pager_t pager;
261 register vm_object_t object;
312
262
313 for (pager = pglist->tqh_first; pager; pager = pager->pg_list.tqe_next)
314 if (pager->pg_handle == handle)
315 return (pager);
263 for (object = pg_list->tqh_first; object != NULL; object = object->pager_object_list.tqe_next)
264 if (object->handle == handle)
265 return (object);
316 return (NULL);
317}
318
319/*
320 * This routine loses a reference to the object -
321 * thus a reference must be gained before calling.
322 */
323int
324pager_cache(object, should_cache)
325 vm_object_t object;
326 boolean_t should_cache;
327{
328 if (object == NULL)
329 return (KERN_INVALID_ARGUMENT);
330
266 return (NULL);
267}
268
269/*
270 * This routine loses a reference to the object -
271 * thus a reference must be gained before calling.
272 */
273int
274pager_cache(object, should_cache)
275 vm_object_t object;
276 boolean_t should_cache;
277{
278 if (object == NULL)
279 return (KERN_INVALID_ARGUMENT);
280
331 vm_object_cache_lock();
332 vm_object_lock(object);
333 if (should_cache)
334 object->flags |= OBJ_CANPERSIST;
335 else
336 object->flags &= ~OBJ_CANPERSIST;
281 if (should_cache)
282 object->flags |= OBJ_CANPERSIST;
283 else
284 object->flags &= ~OBJ_CANPERSIST;
337 vm_object_unlock(object);
338 vm_object_cache_unlock();
339
340 vm_object_deallocate(object);
341
342 return (KERN_SUCCESS);
343}
344
345/*
346 * allocate a physical buffer
347 */
348struct buf *
349getpbuf()
350{
351 int s;
352 struct buf *bp;
353
354 s = splbio();
355 /* get a bp from the swap buffer header pool */
356 while ((bp = bswlist.tqh_first) == NULL) {
357 bswneeded = 1;
285
286 vm_object_deallocate(object);
287
288 return (KERN_SUCCESS);
289}
290
291/*
292 * allocate a physical buffer
293 */
294struct buf *
295getpbuf()
296{
297 int s;
298 struct buf *bp;
299
300 s = splbio();
301 /* get a bp from the swap buffer header pool */
302 while ((bp = bswlist.tqh_first) == NULL) {
303 bswneeded = 1;
358 tsleep((caddr_t) &bswneeded, PVM, "wswbuf", 0);
304 tsleep(&bswneeded, PVM, "wswbuf", 0);
359 }
360 TAILQ_REMOVE(&bswlist, bp, b_freelist);
361 splx(s);
362
363 bzero(bp, sizeof *bp);
364 bp->b_rcred = NOCRED;
365 bp->b_wcred = NOCRED;
366 bp->b_data = (caddr_t) (MAXPHYS * (bp - swbuf)) + swapbkva;

--- 44 unchanged lines hidden (view full) ---

411 if (bp->b_wcred != NOCRED) {
412 crfree(bp->b_wcred);
413 bp->b_wcred = NOCRED;
414 }
415 if (bp->b_vp)
416 pbrelvp(bp);
417
418 if (bp->b_flags & B_WANTED)
305 }
306 TAILQ_REMOVE(&bswlist, bp, b_freelist);
307 splx(s);
308
309 bzero(bp, sizeof *bp);
310 bp->b_rcred = NOCRED;
311 bp->b_wcred = NOCRED;
312 bp->b_data = (caddr_t) (MAXPHYS * (bp - swbuf)) + swapbkva;

--- 44 unchanged lines hidden (view full) ---

357 if (bp->b_wcred != NOCRED) {
358 crfree(bp->b_wcred);
359 bp->b_wcred = NOCRED;
360 }
361 if (bp->b_vp)
362 pbrelvp(bp);
363
364 if (bp->b_flags & B_WANTED)
419 wakeup((caddr_t) bp);
365 wakeup(bp);
420
421 TAILQ_INSERT_HEAD(&bswlist, bp, b_freelist);
422
423 if (bswneeded) {
424 bswneeded = 0;
366
367 TAILQ_INSERT_HEAD(&bswlist, bp, b_freelist);
368
369 if (bswneeded) {
370 bswneeded = 0;
425 wakeup((caddr_t) &bswneeded);
371 wakeup(&bswneeded);
426 }
427 splx(s);
428}
372 }
373 splx(s);
374}