This commit was manufactured by cvs2svn to create tag 'FreeBSD-release/1.1'.
[unix-history] / sys / vm / vm_fault.c
index 8c15e35..1c5f8b2 100644 (file)
@@ -66,7 +66,7 @@
  * rights to redistribute these changes.
  */
 /*
  * rights to redistribute these changes.
  */
 /*
- * $Id$
+ * $Id: vm_fault.c,v 1.14 1994/01/31 04:19:59 davidg Exp $
  */
 
 /*
  */
 
 /*
@@ -82,9 +82,9 @@
 #include "resource.h"
 #include "resourcevar.h"
 
 #include "resource.h"
 #include "resourcevar.h"
 
-#define VM_FAULT_READ_AHEAD 8
-#define VM_FAULT_READ_AHEAD_MIN 4
-#define VM_FAULT_READ_BEHIND 1
+#define VM_FAULT_READ_AHEAD 3
+#define VM_FAULT_READ_AHEAD_MIN 1
+#define VM_FAULT_READ_BEHIND 2
 #define VM_FAULT_READ (VM_FAULT_READ_AHEAD+VM_FAULT_READ_BEHIND+1)
 extern int swap_pager_full;
 extern int vm_pageout_proc_limit;
 #define VM_FAULT_READ (VM_FAULT_READ_AHEAD+VM_FAULT_READ_BEHIND+1)
 extern int swap_pager_full;
 extern int vm_pageout_proc_limit;
@@ -266,11 +266,10 @@ vm_fault(map, vaddr, fault_type, change_wiring)
                         *      wait for it and then retry.
                         */
                        if (m->flags & PG_BUSY) {
                         *      wait for it and then retry.
                         */
                        if (m->flags & PG_BUSY) {
-                               int s;
                                UNLOCK_THINGS;
                                if (m->flags & PG_BUSY) {
                                        m->flags |= PG_WANTED;
                                UNLOCK_THINGS;
                                if (m->flags & PG_BUSY) {
                                        m->flags |= PG_WANTED;
-                                       tsleep((caddr_t)m,PVM,"vmpfw",0);
+                                       tsleep((caddr_t)m,PSWP,"vmpfw",0);
                                }
                                vm_object_deallocate(first_object);
                                goto RetryFault;
                                }
                                vm_object_deallocate(first_object);
                                goto RetryFault;
@@ -316,12 +315,11 @@ vm_fault(map, vaddr, fault_type, change_wiring)
                    || (object == first_object)) {
 
 #if 0
                    || (object == first_object)) {
 
 #if 0
-                       if (curproc && (curproc->p_rlimit[RLIMIT_RSS].rlim_max <
+                       if (curproc && (vaddr < VM_MAXUSER_ADDRESS) &&
+                               (curproc->p_rlimit[RLIMIT_RSS].rlim_max <
                            curproc->p_vmspace->vm_pmap.pm_stats.resident_count * NBPG)) {
                                UNLOCK_AND_DEALLOCATE;
                            curproc->p_vmspace->vm_pmap.pm_stats.resident_count * NBPG)) {
                                UNLOCK_AND_DEALLOCATE;
-                               wakeup(&vm_pages_needed);
-                               vm_pageout_proc_limit = 1;
-                               tsleep(&vm_pageout_proc_limit, PVM, "vmlimt", 0);
+                               vm_fault_free_pages(curproc);
                                goto RetryFault;
                        }
 #endif
                                goto RetryFault;
                        }
 #endif
@@ -558,13 +556,10 @@ vm_fault(map, vaddr, fault_type, change_wiring)
 
                        vm_page_lock_queues();
 
 
                        vm_page_lock_queues();
 
-                       if ((m->flags & PG_CLEAN) && pmap_is_modified(VM_PAGE_TO_PHYS(m)))
-                               m->flags &= ~PG_CLEAN;
-
-                       if ((m->flags & PG_CLEAN) == 0)
-                               m->flags |= PG_LAUNDRY;
                        vm_page_activate(m);
                        pmap_page_protect(VM_PAGE_TO_PHYS(m), VM_PROT_NONE);
                        vm_page_activate(m);
                        pmap_page_protect(VM_PAGE_TO_PHYS(m), VM_PROT_NONE);
+                       if ((m->flags & PG_CLEAN) == 0)
+                               m->flags |= PG_LAUNDRY;
                        vm_page_unlock_queues();
 
                        /*
                        vm_page_unlock_queues();
 
                        /*
@@ -762,15 +757,11 @@ vm_fault(map, vaddr, fault_type, change_wiring)
 
                                vm_page_activate(old_m);
 
 
                                vm_page_activate(old_m);
 
-                               if ((old_m->flags & PG_CLEAN) &&
-                                       pmap_is_modified(VM_PAGE_TO_PHYS(old_m)))
-                                       old_m->flags &= ~PG_CLEAN;
-
-                               if ((old_m->flags & PG_CLEAN) == 0)
-                                       old_m->flags |= PG_LAUNDRY;
 
                                pmap_page_protect(VM_PAGE_TO_PHYS(old_m),
                                                  VM_PROT_NONE);
 
                                pmap_page_protect(VM_PAGE_TO_PHYS(old_m),
                                                  VM_PROT_NONE);
+                               if ((old_m->flags & PG_CLEAN) == 0)
+                                       old_m->flags |= PG_LAUNDRY;
                                copy_m->flags &= ~PG_CLEAN;
                                vm_page_activate(copy_m);
                                vm_page_unlock_queues();
                                copy_m->flags &= ~PG_CLEAN;
                                vm_page_activate(copy_m);
                                vm_page_unlock_queues();
@@ -902,8 +893,10 @@ vm_fault(map, vaddr, fault_type, change_wiring)
                else
                        vm_page_unwire(m);
        }
                else
                        vm_page_unwire(m);
        }
-       else
+       else {
                vm_page_activate(m);
                vm_page_activate(m);
+               vm_pageout_deact_bump(m);
+       }
        vm_page_unlock_queues();
 
        /*
        vm_page_unlock_queues();
 
        /*
@@ -1187,18 +1180,34 @@ vm_fault_additional_pages(first_object, first_offset, m, rbehind, raheada, marra
        if (!vm_pager_has_page(object->pager, object->paging_offset+offset))
                return 0;
 
        if (!vm_pager_has_page(object->pager, object->paging_offset+offset))
                return 0;
 
+       /*
+        * if there is no getmulti routine for this pager, then just allow
+        * one page to be read.
+        */
        if (!object->pager->pg_ops->pgo_getmulti) {
                *reqpage = 0;
                marray[0] = m;
                return 1;
        }
 
        if (!object->pager->pg_ops->pgo_getmulti) {
                *reqpage = 0;
                marray[0] = m;
                return 1;
        }
 
+       /*
+        * try to do any readahead that we might have free pages for.
+        */
        rahead = raheada;
        if (rahead > (vm_page_free_count - vm_page_free_reserved)) {
                rahead = vm_page_free_count - vm_page_free_reserved;
                rbehind = 0;
        }
 
        rahead = raheada;
        if (rahead > (vm_page_free_count - vm_page_free_reserved)) {
                rahead = vm_page_free_count - vm_page_free_reserved;
                rbehind = 0;
        }
 
+       if (vm_page_free_count < vm_page_free_min) {
+               if (rahead > VM_FAULT_READ_AHEAD_MIN)
+                       rahead = VM_FAULT_READ_AHEAD_MIN;
+               rbehind = 0;
+       }
+
+       /*
+        * if we don't have any free pages, then just read one page.
+        */
        if (rahead <= 0) {
                *reqpage = 0;
                marray[0] = m;
        if (rahead <= 0) {
                *reqpage = 0;
                marray[0] = m;
@@ -1210,13 +1219,17 @@ vm_fault_additional_pages(first_object, first_offset, m, rbehind, raheada, marra
         * in memory or on disk not in same object
         */
        toffset = offset - NBPG;
         * in memory or on disk not in same object
         */
        toffset = offset - NBPG;
+       if( rbehind*NBPG > offset)
+               rbehind = offset / NBPG;
        startoffset = offset - rbehind*NBPG;
        startoffset = offset - rbehind*NBPG;
-       while (((int)(toffset+NBPG)) >= 0 && toffset >= startoffset) {
+       while (toffset >= startoffset) {
                if (!vm_fault_page_lookup(first_object, toffset - offsetdiff, &rtobject, &rtoffset, &rtm) ||
                    rtm != 0 || rtobject != object) {
                        startoffset = toffset + NBPG;
                        break;
                }
                if (!vm_fault_page_lookup(first_object, toffset - offsetdiff, &rtobject, &rtoffset, &rtm) ||
                    rtm != 0 || rtobject != object) {
                        startoffset = toffset + NBPG;
                        break;
                }
+               if( toffset == 0)
+                       break;
                toffset -= NBPG;
        }
 
                toffset -= NBPG;
        }
 
@@ -1229,11 +1242,11 @@ vm_fault_additional_pages(first_object, first_offset, m, rbehind, raheada, marra
        while (toffset < object->size && toffset < endoffset) {
                if (!vm_fault_page_lookup(first_object, toffset - offsetdiff, &rtobject, &rtoffset, &rtm) ||
                    rtm != 0 || rtobject != object) {
        while (toffset < object->size && toffset < endoffset) {
                if (!vm_fault_page_lookup(first_object, toffset - offsetdiff, &rtobject, &rtoffset, &rtm) ||
                    rtm != 0 || rtobject != object) {
-                       endoffset = toffset;
                        break;
                }
                toffset += NBPG;
        }
                        break;
                }
                toffset += NBPG;
        }
+       endoffset = toffset;
 
        /* calculate number of bytes of pages */
        size = (endoffset - startoffset) / NBPG;
 
        /* calculate number of bytes of pages */
        size = (endoffset - startoffset) / NBPG;
@@ -1241,11 +1254,11 @@ vm_fault_additional_pages(first_object, first_offset, m, rbehind, raheada, marra
        /* calculate the page offset of the required page */
        treqpage = (offset - startoffset) / NBPG;
                
        /* calculate the page offset of the required page */
        treqpage = (offset - startoffset) / NBPG;
                
-       /* see if we have space */
+       /* see if we have space (again) */
        if (vm_page_free_count >= vm_page_free_reserved + size) {
                bzero(marray, (rahead + rbehind + 1) * sizeof(vm_page_t));
                /*
        if (vm_page_free_count >= vm_page_free_reserved + size) {
                bzero(marray, (rahead + rbehind + 1) * sizeof(vm_page_t));
                /*
-                * get our pages and block for them
+                * get our pages and don't block for them
                 */
                for (i = 0; i < size; i++) {
                        if (i != treqpage)
                 */
                for (i = 0; i < size; i++) {
                        if (i != treqpage)
@@ -1260,6 +1273,10 @@ vm_fault_additional_pages(first_object, first_offset, m, rbehind, raheada, marra
                                break;
                }
 
                                break;
                }
 
+               /*
+                * if we could not get our block of pages, then
+                * free the readahead/readbehind pages.
+                */
                if (i < size) {
                        for (i = 0; i < size; i++) {
                                if (i != treqpage && marray[i])
                if (i < size) {
                        for (i = 0; i < size; i++) {
                                if (i != treqpage && marray[i])
@@ -1273,7 +1290,6 @@ vm_fault_additional_pages(first_object, first_offset, m, rbehind, raheada, marra
                *reqpage = treqpage;
                return size;
        }
                *reqpage = treqpage;
                return size;
        }
-       wakeup((caddr_t) &vm_pages_needed);
        *reqpage = 0;
        marray[0] = m;
        return 1;
        *reqpage = 0;
        marray[0] = m;
        return 1;