summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2008-01-02 04:43:47 +0000
committeralc <alc@FreeBSD.org>2008-01-02 04:43:47 +0000
commit3c35e9380cd7de2ebe4957d7e90864e376bb73b8 (patch)
tree38bc50877391eaf9dd285534bf3d3543e46be8ce /sys/vm
parent0ba0d86d89efcaaea861a659c5b68e746e803d21 (diff)
downloadFreeBSD-src-3c35e9380cd7de2ebe4957d7e90864e376bb73b8.zip
FreeBSD-src-3c35e9380cd7de2ebe4957d7e90864e376bb73b8.tar.gz
Defer setting either PG_CACHED or PG_FREE until after the free page
queues lock is acquired. Otherwise, the state of a reservation's pages' flags and its population count can be inconsistent. That could result in a page being freed twice. Reported by: kris
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vm_page.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index 485b738..cea7a23 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -1332,8 +1332,8 @@ vm_page_free_toq(vm_page_t m)
m->flags &= ~PG_ZERO;
vm_pageq_enqueue(PQ_HOLD, m);
} else {
- m->flags |= PG_FREE;
mtx_lock(&vm_page_queue_free_mtx);
+ m->flags |= PG_FREE;
cnt.v_free_count++;
#if VM_NRESERVLEVEL > 0
if (!vm_reserv_free_page(m))
@@ -1584,9 +1584,9 @@ vm_page_cache(vm_page_t m)
* Insert the page into the object's collection of cached pages
* and the physical memory allocator's cache/free page queues.
*/
- vm_page_flag_set(m, PG_CACHED);
vm_page_flag_clear(m, PG_ZERO);
mtx_lock(&vm_page_queue_free_mtx);
+ m->flags |= PG_CACHED;
cnt.v_cache_count++;
root = object->cache;
if (root == NULL) {
OpenPOWER on IntegriCloud