|
@@ -1033,6 +1033,31 @@ int isolate_lru_page(struct page *page)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Are there way too many processes in the direct reclaim path already?
|
|
|
+ */
|
|
|
+static int too_many_isolated(struct zone *zone, int file,
|
|
|
+ struct scan_control *sc)
|
|
|
+{
|
|
|
+ unsigned long inactive, isolated;
|
|
|
+
|
|
|
+ if (current_is_kswapd())
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ if (!scanning_global_lru(sc))
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ if (file) {
|
|
|
+ inactive = zone_page_state(zone, NR_INACTIVE_FILE);
|
|
|
+ isolated = zone_page_state(zone, NR_ISOLATED_FILE);
|
|
|
+ } else {
|
|
|
+ inactive = zone_page_state(zone, NR_INACTIVE_ANON);
|
|
|
+ isolated = zone_page_state(zone, NR_ISOLATED_ANON);
|
|
|
+ }
|
|
|
+
|
|
|
+ return isolated > inactive;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* shrink_inactive_list() is a helper for shrink_zone(). It returns the number
|
|
|
* of reclaimed pages
|
|
@@ -1048,6 +1073,14 @@ static unsigned long shrink_inactive_list(unsigned long max_scan,
|
|
|
struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(zone, sc);
|
|
|
int lumpy_reclaim = 0;
|
|
|
|
|
|
+ while (unlikely(too_many_isolated(zone, file, sc))) {
|
|
|
+ congestion_wait(WRITE, HZ/10);
|
|
|
+
|
|
|
+ /* We are about to die and free our memory. Return now. */
|
|
|
+ if (fatal_signal_pending(current))
|
|
|
+ return SWAP_CLUSTER_MAX;
|
|
|
+ }
|
|
|
+
|
|
|
/*
|
|
|
* If we need a large contiguous chunk of memory, or have
|
|
|
* trouble getting a small set of contiguous pages, we
|