You need to sign in or sign up before continuing.
提交 05a6fc26 编写于 作者: F Fang Lijun 提交者: Yang Yingliang

arm64/ascend: mm: Add MAP_CHECKNODE flag to check node hugetlb

ascend inclusion
category: bugfix
bugzilla: NA
CVE: NA

-------------------------------------------------

Dvpp use flags MAP_CHECKNODE to enable check node hugetlb.
The global variable numanode will cause the mmap not be
reenterable, so use the flags BITS[26:31] directly.

Fixes: cbdbfc7514ab ("mm: Check numa node hugepages enough when mmap hugetlb")
Signed-off-by: NFang Lijun <fanglijun3@huawei.com>
Reviewed-by: NDing Tianhong <dingtianhong@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
Signed-off-by: NCheng Jian <cj.chengjian@huawei.com>
上级 3aa30a87
...@@ -211,7 +211,7 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -211,7 +211,7 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
inode_lock(inode); inode_lock(inode);
file_accessed(file); file_accessed(file);
if (is_set_cdmmask()) { if (is_set_cdmmask() && (vma->vm_flags & VM_CHECKNODE)) {
ret = hugetlb_checknode(vma, len >> huge_page_shift(h)); ret = hugetlb_checknode(vma, len >> huge_page_shift(h));
if (ret < 0) if (ret < 0)
goto out; goto out;
......
...@@ -234,6 +234,8 @@ extern unsigned int kobjsize(const void *objp); ...@@ -234,6 +234,8 @@ extern unsigned int kobjsize(const void *objp);
#define VM_CDM 0x100000000 /* Contains coherent device memory */ #define VM_CDM 0x100000000 /* Contains coherent device memory */
#endif #endif
#define VM_CHECKNODE 0x200000000
#ifdef CONFIG_ARCH_USES_HIGH_VMA_FLAGS #ifdef CONFIG_ARCH_USES_HIGH_VMA_FLAGS
#define VM_HIGH_ARCH_BIT_0 32 /* bit only usable on 64-bit architectures */ #define VM_HIGH_ARCH_BIT_0 32 /* bit only usable on 64-bit architectures */
#define VM_HIGH_ARCH_BIT_1 33 /* bit only usable on 64-bit architectures */ #define VM_HIGH_ARCH_BIT_1 33 /* bit only usable on 64-bit architectures */
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <asm-generic/mman-common.h> #include <asm-generic/mman-common.h>
#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ #define MAP_GROWSDOWN 0x0100 /* stack-like segment */
#define MAP_CHECKNODE 0x0400 /* hugetlb numa node check */
#define MAP_DENYWRITE 0x0800 /* ETXTBSY */ #define MAP_DENYWRITE 0x0800 /* ETXTBSY */
#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
#define MAP_LOCKED 0x2000 /* pages are locked */ #define MAP_LOCKED 0x2000 /* pages are locked */
......
...@@ -970,7 +970,7 @@ static struct page *dequeue_huge_page_vma(struct hstate *h, ...@@ -970,7 +970,7 @@ static struct page *dequeue_huge_page_vma(struct hstate *h,
if (page && !avoid_reserve && vma_has_reserves(vma, chg)) { if (page && !avoid_reserve && vma_has_reserves(vma, chg)) {
SetPagePrivate(page); SetPagePrivate(page);
h->resv_huge_pages--; h->resv_huge_pages--;
if (is_set_cdmmask()) if (is_set_cdmmask() && (vma->vm_flags & VM_CHECKNODE))
h->resv_huge_pages_node[vma->vm_flags >> CHECKNODE_BITS]--; h->resv_huge_pages_node[vma->vm_flags >> CHECKNODE_BITS]--;
} }
......
...@@ -69,7 +69,6 @@ const int mmap_rnd_compat_bits_max = CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX; ...@@ -69,7 +69,6 @@ const int mmap_rnd_compat_bits_max = CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX;
int mmap_rnd_compat_bits __read_mostly = CONFIG_ARCH_MMAP_RND_COMPAT_BITS; int mmap_rnd_compat_bits __read_mostly = CONFIG_ARCH_MMAP_RND_COMPAT_BITS;
#endif #endif
static unsigned long numanode;
static bool ignore_rlimit_data; static bool ignore_rlimit_data;
core_param(ignore_rlimit_data, ignore_rlimit_data, bool, 0644); core_param(ignore_rlimit_data, ignore_rlimit_data, bool, 0644);
...@@ -1565,8 +1564,9 @@ unsigned long do_mmap(struct file *file, unsigned long addr, ...@@ -1565,8 +1564,9 @@ unsigned long do_mmap(struct file *file, unsigned long addr,
/* set numa node id into vm_flags, /* set numa node id into vm_flags,
* hugetlbfs file mmap will use it to check node * hugetlbfs file mmap will use it to check node
*/ */
if (is_set_cdmmask()) if (is_set_cdmmask() && (flags & MAP_CHECKNODE))
vm_flags |= ((numanode << CHECKNODE_BITS) & CHECKNODE_MASK); vm_flags |= VM_CHECKNODE | ((((flags >> MAP_HUGE_SHIFT) & MAP_HUGE_MASK)
<< CHECKNODE_BITS) & CHECKNODE_MASK);
addr = mmap_region(file, addr, len, vm_flags, pgoff, uf); addr = mmap_region(file, addr, len, vm_flags, pgoff, uf);
if (!IS_ERR_VALUE(addr) && if (!IS_ERR_VALUE(addr) &&
...@@ -1583,12 +1583,6 @@ unsigned long ksys_mmap_pgoff(unsigned long addr, unsigned long len, ...@@ -1583,12 +1583,6 @@ unsigned long ksys_mmap_pgoff(unsigned long addr, unsigned long len,
struct file *file = NULL; struct file *file = NULL;
unsigned long retval; unsigned long retval;
/* get mmap numa node id */
if (is_set_cdmmask()) {
numanode = (flags >> MAP_HUGE_SHIFT) & MAP_HUGE_MASK;
flags &= ~(MAP_HUGE_MASK << MAP_HUGE_SHIFT);
}
if (!(flags & MAP_ANONYMOUS)) { if (!(flags & MAP_ANONYMOUS)) {
audit_mmap_fd(fd, flags); audit_mmap_fd(fd, flags);
file = fget(fd); file = fget(fd);
...@@ -1602,12 +1596,23 @@ unsigned long ksys_mmap_pgoff(unsigned long addr, unsigned long len, ...@@ -1602,12 +1596,23 @@ unsigned long ksys_mmap_pgoff(unsigned long addr, unsigned long len,
} else if (flags & MAP_HUGETLB) { } else if (flags & MAP_HUGETLB) {
struct user_struct *user = NULL; struct user_struct *user = NULL;
struct hstate *hs; struct hstate *hs;
int page_size_log;
hs = hstate_sizelog((flags >> MAP_HUGE_SHIFT) & MAP_HUGE_MASK); /*
* If config cdm node, flags bits [26:31] used for
* mmap hugetlb check node
*/
if (is_set_cdmmask())
page_size_log = 0;
else
page_size_log = (flags >> MAP_HUGE_SHIFT) & MAP_HUGE_MASK;
hs = hstate_sizelog(page_size_log);
if (!hs) if (!hs)
return -EINVAL; return -EINVAL;
len = ALIGN(len, huge_page_size(hs)); len = ALIGN(len, huge_page_size(hs));
/* /*
* VM_NORESERVE is used because the reservations will be * VM_NORESERVE is used because the reservations will be
* taken when vm_ops->mmap() is called * taken when vm_ops->mmap() is called
...@@ -1616,8 +1621,7 @@ unsigned long ksys_mmap_pgoff(unsigned long addr, unsigned long len, ...@@ -1616,8 +1621,7 @@ unsigned long ksys_mmap_pgoff(unsigned long addr, unsigned long len,
*/ */
file = hugetlb_file_setup(HUGETLB_ANON_FILE, len, file = hugetlb_file_setup(HUGETLB_ANON_FILE, len,
VM_NORESERVE, VM_NORESERVE,
&user, HUGETLB_ANONHUGE_INODE, &user, HUGETLB_ANONHUGE_INODE, page_size_log);
(flags >> MAP_HUGE_SHIFT) & MAP_HUGE_MASK);
if (IS_ERR(file)) if (IS_ERR(file))
return PTR_ERR(file); return PTR_ERR(file);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册