From: Matthew Dillon Date: Fri, 28 Oct 2011 17:20:26 +0000 (-0700) Subject: kernel - Fix vm_object->rb_memq race in pageout daemon X-Git-Url: https://gitweb.dragonflybsd.org/~lentferj/dragonfly.git/commitdiff_plain/05b9db808aa970044c8cff8dcc030e1d2b1d4486 kernel - Fix vm_object->rb_memq race in pageout daemon * We were not properly holding a VM object's token while scanning its rb_memq. Hold the token properly and also assert that it is held. --- diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c index 5d7dcb038a..b4e819c66a 100644 --- a/sys/vm/vm_pageout.c +++ b/sys/vm/vm_pageout.c @@ -515,6 +515,7 @@ vm_pageout_object_deactivate_pages(vm_map_t map, vm_object_t object, vm_object_t tobject; int remove_mode; + ASSERT_LWKT_TOKEN_HELD(vm_object_token(object)); lobject = object; while (lobject) { @@ -547,8 +548,10 @@ vm_pageout_object_deactivate_pages(vm_map_t map, vm_object_t object, break; vm_object_drop(tobject); } - if (lobject != object) + if (lobject != object) { + vm_object_lock_swap(); vm_object_drop(lobject); + } lobject = tobject; } if (lobject != object) @@ -676,8 +679,11 @@ vm_pageout_map_deactivate_pages(vm_map_t map, vm_pindex_t desired) tmpe = tmpe->next; } - if (bigobj) + if (bigobj) { + vm_object_hold(bigobj); vm_pageout_object_deactivate_pages(map, bigobj, desired, 0); + vm_object_drop(bigobj); + } /* * Next, hunt around for other pages to deactivate. We actually @@ -691,8 +697,11 @@ vm_pageout_map_deactivate_pages(vm_map_t map, vm_pindex_t desired) case VM_MAPTYPE_NORMAL: case VM_MAPTYPE_VPAGETABLE: obj = tmpe->object.vm_object; - if (obj) + if (obj) { + vm_object_hold(obj); vm_pageout_object_deactivate_pages(map, obj, desired, 0); + vm_object_drop(obj); + } break; default: break;