From c7aebda8a14a3bb94bb038df338549ccde5b56ea Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Fri, 9 Aug 2013 11:11:11 +0000 Subject: The soft and hard busy mechanism rely on the vm object lock to work. Unify the 2 concept into a real, minimal, sxlock where the shared acquisition represent the soft busy and the exclusive acquisition represent the hard busy. The old VPO_WANTED mechanism becames the hard-path for this new lock and it becomes per-page rather than per-object. The vm_object lock becames an interlock for this functionality: it can be held in both read or write mode. However, if the vm_object lock is held in read mode while acquiring or releasing the busy state, the thread owner cannot make any assumption on the busy state unless it is also busying it. Also: - Add a new flag to directly shared busy pages while vm_page_alloc and vm_page_grab are being executed. This will be very helpful once these functions happen under a read object lock. - Move the swapping sleep into its own per-object flag The KPI is heavilly changed this is why the version is bumped. It is very likely that some VM ports users will need to change their own code. Sponsored by: EMC / Isilon storage division Discussed with: alc Reviewed by: jeff, kib Tested by: gavin, bapt (older version) Tested by: pho, scottl --- sys/kern/kern_exec.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'sys/kern/kern_exec.c') diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 156c80d27267..2b62d468df8d 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -937,10 +937,8 @@ exec_map_first_page(imgp) object->pg_color = 0; } #endif - ma[0] = vm_page_grab(object, 0, VM_ALLOC_NORMAL | VM_ALLOC_NOBUSY | - VM_ALLOC_RETRY); + ma[0] = vm_page_grab(object, 0, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); if (ma[0]->valid != VM_PAGE_BITS_ALL) { - vm_page_busy(ma[0]); initial_pagein = VM_INITIAL_PAGEIN; if (initial_pagein > object->size) initial_pagein = object->size; @@ -948,9 +946,8 @@ exec_map_first_page(imgp) if ((ma[i] = vm_page_next(ma[i - 1])) != NULL) { if (ma[i]->valid) break; - if ((ma[i]->oflags & VPO_BUSY) || ma[i]->busy) + if (vm_page_tryxbusy(ma[i])) break; - vm_page_busy(ma[i]); } else { ma[i] = vm_page_alloc(object, i, VM_ALLOC_NORMAL | VM_ALLOC_IFNOTCACHED); @@ -970,8 +967,8 @@ exec_map_first_page(imgp) VM_OBJECT_WUNLOCK(object); return (EIO); } - vm_page_wakeup(ma[0]); } + vm_page_xunbusy(ma[0]); vm_page_lock(ma[0]); vm_page_hold(ma[0]); vm_page_unlock(ma[0]); -- cgit v1.2.3