summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordas <das@FreeBSD.org>2003-03-12 23:13:16 +0000
committerdas <das@FreeBSD.org>2003-03-12 23:13:16 +0000
commit96f973e7de4d8f2a11ecedfae50b316319fd1026 (patch)
tree6cae5d8751656edd0c9fcd23480226ea6d6747ec
parenteb02bdf56a079dea8449cdfa53c66a3d36496504 (diff)
downloadFreeBSD-src-96f973e7de4d8f2a11ecedfae50b316319fd1026.zip
FreeBSD-src-96f973e7de4d8f2a11ecedfae50b316319fd1026.tar.gz
- When the VM daemon is out of swap space and looking for a
process to kill, don't block on a map lock while holding the process lock. Instead, skip processes whose map locks are held and find something else to kill. - Add vm_map_trylock_read() to support the above. Reviewed by: alc, mike (mentor)
-rw-r--r--sys/vm/vm_map.c15
-rw-r--r--sys/vm/vm_map.h3
-rw-r--r--sys/vm/vm_pageout.c9
3 files changed, 23 insertions, 4 deletions
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 33e819d..6e96db3 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -346,6 +346,8 @@ vmspace_exitfree(struct proc *p)
* vmspace_swap_count() - count the approximate swap useage in pages for a
* vmspace.
*
+ * The map must be locked.
+ *
* Swap useage is determined by taking the proportional swap used by
* VM objects backing the VM map. To make up for fractional losses,
* if the VM object has any swap use at all the associated map entries
@@ -358,7 +360,6 @@ vmspace_swap_count(struct vmspace *vmspace)
vm_map_entry_t cur;
int count = 0;
- vm_map_lock_read(map);
for (cur = map->header.next; cur != &map->header; cur = cur->next) {
vm_object_t object;
@@ -374,7 +375,6 @@ vmspace_swap_count(struct vmspace *vmspace)
}
}
}
- vm_map_unlock_read(map);
return (count);
}
@@ -439,6 +439,17 @@ _vm_map_trylock(vm_map_t map, const char *file, int line)
}
int
+_vm_map_trylock_read(vm_map_t map, const char *file, int line)
+{
+ int error;
+
+ error = map->system_map ?
+ !_mtx_trylock(&map->system_mtx, 0, file, line) :
+ lockmgr(&map->lock, LK_EXCLUSIVE | LK_NOWAIT, NULL, curthread);
+ return (error == 0);
+}
+
+int
_vm_map_lock_upgrade(vm_map_t map, const char *file, int line)
{
diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h
index eef9a48..b685a18 100644
--- a/sys/vm/vm_map.h
+++ b/sys/vm/vm_map.h
@@ -248,6 +248,7 @@ void _vm_map_unlock(vm_map_t map, 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);
+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_unlock_and_wait(vm_map_t map, boolean_t user_wait);
@@ -258,6 +259,8 @@ void vm_map_wakeup(vm_map_t map);
#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)
+#define vm_map_trylock_read(map) \
+ _vm_map_trylock_read(map, LOCK_FILE, LOCK_LINE)
#define vm_map_lock_upgrade(map) \
_vm_map_lock_upgrade(map, LOCK_FILE, LOCK_LINE)
#define vm_map_lock_downgrade(map) \
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c
index 8e3c39f..dab4ae2 100644
--- a/sys/vm/vm_pageout.c
+++ b/sys/vm/vm_pageout.c
@@ -1214,8 +1214,13 @@ rescan0:
/*
* get the process size
*/
- size = vmspace_resident_count(p->p_vmspace) +
- vmspace_swap_count(p->p_vmspace);
+ if (!vm_map_trylock_read(&p->p_vmspace->vm_map)) {
+ PROC_UNLOCK(p);
+ continue;
+ }
+ size = vmspace_swap_count(p->p_vmspace);
+ vm_map_unlock_read(&p->p_vmspace->vm_map);
+ size += vmspace_resident_count(p->p_vmspace);
/*
* if the this process is bigger than the biggest one
* remember it.
OpenPOWER on IntegriCloud