patch-2.4.14 linux/mm/oom_kill.c

Next file: linux/mm/page_alloc.c
Previous file: linux/mm/mmap.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.13/linux/mm/oom_kill.c linux/mm/oom_kill.c
@@ -150,7 +150,7 @@
 	 * exit() and clear out its resources quickly...
 	 */
 	p->counter = 5 * HZ;
-	p->flags |= PF_MEMALLOC;
+	p->flags |= PF_MEMALLOC | PF_MEMDIE;
 
 	/* This process has hardware access, be more careful. */
 	if (cap_t(p->cap_effective) & CAP_TO_MASK(CAP_SYS_RAWIO)) {
@@ -168,7 +168,7 @@
  * OR try to be smart about which process to kill. Note that we
  * don't have to be perfect here, we just have to be good.
  */
-void oom_kill(void)
+static void oom_kill(void)
 {
 	struct task_struct *p = select_bad_process(), *q;
 
@@ -193,66 +193,53 @@
 	return;
 }
 
-static inline int node_zones_low(pg_data_t *pgdat)
-{
-	zone_t * zone;
-	int i;
-
-	for (i = pgdat->nr_zones-1; i >= 0; i--) {
-		zone = pgdat->node_zones + i;
-
-		if (zone->free_pages > (zone->pages_low))
-			return 0;
-
-	}
-	return 1;
-}
-
-static int all_zones_low(void)
-{
-	pg_data_t * pgdat = pgdat_list;
-
-	pgdat = pgdat_list;
-	do {
-		if (node_zones_low(pgdat))
-			continue;
-		return 0;
-	} while ((pgdat = pgdat->node_next));
-
-	return 1;
-}
-
 /**
  * out_of_memory - is the system out of memory?
- *
- * Returns 0 if there is still enough memory left,
- * 1 when we are out of memory (otherwise).
  */
-int out_of_memory(void)
+void out_of_memory(void)
 {
-	long cache_mem, limit;
+	static unsigned long first, last, count;
+	unsigned long now, since;
 
-	/* Enough free memory?  Not OOM. */
-	if (!all_zones_low())
-		return 0;
-
-	/* Enough swap space left?  Not OOM. */
+	/*
+	 * Enough swap space left?  Not OOM.
+	 */
 	if (nr_swap_pages > 0)
-		return 0;
+		return;
+
+	now = jiffies;
+	since = now - last;
+	last = now;
+
+	/*
+	 * If it's been a long time since last failure,
+	 * we're not oom.
+	 */
+	last = now;
+	if (since > 5*HZ)
+		goto reset;
+
+	/*
+	 * If we haven't tried for at least one second,
+	 * we're not really oom.
+	 */
+	since = now - first;
+	if (since < HZ)
+		return;
 
 	/*
-	 * If the buffer and page cache (including swap cache) are over
-	 * their (/proc tunable) minimum, we're still not OOM.  We test
-	 * this to make sure we don't return OOM when the system simply
-	 * has a hard time with the cache.
+	 * If we have gotten only a few failures,
+	 * we're not really oom. 
 	 */
-	cache_mem = atomic_read(&page_cache_size);
-	limit = 2;
-	limit *= num_physpages / 100;
+	if (++count < 10)
+		return;
 
-	if (cache_mem > limit)
-		return 0;
+	/*
+	 * Ok, really out of memory. Kill something.
+	 */
+	oom_kill();
 
-	/* Else... */
-	return 1;
+reset:
+	first = now;
+	count = 0;
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)