diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 7a8994585b89108501e8994cabc703129d809bbb..a878f009347cd9707e89ca0d3bd9aba280a1d6d9 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -211,7 +211,7 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) inode_lock(inode); 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)); if (ret < 0) goto out; diff --git a/include/linux/mm.h b/include/linux/mm.h index 679860bb22380581ae02c1c09a86578cb52c5dee..7ea591ec38c4371f5144a8c98522045a2b5c1c20 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -234,6 +234,8 @@ extern unsigned int kobjsize(const void *objp); #define VM_CDM 0x100000000 /* Contains coherent device memory */ #endif +#define VM_CHECKNODE 0x200000000 + #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_1 33 /* bit only usable on 64-bit architectures */ diff --git a/include/uapi/asm-generic/mman.h b/include/uapi/asm-generic/mman.h index 1915bcc107ebb70d4ac3f63985ab8f129b55e999..233a5e82407c1f7ed5e1ab7cb0b84686ce3366ca 100644 --- a/include/uapi/asm-generic/mman.h +++ b/include/uapi/asm-generic/mman.h @@ -5,6 +5,7 @@ #include #define MAP_GROWSDOWN 0x0100 /* stack-like segment */ +#define MAP_CHECKNODE 0x0400 /* hugetlb numa node check */ #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ #define MAP_LOCKED 0x2000 /* pages are locked */ diff --git a/mm/hugetlb.c b/mm/hugetlb.c index efb68abe9f35f5e5b3fcf9d1d8f10ac183d7759e..327d24f0cf0dc83314cc4197b996c6d0d26ef3a8 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -970,7 +970,7 @@ static struct page *dequeue_huge_page_vma(struct hstate *h, if (page && !avoid_reserve && vma_has_reserves(vma, chg)) { SetPagePrivate(page); 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]--; } diff --git a/mm/mmap.c b/mm/mmap.c index 00702331afc15a2ae6a36b59705d19f43c3bbcf9..6197c5590ded76f19a1541286a2598e4ff472f9e 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -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; #endif -static unsigned long numanode; static bool ignore_rlimit_data; core_param(ignore_rlimit_data, ignore_rlimit_data, bool, 0644); @@ -1565,8 +1564,9 @@ unsigned long do_mmap(struct file *file, unsigned long addr, /* set numa node id into vm_flags, * hugetlbfs file mmap will use it to check node */ - if (is_set_cdmmask()) - vm_flags |= ((numanode << CHECKNODE_BITS) & CHECKNODE_MASK); + if (is_set_cdmmask() && (flags & MAP_CHECKNODE)) + 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); if (!IS_ERR_VALUE(addr) && @@ -1583,12 +1583,6 @@ unsigned long ksys_mmap_pgoff(unsigned long addr, unsigned long len, struct file *file = NULL; 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)) { audit_mmap_fd(fd, flags); file = fget(fd); @@ -1602,12 +1596,23 @@ unsigned long ksys_mmap_pgoff(unsigned long addr, unsigned long len, } else if (flags & MAP_HUGETLB) { struct user_struct *user = NULL; 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) return -EINVAL; len = ALIGN(len, huge_page_size(hs)); + /* * VM_NORESERVE is used because the reservations will be * taken when vm_ops->mmap() is called @@ -1616,8 +1621,7 @@ unsigned long ksys_mmap_pgoff(unsigned long addr, unsigned long len, */ file = hugetlb_file_setup(HUGETLB_ANON_FILE, len, VM_NORESERVE, - &user, HUGETLB_ANONHUGE_INODE, - (flags >> MAP_HUGE_SHIFT) & MAP_HUGE_MASK); + &user, HUGETLB_ANONHUGE_INODE, page_size_log); if (IS_ERR(file)) return PTR_ERR(file); }