Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/uvm Call amap_extend() a second time in the case of a bi...



details:   https://anonhg.NetBSD.org/src/rev/8ec32bdc2434
branches:  trunk
changeset: 538657:8ec32bdc2434
user:      atatat <atatat%NetBSD.org@localhost>
date:      Thu Oct 24 20:37:59 2002 +0000

description:
Call amap_extend() a second time in the case of a bimerge (both
backwards and forwards) if the previous entry was backed by an amap.

Fixes pr kern/18789, where netscape 7 + a java applet actually manage
to incur forward and bimerges in userspace.

Code reviewed by fvdl and thorpej.

diffstat:

 sys/uvm/uvm_map.c |  49 +++++++++++++++++++++++++++++++++++++------------
 1 files changed, 37 insertions(+), 12 deletions(-)

diffs (93 lines):

diff -r 60c4a11c5354 -r 8ec32bdc2434 sys/uvm/uvm_map.c
--- a/sys/uvm/uvm_map.c Thu Oct 24 18:51:19 2002 +0000
+++ b/sys/uvm/uvm_map.c Thu Oct 24 20:37:59 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_map.c,v 1.121 2002/10/18 13:18:42 atatat Exp $     */
+/*     $NetBSD: uvm_map.c,v 1.122 2002/10/24 20:37:59 atatat Exp $     */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -71,7 +71,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.121 2002/10/18 13:18:42 atatat Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.122 2002/10/24 20:37:59 atatat Exp $");
 
 #include "opt_ddb.h"
 #include "opt_uvmhist.h"
@@ -745,11 +745,23 @@
                /*
                 * can't extend a shared amap.  note: no need to lock amap to
                 * look at refs since we don't care about its exact value.
-                * if it is one (i.e. we have only reference) it will stay there
+                * if it is one (i.e. we have only reference) it will stay there.
+                *
+                * note that we also can't merge two amaps, so if we
+                * merged with the previous entry which has an amap,
+                * and the next entry also has an amap, we give up.
+                *
+                * XXX should we attempt to deal with someone refilling
+                * the deallocated region between two entries that are
+                * backed by the same amap (ie, arefs is 2, "prev" and
+                * "next" refer to it, and adding this allocation will
+                * close the hole, thus restoring arefs to 1 and
+                * deallocating the "next" vm_map_entry)?  -- @@@
                 */
 
                if (prev_entry->next->aref.ar_amap &&
-                   amap_refs(prev_entry->next->aref.ar_amap) != 1) {
+                   (amap_refs(prev_entry->next->aref.ar_amap) != 1 ||
+                    (merged && prev_entry->aref.ar_amap))) {
                        goto nomerge;
                }
 
@@ -771,16 +783,33 @@
                        goto nomerge;
                }
 
+               /*
+                * XXX call amap_extend() to merge backwards here if needed.  -- @@@
+                */
+               if (merged) {
+                       if (prev_entry->aref.ar_amap) {
+                               error = amap_extend(prev_entry,
+                                   prev_entry->next->end -
+                                   prev_entry->next->start);
+                               if (error) {
+                                       vm_map_unlock(map);
+                                       if (new_entry) {
+                                               uvm_mapent_free(new_entry);
+                                       }
+                                       return error;
+                               }
+                       }
+               }
+
                if (merged) {
                        if (kmap) {
                                UVMCNT_DECR(map_kbackmerge);
                                UVMCNT_INCR(map_kbimerge);
                        } else {
-                               UVMCNT_DECR(map_kbackmerge);
-                               UVMCNT_INCR(map_kbimerge);
+                               UVMCNT_DECR(map_ubackmerge);
+                               UVMCNT_INCR(map_ubimerge);
                        }
-               }
-               else {
+               } else {
                        if (kmap)
                                UVMCNT_INCR(map_kforwmerge);
                        else
@@ -796,10 +825,6 @@
                if (uobj && uobj->pgops->pgo_detach && !merged)
                        uobj->pgops->pgo_detach(uobj);
 
-               /*
-                * XXX call amap_extend() to merge backwards here.  -- @@@
-                */
-
                if (merged) {
                        struct vm_map_entry *dead = prev_entry->next;
                        prev_entry->end = dead->end;



Home | Main Index | Thread Index | Old Index