From: Matthew Dillon Date: Thu, 16 Aug 2012 18:42:25 +0000 (-0700) Subject: kernel - Fix incorrect dirty/reprotect code in pageout X-Git-Tag: v3.0.3~5 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/4d289d94806fbaf2b1d0d81acf036409bdd0e735?ds=sidebyside kernel - Fix incorrect dirty/reprotect code in pageout * vm_object_page_collect_flush() was trying to re-protect VM pages that were still marked dirty after pageout I/O was initiated without owning the BUSY bit on the page. This operation could race whatever I/O was going on and multiple issues. Remove the re-protect. Just don't do it. It's an unnecessary operation. We still re-set PG_CLEANCHK on the page and that should be fine insofar as the pageout daemon goes. * Note that the pageout_flush code protects the VM pages properly (to read-only) prior to initiating I/O . * Should fix bug #2350 * Might be related to the wire-count bug considering that we were messing with the page's pmap without owning the BUSY bit. Small chance. --- diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index c4f09c5023..e0cbf5ec28 100644 --- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -99,7 +99,7 @@ static void vm_object_qcollapse(vm_object_t object, vm_object_t backing_object); -static int vm_object_page_collect_flush(vm_object_t object, vm_page_t p, +static void vm_object_page_collect_flush(vm_object_t object, vm_page_t p, int pagerflags); static void vm_object_lock_init(vm_object_t); @@ -1241,7 +1241,7 @@ done: * * The caller must hold the object. */ -static int +static void vm_object_page_collect_flush(vm_object_t object, vm_page_t p, int pagerflags) { int runlen; @@ -1343,9 +1343,15 @@ vm_object_page_collect_flush(vm_object_t object, vm_page_t p, int pagerflags) vm_pageout_flush(ma, runlen, pagerflags); + /* + * WARNING: Related pages are still held but the BUSY was inherited + * by the pageout I/O, so the pages might not be busy any + * more. We cannot re-protect the page without waiting + * for the I/O to complete and then busying it again. + */ for (i = 0; i < runlen; i++) { if (ma[i]->valid & ma[i]->dirty) { - vm_page_protect(ma[i], VM_PROT_READ); + /*vm_page_protect(ma[i], VM_PROT_READ);*/ vm_page_flag_set(ma[i], PG_CLEANCHK); /* @@ -1358,7 +1364,7 @@ vm_object_page_collect_flush(vm_object_t object, vm_page_t p, int pagerflags) } vm_page_unhold(ma[i]); } - return(maxf + 1); + /*return(maxf + 1);*/ } /*