From: Liu Shixin <liushixin2@huawei.com> hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IAFWQH -------------------------------- Next patch will support to allocate page from a dpool for zram and zspool if they are bounded with a memcg, and the memcg is bounded with the dpool. As a preparation, support to allocate page by specifying memcg. Signed-off-by: Liu Shixin <liushixin2@huawei.com> --- include/linux/dynamic_pool.h | 13 ++++++++----- mm/dynamic_pool.c | 22 +++++++++++++++------- mm/page_alloc.c | 4 ++-- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/include/linux/dynamic_pool.h b/include/linux/dynamic_pool.h index 9f53ad2d8064..0d64c5a02bd4 100644 --- a/include/linux/dynamic_pool.h +++ b/include/linux/dynamic_pool.h @@ -97,14 +97,15 @@ static inline bool page_from_or_in_dynamic_pool(struct page *page) } int dynamic_pool_can_attach(struct task_struct *tsk, struct mem_cgroup *memcg); -struct page *dynamic_pool_alloc_page(gfp_t gfp, unsigned int order, - unsigned int alloc_flags); +struct page *dynamic_pool_alloc_page(struct mem_cgroup *memcg, gfp_t gfp, + unsigned int order, unsigned int alloc_flags); void dynamic_pool_free_page(struct page *page); void dynamic_pool_bind_file(struct hugetlbfs_inode_info *p, struct hstate *h); void dynamic_pool_unbind_file(struct hugetlbfs_inode_info *p); int dynamic_pool_hugetlb_acct_memory(struct hstate *h, long delta, struct hugetlbfs_inode_info *p); -bool dynamic_pool_should_alloc(gfp_t gfp_mask, unsigned int order); +bool dynamic_pool_should_alloc(gfp_t gfp_mask, unsigned int order, + struct mem_cgroup *memcg); struct folio *dynamic_pool_alloc_hugepage(struct hugetlbfs_inode_info *p, struct hstate *h, bool reserved); void dynamic_pool_free_hugepage(struct folio *folio, bool restore_reserve); @@ -147,7 +148,8 @@ static inline int dynamic_pool_can_attach(struct task_struct *tsk, return 0; } -static inline struct page *dynamic_pool_alloc_page(gfp_t gfp, unsigned int order, +static inline struct page *dynamic_pool_alloc_page(struct mem_cgroup *memcg, + gfp_t gfp, unsigned int order, unsigned int alloc_flags) { return NULL; @@ -190,7 +192,8 @@ static inline void dynamic_pool_free_hugepage(struct folio *folio, } #endif -static inline bool dynamic_pool_should_alloc(gfp_t gfp_mask, unsigned int order) +static inline bool dynamic_pool_should_alloc(gfp_t gfp_mask, unsigned int order, + struct mem_cgroup *memcg) { return false; } diff --git a/mm/dynamic_pool.c b/mm/dynamic_pool.c index c5a45b1d3484..4dc9e80c2cb7 100644 --- a/mm/dynamic_pool.c +++ b/mm/dynamic_pool.c @@ -702,14 +702,19 @@ int dynamic_pool_can_attach(struct task_struct *tsk, struct mem_cgroup *memcg) return ret; } -bool dynamic_pool_should_alloc(gfp_t gfp_mask, unsigned int order) +bool dynamic_pool_should_alloc(gfp_t gfp_mask, unsigned int order, + struct mem_cgroup *memcg) { gfp_t gfp = gfp_mask & GFP_HIGHUSER_MOVABLE; - if (current->flags & PF_KTHREAD) + if (order != 0) return false; - if (order != 0) + /* Ignore the following restrictions if memcg is specfied */ + if (memcg) + return true; + + if (current->flags & PF_KTHREAD) return false; /* @@ -728,8 +733,8 @@ bool dynamic_pool_should_alloc(gfp_t gfp_mask, unsigned int order) return true; } -struct page *dynamic_pool_alloc_page(gfp_t gfp, unsigned int order, - unsigned int alloc_flags) +struct page *dynamic_pool_alloc_page(struct mem_cgroup *memcg, gfp_t gfp, + unsigned int order, unsigned int alloc_flags) { struct dynamic_pool *dpool; struct pages_pool *pool; @@ -739,10 +744,13 @@ struct page *dynamic_pool_alloc_page(gfp_t gfp, unsigned int order, if (!dpool_enabled) return NULL; - if (!dynamic_pool_should_alloc(gfp, order)) + if (!dynamic_pool_should_alloc(gfp, order, memcg)) return NULL; - dpool = dpool_get_from_task(current); + if (memcg) + dpool = dpool_get_from_memcg(memcg); + else + dpool = dpool_get_from_task(current); if (!dpool) return NULL; diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 6ec10acc9106..fcf29801c490 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -4347,7 +4347,7 @@ static inline bool mem_reliable_fallback_dpool(gfp_t gfp_mask, unsigned int orde if (!(gfp_mask & GFP_RELIABLE)) return false; - return dynamic_pool_should_alloc(gfp_mask & ~GFP_RELIABLE, order); + return dynamic_pool_should_alloc(gfp_mask & ~GFP_RELIABLE, order, NULL); } #else static inline struct zone *mem_reliable_fallback_zone(gfp_t gfp_mask, @@ -5036,7 +5036,7 @@ struct page *__alloc_pages(gfp_t gfp, unsigned int order, int preferred_nid, /* Before alloc from buddy system, alloc from dpool firstly */ if (dpool_enabled) { - page = dynamic_pool_alloc_page(alloc_gfp, order, alloc_flags); + page = dynamic_pool_alloc_page(NULL, alloc_gfp, order, alloc_flags); if (page) goto out; } -- 2.43.0