diff options
| -rw-r--r-- | include/linux/page-flags.h | 8 | ||||
| -rw-r--r-- | mm/debug.c | 3 | ||||
| -rw-r--r-- | mm/vmscan.c | 12 | ||||
| -rw-r--r-- | mm/zcache.c | 13 |
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; } |
