Source-Changes-HG archive

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

[src/trunk]: src/sys/uvm - Move pre-check from uvm_obj_destroy() to ubc_purge...



details:   https://anonhg.NetBSD.org/src/rev/47eed4a54395
branches:  trunk
changeset: 766209:47eed4a54395
user:      rmind <rmind%NetBSD.org@localhost>
date:      Sat Jun 18 21:14:43 2011 +0000

description:
- Move pre-check from uvm_obj_destroy() to ubc_purge(), keep it abstracted.
- Add comments noting the race between ubc_alloc() and ubc_purge().

diffstat:

 sys/uvm/uvm_bio.c    |  23 +++++++++++++++++------
 sys/uvm/uvm_object.c |  11 +++++------
 2 files changed, 22 insertions(+), 12 deletions(-)

diffs (96 lines):

diff -r 51ba27021634 -r 47eed4a54395 sys/uvm/uvm_bio.c
--- a/sys/uvm/uvm_bio.c Sat Jun 18 21:13:29 2011 +0000
+++ b/sys/uvm/uvm_bio.c Sat Jun 18 21:14:43 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_bio.c,v 1.75 2011/06/17 09:50:52 hannken Exp $     */
+/*     $NetBSD: uvm_bio.c,v 1.76 2011/06/18 21:14:43 rmind Exp $       */
 
 /*
  * Copyright (c) 1998 Chuck Silvers.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_bio.c,v 1.75 2011/06/17 09:50:52 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_bio.c,v 1.76 2011/06/18 21:14:43 rmind Exp $");
 
 #include "opt_uvmhist.h"
 #include "opt_ubc.h"
@@ -481,12 +481,12 @@
        slot_offset = (vaddr_t)(offset & ((voff_t)ubc_winsize - 1));
        *lenp = MIN(*lenp, ubc_winsize - slot_offset);
 
+       mutex_enter(ubc_object.uobj.vmobjlock);
+again:
        /*
-        * The object is already referenced, so we do not need to add a ref.
+        * The UVM object is already referenced.
         * Lock order: UBC object -> ubc_map::uobj.
         */
-       mutex_enter(ubc_object.uobj.vmobjlock);
-again:
        umap = ubc_find_mapping(uobj, umap_offset);
        if (umap == NULL) {
                struct uvm_object *oobj;
@@ -503,10 +503,14 @@
                oobj = umap->uobj;
 
                /*
-                * remove from old hash (if any), add to new hash.
+                * Remove from old hash (if any), add to new hash.
                 */
 
                if (oobj != NULL) {
+                       /*
+                        * Mapping must be removed before the list entry,
+                        * since there is a race with ubc_purge().
+                        */
                        if (umap->flags & UMAP_MAPPING_CACHED) {
                                umap->flags &= ~UMAP_MAPPING_CACHED;
                                mutex_enter(oobj->vmobjlock);
@@ -792,6 +796,13 @@
 
        KASSERT(uobj->uo_npages == 0);
 
+       /*
+        * Safe to check without lock held, as ubc_alloc() removes
+        * the mapping and list entry in the correct order.
+        */
+       if (__predict_true(LIST_EMPTY(&uobj->uo_ubc))) {
+               return;
+       }
        mutex_enter(ubc_object.uobj.vmobjlock);
        while ((umap = LIST_FIRST(&uobj->uo_ubc)) != NULL) {
                KASSERT(umap->refcount == 0);
diff -r 51ba27021634 -r 47eed4a54395 sys/uvm/uvm_object.c
--- a/sys/uvm/uvm_object.c      Sat Jun 18 21:13:29 2011 +0000
+++ b/sys/uvm/uvm_object.c      Sat Jun 18 21:14:43 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_object.c,v 1.9 2011/06/12 06:36:38 mrg Exp $       */
+/*     $NetBSD: uvm_object.c,v 1.10 2011/06/18 21:14:43 rmind Exp $    */
 
 /*
  * Copyright (c) 2006, 2010 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_object.c,v 1.9 2011/06/12 06:36:38 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_object.c,v 1.10 2011/06/18 21:14:43 rmind Exp $");
 
 #include "opt_ddb.h"
 
@@ -84,10 +84,9 @@
 
        KASSERT(rb_tree_iterate(&uo->rb_tree, NULL, RB_DIR_LEFT) == NULL);
 
-       /* Purge any UBC entries with this object. */
-       if (__predict_false(!LIST_EMPTY(&uo->uo_ubc))) {
-               ubc_purge(uo);
-       }
+       /* Purge any UBC entries associated with this object. */
+       ubc_purge(uo);
+
        /* Destroy the lock, if requested. */
        if (dlock) {
                mutex_obj_free(uo->vmobjlock);



Home | Main Index | Thread Index | Old Index