summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2003-05-31 19:40:57 +0000
committeralc <alc@FreeBSD.org>2003-05-31 19:40:57 +0000
commitbd43f8c10db2b8db267ad66e35793c353a4bfa77 (patch)
tree4dcea8bba6b8c8623cc8c41fa6c39453a3d14a9a /sys
parent70af1dfe88ac4e99faf3ed514318d4bc10e1d849 (diff)
downloadFreeBSD-src-bd43f8c10db2b8db267ad66e35793c353a4bfa77.zip
FreeBSD-src-bd43f8c10db2b8db267ad66e35793c353a4bfa77.tar.gz
Add vm object locking to vm_object_madvise().
Diffstat (limited to 'sys')
-rw-r--r--sys/vm/vm_object.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index dc00ded..a4be0ab 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -970,13 +970,13 @@ void
vm_object_madvise(vm_object_t object, vm_pindex_t pindex, int count, int advise)
{
vm_pindex_t end, tpindex;
- vm_object_t tobject;
+ vm_object_t backing_object, tobject;
vm_page_t m;
if (object == NULL)
return;
- vm_object_lock(object);
+ mtx_lock(&Giant);
end = pindex + count;
@@ -987,6 +987,7 @@ vm_object_madvise(vm_object_t object, vm_pindex_t pindex, int count, int advise)
relookup:
tobject = object;
tpindex = pindex;
+ VM_OBJECT_LOCK(tobject);
shadowlookup:
/*
* MADV_FREE only operates on OBJT_DEFAULT or OBJT_SWAP pages
@@ -996,7 +997,7 @@ shadowlookup:
if ((tobject->type != OBJT_DEFAULT &&
tobject->type != OBJT_SWAP) ||
(tobject->flags & OBJ_ONEMAPPING) == 0) {
- continue;
+ goto unlock_tobject;
}
}
@@ -1012,9 +1013,12 @@ shadowlookup:
/*
* next object
*/
- tobject = tobject->backing_object;
- if (tobject == NULL)
- continue;
+ backing_object = tobject->backing_object;
+ if (backing_object == NULL)
+ goto unlock_tobject;
+ VM_OBJECT_LOCK(backing_object);
+ VM_OBJECT_UNLOCK(tobject);
+ tobject = backing_object;
tpindex += OFF_TO_IDX(tobject->backing_object_offset);
goto shadowlookup;
}
@@ -1031,10 +1035,12 @@ shadowlookup:
(m->flags & PG_UNMANAGED) ||
m->valid != VM_PAGE_BITS_ALL) {
vm_page_unlock_queues();
- continue;
+ goto unlock_tobject;
}
- if (vm_page_sleep_if_busy(m, TRUE, "madvpo"))
+ if (vm_page_sleep_if_busy(m, TRUE, "madvpo")) {
+ VM_OBJECT_UNLOCK(tobject);
goto relookup;
+ }
if (advise == MADV_WILLNEED) {
vm_page_activate(m);
} else if (advise == MADV_DONTNEED) {
@@ -1063,8 +1069,10 @@ shadowlookup:
vm_page_unlock_queues();
if (advise == MADV_FREE && tobject->type == OBJT_SWAP)
swap_pager_freespace(tobject, tpindex, 1);
+unlock_tobject:
+ VM_OBJECT_UNLOCK(tobject);
}
- vm_object_unlock(object);
+ mtx_unlock(&Giant);
}
/*
OpenPOWER on IntegriCloud