summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Liu <bob.liu@oracle.com>2013-08-06 19:36:17 +0800
committerKyle Yan <kyan@codeaurora.org>2016-05-31 15:27:11 -0700
commit5248c3b4e4e57bd37aaa3a130a6038921becc89a (patch)
treeed1f113eef95df78d036c43e309f5d60e6ce229e
parenta851b0a3c8b41c0eea4bc6bd7587feada670a267 (diff)
mm: add WasActive page flag
Zcache could be ineffective if the compressed memory pool is full with compressed inactive file pages and most of them will be never used again. So we pick up pages from active file list only, those pages would probably be accessed again. Compress them in memory can reduce the latency significantly compared with rereading from disk. When a file page is shrunk from active file list to inactive file list, PageActive flag is also cleared. So adding an extra WasActive page flag for zcache to know whether the file page was shrunk from the active list. Change-Id: Ida1f4db17075d1f6f825ef7ce2b3bae4eb799e3f Signed-off-by: Bob Liu <bob.liu@oracle.com> Patch-mainline: linux-mm @ 2013-08-06 11:36:17 [vinmenon@codeaurora.org: trivial merge conflict fixes, checkpatch fixes, fix the definitions of was_active page flag so that it does not create compile time errors with CONFIG_CLEANCACHE disabled. Also remove the unnecessary use of PG_was_active in PAGE_FLAGS_CHECK_AT_PREP. Since was_active is a requirement for zcache, make the definitions dependent on CONFIG_ZCACHE rather than CONFIG_CLEANCACHE.] Signed-off-by: Vinayak Menon <vinmenon@codeaurora.org>
-rw-r--r--include/linux/page-flags.h8
-rw-r--r--mm/debug.c3
-rw-r--r--mm/vmscan.c12
-rw-r--r--mm/zcache.c13
4 files changed, 35 insertions, 1 deletions
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index bb53c7b86315..4b115168607f 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -108,6 +108,9 @@ enum pageflags {
PG_young,
PG_idle,
#endif
+#ifdef CONFIG_ZCACHE
+ PG_was_active,
+#endif
__NR_PAGEFLAGS,
/* Filesystems */
@@ -224,6 +227,11 @@ PAGEFLAG(SwapBacked, swapbacked) __CLEARPAGEFLAG(SwapBacked, swapbacked)
__SETPAGEFLAG(SwapBacked, swapbacked)
__PAGEFLAG(SlobFree, slob_free)
+#ifdef CONFIG_ZCACHE
+PAGEFLAG(WasActive, was_active)
+#else
+PAGEFLAG_FALSE(WasActive)
+#endif
/*
* Private page markings that may be used by the filesystem that owns the page
diff --git a/mm/debug.c b/mm/debug.c
index 668aa35191ca..5cf26f8c69a3 100644
--- a/mm/debug.c
+++ b/mm/debug.c
@@ -47,6 +47,9 @@ static const struct trace_print_flags pageflag_names[] = {
{1UL << PG_young, "young" },
{1UL << PG_idle, "idle" },
#endif
+#ifdef CONFIG_ZCACHE
+ {1UL << PG_was_active, "was_active" },
+#endif
};
static void dump_flags(unsigned long flags,
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 3f702c2f9d58..9c92f7d1be90 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1575,6 +1575,7 @@ putback_inactive_pages(struct lruvec *lruvec, struct list_head *page_list)
while (!list_empty(page_list)) {
struct page *page = lru_to_page(page_list);
int lru;
+ int file;
VM_BUG_ON_PAGE(PageLRU(page), page);
list_del(&page->lru);
@@ -1591,8 +1592,11 @@ putback_inactive_pages(struct lruvec *lruvec, struct list_head *page_list)
lru = page_lru(page);
add_page_to_lru_list(page, lruvec, lru);
+ file = is_file_lru(lru);
+ if (IS_ENABLED(CONFIG_ZCACHE))
+ if (file)
+ SetPageWasActive(page);
if (is_active_lru(lru)) {
- int file = is_file_lru(lru);
int numpages = hpage_nr_pages(page);
reclaim_stat->recent_rotated[file] += numpages;
}
@@ -1917,6 +1921,12 @@ static void shrink_active_list(unsigned long nr_to_scan,
}
ClearPageActive(page); /* we are de-activating */
+ if (IS_ENABLED(CONFIG_ZCACHE))
+ /*
+ * For zcache to know whether the page is from active
+ * file list
+ */
+ SetPageWasActive(page);
list_add(&page->lru, &l_inactive);
}
diff --git a/mm/zcache.c b/mm/zcache.c
index 28c070b99e06..322b8f836a49 100644
--- a/mm/zcache.c
+++ b/mm/zcache.c
@@ -68,6 +68,7 @@ static u64 zcache_dup_entry;
static u64 zcache_zbud_alloc_fail;
static u64 zcache_evict_zpages;
static u64 zcache_evict_filepages;
+static u64 zcache_inactive_pages_refused;
static u64 zcache_reclaim_fail;
static u64 zcache_pool_shrink;
static u64 zcache_pool_shrink_fail;
@@ -648,6 +649,17 @@ static void zcache_store_page(int pool_id, struct cleancache_filekey key,
struct zcache_pool *zpool = zcache.pools[pool_id];
+ /*
+ * Zcache will be ineffective if the compressed memory pool is full with
+ * compressed inactive file pages and most of them will never be used
+ * again.
+ * So we refuse to compress pages that are not from active file list.
+ */
+ if (!PageWasActive(page)) {
+ zcache_inactive_pages_refused++;
+ return;
+ }
+
if (zcache_is_full()) {
zcache_pool_limit_hit++;
if (zbud_reclaim_page(zpool->pool, 8)) {
@@ -762,6 +774,7 @@ map:
/* update stats */
atomic_dec(&zcache_stored_pages);
zpool->size = zbud_get_pool_size(zpool->pool);
+ SetPageWasActive(page);
return ret;
}