From 9f1e6d707cc4df1a0a6ad5d4496cd2dcc6db6000 Mon Sep 17 00:00:00 2001 From: Ken Sato Date: Mon, 30 Nov 2020 14:23:51 +0900 Subject: [PATCH] get_mempolicy: Support (MPOL_F_NODE | MPOL_F_ADDR) specified If flags specifies both MPOL_F_NODE and MPOL_F_ADDR, get_mempolicy() will return the node ID of the node on which the address addr is allocated into the location pointed to by mode. Change-Id: Id485e3f4838e3679d877a95e53b21e3421cac88a --- kernel/mem.c | 41 +++++++++++++++++++++++++++++++++++++++++ kernel/syscall.c | 14 ++++++++++++++ lib/include/memory.h | 2 ++ 3 files changed, 57 insertions(+) diff --git a/kernel/mem.c b/kernel/mem.c index 62562cf4..fdd29db6 100644 --- a/kernel/mem.c +++ b/kernel/mem.c @@ -2931,3 +2931,44 @@ retry: return ptep; } + +int phys_to_nid(unsigned long p) +{ + int i, numa_id = -1, _numa_id; + unsigned long _start, _end; + + for (i = 0; i < ihk_mc_get_nr_memory_chunks(); i++) { + ihk_mc_get_memory_chunk(i, &_start, &_end, &_numa_id); + + if (p >= _start && p < _end) { + numa_id = _numa_id; + goto out; + } + } + +out: + return numa_id; +} + +int lookup_node(struct process_vm *vm, void *addr) +{ + int node, err, reason = PF_POPULATE | PF_USER; + pte_t *ptep; + + err = page_fault_process_vm(vm, (void *)addr, reason); + if (err) { + node = err; + goto out; + } + + ptep = ihk_mc_pt_lookup_pte(vm->address_space->page_table, + (void *)addr, 0, NULL, NULL, NULL); + if (!ptep || !pte_is_present(ptep)) { + node = -ENOENT; + goto out; + } + + node = phys_to_nid(pte_get_phys(ptep)); +out: + return node; +} diff --git a/kernel/syscall.c b/kernel/syscall.c index 817bfb00..5b708e61 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -10153,6 +10153,20 @@ SYSCALL_DECLARE(get_mempolicy) } } + /* case of MPOL_F_NODE and MPOL_F_ADDR are specified */ + if (flags & MPOL_F_NODE && flags & MPOL_F_ADDR) { + /* return the node ID which addr is allocated by mode */ + int nid; + + nid = lookup_node(vm, (void *)addr); + error = copy_to_user(mode, &nid, sizeof(int)); + if (error) { + error = -EFAULT; + goto out; + } + goto out; + } + /* Special case of MPOL_F_MEMS_ALLOWED */ if (flags == MPOL_F_MEMS_ALLOWED) { if (nodemask) { diff --git a/lib/include/memory.h b/lib/include/memory.h index 141111cb..e2b30c7b 100644 --- a/lib/include/memory.h +++ b/lib/include/memory.h @@ -20,6 +20,8 @@ struct process_vm; unsigned long virt_to_phys(void *v); void *phys_to_virt(unsigned long p); +int phys_to_nid(unsigned long p); +int lookup_node(struct process_vm *vm, void *addr); int copy_from_user(void *dst, const void *src, size_t siz); int strlen_user(const char *s); int strcpy_from_user(char *dst, const char *src);