aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Weiner <hannes@cmpxchg.org>2013-02-22 19:32:14 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-23 20:50:09 -0500
commit10316b313cbde4b778c3d1b4b2fe2adbcbe84a48 (patch)
tree3e91c097ac6409604acae2695fb2984ebda55615
parentd778df51c09264076fe0208c099ef7d428f21790 (diff)
mm: vmscan: clarify how swappiness, highest priority, memcg interact
A swappiness of 0 has a slightly different meaning for global reclaim (may swap if file cache really low) and memory cgroup reclaim (never swap, ever). In addition, global reclaim at highest priority will scan all LRU lists equal to their size and ignore other balancing heuristics. UNLESS swappiness forbids swapping, then the lists are balanced based on recent reclaim effectiveness. UNLESS file cache is running low, then anonymous pages are force-scanned. This (total mess of a) behaviour is implicit and not obvious from the way the code is organized. At least make it apparent in the code flow and document the conditions. It will be it easier to come up with sane semantics later. Signed-off-by: Johannes Weiner <hannes@cmpxchg.org> Reviewed-by: Rik van Riel <riel@redhat.com> Reviewed-by: Satoru Moriya <satoru.moriya@hds.com> Reviewed-by: Michal Hocko <mhocko@suse.cz> Acked-by: Mel Gorman <mgorman@suse.de> Cc: Hugh Dickins <hughd@google.com> Cc: Simon Jeons <simon.jeons@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--mm/vmscan.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c
index e4521ba1ddd0..68586c887611 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1656,7 +1656,6 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc,
1656 struct zone_reclaim_stat *reclaim_stat = &lruvec->reclaim_stat; 1656 struct zone_reclaim_stat *reclaim_stat = &lruvec->reclaim_stat;
1657 u64 fraction[2], denominator; 1657 u64 fraction[2], denominator;
1658 enum lru_list lru; 1658 enum lru_list lru;
1659 int noswap = 0;
1660 bool force_scan = false; 1659 bool force_scan = false;
1661 struct zone *zone = lruvec_zone(lruvec); 1660 struct zone *zone = lruvec_zone(lruvec);
1662 1661
@@ -1677,13 +1676,38 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc,
1677 1676
1678 /* If we have no swap space, do not bother scanning anon pages. */ 1677 /* If we have no swap space, do not bother scanning anon pages. */
1679 if (!sc->may_swap || (nr_swap_pages <= 0)) { 1678 if (!sc->may_swap || (nr_swap_pages <= 0)) {
1680 noswap = 1;
1681 fraction[0] = 0; 1679 fraction[0] = 0;
1682 fraction[1] = 1; 1680 fraction[1] = 1;
1683 denominator = 1; 1681 denominator = 1;
1684 goto out; 1682 goto out;
1685 } 1683 }
1686 1684
1685 /*
1686 * Global reclaim will swap to prevent OOM even with no
1687 * swappiness, but memcg users want to use this knob to
1688 * disable swapping for individual groups completely when
1689 * using the memory controller's swap limit feature would be
1690 * too expensive.
1691 */
1692 if (!global_reclaim(sc) && !vmscan_swappiness(sc)) {
1693 fraction[0] = 0;
1694 fraction[1] = 1;
1695 denominator = 1;
1696 goto out;
1697 }
1698
1699 /*
1700 * Do not apply any pressure balancing cleverness when the
1701 * system is close to OOM, scan both anon and file equally
1702 * (unless the swappiness setting disagrees with swapping).
1703 */
1704 if (!sc->priority && vmscan_swappiness(sc)) {
1705 fraction[0] = 1;
1706 fraction[1] = 1;
1707 denominator = 1;
1708 goto out;
1709 }
1710
1687 anon = get_lru_size(lruvec, LRU_ACTIVE_ANON) + 1711 anon = get_lru_size(lruvec, LRU_ACTIVE_ANON) +
1688 get_lru_size(lruvec, LRU_INACTIVE_ANON); 1712 get_lru_size(lruvec, LRU_INACTIVE_ANON);
1689 file = get_lru_size(lruvec, LRU_ACTIVE_FILE) + 1713 file = get_lru_size(lruvec, LRU_ACTIVE_FILE) +
@@ -1765,13 +1789,10 @@ out:
1765 unsigned long scan; 1789 unsigned long scan;
1766 1790
1767 size = get_lru_size(lruvec, lru); 1791 size = get_lru_size(lruvec, lru);
1768 if (sc->priority || noswap || !vmscan_swappiness(sc)) { 1792 scan = size >> sc->priority;
1769 scan = size >> sc->priority; 1793 if (!scan && force_scan)
1770 if (!scan && force_scan) 1794 scan = min(size, SWAP_CLUSTER_MAX);
1771 scan = min(size, SWAP_CLUSTER_MAX); 1795 scan = div64_u64(scan * fraction[file], denominator);
1772 scan = div64_u64(scan * fraction[file], denominator);
1773 } else
1774 scan = size;
1775 nr[lru] = scan; 1796 nr[lru] = scan;
1776 } 1797 }
1777} 1798}