proc->thread stage 2: MAJOR revamping of system calls, ucred, jail API,
[dragonfly.git] / sys / vm / vm_pager.c
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
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *      This product includes software developed by the University of
19  *      California, Berkeley and its contributors.
20  * 4. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  *      from: @(#)vm_pager.c    8.6 (Berkeley) 1/12/94
37  *
38  *
39  * Copyright (c) 1987, 1990 Carnegie-Mellon University.
40  * All rights reserved.
41  *
42  * Authors: Avadis Tevanian, Jr., Michael Wayne Young
43  *
44  * Permission to use, copy, modify and distribute this software and
45  * its documentation is hereby granted, provided that both the copyright
46  * notice and this permission notice appear in all copies of the
47  * software, derivative works or modified versions, and any portions
48  * thereof, and that both notices appear in supporting documentation.
49  *
50  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
51  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
52  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
53  *
54  * Carnegie Mellon requests users of this software to return to
55  *
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  * $FreeBSD: src/sys/vm/vm_pager.c,v 1.54.2.2 2001/11/18 07:11:00 dillon Exp $
65  * $DragonFly: src/sys/vm/vm_pager.c,v 1.3 2003/06/19 01:55:08 dillon Exp $
66  */
67
68 /*
69  *      Paging space routine stubs.  Emulates a matchmaker-like interface
70  *      for builtin pagers.
71  */
72
73 #include <sys/param.h>
74 #include <sys/systm.h>
75 #include <sys/kernel.h>
76 #include <sys/vnode.h>
77 #include <sys/buf.h>
78 #include <sys/ucred.h>
79 #include <sys/malloc.h>
80 #include <sys/proc.h>
81
82 #include <vm/vm.h>
83 #include <vm/vm_param.h>
84 #include <vm/vm_object.h>
85 #include <vm/vm_page.h>
86 #include <vm/vm_pager.h>
87 #include <vm/vm_extern.h>
88
89 #include <sys/buf2.h>
90
91 MALLOC_DEFINE(M_VMPGDATA, "VM pgdata", "XXX: VM pager private data");
92
93 extern struct pagerops defaultpagerops;
94 extern struct pagerops swappagerops;
95 extern struct pagerops vnodepagerops;
96 extern struct pagerops devicepagerops;
97 extern struct pagerops physpagerops;
98
99 int cluster_pbuf_freecnt = -1;  /* unlimited to begin with */
100
101 static int dead_pager_getpages __P((vm_object_t, vm_page_t *, int, int));
102 static vm_object_t dead_pager_alloc __P((void *, vm_ooffset_t, vm_prot_t,
103         vm_ooffset_t));
104 static void dead_pager_putpages __P((vm_object_t, vm_page_t *, int, int, int *));
105 static boolean_t dead_pager_haspage __P((vm_object_t, vm_pindex_t, int *, int *));
106 static void dead_pager_dealloc __P((vm_object_t));
107
108 static int
109 dead_pager_getpages(obj, ma, count, req)
110         vm_object_t obj;
111         vm_page_t *ma;
112         int count;
113         int req;
114 {
115         return VM_PAGER_FAIL;
116 }
117
118 static vm_object_t
119 dead_pager_alloc(handle, size, prot, off)
120         void *handle;
121         vm_ooffset_t size;
122         vm_prot_t prot;
123         vm_ooffset_t off;
124 {
125         return NULL;
126 }
127
128 static void
129 dead_pager_putpages(object, m, count, flags, rtvals)
130         vm_object_t object;
131         vm_page_t *m;
132         int count;
133         int flags;
134         int *rtvals;
135 {
136         int i;
137
138         for (i = 0; i < count; i++) {
139                 rtvals[i] = VM_PAGER_AGAIN;
140         }
141 }
142
143 static int
144 dead_pager_haspage(object, pindex, prev, next)
145         vm_object_t object;
146         vm_pindex_t pindex;
147         int *prev;
148         int *next;
149 {
150         if (prev)
151                 *prev = 0;
152         if (next)
153                 *next = 0;
154         return FALSE;
155 }
156
157 static void
158 dead_pager_dealloc(object)
159         vm_object_t object;
160 {
161         return;
162 }
163
164 static struct pagerops deadpagerops = {
165         NULL,
166         dead_pager_alloc,
167         dead_pager_dealloc,
168         dead_pager_getpages,
169         dead_pager_putpages,
170         dead_pager_haspage,
171         NULL
172 };
173
174 struct pagerops *pagertab[] = {
175         &defaultpagerops,       /* OBJT_DEFAULT */
176         &swappagerops,          /* OBJT_SWAP */
177         &vnodepagerops,         /* OBJT_VNODE */
178         &devicepagerops,        /* OBJT_DEVICE */
179         &physpagerops,          /* OBJT_PHYS */
180         &deadpagerops           /* OBJT_DEAD */
181 };
182
183 int npagers = sizeof(pagertab) / sizeof(pagertab[0]);
184
185 /*
186  * Kernel address space for mapping pages.
187  * Used by pagers where KVAs are needed for IO.
188  *
189  * XXX needs to be large enough to support the number of pending async
190  * cleaning requests (NPENDINGIO == 64) * the maximum swap cluster size
191  * (MAXPHYS == 64k) if you want to get the most efficiency.
192  */
193 #define PAGER_MAP_SIZE  (8 * 1024 * 1024)
194
195 int pager_map_size = PAGER_MAP_SIZE;
196 vm_map_t pager_map;
197 static int bswneeded;
198 static vm_offset_t swapbkva;            /* swap buffers kva */
199
200 void
201 vm_pager_init()
202 {
203         struct pagerops **pgops;
204
205         /*
206          * Initialize known pagers
207          */
208         for (pgops = pagertab; pgops < &pagertab[npagers]; pgops++)
209                 if (pgops && ((*pgops)->pgo_init != NULL))
210                         (*(*pgops)->pgo_init) ();
211 }
212
213 void
214 vm_pager_bufferinit()
215 {
216         struct buf *bp;
217         int i;
218
219         bp = swbuf;
220         /*
221          * Now set up swap and physical I/O buffer headers.
222          */
223         for (i = 0; i < nswbuf; i++, bp++) {
224                 TAILQ_INSERT_HEAD(&bswlist, bp, b_freelist);
225                 BUF_LOCKINIT(bp);
226                 LIST_INIT(&bp->b_dep);
227                 bp->b_rcred = bp->b_wcred = NOCRED;
228                 bp->b_xflags = 0;
229         }
230
231         cluster_pbuf_freecnt = nswbuf / 2;
232
233         swapbkva = kmem_alloc_pageable(pager_map, nswbuf * MAXPHYS);
234         if (!swapbkva)
235                 panic("Not enough pager_map VM space for physical buffers");
236 }
237
238 /*
239  * Allocate an instance of a pager of the given type.
240  * Size, protection and offset parameters are passed in for pagers that
241  * need to perform page-level validation (e.g. the device pager).
242  */
243 vm_object_t
244 vm_pager_allocate(objtype_t type, void *handle, vm_ooffset_t size, vm_prot_t prot,
245                   vm_ooffset_t off)
246 {
247         struct pagerops *ops;
248
249         ops = pagertab[type];
250         if (ops)
251                 return ((*ops->pgo_alloc) (handle, size, prot, off));
252         return (NULL);
253 }
254
255 void
256 vm_pager_deallocate(object)
257         vm_object_t object;
258 {
259         (*pagertab[object->type]->pgo_dealloc) (object);
260 }
261
262 /*
263  *      vm_pager_strategy:
264  *
265  *      called with no specific spl
266  *      Execute strategy routine directly to pager.
267  */
268
269 void
270 vm_pager_strategy(vm_object_t object, struct buf *bp)
271 {
272         if (pagertab[object->type]->pgo_strategy) {
273             (*pagertab[object->type]->pgo_strategy)(object, bp);
274         } else {
275                 bp->b_flags |= B_ERROR;
276                 bp->b_error = ENXIO;
277                 biodone(bp);
278         }
279 }
280
281 /*
282  * vm_pager_get_pages() - inline, see vm/vm_pager.h
283  * vm_pager_put_pages() - inline, see vm/vm_pager.h
284  * vm_pager_has_page() - inline, see vm/vm_pager.h
285  * vm_pager_page_inserted() - inline, see vm/vm_pager.h
286  * vm_pager_page_removed() - inline, see vm/vm_pager.h
287  */
288
289 #if 0
290 /*
291  *      vm_pager_sync:
292  *
293  *      Called by pageout daemon before going back to sleep.
294  *      Gives pagers a chance to clean up any completed async pageing 
295  *      operations.
296  */
297 void
298 vm_pager_sync()
299 {
300         struct pagerops **pgops;
301
302         for (pgops = pagertab; pgops < &pagertab[npagers]; pgops++)
303                 if (pgops && ((*pgops)->pgo_sync != NULL))
304                         (*(*pgops)->pgo_sync) ();
305 }
306
307 #endif
308
309 vm_offset_t
310 vm_pager_map_page(m)
311         vm_page_t m;
312 {
313         vm_offset_t kva;
314
315         kva = kmem_alloc_wait(pager_map, PAGE_SIZE);
316         pmap_kenter(kva, VM_PAGE_TO_PHYS(m));
317         return (kva);
318 }
319
320 void
321 vm_pager_unmap_page(kva)
322         vm_offset_t kva;
323 {
324         pmap_kremove(kva);
325         kmem_free_wakeup(pager_map, kva, PAGE_SIZE);
326 }
327
328 vm_object_t
329 vm_pager_object_lookup(pg_list, handle)
330         register struct pagerlst *pg_list;
331         void *handle;
332 {
333         register vm_object_t object;
334
335         for (object = TAILQ_FIRST(pg_list); object != NULL; object = TAILQ_NEXT(object,pager_object_list))
336                 if (object->handle == handle)
337                         return (object);
338         return (NULL);
339 }
340
341 /*
342  * initialize a physical buffer
343  */
344
345 static void
346 initpbuf(struct buf *bp)
347 {
348         bp->b_rcred = NOCRED;
349         bp->b_wcred = NOCRED;
350         bp->b_qindex = QUEUE_NONE;
351         bp->b_data = (caddr_t) (MAXPHYS * (bp - swbuf)) + swapbkva;
352         bp->b_kvabase = bp->b_data;
353         bp->b_kvasize = MAXPHYS;
354         bp->b_xflags = 0;
355         bp->b_flags = 0;
356         bp->b_error = 0;
357         BUF_LOCK(bp, LK_EXCLUSIVE);
358 }
359
360 /*
361  * allocate a physical buffer
362  *
363  *      There are a limited number (nswbuf) of physical buffers.  We need
364  *      to make sure that no single subsystem is able to hog all of them,
365  *      so each subsystem implements a counter which is typically initialized
366  *      to 1/2 nswbuf.  getpbuf() decrements this counter in allocation and
367  *      increments it on release, and blocks if the counter hits zero.  A
368  *      subsystem may initialize the counter to -1 to disable the feature,
369  *      but it must still be sure to match up all uses of getpbuf() with 
370  *      relpbuf() using the same variable.
371  *
372  *      NOTE: pfreecnt can be NULL, but this 'feature' will be removed
373  *      relatively soon when the rest of the subsystems get smart about it. XXX
374  */
375 struct buf *
376 getpbuf(pfreecnt)
377         int *pfreecnt;
378 {
379         int s;
380         struct buf *bp;
381
382         s = splvm();
383
384         for (;;) {
385                 if (pfreecnt) {
386                         while (*pfreecnt == 0) {
387                                 tsleep(pfreecnt, PVM, "wswbuf0", 0);
388                         }
389                 }
390
391                 /* get a bp from the swap buffer header pool */
392                 if ((bp = TAILQ_FIRST(&bswlist)) != NULL)
393                         break;
394
395                 bswneeded = 1;
396                 tsleep(&bswneeded, PVM, "wswbuf1", 0);
397                 /* loop in case someone else grabbed one */
398         }
399         TAILQ_REMOVE(&bswlist, bp, b_freelist);
400         if (pfreecnt)
401                 --*pfreecnt;
402         splx(s);
403
404         initpbuf(bp);
405         return bp;
406 }
407
408 /*
409  * allocate a physical buffer, if one is available.
410  *
411  *      Note that there is no NULL hack here - all subsystems using this
412  *      call understand how to use pfreecnt.
413  */
414 struct buf *
415 trypbuf(pfreecnt)
416         int *pfreecnt;
417 {
418         int s;
419         struct buf *bp;
420
421         s = splvm();
422         if (*pfreecnt == 0 || (bp = TAILQ_FIRST(&bswlist)) == NULL) {
423                 splx(s);
424                 return NULL;
425         }
426         TAILQ_REMOVE(&bswlist, bp, b_freelist);
427
428         --*pfreecnt;
429
430         splx(s);
431
432         initpbuf(bp);
433
434         return bp;
435 }
436
437 /*
438  * release a physical buffer
439  *
440  *      NOTE: pfreecnt can be NULL, but this 'feature' will be removed
441  *      relatively soon when the rest of the subsystems get smart about it. XXX
442  */
443 void
444 relpbuf(bp, pfreecnt)
445         struct buf *bp;
446         int *pfreecnt;
447 {
448         int s;
449
450         s = splvm();
451
452         if (bp->b_rcred != NOCRED) {
453                 crfree(bp->b_rcred);
454                 bp->b_rcred = NOCRED;
455         }
456         if (bp->b_wcred != NOCRED) {
457                 crfree(bp->b_wcred);
458                 bp->b_wcred = NOCRED;
459         }
460
461         if (bp->b_vp)
462                 pbrelvp(bp);
463
464         BUF_UNLOCK(bp);
465
466         TAILQ_INSERT_HEAD(&bswlist, bp, b_freelist);
467
468         if (bswneeded) {
469                 bswneeded = 0;
470                 wakeup(&bswneeded);
471         }
472         if (pfreecnt) {
473                 if (++*pfreecnt == 1)
474                         wakeup(pfreecnt);
475         }
476         splx(s);
477 }
478
479 /********************************************************
480  *              CHAINING FUNCTIONS                      *
481  ********************************************************
482  *
483  *      These functions support recursion of I/O operations
484  *      on bp's, typically by chaining one or more 'child' bp's
485  *      to the parent.  Synchronous, asynchronous, and semi-synchronous
486  *      chaining is possible.
487  */
488
489 /*
490  *      vm_pager_chain_iodone:
491  *
492  *      io completion routine for child bp.  Currently we fudge a bit
493  *      on dealing with b_resid.   Since users of these routines may issue
494  *      multiple children simultaniously, sequencing of the error can be lost.
495  */
496
497 static void
498 vm_pager_chain_iodone(struct buf *nbp)
499 {
500         struct buf *bp;
501
502         if ((bp = nbp->b_chain.parent) != NULL) {
503                 if (nbp->b_flags & B_ERROR) {
504                         bp->b_flags |= B_ERROR;
505                         bp->b_error = nbp->b_error;
506                 } else if (nbp->b_resid != 0) {
507                         bp->b_flags |= B_ERROR;
508                         bp->b_error = EINVAL;
509                 } else {
510                         bp->b_resid -= nbp->b_bcount;
511                 }
512                 nbp->b_chain.parent = NULL;
513                 --bp->b_chain.count;
514                 if (bp->b_flags & B_WANT) {
515                         bp->b_flags &= ~B_WANT;
516                         wakeup(bp);
517                 }
518                 if (!bp->b_chain.count && (bp->b_xflags & BX_AUTOCHAINDONE)) {
519                         bp->b_xflags &= ~BX_AUTOCHAINDONE;
520                         if (bp->b_resid != 0 && !(bp->b_flags & B_ERROR)) {
521                                 bp->b_flags |= B_ERROR;
522                                 bp->b_error = EINVAL;
523                         }
524                         biodone(bp);
525                 }
526         }
527         nbp->b_flags |= B_DONE;
528         nbp->b_flags &= ~B_ASYNC;
529         relpbuf(nbp, NULL);
530 }
531
532 /*
533  *      getchainbuf:
534  *
535  *      Obtain a physical buffer and chain it to its parent buffer.  When
536  *      I/O completes, the parent buffer will be B_SIGNAL'd.  Errors are
537  *      automatically propogated to the parent
538  *
539  *      Since these are brand new buffers, we do not have to clear B_INVAL
540  *      and B_ERROR because they are already clear.
541  */
542
543 struct buf *
544 getchainbuf(struct buf *bp, struct vnode *vp, int flags)
545 {
546         struct buf *nbp = getpbuf(NULL);
547
548         nbp->b_chain.parent = bp;
549         ++bp->b_chain.count;
550
551         if (bp->b_chain.count > 4)
552                 waitchainbuf(bp, 4, 0);
553
554         nbp->b_flags = B_CALL | (bp->b_flags & B_ORDERED) | flags;
555         nbp->b_rcred = nbp->b_wcred = proc0.p_ucred;
556         nbp->b_iodone = vm_pager_chain_iodone;
557
558         crhold(nbp->b_rcred);
559         crhold(nbp->b_wcred);
560
561         if (vp)
562                 pbgetvp(vp, nbp);
563         return(nbp);
564 }
565
566 void
567 flushchainbuf(struct buf *nbp)
568 {
569         if (nbp->b_bcount) {
570                 nbp->b_bufsize = nbp->b_bcount;
571                 if ((nbp->b_flags & B_READ) == 0)
572                         nbp->b_dirtyend = nbp->b_bcount;
573                 BUF_KERNPROC(nbp);
574                 VOP_STRATEGY(nbp->b_vp, nbp);
575         } else {
576                 biodone(nbp);
577         }
578 }
579
580 void
581 waitchainbuf(struct buf *bp, int count, int done)
582 {
583         int s;
584
585         s = splbio();
586         while (bp->b_chain.count > count) {
587                 bp->b_flags |= B_WANT;
588                 tsleep(bp, PRIBIO + 4, "bpchain", 0);
589         }
590         if (done) {
591                 if (bp->b_resid != 0 && !(bp->b_flags & B_ERROR)) {
592                         bp->b_flags |= B_ERROR;
593                         bp->b_error = EINVAL;
594                 }
595                 biodone(bp);
596         }
597         splx(s);
598 }
599
600 void
601 autochaindone(struct buf *bp)
602 {
603         int s;
604
605         s = splbio();
606         if (bp->b_chain.count == 0)
607                 biodone(bp);
608         else
609                 bp->b_xflags |= BX_AUTOCHAINDONE;
610         splx(s);
611 }
612