hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IAFWQH ---------------------------------------- If the page to write comes from memcg and the memcg is bounded with a zspool, use the zspool. Otherwise, use zspool 0. Signed-off-by: Jinjiang Tu <tujinjiang@huawei.com> --- .../multi_pool_zram/multi_pool_zram_drv.c | 29 ++++++++++++++++++- include/linux/memcontrol.h | 2 ++ mm/memcontrol.c | 18 ++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/drivers/block/multi_pool_zram/multi_pool_zram_drv.c b/drivers/block/multi_pool_zram/multi_pool_zram_drv.c index 9890afa6e4ee..c3f29d44a9fc 100644 --- a/drivers/block/multi_pool_zram/multi_pool_zram_drv.c +++ b/drivers/block/multi_pool_zram/multi_pool_zram_drv.c @@ -191,6 +191,33 @@ static void reset_memcg(struct zram *zram) } } +static int get_pool_index_from_page(struct zram *zram, struct page *page) +{ + struct folio *folio = page_folio(page); + struct mem_cgroup *memcg; + int res = DEFAULT_ZPOOL_INDEX; + int i; + + folio_memcg_lock(folio); + memcg = page_memcg(page); + if (!memcg) + goto out; + + for (i = 0; i < NR_ZPOOL; i++) { + if (i == DEFAULT_ZPOOL_INDEX) + continue; + + if (multi_pool_zram_is_target_memcg(memcg, zram->pool_memcg[i])) { + res = i; + break; + } + } + +out: + folio_memcg_unlock(folio); + return res; +} + #if PAGE_SIZE != 4096 static inline bool is_partial_io(struct bio_vec *bvec) { @@ -563,7 +590,7 @@ static int zram_write_page(struct zram *zram, struct page *page, u32 index) } kunmap_atomic(mem); - pool_index = DEFAULT_ZPOOL_INDEX; + pool_index = get_pool_index_from_page(zram, page); pool = zram->mem_pool[pool_index]; compress_again: zstrm = zcomp_stream_get(zram->comp); diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index c0e30821c94b..dcc42b60bc7a 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -1326,6 +1326,8 @@ int mem_cgroup_force_empty(struct mem_cgroup *memcg); struct mem_cgroup *memcg_get_from_path(char *path, size_t buflen); void memcg_charge_zram(struct mem_cgroup *memcg, unsigned int nr_pages); void memcg_uncharge_zram(struct mem_cgroup *memcg, unsigned int nr_pages); +bool multi_pool_zram_is_target_memcg(struct mem_cgroup *memcg, + struct mem_cgroup *target_memcg); #endif #else /* CONFIG_MEMCG */ diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 960028758d92..feb48eccf578 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -2234,6 +2234,7 @@ void folio_memcg_lock(struct folio *folio) memcg->move_lock_task = current; memcg->move_lock_flags = flags; } +EXPORT_SYMBOL(folio_memcg_lock); static void __folio_memcg_unlock(struct mem_cgroup *memcg) { @@ -2261,6 +2262,7 @@ void folio_memcg_unlock(struct folio *folio) { __folio_memcg_unlock(folio_memcg(folio)); } +EXPORT_SYMBOL(folio_memcg_unlock); struct memcg_stock_pcp { local_lock_t stock_lock; @@ -4205,6 +4207,22 @@ static u64 mem_cgroup_zram_usage(struct cgroup_subsys_state *css, return (u64)atomic64_read(&memcg->zram_usage) * PAGE_SIZE; } + +bool multi_pool_zram_is_target_memcg(struct mem_cgroup *memcg, + struct mem_cgroup *target_memcg) +{ + int ret = false; + + rcu_read_lock(); + for (; memcg != root_mem_cgroup; memcg = parent_mem_cgroup(memcg)) + if (memcg == target_memcg) { + ret = true; + break; + } + rcu_read_unlock(); + return ret; +} +EXPORT_SYMBOL(multi_pool_zram_is_target_memcg); #else static inline void memcg_zram_usage_init(struct mem_cgroup *memcg) { -- 2.43.0