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