BSD 4_3_Net_2 release
[unix-history] / usr / src / sys / vm / vm_pager.c
index 12efff5..c221334 100644 (file)
@@ -1,16 +1,65 @@
 /* 
 /* 
- * Copyright (c) 1985, 1986 Avadis Tevanian, Jr., Michael Wayne Young
- * Copyright (c) 1987 Carnegie-Mellon University
  * Copyright (c) 1991 Regents of the University of California.
  * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * The Mach Operating System project at Carnegie-Mellon University.
  *
  * Copyright (c) 1991 Regents of the University of California.
  * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * The Mach Operating System project at Carnegie-Mellon University.
  *
- * The CMU software License Agreement specifies the terms and conditions
- * for use and redistribution.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
  *
  *
- *     @(#)vm_pager.c  7.1 (Berkeley) %G%
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)vm_pager.c  7.4 (Berkeley) 5/7/91
+ *
+ *
+ * Copyright (c) 1987, 1990 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Authors: Avadis Tevanian, Jr., Michael Wayne Young
+ * 
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ * 
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 
+ * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ * 
+ * Carnegie Mellon requests users of this software to return to
+ *
+ *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
  */
 
 /*
  */
 
 /*
  */
 
 #include "param.h"
  */
 
 #include "param.h"
-#include "queue.h"
 #include "malloc.h"
 
 #include "malloc.h"
 
-#include "../vm/vm_param.h"
-#include "../vm/vm_pager.h"
-#include "../vm/vm_page.h"
-#include "../vm/vm_prot.h"
-#include "../vm/vm_map.h"
-#include "../vm/vm_kern.h"
-
-#include "../vm/pmap.h"
+#include "vm.h"
+#include "vm_page.h"
+#include "vm_kern.h"
 
 #include "swappager.h"
 
 #include "swappager.h"
+
 #if NSWAPPAGER > 0
 extern struct pagerops swappagerops;
 #else
 #if NSWAPPAGER > 0
 extern struct pagerops swappagerops;
 #else
-#define        swappagerops    PAGER_OPS_NULL
+#define        swappagerops    NULL
 #endif
 #include "vnodepager.h"
 #if NVNODEPAGER > 0
 extern struct pagerops vnodepagerops;
 #else
 #endif
 #include "vnodepager.h"
 #if NVNODEPAGER > 0
 extern struct pagerops vnodepagerops;
 #else
-#define        vnodepagerops   PAGER_OPS_NULL
+#define        vnodepagerops   NULL
 #endif
 #include "devpager.h"
 #if NDEVPAGER > 0
 extern struct pagerops devicepagerops;
 #else
 #endif
 #include "devpager.h"
 #if NDEVPAGER > 0
 extern struct pagerops devicepagerops;
 #else
-#define        devicepagerops  PAGER_OPS_NULL
+#define        devicepagerops  NULL
 #endif
 
 struct pagerops *pagertab[] = {
 #endif
 
 struct pagerops *pagertab[] = {
@@ -57,7 +101,7 @@ struct pagerops *pagertab[] = {
 };
 int npagers = sizeof (pagertab) / sizeof (pagertab[0]);
 
 };
 int npagers = sizeof (pagertab) / sizeof (pagertab[0]);
 
-struct pagerops *dfltpagerops = PAGER_OPS_NULL;        /* default pager */
+struct pagerops *dfltpagerops = NULL;  /* default pager */
 
 /*
  * Kernel address space for mapping pages.
 
 /*
  * Kernel address space for mapping pages.
@@ -65,24 +109,24 @@ struct pagerops *dfltpagerops = PAGER_OPS_NULL;    /* default pager */
  */
 #define PAGER_MAP_SIZE (256 * PAGE_SIZE)
 vm_map_t pager_map;
  */
 #define PAGER_MAP_SIZE (256 * PAGE_SIZE)
 vm_map_t pager_map;
+vm_offset_t pager_sva, pager_eva;
 
 void
 vm_pager_init()
 {
 
 void
 vm_pager_init()
 {
-       vm_offset_t whocares1, whocares2;
        struct pagerops **pgops;
 
        /*
         * Allocate a kernel submap for tracking get/put page mappings
         */
        struct pagerops **pgops;
 
        /*
         * Allocate a kernel submap for tracking get/put page mappings
         */
-       pager_map = kmem_suballoc(kernel_map, &whocares1, &whocares2,
+       pager_map = kmem_suballoc(kernel_map, &pager_sva, &pager_eva,
                                  PAGER_MAP_SIZE, FALSE);
        /*
         * Initialize known pagers
         */
        for (pgops = pagertab; pgops < &pagertab[npagers]; pgops++)
                (*(*pgops)->pgo_init)();
                                  PAGER_MAP_SIZE, FALSE);
        /*
         * Initialize known pagers
         */
        for (pgops = pagertab; pgops < &pagertab[npagers]; pgops++)
                (*(*pgops)->pgo_init)();
-       if (dfltpagerops == PAGER_OPS_NULL)
+       if (dfltpagerops == NULL)
                panic("no default pager");
 }
 
                panic("no default pager");
 }
 
@@ -107,7 +151,7 @@ void
 vm_pager_deallocate(pager)
        vm_pager_t      pager;
 {
 vm_pager_deallocate(pager)
        vm_pager_t      pager;
 {
-       if (pager == vm_pager_null)
+       if (pager == NULL)
                panic("vm_pager_deallocate: null pager");
 
        VM_PAGER_DEALLOC(pager);
                panic("vm_pager_deallocate: null pager");
 
        VM_PAGER_DEALLOC(pager);
@@ -120,7 +164,7 @@ vm_pager_get(pager, m, sync)
 {
        extern boolean_t vm_page_zero_fill();
 
 {
        extern boolean_t vm_page_zero_fill();
 
-       if (pager == vm_pager_null)
+       if (pager == NULL)
                return(vm_page_zero_fill(m) ? VM_PAGER_OK : VM_PAGER_FAIL);
        return(VM_PAGER_GET(pager, m, sync));
 }
                return(vm_page_zero_fill(m) ? VM_PAGER_OK : VM_PAGER_FAIL);
        return(VM_PAGER_GET(pager, m, sync));
 }
@@ -130,7 +174,7 @@ vm_pager_put(pager, m, sync)
        vm_page_t       m;
        boolean_t       sync;
 {
        vm_page_t       m;
        boolean_t       sync;
 {
-       if (pager == vm_pager_null)
+       if (pager == NULL)
                panic("vm_pager_put: null pager");
        return(VM_PAGER_PUT(pager, m, sync));
 }
                panic("vm_pager_put: null pager");
        return(VM_PAGER_PUT(pager, m, sync));
 }
@@ -140,7 +184,7 @@ vm_pager_has_page(pager, offset)
        vm_pager_t      pager;
        vm_offset_t     offset;
 {
        vm_pager_t      pager;
        vm_offset_t     offset;
 {
-       if (pager == vm_pager_null)
+       if (pager == NULL)
                panic("vm_pager_has_page");
        return(VM_PAGER_HASPAGE(pager, offset));
 }
                panic("vm_pager_has_page");
        return(VM_PAGER_HASPAGE(pager, offset));
 }
@@ -155,7 +199,7 @@ vm_pager_sync()
        struct pagerops **pgops;
 
        for (pgops = pagertab; pgops < &pagertab[npagers]; pgops++)
        struct pagerops **pgops;
 
        for (pgops = pagertab; pgops < &pagertab[npagers]; pgops++)
-               (*(*pgops)->pgo_putpage)(VM_PAGER_NULL, VM_PAGE_NULL, FALSE);
+               (*(*pgops)->pgo_putpage)(NULL, NULL, FALSE);
 }
 
 vm_offset_t
 }
 
 vm_offset_t
@@ -164,18 +208,18 @@ vm_pager_map_page(m)
 {
        vm_offset_t kva;
 
 {
        vm_offset_t kva;
 
+#ifdef DEBUG
+       if (!m->busy || m->active)
+               panic("vm_pager_map_page: page active or not busy");
+       if (m->pagerowned)
+               printf("vm_pager_map_page: page %x already in pager\n", m);
+#endif
        kva = kmem_alloc_wait(pager_map, PAGE_SIZE);
        kva = kmem_alloc_wait(pager_map, PAGE_SIZE);
-#if 1
-       /*
-        * XXX: cannot use pmap_enter as the mapping would be
-        * removed by a pmap_remove_all().
-        */
-       *(int *)kvtopte(kva) = VM_PAGE_TO_PHYS(m) | PG_CI | PG_V;
-       TBIS(kva);
-#else
+#ifdef DEBUG
+       m->pagerowned = 1;
+#endif
        pmap_enter(vm_map_pmap(pager_map), kva, VM_PAGE_TO_PHYS(m),
                   VM_PROT_DEFAULT, TRUE);
        pmap_enter(vm_map_pmap(pager_map), kva, VM_PAGE_TO_PHYS(m),
                   VM_PROT_DEFAULT, TRUE);
-#endif
        return(kva);
 }
 
        return(kva);
 }
 
@@ -183,11 +227,20 @@ void
 vm_pager_unmap_page(kva)
        vm_offset_t     kva;
 {
 vm_pager_unmap_page(kva)
        vm_offset_t     kva;
 {
-#if 1
-       *(int *)kvtopte(kva) = PG_NV;
-       TBIS(kva);
+#ifdef DEBUG
+       vm_page_t m;
+
+       m = PHYS_TO_VM_PAGE(pmap_extract(vm_map_pmap(pager_map), kva));
 #endif
 #endif
+       pmap_remove(vm_map_pmap(pager_map), kva, kva + PAGE_SIZE);
        kmem_free_wakeup(pager_map, kva, PAGE_SIZE);
        kmem_free_wakeup(pager_map, kva, PAGE_SIZE);
+#ifdef DEBUG
+       if (m->pagerowned)
+               m->pagerowned = 0;
+       else
+               printf("vm_pager_unmap_page: page %x(%x/%x) not owned\n",
+                      m, kva, VM_PAGE_TO_PHYS(m));
+#endif
 }
 
 vm_pager_t
 }
 
 vm_pager_t
@@ -203,7 +256,7 @@ vm_pager_lookup(list, handle)
                        return(pager);
                pager = (vm_pager_t) queue_next(&pager->pg_list);
        }
                        return(pager);
                pager = (vm_pager_t) queue_next(&pager->pg_list);
        }
-       return(VM_PAGER_NULL);
+       return(NULL);
 }
 
 /*
 }
 
 /*
@@ -214,7 +267,7 @@ pager_cache(object, should_cache)
        vm_object_t     object;
        boolean_t       should_cache;
 {
        vm_object_t     object;
        boolean_t       should_cache;
 {
-       if (object == VM_OBJECT_NULL)
+       if (object == NULL)
                return(KERN_INVALID_ARGUMENT);
 
        vm_object_cache_lock();
                return(KERN_INVALID_ARGUMENT);
 
        vm_object_cache_lock();