From: Liu Shixin liushixin2@huawei.com
hulk inclusion category: feature bugzilla: 46904, https://gitee.com/openeuler/kernel/issues/I6BDME CVE: NA
--------------------------------
Add CONFIG_DYNAMIC_HUGETLB in struct mem_cgroup_extension and struct hugetlbfs_inode_info to isolate the member.
Add CONFIG_DYNAMIC_HUGETLB for pageflag PG_pool to isolate it.
Signed-off-by: Liu Shixin liushixin2@huawei.com Reviewed-by: Kefeng Wang wangkefeng.wang@huawei.com Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com --- fs/hugetlbfs/inode.c | 4 ++++ include/linux/hugetlb.h | 2 ++ include/linux/memcontrol.h | 2 ++ include/linux/page-flags.h | 10 +++++++++- include/trace/events/mmflags.h | 8 +++++++- mm/hugetlb.c | 22 +++++++++++++++++----- 6 files changed, 41 insertions(+), 7 deletions(-)
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 30a29936372c..e411103d2cf4 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -1164,8 +1164,10 @@ static struct inode *hugetlbfs_alloc_inode(struct super_block *sb) * private inode. This simplifies hugetlbfs_destroy_inode. */ mpol_shared_policy_init(&p->policy, NULL); +#ifdef CONFIG_DYNAMIC_HUGETLB /* Initialize hpool here in case of a quick call to destroy */ p->hpool = get_dhugetlb_pool_from_task(current); +#endif
return &p->vfs_inode; } @@ -1180,8 +1182,10 @@ static void hugetlbfs_destroy_inode(struct inode *inode) { hugetlbfs_inc_free_inodes(HUGETLBFS_SB(inode->i_sb)); mpol_free_shared_policy(&HUGETLBFS_I(inode)->policy); +#ifdef CONFIG_DYNAMIC_HUGETLB dhugetlb_pool_put(HUGETLBFS_I(inode)->hpool); HUGETLBFS_I(inode)->hpool = NULL; +#endif call_rcu(&inode->i_rcu, hugetlbfs_i_callback); }
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 3a82ea9283ec..92fd6e2cbaf3 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -289,7 +289,9 @@ struct hugetlbfs_inode_info { struct shared_policy policy; struct inode vfs_inode; unsigned int seals; +#ifdef CONFIG_DYNAMIC_HUGETLB struct dhugetlb_pool *hpool; +#endif };
static inline struct hugetlbfs_inode_info *HUGETLBFS_I(struct inode *inode) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 22f40d5e0e8b..594925ea3076 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -326,7 +326,9 @@ struct mem_cgroup { };
struct mem_cgroup_extension { +#ifdef CONFIG_DYNAMIC_HUGETLB struct dhugetlb_pool *hpool; +#endif #ifdef CONFIG_MEMCG_QOS /* Currently support 0 and -1. * in the future it can expand to other value. diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index fd6cd68e00a2..feca326f0563 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -102,7 +102,9 @@ enum pageflags { PG_idle, #endif PG_percpu_ref, +#ifdef CONFIG_DYNAMIC_HUGETLB PG_pool, +#endif __NR_PAGEFLAGS,
/* Filesystems */ @@ -285,7 +287,13 @@ PAGEFLAG(Active, active, PF_HEAD) __CLEARPAGEFLAG(Active, active, PF_HEAD) __PAGEFLAG(Slab, slab, PF_NO_TAIL) __PAGEFLAG(SlobFree, slob_free, PF_NO_TAIL) PAGEFLAG(Checked, checked, PF_NO_COMPOUND) /* Used by some filesystems */ +#ifdef CONFIG_DYNAMIC_HUGETLB PAGEFLAG(Pool, pool, PF_NO_TAIL) +#define __PG_POOL (1UL << PG_pool) +#else +PAGEFLAG_FALSE(Pool) +#define __PG_POOL 0 +#endif
/* Xen */ PAGEFLAG(Pinned, pinned, PF_NO_COMPOUND) @@ -772,7 +780,7 @@ static inline void ClearPageSlabPfmemalloc(struct page *page) 1UL << PG_private | 1UL << PG_private_2 | \ 1UL << PG_writeback | 1UL << PG_reserved | \ 1UL << PG_slab | 1UL << PG_active | \ - 1UL << PG_pool | \ + __PG_POOL | \ 1UL << PG_unevictable | __PG_MLOCKED)
/* diff --git a/include/trace/events/mmflags.h b/include/trace/events/mmflags.h index 4d06b47129f3..45add2ab8790 100644 --- a/include/trace/events/mmflags.h +++ b/include/trace/events/mmflags.h @@ -79,9 +79,14 @@ #define IF_HAVE_PG_IDLE(flag,string) #endif
+#ifdef CONFIG_DYNAMIC_HUGETLB +#define IF_HAVE_PG_POOL(flag,string) ,{1UL << flag, string} +#else +#define IF_HAVE_PG_POOL(flag,string) +#endif + #define __def_pageflag_names \ {1UL << PG_locked, "locked" }, \ - {1UL << PG_pool, "pool" }, \ {1UL << PG_waiters, "waiters" }, \ {1UL << PG_error, "error" }, \ {1UL << PG_referenced, "referenced" }, \ @@ -102,6 +107,7 @@ {1UL << PG_swapbacked, "swapbacked" }, \ {1UL << PG_unevictable, "unevictable" } \ IF_HAVE_PG_MLOCK(PG_mlocked, "mlocked" ) \ +IF_HAVE_PG_POOL(PG_pool, "pool" ) \ IF_HAVE_PG_UNCACHED(PG_uncached, "uncached" ) \ IF_HAVE_PG_HWPOISON(PG_hwpoison, "hwpoison" ) \ IF_HAVE_PG_IDLE(PG_young, "young" ) \ diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 4c8c91acd6d5..8b88ac4620d5 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -601,6 +601,18 @@ static long region_del(struct resv_map *resv, long f, long t) return del; }
+#ifdef CONFIG_DYNAMIC_HUGETLB +static struct dhugetlb_pool *get_hpool_from_inode(struct inode *inode) +{ + return HUGETLBFS_I(inode)->hpool; +} +#else +static struct dhugetlb_pool *get_hpool_from_inode(struct inode *inode) +{ + return NULL; +} +#endif + /* * A rare out of memory error was encountered which prevented removal of * the reserve map region for a page. The huge page itself was free'ed @@ -615,7 +627,7 @@ void hugetlb_fix_reserve_counts(struct inode *inode) struct hugepage_subpool *spool = subpool_inode(inode); long rsv_adjust; bool reserved = false; - struct dhugetlb_pool *hpool = HUGETLBFS_I(inode)->hpool; + struct dhugetlb_pool *hpool = get_hpool_from_inode(inode);
rsv_adjust = hugepage_subpool_get_pages(spool, 1, hpool); if (rsv_adjust > 0) { @@ -2380,7 +2392,7 @@ struct page *alloc_huge_page(struct vm_area_struct *vma, int ret, idx; struct hugetlb_cgroup *h_cg; struct dhugetlb_pool *hpool = - HUGETLBFS_I(file_inode(vma->vm_file))->hpool; + get_hpool_from_inode(file_inode(vma->vm_file));
idx = hstate_index(h); /* @@ -4673,7 +4685,7 @@ static void hugetlb_vm_op_close(struct vm_area_struct *vma) unsigned long reserve, start, end; long gbl_reserve; struct dhugetlb_pool *hpool = - HUGETLBFS_I(file_inode(vma->vm_file))->hpool; + get_hpool_from_inode(file_inode(vma->vm_file));
if (!resv || !is_vma_resv_set(vma, HPAGE_RESV_OWNER)) return; @@ -6073,7 +6085,7 @@ int hugetlb_reserve_pages(struct inode *inode, struct hugepage_subpool *spool = subpool_inode(inode); struct resv_map *resv_map; long gbl_reserve; - struct dhugetlb_pool *hpool = HUGETLBFS_I(inode)->hpool; + struct dhugetlb_pool *hpool = get_hpool_from_inode(inode);
/* This should never happen */ if (from > to) { @@ -6192,7 +6204,7 @@ long hugetlb_unreserve_pages(struct inode *inode, long start, long end, long chg = 0; struct hugepage_subpool *spool = subpool_inode(inode); long gbl_reserve; - struct dhugetlb_pool *hpool = HUGETLBFS_I(inode)->hpool; + struct dhugetlb_pool *hpool = get_hpool_from_inode(inode);
/* * Since this routine can be called in the evict inode path for all