All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gregory Price <gourry.memverge@gmail.com>
To: linux-mm@kvack.org
Cc: linux-doc@vger.kernel.org, linux-fsdevel@vger.kernel.org,
	linux-api@vger.kernel.org, linux-arch@vger.kernel.org,
	linux-kernel@vger.kernel.org, akpm@linux-foundation.org,
	arnd@arndb.de, tglx@linutronix.de, luto@kernel.org,
	mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com,
	x86@kernel.org, hpa@zytor.com, mhocko@kernel.org, tj@kernel.org,
	ying.huang@intel.com, Gregory Price <gregory.price@memverge.com>
Subject: [RFC PATCH 05/11] mm/mempolicy: modify set_mempolicy_home_node to take a task argument
Date: Wed, 22 Nov 2023 16:11:54 -0500	[thread overview]
Message-ID: <20231122211200.31620-6-gregory.price@memverge.com> (raw)
In-Reply-To: <20231122211200.31620-1-gregory.price@memverge.com>

To make mempolicy fetchable by external tasks, we must first change
the callstack to take a task as an argument.

Modify the following functions to require a task argument:
    set_mempolicy_home_node

First we refactor set_mempolicy_home_node to __set_mempolicy_home_node
which accepts a task argument, and change the syscall definition to pass
in (current).

The only functional change in this patch is related to the way task->mm
is acquired. Originally, set_mempolicy_home_node would acquire task->mm
directly via (current->mm).  This is unsafe to do in a non-current
context.  However, utilizing get_task_mm would break the original
functionality of do_get_mempolicy due to the following check
in get_task_mm:

  if (mm) {
    if (task->flags & PF_KTHREAD)
      mm = NULL;
    else
      mmget(mm);
  }

To retain the original behavior, if (task == current) we access
the task->mm directly, but if (task != current) we will utilize
get_task_mm to safely access the mm.  We always take a reference
to the mm to keep the cleanup semantics simple.

Signed-off-by: Gregory Price <gregory.price@memverge.com>
---
 mm/mempolicy.c | 62 +++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 49 insertions(+), 13 deletions(-)

diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 4519f39b1a07..540163f5d349 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -1521,39 +1521,67 @@ static long kernel_mbind(unsigned long start, unsigned long len,
 	return do_mbind(start, len, lmode, mode_flags, &nodes, flags);
 }
 
-SYSCALL_DEFINE4(set_mempolicy_home_node, unsigned long, start, unsigned long, len,
-		unsigned long, home_node, unsigned long, flags)
+static long __set_mempolicy_home_node(struct task_struct *task,
+				      unsigned long start,
+				      unsigned long len,
+				      unsigned long home_node,
+				      unsigned long flags)
 {
-	struct mm_struct *mm = current->mm;
+	struct mm_struct *mm;
 	struct vm_area_struct *vma, *prev;
 	struct mempolicy *new, *old;
 	unsigned long end;
 	int err = -ENOENT;
+
+	/*
+	 * Behavior when task == current allows a task modifying itself
+	 * to bypass the check in get_task_mm and acquire the mm directly
+	 */
+	if (task == current) {
+		mm = task->mm;
+		mmget(mm);
+	} else
+		mm = get_task_mm(task);
+
+	if (!mm)
+		return -ENODEV;
+
 	VMA_ITERATOR(vmi, mm, start);
 
 	start = untagged_addr(start);
-	if (start & ~PAGE_MASK)
-		return -EINVAL;
+	if (start & ~PAGE_MASK) {
+		err = -EINVAL;
+		goto mm_out;
+	}
 	/*
 	 * flags is used for future extension if any.
 	 */
-	if (flags != 0)
-		return -EINVAL;
+	if (flags != 0) {
+		err = -EINVAL;
+		goto mm_out;
+	}
 
 	/*
 	 * Check home_node is online to avoid accessing uninitialized
 	 * NODE_DATA.
 	 */
-	if (home_node >= MAX_NUMNODES || !node_online(home_node))
-		return -EINVAL;
+	if (home_node >= MAX_NUMNODES || !node_online(home_node)) {
+		err = -EINVAL;
+		goto mm_out;
+	}
 
 	len = PAGE_ALIGN(len);
 	end = start + len;
 
-	if (end < start)
-		return -EINVAL;
-	if (end == start)
-		return 0;
+	if (end < start) {
+		err = -EINVAL;
+		goto mm_out;
+	}
+	if (end == start) {
+		err = 0;
+		goto mm_out;
+	}
+
 	mmap_write_lock(mm);
 	prev = vma_prev(&vmi);
 	for_each_vma_range(vmi, vma, end) {
@@ -1585,9 +1613,17 @@ SYSCALL_DEFINE4(set_mempolicy_home_node, unsigned long, start, unsigned long, le
 			break;
 	}
 	mmap_write_unlock(mm);
+mm_out:
+	mmput(mm);
 	return err;
 }
 
+SYSCALL_DEFINE4(set_mempolicy_home_node, unsigned long, start, unsigned long, len,
+		unsigned long, home_node, unsigned long, flags)
+{
+	return __set_mempolicy_home_node(current, start, len, home_node, flags);
+}
+
 SYSCALL_DEFINE6(mbind, unsigned long, start, unsigned long, len,
 		unsigned long, mode, const unsigned long __user *, nmask,
 		unsigned long, maxnode, unsigned int, flags)
-- 
2.39.1


  parent reply	other threads:[~2023-11-22 21:12 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-22 21:11 [RFC PATCH 00/11] mm/mempolicy: Make task->mempolicy externally modifiable via syscall and procfs Gregory Price
2023-11-22 21:11 ` [RFC PATCH 01/11] mm/mempolicy: refactor do_set_mempolicy for code re-use Gregory Price
2023-11-22 21:11 ` [RFC PATCH 02/11] mm/mempolicy: swap cond reference counting logic in do_get_mempolicy Gregory Price
2023-11-28 14:07   ` Michal Hocko
     [not found]     ` <ZWX0ytAwmOdooHdZ@memverge.com>
2023-11-28 14:28       ` Michal Hocko
2023-11-22 21:11 ` [RFC PATCH 03/11] mm/mempolicy: refactor set_mempolicy stack to take a task argument Gregory Price
2023-11-22 21:11 ` [RFC PATCH 04/11] mm/mempolicy: modify get_mempolicy call " Gregory Price
2023-11-28 14:07   ` Michal Hocko
     [not found]     ` <ZWX1U1gCTXC+lFXn@memverge.com>
2023-11-28 14:49       ` Michal Hocko
2023-11-22 21:11 ` Gregory Price [this message]
2023-11-28 14:07   ` [RFC PATCH 05/11] mm/mempolicy: modify set_mempolicy_home_node " Michal Hocko
2023-11-28 14:14     ` Gregory Price
2023-11-22 21:11 ` [RFC PATCH 06/11] mm/mempolicy: modify do_mbind to operate on task argument instead of current Gregory Price
2023-11-28 14:11   ` Michal Hocko
2023-11-28 14:51     ` Gregory Price
2023-11-28 18:08     ` Gregory Price
2023-11-22 21:11 ` [RFC PATCH 07/11] mm/mempolicy: add task mempolicy syscall variants Gregory Price
2023-11-24  7:56   ` kernel test robot
2023-11-24  7:56   ` kernel test robot
2023-11-24  7:57   ` kernel test robot
2023-11-22 21:11 ` [RFC PATCH 08/11] mm/mempolicy: export replace_mempolicy for use by procfs Gregory Price
2023-11-22 21:11 ` [RFC PATCH 09/11] mm/mempolicy: build mpol_parse_str unconditionally Gregory Price
2023-11-22 21:11 ` [RFC PATCH 10/11] mm/mempolicy: mpol_parse_str should ignore trailing characters in nodelist Gregory Price
2023-11-22 21:12 ` [RFC PATCH 11/11] fs/proc: Add mempolicy attribute to allow read/write of task mempolicy Gregory Price
2023-11-22 21:33 ` [RFC PATCH 00/11] mm/mempolicy: Make task->mempolicy externally modifiable via syscall and procfs Andrew Morton
2023-11-22 21:35   ` Andrew Morton
2023-11-22 22:24   ` Gregory Price
2023-11-27 15:29     ` Michal Hocko
2023-11-27 16:14       ` Gregory Price
2023-11-28  9:45         ` Michal Hocko
2023-11-28 13:15           ` Gregory Price

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=20231122211200.31620-6-gregory.price@memverge.com \
    --to=gourry.memverge@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=arnd@arndb.de \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=gregory.price@memverge.com \
    --cc=hpa@zytor.com \
    --cc=linux-api@vger.kernel.org \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=luto@kernel.org \
    --cc=mhocko@kernel.org \
    --cc=mingo@redhat.com \
    --cc=tglx@linutronix.de \
    --cc=tj@kernel.org \
    --cc=x86@kernel.org \
    --cc=ying.huang@intel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.