summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2010-09-19 17:43:22 +0000
committeralc <alc@FreeBSD.org>2010-09-19 17:43:22 +0000
commitf3dba8dd74cc15ab257490b9d68192a103c8f07e (patch)
tree2cee60e1d6c1322844dbe0e1d34f347368c2986d /sys/vm
parenta67dfa17fa374c90926bad24ba3ce7cb6e727e80 (diff)
downloadFreeBSD-src-f3dba8dd74cc15ab257490b9d68192a103c8f07e.zip
FreeBSD-src-f3dba8dd74cc15ab257490b9d68192a103c8f07e.tar.gz
Make refinements to r212824. In particular, don't make
vm_map_unlock_nodefer() part of the synchronization interface for maps. Add comments to vm_map_unlock_and_wait() and vm_map_wakeup() describing how they should be used. In particular, describe the deferred deallocations issue with vm_map_unlock_and_wait(). Redo the implementation of vm_map_unlock_and_wait() so that it passes along the caller's file and line information, just like the other map locking primitives. Reviewed by: kib X-MFC after: r212824
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vm_map.c40
-rw-r--r--sys/vm/vm_map.h7
2 files changed, 27 insertions, 20 deletions
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 489ed3dd..c934db7 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -470,16 +470,6 @@ vm_map_process_deferred(void)
}
void
-_vm_map_unlock_nodefer(vm_map_t map, const char *file, int line)
-{
-
- if (map->system_map)
- _mtx_unlock_flags(&map->system_mtx, 0, file, line);
- else
- _sx_xunlock(&map->lock, file, line);
-}
-
-void
_vm_map_unlock(vm_map_t map, const char *file, int line)
{
@@ -637,19 +627,37 @@ _vm_map_assert_locked_read(vm_map_t map, const char *file, int line)
#endif
/*
- * vm_map_unlock_and_wait:
+ * _vm_map_unlock_and_wait:
+ *
+ * Atomically releases the lock on the specified map and puts the calling
+ * thread to sleep. The calling thread will remain asleep until either
+ * vm_map_wakeup() is performed on the map or the specified timeout is
+ * exceeded.
+ *
+ * WARNING! This function does not perform deferred deallocations of
+ * objects and map entries. Therefore, the calling thread is expected to
+ * reacquire the map lock after reawakening and later perform an ordinary
+ * unlock operation, such as vm_map_unlock(), before completing its
+ * operation on the map.
*/
int
-vm_map_unlock_and_wait(vm_map_t map, int timo)
+_vm_map_unlock_and_wait(vm_map_t map, int timo, const char *file, int line)
{
mtx_lock(&map_sleep_mtx);
- vm_map_unlock_nodefer(map);
- return (msleep(&map->root, &map_sleep_mtx, PDROP | PVM, "vmmaps", timo));
+ if (map->system_map)
+ _mtx_unlock_flags(&map->system_mtx, 0, file, line);
+ else
+ _sx_xunlock(&map->lock, file, line);
+ return (msleep(&map->root, &map_sleep_mtx, PDROP | PVM, "vmmaps",
+ timo));
}
/*
* vm_map_wakeup:
+ *
+ * Awaken any threads that have slept on the map using
+ * vm_map_unlock_and_wait().
*/
void
vm_map_wakeup(vm_map_t map)
@@ -657,8 +665,8 @@ vm_map_wakeup(vm_map_t map)
/*
* Acquire and release map_sleep_mtx to prevent a wakeup()
- * from being performed (and lost) between the vm_map_unlock()
- * and the msleep() in vm_map_unlock_and_wait().
+ * from being performed (and lost) between the map unlock
+ * and the msleep() in _vm_map_unlock_and_wait().
*/
mtx_lock(&map_sleep_mtx);
mtx_unlock(&map_sleep_mtx);
diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h
index 292522e..18a1edf 100644
--- a/sys/vm/vm_map.h
+++ b/sys/vm/vm_map.h
@@ -266,7 +266,7 @@ vmspace_pmap(struct vmspace *vmspace)
void _vm_map_lock(vm_map_t map, const char *file, int line);
void _vm_map_unlock(vm_map_t map, const char *file, int line);
-void _vm_map_unlock_nodefer(vm_map_t map, const char *file, int line);
+int _vm_map_unlock_and_wait(vm_map_t map, int timo, const char *file, int line);
void _vm_map_lock_read(vm_map_t map, const char *file, int line);
void _vm_map_unlock_read(vm_map_t map, const char *file, int line);
int _vm_map_trylock(vm_map_t map, const char *file, int line);
@@ -274,13 +274,12 @@ int _vm_map_trylock_read(vm_map_t map, const char *file, int line);
int _vm_map_lock_upgrade(vm_map_t map, const char *file, int line);
void _vm_map_lock_downgrade(vm_map_t map, const char *file, int line);
int vm_map_locked(vm_map_t map);
-int vm_map_unlock_and_wait(vm_map_t map, int timo);
void vm_map_wakeup(vm_map_t map);
#define vm_map_lock(map) _vm_map_lock(map, LOCK_FILE, LOCK_LINE)
#define vm_map_unlock(map) _vm_map_unlock(map, LOCK_FILE, LOCK_LINE)
-#define vm_map_unlock_nodefer(map) \
- _vm_map_unlock_nodefer(map, LOCK_FILE, LOCK_LINE)
+#define vm_map_unlock_and_wait(map, timo) \
+ _vm_map_unlock_and_wait(map, timo, LOCK_FILE, LOCK_LINE)
#define vm_map_lock_read(map) _vm_map_lock_read(map, LOCK_FILE, LOCK_LINE)
#define vm_map_unlock_read(map) _vm_map_unlock_read(map, LOCK_FILE, LOCK_LINE)
#define vm_map_trylock(map) _vm_map_trylock(map, LOCK_FILE, LOCK_LINE)
OpenPOWER on IntegriCloud