All of lore.kernel.org
 help / color / mirror / Atom feed
From: Joonsoo Kim <js1304@gmail.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: Linux Memory Management List <linux-mm@kvack.org>,
	LKML <linux-kernel@vger.kernel.org>,
	Johannes Weiner <hannes@cmpxchg.org>,
	Michal Hocko <mhocko@kernel.org>, Hugh Dickins <hughd@google.com>,
	Minchan Kim <minchan@kernel.org>,
	Vlastimil Babka <vbabka@suse.cz>,
	Mel Gorman <mgorman@techsingularity.net>,
	kernel-team@lge.com, Joonsoo Kim <iamjoonsoo.kim@lge.com>
Subject: Re: [PATCH 3/9] mm/workingset: extend the workingset detection for anon LRU
Date: Fri, 14 Feb 2020 13:07:53 +0900	[thread overview]
Message-ID: <CAAmzW4NGwvTiE_unACAcSZUH9V3tO0qR=ZPxi=q9s=zDi53DeQ@mail.gmail.com> (raw)
In-Reply-To: <1581401993-20041-4-git-send-email-iamjoonsoo.kim@lge.com>

2020년 2월 11일 (화) 오후 3:20, <js1304@gmail.com>님이 작성:
>
> From: Joonsoo Kim <iamjoonsoo.kim@lge.com>
>
> In the following patch, workingset detection will be applied to
> anonymous LRU. To prepare it, this patch adds some code to
> distinguish/handle the both LRUs.
>
> Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>
> ---
>  include/linux/mmzone.h | 14 +++++++++-----
>  mm/memcontrol.c        | 12 ++++++++----
>  mm/vmscan.c            | 15 ++++++++++-----
>  mm/vmstat.c            |  6 ++++--
>  mm/workingset.c        | 35 ++++++++++++++++++++++-------------
>  5 files changed, 53 insertions(+), 29 deletions(-)

This patch should be changed as following.

-       enum lru_list active_lru = page_lru_base_type(page) + LRU_ACTIVE_FILE;
+       enum lru_list active_lru = page_lru_base_type(page) + LRU_ACTIVE;

Whole fixed patch is as following.

--------------------->8----------------------
From 2b0691140d11c4e9a0f1500dda831b70697b2a00 Mon Sep 17 00:00:00 2001
From: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Date: Fri, 15 Nov 2019 09:40:22 +0900
Subject: [PATCH] mm/workingset: extend the workingset detection for anon LRU

In the following patch, workingset detection will be applied to
anonymous LRU. To prepare it, this patch adds some code to
distinguish/handle the both LRUs.

Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>
---
 include/linux/mmzone.h | 14 +++++++++-----
 mm/memcontrol.c        | 12 ++++++++----
 mm/vmscan.c            | 15 ++++++++++-----
 mm/vmstat.c            |  6 ++++--
 mm/workingset.c        | 35 ++++++++++++++++++++++-------------
 5 files changed, 53 insertions(+), 29 deletions(-)

diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 5334ad8fc7bd..b78fd8c7284b 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -220,8 +220,12 @@ enum node_stat_item {
  NR_ISOLATED_ANON, /* Temporary isolated pages from anon lru */
  NR_ISOLATED_FILE, /* Temporary isolated pages from file lru */
  WORKINGSET_NODES,
- WORKINGSET_REFAULT,
- WORKINGSET_ACTIVATE,
+ WORKINGSET_REFAULT_BASE,
+ WORKINGSET_REFAULT_ANON = WORKINGSET_REFAULT_BASE,
+ WORKINGSET_REFAULT_FILE,
+ WORKINGSET_ACTIVATE_BASE,
+ WORKINGSET_ACTIVATE_ANON = WORKINGSET_ACTIVATE_BASE,
+ WORKINGSET_ACTIVATE_FILE,
  WORKINGSET_RESTORE,
  WORKINGSET_NODERECLAIM,
  NR_ANON_MAPPED, /* Mapped anonymous pages */
@@ -304,10 +308,10 @@ enum lruvec_flags {
 struct lruvec {
  struct list_head lists[NR_LRU_LISTS];
  struct zone_reclaim_stat reclaim_stat;
- /* Evictions & activations on the inactive file list */
- atomic_long_t inactive_age;
+ /* Evictions & activations on the inactive list */
+ atomic_long_t inactive_age[2];
  /* Refaults at the time of last reclaim cycle */
- unsigned long refaults;
+ unsigned long refaults[2];
  /* Various lruvec state flags (enum lruvec_flags) */
  unsigned long flags;
 #ifdef CONFIG_MEMCG
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 6c83cf4ed970..8f4473d6ff9c 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1431,10 +1431,14 @@ static char *memory_stat_format(struct
mem_cgroup *memcg)
  seq_buf_printf(&s, "%s %lu\n", vm_event_name(PGMAJFAULT),
         memcg_events(memcg, PGMAJFAULT));

- seq_buf_printf(&s, "workingset_refault %lu\n",
-        memcg_page_state(memcg, WORKINGSET_REFAULT));
- seq_buf_printf(&s, "workingset_activate %lu\n",
-        memcg_page_state(memcg, WORKINGSET_ACTIVATE));
+ seq_buf_printf(&s, "workingset_refault_anon %lu\n",
+        memcg_page_state(memcg, WORKINGSET_REFAULT_ANON));
+ seq_buf_printf(&s, "workingset_refault_file %lu\n",
+        memcg_page_state(memcg, WORKINGSET_REFAULT_FILE));
+ seq_buf_printf(&s, "workingset_activate_anon %lu\n",
+        memcg_page_state(memcg, WORKINGSET_ACTIVATE_ANON));
+ seq_buf_printf(&s, "workingset_activate_file %lu\n",
+        memcg_page_state(memcg, WORKINGSET_ACTIVATE_FILE));
  seq_buf_printf(&s, "workingset_nodereclaim %lu\n",
         memcg_page_state(memcg, WORKINGSET_NODERECLAIM));

diff --git a/mm/vmscan.c b/mm/vmscan.c
index 4122a841dfce..74c3adefc933 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -2735,7 +2735,10 @@ static bool shrink_node(pg_data_t *pgdat,
struct scan_control *sc)
  if (!sc->force_deactivate) {
  unsigned long refaults;

- if (inactive_is_low(target_lruvec, LRU_INACTIVE_ANON))
+ refaults = lruvec_page_state(target_lruvec,
+ WORKINGSET_ACTIVATE_ANON);
+ if (refaults != target_lruvec->refaults[0] ||
+ inactive_is_low(target_lruvec, LRU_INACTIVE_ANON))
  sc->may_deactivate |= DEACTIVATE_ANON;
  else
  sc->may_deactivate &= ~DEACTIVATE_ANON;
@@ -2746,8 +2749,8 @@ static bool shrink_node(pg_data_t *pgdat, struct
scan_control *sc)
  * rid of any stale active pages quickly.
  */
  refaults = lruvec_page_state(target_lruvec,
-      WORKINGSET_ACTIVATE);
- if (refaults != target_lruvec->refaults ||
+ WORKINGSET_ACTIVATE_FILE);
+ if (refaults != target_lruvec->refaults[1] ||
      inactive_is_low(target_lruvec, LRU_INACTIVE_FILE))
  sc->may_deactivate |= DEACTIVATE_FILE;
  else
@@ -3026,8 +3029,10 @@ static void snapshot_refaults(struct mem_cgroup
*target_memcg, pg_data_t *pgdat)
  unsigned long refaults;

  target_lruvec = mem_cgroup_lruvec(target_memcg, pgdat);
- refaults = lruvec_page_state(target_lruvec, WORKINGSET_ACTIVATE);
- target_lruvec->refaults = refaults;
+ refaults = lruvec_page_state(target_lruvec, WORKINGSET_ACTIVATE_ANON);
+ target_lruvec->refaults[0] = refaults;
+ refaults = lruvec_page_state(target_lruvec, WORKINGSET_ACTIVATE_FILE);
+ target_lruvec->refaults[1] = refaults;
 }

 /*
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 78d53378db99..3cdf8e9b0ba2 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -1146,8 +1146,10 @@ const char * const vmstat_text[] = {
  "nr_isolated_anon",
  "nr_isolated_file",
  "workingset_nodes",
- "workingset_refault",
- "workingset_activate",
+ "workingset_refault_anon",
+ "workingset_refault_file",
+ "workingset_activate_anon",
+ "workingset_activate_file",
  "workingset_restore",
  "workingset_nodereclaim",
  "nr_anon_pages",
diff --git a/mm/workingset.c b/mm/workingset.c
index 474186b76ced..5fb8f85d1fec 100644
--- a/mm/workingset.c
+++ b/mm/workingset.c
@@ -15,6 +15,7 @@
 #include <linux/dax.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
+#include <linux/mm_inline.h>

 /*
  * Double CLOCK lists
@@ -156,7 +157,7 @@
  *
  * Implementation
  *
- * For each node's file LRU lists, a counter for inactive evictions
+ * For each node's anon/file LRU lists, a counter for inactive evictions
  * and activations is maintained (node->inactive_age).
  *
  * On eviction, a snapshot of this counter (along with some bits to
@@ -213,7 +214,8 @@ static void unpack_shadow(void *shadow, int
*memcgidp, pg_data_t **pgdat,
  *workingsetp = workingset;
 }

-static void advance_inactive_age(struct mem_cgroup *memcg, pg_data_t *pgdat)
+static void advance_inactive_age(struct mem_cgroup *memcg, pg_data_t *pgdat,
+ int is_file)
 {
  /*
  * Reclaiming a cgroup means reclaiming all its children in a
@@ -230,7 +232,7 @@ static void advance_inactive_age(struct mem_cgroup
*memcg, pg_data_t *pgdat)
  struct lruvec *lruvec;

  lruvec = mem_cgroup_lruvec(memcg, pgdat);
- atomic_long_inc(&lruvec->inactive_age);
+ atomic_long_inc(&lruvec->inactive_age[is_file]);
  } while (memcg && (memcg = parent_mem_cgroup(memcg)));
 }

@@ -248,18 +250,19 @@ void *workingset_eviction(struct page *page,
struct mem_cgroup *target_memcg)
  unsigned long eviction;
  struct lruvec *lruvec;
  int memcgid;
+ int is_file = page_is_file_cache(page);

  /* Page is fully exclusive and pins page->mem_cgroup */
  VM_BUG_ON_PAGE(PageLRU(page), page);
  VM_BUG_ON_PAGE(page_count(page), page);
  VM_BUG_ON_PAGE(!PageLocked(page), page);

- advance_inactive_age(page_memcg(page), pgdat);
+ advance_inactive_age(page_memcg(page), pgdat, is_file);

  lruvec = mem_cgroup_lruvec(target_memcg, pgdat);
  /* XXX: target_memcg can be NULL, go through lruvec */
  memcgid = mem_cgroup_id(lruvec_memcg(lruvec));
- eviction = atomic_long_read(&lruvec->inactive_age);
+ eviction = atomic_long_read(&lruvec->inactive_age[is_file]);
  return pack_shadow(memcgid, pgdat, eviction, PageWorkingset(page));
 }

@@ -278,13 +281,16 @@ void workingset_refault(struct page *page, void *shadow)
  struct lruvec *eviction_lruvec;
  unsigned long refault_distance;
  struct pglist_data *pgdat;
- unsigned long active_file;
+ unsigned long active;
  struct mem_cgroup *memcg;
  unsigned long eviction;
  struct lruvec *lruvec;
  unsigned long refault;
  bool workingset;
  int memcgid;
+ int is_file = page_is_file_cache(page);
+ enum lru_list active_lru = page_lru_base_type(page) + LRU_ACTIVE;
+ enum node_stat_item workingset_stat;

  unpack_shadow(shadow, &memcgid, &pgdat, &eviction, &workingset);

@@ -309,8 +315,8 @@ void workingset_refault(struct page *page, void *shadow)
  if (!mem_cgroup_disabled() && !eviction_memcg)
  goto out;
  eviction_lruvec = mem_cgroup_lruvec(eviction_memcg, pgdat);
- refault = atomic_long_read(&eviction_lruvec->inactive_age);
- active_file = lruvec_page_state(eviction_lruvec, NR_ACTIVE_FILE);
+ refault = atomic_long_read(&eviction_lruvec->inactive_age[is_file]);
+ active = lruvec_page_state(eviction_lruvec, active_lru);

  /*
  * Calculate the refault distance
@@ -341,19 +347,21 @@ void workingset_refault(struct page *page, void *shadow)
  memcg = page_memcg(page);
  lruvec = mem_cgroup_lruvec(memcg, pgdat);

- inc_lruvec_state(lruvec, WORKINGSET_REFAULT);
+ workingset_stat = WORKINGSET_REFAULT_BASE + is_file;
+ inc_lruvec_state(lruvec, workingset_stat);

  /*
  * Compare the distance to the existing workingset size. We
  * don't act on pages that couldn't stay resident even if all
  * the memory was available to the page cache.
  */
- if (refault_distance > active_file)
+ if (refault_distance > active)
  goto out;

  SetPageActive(page);
- advance_inactive_age(memcg, pgdat);
- inc_lruvec_state(lruvec, WORKINGSET_ACTIVATE);
+ advance_inactive_age(memcg, pgdat, is_file);
+ workingset_stat = WORKINGSET_ACTIVATE_BASE + is_file;
+ inc_lruvec_state(lruvec, workingset_stat);

  /* Page was active prior to eviction */
  if (workingset) {
@@ -371,6 +379,7 @@ void workingset_refault(struct page *page, void *shadow)
 void workingset_activation(struct page *page)
 {
  struct mem_cgroup *memcg;
+ int is_file = page_is_file_cache(page);

  rcu_read_lock();
  /*
@@ -383,7 +392,7 @@ void workingset_activation(struct page *page)
  memcg = page_memcg_rcu(page);
  if (!mem_cgroup_disabled() && !memcg)
  goto out;
- advance_inactive_age(memcg, page_pgdat(page));
+ advance_inactive_age(memcg, page_pgdat(page), is_file);
 out:
  rcu_read_unlock();
 }
-- 
2.17.1

  reply	other threads:[~2020-02-14  4:08 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-11  6:19 [PATCH 0/9] workingset protection/detection on the anonymous LRU list js1304
2020-02-11  6:19 ` [PATCH 1/9] mm/vmscan: make active/inactive ratio as 1:1 for anon lru js1304
2020-02-27  2:29   ` [mm/vmscan] dcf33bfdfb: vm-scalability.median 402.4% improvement kernel test robot
2020-02-27  2:29     ` kernel test robot
2020-02-11  6:19 ` [PATCH 2/9] mm/vmscan: protect the workingset on anonymous LRU js1304
2020-02-11  6:19 ` [PATCH 3/9] mm/workingset: extend the workingset detection for anon LRU js1304
2020-02-14  4:07   ` Joonsoo Kim [this message]
2020-02-14  4:07     ` Joonsoo Kim
2020-02-28  7:42   ` [mm/workingset] 323c95f095: fio.read_bw_MBps 19.5% improvement kernel test robot
2020-02-28  7:42     ` kernel test robot
2020-02-28 10:03     ` Joonsoo Kim
2020-02-28 10:03       ` Joonsoo Kim
2020-02-28 10:03       ` Joonsoo Kim
2020-02-11  6:19 ` [PATCH 4/9] mm/swapcache: support to handle the value in swapcache js1304
2020-02-11  6:19 ` [PATCH 5/9] mm/workingset: use the node counter if memcg is the root memcg js1304
2020-02-11  6:19 ` [PATCH 6/9] mm/workingset: handle the page without memcg js1304
2020-02-11  6:19 ` [PATCH 7/9] mm/swap: implement workingset detection for anonymous LRU js1304
2020-02-11  6:19 ` [PATCH 8/9] mm/vmscan: restore active/inactive ratio " js1304
2020-02-11  6:19 ` [PATCH 9/9] mm/swap: count a new anonymous page as a reclaim_state's rotate js1304
2020-02-12  3:35 ` Hillf Danton
2020-02-12 11:00   ` Joonsoo Kim
2020-02-12 11:00     ` Joonsoo Kim
2020-02-14  4:12 ` [PATCH 0/9] workingset protection/detection on the anonymous LRU list Joonsoo Kim
2020-02-14  4:12   ` Joonsoo Kim

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAAmzW4NGwvTiE_unACAcSZUH9V3tO0qR=ZPxi=q9s=zDi53DeQ@mail.gmail.com' \
    --to=js1304@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=hannes@cmpxchg.org \
    --cc=hughd@google.com \
    --cc=iamjoonsoo.kim@lge.com \
    --cc=kernel-team@lge.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mgorman@techsingularity.net \
    --cc=mhocko@kernel.org \
    --cc=minchan@kernel.org \
    --cc=vbabka@suse.cz \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.