From: Prakash Sangappa <prakash.sangappa@oracle.com>
To: linux-kernel@vger.kernel.org, linux-mm@kvack.org
Cc: dave.hansen@intel.com, mhocko@suse.com, nao.horiguchi@gmail.com,
akpm@linux-foundation.org, kirill.shutemov@linux.intel.com,
khandual@linux.vnet.ibm.com, steven.sistare@oracle.com,
prakash.sangappa@oracle.com
Subject: [PATCH V2 3/6] Provide process address range to numa node id mapping
Date: Wed, 12 Sep 2018 13:24:01 -0700 [thread overview]
Message-ID: <1536783844-4145-4-git-send-email-prakash.sangappa@oracle.com> (raw)
In-Reply-To: <1536783844-4145-1-git-send-email-prakash.sangappa@oracle.com>
This patch provides process address range to numa node information
thru /proc/<pid>/numa_vamaps file. For address ranges not having
any pages mapped, a '-' is printed instead of the numa node id.
Following is the sample of the file format
00400000-00410000 N1
00410000-0047f000 N0
0047f000-00480000 N2
00480000-00481000 -
00481000-004a0000 N0
004a0000-004a2000 -
004a2000-004aa000 N2
004aa000-004ad000 N0
004ad000-004ae000 -
..
Signed-off-by: Prakash Sangappa <prakash.sangappa@oracle.com>
Reviewed-by: Steve Sistare <steven.sistare@oracle.com>
---
fs/proc/task_mmu.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 158 insertions(+)
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 02b553c..1371e379 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -1845,6 +1845,162 @@ static int show_numa_map(struct seq_file *m, void *v)
return 0;
}
+static int gather_hole_info_vamap(unsigned long start, unsigned long end,
+ struct mm_walk *walk)
+{
+ struct numa_maps *md = walk->private;
+ struct vm_area_struct *vma = walk->vma;
+
+ /*
+ * If in a nid, end walk at hole start.
+ * If no nid and vma changes, end walk at next vma start.
+ */
+ if (md->nid >= 0 || vma != find_vma(walk->mm, start)) {
+ md->nextaddr = start;
+ return 1;
+ }
+
+ if (md->nid == NUMA_VAMAPS_NID_NONE)
+ md->nid = NUMA_VAMAPS_NID_NOPAGES;
+
+ return 0;
+}
+
+static int vamap_vprintf(struct numa_vamaps_private *nvm, const char *f, ...)
+{
+ va_list args;
+ int len, space;
+
+ space = NUMA_VAMAPS_BUFSZ - nvm->count;
+ va_start(args, f);
+ len = vsnprintf(nvm->buf + nvm->count, space, f, args);
+ va_end(args);
+ if (len < space) {
+ nvm->count += len;
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * Display va-range to numa node info via /proc
+ */
+static ssize_t numa_vamaps_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct numa_vamaps_private *nvm = file->private_data;
+ struct vm_area_struct *vma, *tailvma;
+ struct numa_maps *md = &nvm->md;
+ struct mm_struct *mm = nvm->mm;
+ u64 vm_start = nvm->vm_start;
+ size_t ucount;
+ struct mm_walk walk = {
+ .hugetlb_entry = gather_hugetlb_stats,
+ .pmd_entry = gather_pte_stats,
+ .pte_hole = gather_hole_info_vamap,
+ .private = md,
+ .mm = mm,
+ };
+ int ret = 0, copied = 0, done = 0;
+
+ if (!mm || !mmget_not_zero(mm))
+ return 0;
+
+ if (count <= 0)
+ goto out_mm;
+
+ /* First copy leftover contents in buffer */
+ if (nvm->from)
+ goto docopy;
+
+repeat:
+ down_read(&mm->mmap_sem);
+ vma = find_vma(mm, vm_start);
+ if (!vma) {
+ done = 1;
+ goto out;
+ }
+
+ if (vma->vm_start > vm_start)
+ vm_start = vma->vm_start;
+
+ while (nvm->count < count) {
+ u64 vm_end;
+
+ /* Ensure we start with an empty numa_maps statistics */
+ memset(md, 0, sizeof(*md));
+ md->nid = NUMA_VAMAPS_NID_NONE; /* invalid nodeid at start */
+ md->nextaddr = 0;
+ md->isvamaps = 1;
+
+ if (walk_page_range(vm_start, vma->vm_end, &walk) < 0)
+ break;
+
+ /* nextaddr ends the range. if 0, reached the vma end */
+ vm_end = (md->nextaddr ? md->nextaddr : vma->vm_end);
+
+ /* break if buffer full */
+ if (md->nid >= 0 && md->node[md->nid]) {
+ if (vamap_vprintf(nvm, "%08lx-%08lx N%ld\n", vm_start,
+ vm_end, md->nid))
+ break;
+ } else if (vamap_vprintf(nvm, "%08lx-%08lx - \n", vm_start,
+ vm_end)) {
+ break;
+ }
+
+ /* advance to next VA */
+ vm_start = vm_end;
+ if (vm_end == vma->vm_end) {
+ vma = vma->vm_next;
+ if (!vma) {
+ done = 1;
+ break;
+ }
+ vm_start = vma->vm_start;
+ }
+ }
+out:
+ /* last, add gate vma details */
+ if (!vma && (tailvma = get_gate_vma(mm)) != NULL &&
+ vm_start < tailvma->vm_end) {
+ done = 0;
+ if (!vamap_vprintf(nvm, "%08lx-%08lx - \n",
+ tailvma->vm_start, tailvma->vm_end)) {
+ done = 1;
+ vm_start = tailvma->vm_end;
+ }
+ }
+
+ up_read(&mm->mmap_sem);
+docopy:
+ ucount = min(count, nvm->count);
+ if (ucount && copy_to_user(buf, nvm->buf + nvm->from, ucount)) {
+ ret = -EFAULT;
+ goto out_mm;;
+ }
+ copied += ucount;
+ count -= ucount;
+ nvm->count -= ucount;
+ buf += ucount;
+ if (!done && count) {
+ nvm->from = 0;
+ goto repeat;
+ }
+ /* somthing left in the buffer */
+ if (nvm->count)
+ nvm->from += ucount;
+ else
+ nvm->from = 0;
+
+ nvm->vm_start = vm_start;
+ ret = copied;
+ *ppos += copied;
+out_mm:
+ mmput(mm);
+ return ret;
+}
+
static const struct seq_operations proc_pid_numa_maps_op = {
.start = m_start,
.next = m_next,
@@ -1895,6 +2051,8 @@ const struct file_operations proc_pid_numa_maps_operations = {
const struct file_operations proc_numa_vamaps_operations = {
.open = numa_vamaps_open,
+ .read = numa_vamaps_read,
+ .llseek = noop_llseek,
.release = numa_vamaps_release,
};
#endif /* CONFIG_NUMA */
--
2.7.4
next prev parent reply other threads:[~2018-09-12 20:25 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-09-12 20:23 [PATCH V2 0/6] VA to numa node information Prakash Sangappa
2018-09-12 20:23 ` [PATCH V2 1/6] Add check to match numa node id when gathering pte stats Prakash Sangappa
2018-09-12 20:24 ` [PATCH V2 2/6] Add /proc/<pid>/numa_vamaps file for numa node information Prakash Sangappa
2018-09-12 20:24 ` Prakash Sangappa [this message]
2018-09-12 20:24 ` [PATCH V2 4/6] Add support to lseek /proc/<pid>/numa_vamaps file Prakash Sangappa
2018-09-12 20:24 ` [PATCH V2 5/6] File /proc/<pid>/numa_vamaps access needs PTRACE_MODE_READ_REALCREDS check Prakash Sangappa
2018-09-12 20:24 ` [PATCH V2 6/6] /proc/pid/numa_vamaps: document in Documentation/filesystems/proc.txt Prakash Sangappa
2018-09-13 8:40 ` [PATCH V2 0/6] VA to numa node information Michal Hocko
2018-09-13 22:32 ` prakash.sangappa
2018-09-14 0:10 ` Andrew Morton
2018-09-14 0:25 ` Dave Hansen
2018-09-15 1:31 ` Prakash Sangappa
2018-09-14 5:56 ` Michal Hocko
2018-09-14 16:01 ` Steven Sistare
2018-09-14 18:04 ` Prakash Sangappa
2018-09-14 19:01 ` Dave Hansen
2018-09-24 17:14 ` Michal Hocko
2018-11-10 4:48 ` Prakash Sangappa
2018-11-26 19:20 ` Steven Sistare
2018-12-18 23:46 ` prakash.sangappa
2018-12-19 20:52 ` Michal Hocko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1536783844-4145-4-git-send-email-prakash.sangappa@oracle.com \
--to=prakash.sangappa@oracle.com \
--cc=akpm@linux-foundation.org \
--cc=dave.hansen@intel.com \
--cc=khandual@linux.vnet.ibm.com \
--cc=kirill.shutemov@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mhocko@suse.com \
--cc=nao.horiguchi@gmail.com \
--cc=steven.sistare@oracle.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).