summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2010-04-06 10:43:01 +0000
committerkib <kib@FreeBSD.org>2010-04-06 10:43:01 +0000
commit47feb6893a7e6951cc6222a540259f6cfa144194 (patch)
treea5625108ba035786ce15e0432fc843dd55858bc0 /sys/vm
parente9fbee49d7ea41f69a621391939d5d7b8b13f82e (diff)
downloadFreeBSD-src-47feb6893a7e6951cc6222a540259f6cfa144194.zip
FreeBSD-src-47feb6893a7e6951cc6222a540259f6cfa144194.tar.gz
When OOM searches for a process to kill, ignore the processes already
killed by OOM. When killed process waits for a page allocation, try to satisfy the request as fast as possible. This removes the often encountered deadlock, where OOM continously selects the same victim process, that sleeps uninterruptibly waiting for a page. The killed process may still sleep if page cannot be obtained immediately, but testing has shown that system has much higher chance to survive in OOM situation with the patch. In collaboration with: pho Reviewed by: alc MFC after: 4 weeks
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vm_fault.c21
-rw-r--r--sys/vm/vm_pageout.c4
2 files changed, 17 insertions, 8 deletions
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index 0a5a412..f409856 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -216,7 +216,7 @@ vm_fault(vm_map_t map, vm_offset_t vaddr, vm_prot_t fault_type,
vm_object_t next_object;
vm_page_t marray[VM_FAULT_READ];
int hardfault;
- int faultcount, ahead, behind;
+ int faultcount, ahead, behind, alloc_req;
struct faultstate fs;
struct vnode *vp;
int locked, error;
@@ -386,9 +386,14 @@ RetryFault:;
/*
* Allocate a new page for this object/offset pair.
+ *
+ * Unlocked read of the p_flag is harmless. At
+ * worst, the P_KILLED might be not observed
+ * there, and allocation can fail, causing
+ * restart and new reading of the p_flag.
*/
fs.m = NULL;
- if (!vm_page_count_severe()) {
+ if (!vm_page_count_severe() || P_KILLED(curproc)) {
#if VM_NRESERVLEVEL > 0
if ((fs.object->flags & OBJ_COLORED) == 0) {
fs.object->flags |= OBJ_COLORED;
@@ -396,10 +401,13 @@ RetryFault:;
fs.pindex;
}
#endif
+ alloc_req = P_KILLED(curproc) ?
+ VM_ALLOC_SYSTEM : VM_ALLOC_NORMAL;
+ if (fs.object->type != OBJT_VNODE &&
+ fs.object->backing_object == NULL)
+ alloc_req |= VM_ALLOC_ZERO;
fs.m = vm_page_alloc(fs.object, fs.pindex,
- (fs.object->type == OBJT_VNODE ||
- fs.object->backing_object != NULL) ?
- VM_ALLOC_NORMAL : VM_ALLOC_ZERO);
+ alloc_req);
}
if (fs.m == NULL) {
unlock_and_deallocate(&fs);
@@ -424,7 +432,8 @@ readrest:
int reqpage = 0;
u_char behavior = vm_map_entry_behavior(fs.entry);
- if (behavior == MAP_ENTRY_BEHAV_RANDOM) {
+ if (behavior == MAP_ENTRY_BEHAV_RANDOM ||
+ P_KILLED(curproc)) {
ahead = 0;
behind = 0;
} else {
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c
index 723b14d..dc2b3b7 100644
--- a/sys/vm/vm_pageout.c
+++ b/sys/vm/vm_pageout.c
@@ -1206,10 +1206,10 @@ vm_pageout_oom(int shortage)
if (PROC_TRYLOCK(p) == 0)
continue;
/*
- * If this is a system or protected process, skip it.
+ * If this is a system, protected or killed process, skip it.
*/
if ((p->p_flag & (P_INEXEC | P_PROTECTED | P_SYSTEM)) ||
- (p->p_pid == 1) ||
+ (p->p_pid == 1) || P_KILLED(p) ||
((p->p_pid < 48) && (swap_pager_avail != 0))) {
PROC_UNLOCK(p);
continue;
OpenPOWER on IntegriCloud