|
@@ -1438,6 +1438,19 @@ putback_inactive_pages(struct lruvec *lruvec, struct list_head *page_list)
|
|
list_splice(&pages_to_free, page_list);
|
|
list_splice(&pages_to_free, page_list);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * If a kernel thread (such as nfsd for loop-back mounts) services
|
|
|
|
+ * a backing device by writing to the page cache it sets PF_LESS_THROTTLE.
|
|
|
|
+ * In that case we should only throttle if the backing device it is
|
|
|
|
+ * writing to is congested. In other cases it is safe to throttle.
|
|
|
|
+ */
|
|
|
|
+static int current_may_throttle(void)
|
|
|
|
+{
|
|
|
|
+ return !(current->flags & PF_LESS_THROTTLE) ||
|
|
|
|
+ current->backing_dev_info == NULL ||
|
|
|
|
+ bdi_write_congested(current->backing_dev_info);
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* shrink_inactive_list() is a helper for shrink_zone(). It returns the number
|
|
* shrink_inactive_list() is a helper for shrink_zone(). It returns the number
|
|
* of reclaimed pages
|
|
* of reclaimed pages
|
|
@@ -1566,7 +1579,8 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,
|
|
* implies that pages are cycling through the LRU faster than
|
|
* implies that pages are cycling through the LRU faster than
|
|
* they are written so also forcibly stall.
|
|
* they are written so also forcibly stall.
|
|
*/
|
|
*/
|
|
- if (nr_unqueued_dirty == nr_taken || nr_immediate)
|
|
|
|
|
|
+ if ((nr_unqueued_dirty == nr_taken || nr_immediate) &&
|
|
|
|
+ current_may_throttle())
|
|
congestion_wait(BLK_RW_ASYNC, HZ/10);
|
|
congestion_wait(BLK_RW_ASYNC, HZ/10);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1575,7 +1589,8 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,
|
|
* is congested. Allow kswapd to continue until it starts encountering
|
|
* is congested. Allow kswapd to continue until it starts encountering
|
|
* unqueued dirty pages or cycling through the LRU too quickly.
|
|
* unqueued dirty pages or cycling through the LRU too quickly.
|
|
*/
|
|
*/
|
|
- if (!sc->hibernation_mode && !current_is_kswapd())
|
|
|
|
|
|
+ if (!sc->hibernation_mode && !current_is_kswapd() &&
|
|
|
|
+ current_may_throttle())
|
|
wait_iff_congested(zone, BLK_RW_ASYNC, HZ/10);
|
|
wait_iff_congested(zone, BLK_RW_ASYNC, HZ/10);
|
|
|
|
|
|
trace_mm_vmscan_lru_shrink_inactive(zone->zone_pgdat->node_id,
|
|
trace_mm_vmscan_lru_shrink_inactive(zone->zone_pgdat->node_id,
|