Fixes from John Dyson:
authorDavid Greenman <davidg@Root.COM>
Wed, 9 Feb 1994 07:03:10 +0000 (07:03 +0000)
committerDavid Greenman <davidg@Root.COM>
Wed, 9 Feb 1994 07:03:10 +0000 (07:03 +0000)
vm_page.c
vm_page_deactivate had a window that interrupts were
not disabled, but should have been.

vm_object.c
in 3 places, a page was being protected VM_PROT_NONE, which
if the page is pager mapped, can cause a system failure
because a pager mapping could disappear.  Now, we block when
a page is busy.

swap_pager.c
a deadlock could occur because a process could be waiting on
a swap clean entry, and that case was not handled correctly.
now, user processes dont call swap_pager_clean and the
normal user process wakes-up the pagedaemon when no swap clean
entries are available.

sys/vm/swap_pager.c
sys/vm/vm_object.c
sys/vm/vm_page.c

index ffe1ba6..de46064 100644 (file)
@@ -38,7 +38,7 @@
  * from: Utah $Hdr: swap_pager.c 1.4 91/04/30$
  * from: @(#)swap_pager.c      7.4 (Berkeley) 5/7/91
  *
  * from: Utah $Hdr: swap_pager.c 1.4 91/04/30$
  * from: @(#)swap_pager.c      7.4 (Berkeley) 5/7/91
  *
- * $Id: swap_pager.c,v 1.14 1994/01/17 09:33:20 davidg Exp $
+ * $Id: swap_pager.c,v 1.15 1994/01/31 04:19:55 davidg Exp $
  */
 
 /*
  */
 
 /*
@@ -951,12 +951,18 @@ swap_pager_io(swp, m, count, reqpage, flags)
                                return VM_PAGER_TRYAGAIN;
 */
                        s = splbio();
                                return VM_PAGER_TRYAGAIN;
 */
                        s = splbio();
-                       (void) swap_pager_clean(NULL, B_WRITE);
+                       if( curproc == pageproc)
+                               (void) swap_pager_clean(NULL, B_WRITE);
+                       else
+                               wakeup((caddr_t) &vm_pages_needed);
                        while (queue_empty(&swap_pager_free)) { 
                                swap_pager_needflags |= SWAP_FREE_NEEDED;
                                tsleep((caddr_t)&swap_pager_free,
                                        PVM, "swpfre", 0);
                        while (queue_empty(&swap_pager_free)) { 
                                swap_pager_needflags |= SWAP_FREE_NEEDED;
                                tsleep((caddr_t)&swap_pager_free,
                                        PVM, "swpfre", 0);
-                               (void) swap_pager_clean(NULL, B_WRITE);
+                               if (curproc == pageproc)
+                                       (void) swap_pager_clean(NULL, B_WRITE);
+                               else
+                                       wakeup((caddr_t) &vm_pages_needed);
                        }
                        splx(s);
                }
                        }
                        splx(s);
                }
@@ -1342,6 +1348,7 @@ swap_pager_iodone(bp)
            queue_empty(&swap_pager_inuse)) { 
                swap_pager_needflags &= ~SWAP_FREE_NEEDED;
                wakeup((caddr_t)&swap_pager_free);
            queue_empty(&swap_pager_inuse)) { 
                swap_pager_needflags &= ~SWAP_FREE_NEEDED;
                wakeup((caddr_t)&swap_pager_free);
+               wakeup((caddr_t)&vm_pages_needed);
        }
 
        if (vm_pageout_pages_needed) {
        }
 
        if (vm_pageout_pages_needed) {
index f2f0782..b0e5b09 100644 (file)
@@ -34,7 +34,7 @@
  * SUCH DAMAGE.
  *
  *     from: @(#)vm_object.c   7.4 (Berkeley) 5/7/91
  * SUCH DAMAGE.
  *
  *     from: @(#)vm_object.c   7.4 (Berkeley) 5/7/91
- *     $Id: vm_object.c,v 1.18 1994/01/24 05:12:44 davidg Exp $
+ *     $Id: vm_object.c,v 1.19 1994/01/31 04:20:52 davidg Exp $
  *
  *
  * Copyright (c) 1987, 1990 Carnegie-Mellon University.
  *
  *
  * Copyright (c) 1987, 1990 Carnegie-Mellon University.
@@ -694,15 +694,22 @@ vm_object_pmap_remove(object, start, end)
        register vm_offset_t    end;
 {
        register vm_page_t      p;
        register vm_offset_t    end;
 {
        register vm_page_t      p;
-       vm_offset_t size = ((end - start) + PAGE_SIZE - 1) / PAGE_SIZE;
+       vm_offset_t size;
 
        if (object == NULL)
                return;
 
        vm_object_lock(object);
 
        if (object == NULL)
                return;
 
        vm_object_lock(object);
+again:
+       size = ((end - start) + PAGE_SIZE - 1) / PAGE_SIZE;
        p = (vm_page_t) queue_first(&object->memq);
        while (!queue_end(&object->memq, (queue_entry_t) p)) {
                if ((start <= p->offset) && (p->offset < end)) {
        p = (vm_page_t) queue_first(&object->memq);
        while (!queue_end(&object->memq, (queue_entry_t) p)) {
                if ((start <= p->offset) && (p->offset < end)) {
+                       if (p->flags & PG_BUSY) {
+                               p->flags |= PG_WANTED;
+                               tsleep((caddr_t) p, PVM, "vmopmr", 0);
+                               goto again;
+                       }
                        pmap_page_protect(VM_PAGE_TO_PHYS(p), VM_PROT_NONE);
                        if ((p->flags & PG_CLEAN) == 0)
                                p->flags |= PG_LAUNDRY;
                        pmap_page_protect(VM_PAGE_TO_PHYS(p), VM_PROT_NONE);
                        if ((p->flags & PG_CLEAN) == 0)
                                p->flags |= PG_LAUNDRY;
@@ -713,35 +720,6 @@ vm_object_pmap_remove(object, start, end)
        vm_object_unlock(object);
 }
 
        vm_object_unlock(object);
 }
 
-void
-vm_object_save_pmap_attributes(vm_object_t object,
-       vm_offset_t start, vm_offset_t end) {
-
-       vm_page_t p;
-
-       if (!object)
-               return;
-
-       if (object->shadow) {
-               vm_object_save_pmap_attributes(object->shadow,
-                       object->shadow_offset + start,
-                       object->shadow_offset + end);
-       }
-
-       p = (vm_page_t) queue_first(&object->memq);
-       while (!queue_end(&object->memq, (queue_entry_t) p)) {
-               if ((start <= p->offset) && (p->offset < end)) {
-                       if ((p->flags & PG_CLEAN) 
-                                && pmap_is_modified(VM_PAGE_TO_PHYS(p))) {
-                               p->flags &= ~PG_CLEAN;
-                       }
-                       if ((p->flags & PG_CLEAN) == 0)
-                               p->flags |= PG_LAUNDRY;
-               }
-               p = (vm_page_t) queue_next(&p->listq);
-       }
-}
-
 /*
  *     vm_object_copy:
  *
 /*
  *     vm_object_copy:
  *
@@ -1522,12 +1500,18 @@ vm_object_page_remove(object, start, end)
 
        start = trunc_page(start);
        end = round_page(end);
 
        start = trunc_page(start);
        end = round_page(end);
+again:
        size = end-start;
        if (size > 4*PAGE_SIZE || size >= object->size/4) {
                p = (vm_page_t) queue_first(&object->memq);
                while (!queue_end(&object->memq, (queue_entry_t) p) && size > 0) {
                        next = (vm_page_t) queue_next(&p->listq);
                        if ((start <= p->offset) && (p->offset < end)) {
        size = end-start;
        if (size > 4*PAGE_SIZE || size >= object->size/4) {
                p = (vm_page_t) queue_first(&object->memq);
                while (!queue_end(&object->memq, (queue_entry_t) p) && size > 0) {
                        next = (vm_page_t) queue_next(&p->listq);
                        if ((start <= p->offset) && (p->offset < end)) {
+                               if (p->flags & PG_BUSY) {
+                                       p->flags |= PG_WANTED;
+                                       tsleep((caddr_t) p, PVM, "vmopar", 0);
+                                       goto again;
+                               }
                                pmap_page_protect(VM_PAGE_TO_PHYS(p), VM_PROT_NONE);
                                vm_page_lock_queues();
                                vm_page_free(p);
                                pmap_page_protect(VM_PAGE_TO_PHYS(p), VM_PROT_NONE);
                                vm_page_lock_queues();
                                vm_page_free(p);
@@ -1539,6 +1523,11 @@ vm_object_page_remove(object, start, end)
        } else {
                while (size > 0) {
                        while (p = vm_page_lookup(object, start)) {
        } else {
                while (size > 0) {
                        while (p = vm_page_lookup(object, start)) {
+                               if (p->flags & PG_BUSY) {
+                                       p->flags |= PG_WANTED;
+                                       tsleep((caddr_t) p, PVM, "vmopar", 0);
+                                       goto again;
+                               }
                                pmap_page_protect(VM_PAGE_TO_PHYS(p), VM_PROT_NONE);
                                vm_page_lock_queues();
                                vm_page_free(p);
                                pmap_page_protect(VM_PAGE_TO_PHYS(p), VM_PROT_NONE);
                                vm_page_lock_queues();
                                vm_page_free(p);
index 7f9edd6..101d949 100644 (file)
@@ -34,7 +34,7 @@
  * SUCH DAMAGE.
  *
  *     from: @(#)vm_page.c     7.4 (Berkeley) 5/7/91
  * SUCH DAMAGE.
  *
  *     from: @(#)vm_page.c     7.4 (Berkeley) 5/7/91
- *     $Id: vm_page.c,v 1.10 1994/01/31 04:21:10 davidg Exp $
+ *     $Id: vm_page.c,v 1.11 1994/01/31 04:32:41 davidg Exp $
  */
 
 /*
  */
 
 /*
@@ -745,7 +745,7 @@ vm_page_deactivate(m)
         *      Paul Mackerras (paulus@cs.anu.edu.au) 9-Jan-93.
         */
 
         *      Paul Mackerras (paulus@cs.anu.edu.au) 9-Jan-93.
         */
 
-       spl = vm_disable_intr();
+       spl = splhigh();
        m->deact = 0;
        if (!(m->flags & PG_INACTIVE) && m->wire_count == 0) {
                pmap_clear_reference(VM_PAGE_TO_PHYS(m));
        m->deact = 0;
        if (!(m->flags & PG_INACTIVE) && m->wire_count == 0) {
                pmap_clear_reference(VM_PAGE_TO_PHYS(m));
@@ -756,15 +756,12 @@ vm_page_deactivate(m)
                }
                queue_enter(&vm_page_queue_inactive, m, vm_page_t, pageq);
                m->flags |= PG_INACTIVE;
                }
                queue_enter(&vm_page_queue_inactive, m, vm_page_t, pageq);
                m->flags |= PG_INACTIVE;
-               vm_set_intr(spl);
                vm_page_inactive_count++;
                pmap_page_protect(VM_PAGE_TO_PHYS(m), VM_PROT_NONE);
                if ((m->flags & PG_CLEAN) == 0)
                        m->flags |= PG_LAUNDRY;
                vm_page_inactive_count++;
                pmap_page_protect(VM_PAGE_TO_PHYS(m), VM_PROT_NONE);
                if ((m->flags & PG_CLEAN) == 0)
                        m->flags |= PG_LAUNDRY;
-       } else {
-               vm_set_intr(spl);
        } 
        } 
-
+       splx(spl);
 }
 
 /*
 }
 
 /*