From: Kamezawa Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
To: David Rientjes <rientjes@google.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
Andrew Morton <akpm@linux-foundation.org>,
Dave Jones <davej@redhat.com>,
KOSAKI Motohiro <kosaki.motohiro@gmail.com>,
bhutchings@solarflare.com,
Konstantin Khlebnikov <khlebnikov@openvz.org>,
Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>,
Hugh Dickins <hughd@google.com>,
linux-kernel@vger.kernel.org, linux-mm@kvack.org
Subject: [patch for-3.7 v3] mm, mempolicy: hold task->mempolicy refcount while reading numa_maps.
Date: Fri, 19 Oct 2012 17:35:16 +0900 [thread overview]
Message-ID: <508110C4.6030805@jp.fujitsu.com> (raw)
In-Reply-To: <alpine.DEB.2.00.1210181255470.26994@chino.kir.corp.google.com>
(2012/10/19 5:03), David Rientjes wrote:
> On Thu, 18 Oct 2012, Kamezawa Hiroyuki wrote:
>> @@ -132,7 +162,7 @@ static void *m_start(struct seq_file *m, loff_t *pos)
>> tail_vma = get_gate_vma(priv->task->mm);
>> priv->tail_vma = tail_vma;
>> -
>> + hold_task_mempolicy(priv);
>> /* Start with last addr hint */
>> vma = find_vma(mm, last_addr);
>> if (last_addr && vma) {
>> @@ -159,6 +189,7 @@ out:
>> if (vma)
>> return vma;
>> + release_task_mempolicy(priv);
>> /* End of vmas has been reached */
>> m->version = (tail_vma != NULL)? 0: -1UL;
>> up_read(&mm->mmap_sem);
>
> Otherwise looks good, but please remove the two task_lock()'s in
> show_numa_map() that I added as part of this since you're replacing the
> need for locking.
>
Thank you for your review.
How about this ?
==
From c5849c9034abeec3f26bf30dadccd393b0c5c25e Mon Sep 17 00:00:00 2001
From: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Date: Fri, 19 Oct 2012 17:00:55 +0900
Subject: [PATCH] hold task->mempolicy while numa_maps scans.
/proc/<pid>/numa_maps scans vma and show mempolicy under
mmap_sem. It sometimes accesses task->mempolicy which can
be freed without mmap_sem and numa_maps can show some
garbage while scanning.
This patch tries to take reference count of task->mempolicy at reading
numa_maps before calling get_vma_policy(). By this, task->mempolicy
will not be freed until numa_maps reaches its end.
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
V2->v3
- updated comments to be more verbose.
- removed task_lock() in numa_maps code.
V1->V2
- access task->mempolicy only once and remember it. Becase kernel/exit.c
can overwrite it.
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
---
fs/proc/internal.h | 4 ++++
fs/proc/task_mmu.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 50 insertions(+), 3 deletions(-)
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index cceaab0..43973b0 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -12,6 +12,7 @@
#include <linux/sched.h>
#include <linux/proc_fs.h>
struct ctl_table_header;
+struct mempolicy;
extern struct proc_dir_entry proc_root;
#ifdef CONFIG_PROC_SYSCTL
@@ -74,6 +75,9 @@ struct proc_maps_private {
#ifdef CONFIG_MMU
struct vm_area_struct *tail_vma;
#endif
+#ifdef CONFIG_NUMA
+ struct mempolicy *task_mempolicy;
+#endif
};
void proc_init_inodecache(void);
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 14df880..2371fea 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -89,11 +89,55 @@ static void pad_len_spaces(struct seq_file *m, int len)
len = 1;
seq_printf(m, "%*c", len, ' ');
}
+#ifdef CONFIG_NUMA
+/*
+ * These functions are for numa_maps but called in generic **maps seq_file
+ * ->start(), ->stop() ops.
+ *
+ * numa_maps scans all vmas under mmap_sem and checks their mempolicy.
+ * Each mempolicy object is controlled by reference counting. The problem here
+ * is how to avoid accessing dead mempolicy object.
+ *
+ * Because we're holding mmap_sem while reading seq_file, it's safe to access
+ * each vma's mempolicy, no vma objects will never drop refs to mempolicy.
+ *
+ * A task's mempolicy (task->mempolicy) has different behavior. task->mempolicy
+ * is set and replaced under mmap_sem but unrefed and cleared under task_lock().
+ * So, without task_lock(), we cannot trust get_vma_policy() because we cannot
+ * gurantee the task never exits under us. But taking task_lock() around
+ * get_vma_plicy() causes lock order problem.
+ *
+ * To access task->mempolicy without lock, we hold a reference count of an
+ * object pointed by task->mempolicy and remember it. This will guarantee
+ * that task->mempolicy points to an alive object or NULL in numa_maps accesses.
+ */
+static void hold_task_mempolicy(struct proc_maps_private *priv)
+{
+ struct task_struct *task = priv->task;
+
+ task_lock(task);
+ priv->task_mempolicy = task->mempolicy;
+ mpol_get(priv->task_mempolicy);
+ task_unlock(task);
+}
+static void release_task_mempolicy(struct proc_maps_private *priv)
+{
+ mpol_put(priv->task_mempolicy);
+}
+#else
+static void hold_task_mempolicy(struct proc_maps_private *priv)
+{
+}
+static void release_task_mempolicy(struct proc_maps_private *priv)
+{
+}
+#endif
static void vma_stop(struct proc_maps_private *priv, struct vm_area_struct *vma)
{
if (vma && vma != priv->tail_vma) {
struct mm_struct *mm = vma->vm_mm;
+ release_task_mempolicy(priv);
up_read(&mm->mmap_sem);
mmput(mm);
}
@@ -132,7 +176,7 @@ static void *m_start(struct seq_file *m, loff_t *pos)
tail_vma = get_gate_vma(priv->task->mm);
priv->tail_vma = tail_vma;
-
+ hold_task_mempolicy(priv);
/* Start with last addr hint */
vma = find_vma(mm, last_addr);
if (last_addr && vma) {
@@ -159,6 +203,7 @@ out:
if (vma)
return vma;
+ release_task_mempolicy(priv);
/* End of vmas has been reached */
m->version = (tail_vma != NULL)? 0: -1UL;
up_read(&mm->mmap_sem);
@@ -1178,11 +1223,9 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid)
walk.private = md;
walk.mm = mm;
- task_lock(task);
pol = get_vma_policy(task, vma, vma->vm_start);
mpol_to_str(buffer, sizeof(buffer), pol, 0);
mpol_cond_put(pol);
- task_unlock(task);
seq_printf(m, "%08lx %s", vma->vm_start, buffer);
--
1.7.10.2
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
WARNING: multiple messages have this Message-ID (diff)
From: Kamezawa Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
To: David Rientjes <rientjes@google.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
Andrew Morton <akpm@linux-foundation.org>,
Dave Jones <davej@redhat.com>,
KOSAKI Motohiro <kosaki.motohiro@gmail.com>,
bhutchings@solarflare.com,
Konstantin Khlebnikov <khlebnikov@openvz.org>,
Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>,
Hugh Dickins <hughd@google.com>,
linux-kernel@vger.kernel.org, linux-mm@kvack.org
Subject: [patch for-3.7 v3] mm, mempolicy: hold task->mempolicy refcount while reading numa_maps.
Date: Fri, 19 Oct 2012 17:35:16 +0900 [thread overview]
Message-ID: <508110C4.6030805@jp.fujitsu.com> (raw)
In-Reply-To: <alpine.DEB.2.00.1210181255470.26994@chino.kir.corp.google.com>
(2012/10/19 5:03), David Rientjes wrote:
> On Thu, 18 Oct 2012, Kamezawa Hiroyuki wrote:
>> @@ -132,7 +162,7 @@ static void *m_start(struct seq_file *m, loff_t *pos)
>> tail_vma = get_gate_vma(priv->task->mm);
>> priv->tail_vma = tail_vma;
>> -
>> + hold_task_mempolicy(priv);
>> /* Start with last addr hint */
>> vma = find_vma(mm, last_addr);
>> if (last_addr && vma) {
>> @@ -159,6 +189,7 @@ out:
>> if (vma)
>> return vma;
>> + release_task_mempolicy(priv);
>> /* End of vmas has been reached */
>> m->version = (tail_vma != NULL)? 0: -1UL;
>> up_read(&mm->mmap_sem);
>
> Otherwise looks good, but please remove the two task_lock()'s in
> show_numa_map() that I added as part of this since you're replacing the
> need for locking.
>
Thank you for your review.
How about this ?
==
From c5849c9034abeec3f26bf30dadccd393b0c5c25e Mon Sep 17 00:00:00 2001
From: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Date: Fri, 19 Oct 2012 17:00:55 +0900
Subject: [PATCH] hold task->mempolicy while numa_maps scans.
/proc/<pid>/numa_maps scans vma and show mempolicy under
mmap_sem. It sometimes accesses task->mempolicy which can
be freed without mmap_sem and numa_maps can show some
garbage while scanning.
This patch tries to take reference count of task->mempolicy at reading
numa_maps before calling get_vma_policy(). By this, task->mempolicy
will not be freed until numa_maps reaches its end.
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
V2->v3
- updated comments to be more verbose.
- removed task_lock() in numa_maps code.
V1->V2
- access task->mempolicy only once and remember it. Becase kernel/exit.c
can overwrite it.
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
---
fs/proc/internal.h | 4 ++++
fs/proc/task_mmu.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 50 insertions(+), 3 deletions(-)
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index cceaab0..43973b0 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -12,6 +12,7 @@
#include <linux/sched.h>
#include <linux/proc_fs.h>
struct ctl_table_header;
+struct mempolicy;
extern struct proc_dir_entry proc_root;
#ifdef CONFIG_PROC_SYSCTL
@@ -74,6 +75,9 @@ struct proc_maps_private {
#ifdef CONFIG_MMU
struct vm_area_struct *tail_vma;
#endif
+#ifdef CONFIG_NUMA
+ struct mempolicy *task_mempolicy;
+#endif
};
void proc_init_inodecache(void);
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 14df880..2371fea 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -89,11 +89,55 @@ static void pad_len_spaces(struct seq_file *m, int len)
len = 1;
seq_printf(m, "%*c", len, ' ');
}
+#ifdef CONFIG_NUMA
+/*
+ * These functions are for numa_maps but called in generic **maps seq_file
+ * ->start(), ->stop() ops.
+ *
+ * numa_maps scans all vmas under mmap_sem and checks their mempolicy.
+ * Each mempolicy object is controlled by reference counting. The problem here
+ * is how to avoid accessing dead mempolicy object.
+ *
+ * Because we're holding mmap_sem while reading seq_file, it's safe to access
+ * each vma's mempolicy, no vma objects will never drop refs to mempolicy.
+ *
+ * A task's mempolicy (task->mempolicy) has different behavior. task->mempolicy
+ * is set and replaced under mmap_sem but unrefed and cleared under task_lock().
+ * So, without task_lock(), we cannot trust get_vma_policy() because we cannot
+ * gurantee the task never exits under us. But taking task_lock() around
+ * get_vma_plicy() causes lock order problem.
+ *
+ * To access task->mempolicy without lock, we hold a reference count of an
+ * object pointed by task->mempolicy and remember it. This will guarantee
+ * that task->mempolicy points to an alive object or NULL in numa_maps accesses.
+ */
+static void hold_task_mempolicy(struct proc_maps_private *priv)
+{
+ struct task_struct *task = priv->task;
+
+ task_lock(task);
+ priv->task_mempolicy = task->mempolicy;
+ mpol_get(priv->task_mempolicy);
+ task_unlock(task);
+}
+static void release_task_mempolicy(struct proc_maps_private *priv)
+{
+ mpol_put(priv->task_mempolicy);
+}
+#else
+static void hold_task_mempolicy(struct proc_maps_private *priv)
+{
+}
+static void release_task_mempolicy(struct proc_maps_private *priv)
+{
+}
+#endif
static void vma_stop(struct proc_maps_private *priv, struct vm_area_struct *vma)
{
if (vma && vma != priv->tail_vma) {
struct mm_struct *mm = vma->vm_mm;
+ release_task_mempolicy(priv);
up_read(&mm->mmap_sem);
mmput(mm);
}
@@ -132,7 +176,7 @@ static void *m_start(struct seq_file *m, loff_t *pos)
tail_vma = get_gate_vma(priv->task->mm);
priv->tail_vma = tail_vma;
-
+ hold_task_mempolicy(priv);
/* Start with last addr hint */
vma = find_vma(mm, last_addr);
if (last_addr && vma) {
@@ -159,6 +203,7 @@ out:
if (vma)
return vma;
+ release_task_mempolicy(priv);
/* End of vmas has been reached */
m->version = (tail_vma != NULL)? 0: -1UL;
up_read(&mm->mmap_sem);
@@ -1178,11 +1223,9 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid)
walk.private = md;
walk.mm = mm;
- task_lock(task);
pol = get_vma_policy(task, vma, vma->vm_start);
mpol_to_str(buffer, sizeof(buffer), pol, 0);
mpol_cond_put(pol);
- task_unlock(task);
seq_printf(m, "%08lx %s", vma->vm_start, buffer);
--
1.7.10.2
next prev parent reply other threads:[~2012-10-19 8:36 UTC|newest]
Thread overview: 117+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-10-08 15:09 mpol_to_str revisited Dave Jones
2012-10-08 15:09 ` Dave Jones
2012-10-08 15:15 ` Dave Jones
2012-10-08 15:15 ` Dave Jones
2012-10-08 20:46 ` David Rientjes
2012-10-08 20:46 ` David Rientjes
2012-10-08 20:35 ` David Rientjes
2012-10-08 20:35 ` David Rientjes
2012-10-08 20:52 ` Dave Jones
2012-10-08 20:52 ` Dave Jones
2012-10-16 0:48 ` David Rientjes
2012-10-16 0:48 ` David Rientjes
2012-10-09 0:33 ` Ben Hutchings
2012-10-16 2:34 ` KOSAKI Motohiro
2012-10-16 2:34 ` KOSAKI Motohiro
2012-10-16 3:58 ` David Rientjes
2012-10-16 3:58 ` David Rientjes
2012-10-16 5:10 ` KOSAKI Motohiro
2012-10-16 5:10 ` KOSAKI Motohiro
2012-10-16 6:10 ` David Rientjes
2012-10-16 6:10 ` David Rientjes
2012-10-16 23:39 ` KOSAKI Motohiro
2012-10-16 23:39 ` KOSAKI Motohiro
2012-10-17 0:12 ` David Rientjes
2012-10-17 0:12 ` David Rientjes
2012-10-17 0:31 ` [patch for-3.7] mm, mempolicy: fix printing stack contents in numa_maps David Rientjes
2012-10-17 0:31 ` David Rientjes
2012-10-17 1:38 ` KOSAKI Motohiro
2012-10-17 1:38 ` KOSAKI Motohiro
2012-10-17 1:49 ` David Rientjes
2012-10-17 1:49 ` David Rientjes
2012-10-17 1:53 ` KOSAKI Motohiro
2012-10-17 1:53 ` KOSAKI Motohiro
2012-10-17 4:05 ` Dave Jones
2012-10-17 4:05 ` Dave Jones
2012-10-17 5:24 ` David Rientjes
2012-10-17 5:24 ` David Rientjes
2012-10-17 5:42 ` Kamezawa Hiroyuki
2012-10-17 5:42 ` Kamezawa Hiroyuki
2012-10-17 8:49 ` KOSAKI Motohiro
2012-10-17 8:49 ` KOSAKI Motohiro
2012-10-17 19:50 ` David Rientjes
2012-10-17 19:50 ` David Rientjes
2012-10-17 21:05 ` KOSAKI Motohiro
2012-10-17 21:05 ` KOSAKI Motohiro
2012-10-17 21:27 ` David Rientjes
2012-10-17 21:27 ` David Rientjes
2012-10-17 18:14 ` Dave Jones
2012-10-17 18:14 ` Dave Jones
2012-10-17 19:21 ` David Rientjes
2012-10-17 19:21 ` David Rientjes
2012-10-17 19:32 ` Dave Jones
2012-10-17 19:32 ` Dave Jones
2012-10-17 19:38 ` David Rientjes
2012-10-17 19:38 ` David Rientjes
2012-10-17 19:45 ` Dave Jones
2012-10-17 19:45 ` Dave Jones
2012-10-17 20:28 ` [patch for-3.7] mm, mempolicy: avoid taking mutex inside spinlock when reading numa_maps David Rientjes
2012-10-17 20:28 ` David Rientjes
2012-10-17 21:31 ` [patch for-3.7 v2] " David Rientjes
2012-10-17 21:31 ` David Rientjes
2012-10-18 4:06 ` Kamezawa Hiroyuki
2012-10-18 4:06 ` Kamezawa Hiroyuki
2012-10-18 4:14 ` Linus Torvalds
2012-10-18 4:14 ` Linus Torvalds
2012-10-18 4:41 ` Kamezawa Hiroyuki
2012-10-18 4:41 ` Kamezawa Hiroyuki
2012-10-18 4:34 ` Kamezawa Hiroyuki
2012-10-18 4:34 ` Kamezawa Hiroyuki
2012-10-18 20:03 ` David Rientjes
2012-10-18 20:03 ` David Rientjes
2012-10-19 8:35 ` Kamezawa Hiroyuki [this message]
2012-10-19 8:35 ` [patch for-3.7 v3] mm, mempolicy: hold task->mempolicy refcount while " Kamezawa Hiroyuki
2012-10-19 9:28 ` David Rientjes
2012-10-19 9:28 ` David Rientjes
2012-10-22 2:47 ` Kamezawa Hiroyuki
2012-10-22 2:47 ` Kamezawa Hiroyuki
2012-10-22 20:55 ` Andrew Morton
2012-10-22 20:55 ` Andrew Morton
2012-10-22 20:56 ` David Rientjes
2012-10-22 20:56 ` David Rientjes
2012-10-19 19:15 ` KOSAKI Motohiro
2012-10-19 19:15 ` KOSAKI Motohiro
2012-10-19 6:51 ` [patch for-3.7 v2] mm, mempolicy: avoid taking mutex inside spinlock when " KOSAKI Motohiro
2012-10-19 6:51 ` KOSAKI Motohiro
2012-10-18 4:35 ` David Rientjes
2012-10-18 4:35 ` David Rientjes
2012-10-24 23:30 ` [patch for-3.7] mm, mempolicy: fix printing stack contents in numa_maps Sasha Levin
2012-10-24 23:30 ` Sasha Levin
2012-10-24 23:34 ` David Rientjes
2012-10-24 23:34 ` David Rientjes
2012-10-24 23:37 ` Sasha Levin
2012-10-24 23:37 ` Sasha Levin
2012-10-25 0:08 ` David Rientjes
2012-10-25 0:08 ` David Rientjes
2012-10-25 0:54 ` KOSAKI Motohiro
2012-10-25 0:54 ` KOSAKI Motohiro
2012-10-25 1:15 ` David Rientjes
2012-10-25 1:15 ` David Rientjes
2012-10-25 12:19 ` Peter Zijlstra
2012-10-25 12:19 ` Peter Zijlstra
2012-10-25 14:39 ` Peter Zijlstra
2012-10-25 14:39 ` Peter Zijlstra
2012-10-25 17:23 ` Sasha Levin
2012-10-25 17:23 ` Sasha Levin
2012-10-25 20:22 ` David Rientjes
2012-10-25 20:22 ` David Rientjes
2012-10-25 23:09 ` Linus Torvalds
2012-10-25 23:09 ` Linus Torvalds
2012-10-26 8:48 ` Peter Zijlstra
2012-10-26 8:48 ` Peter Zijlstra
2012-10-31 18:29 ` Sasha Levin
2012-10-31 18:29 ` Sasha Levin
2012-11-21 0:59 ` Sasha Levin
2012-11-21 0:59 ` Sasha Levin
2012-10-17 1:33 ` mpol_to_str revisited KOSAKI Motohiro
2012-10-17 1:33 ` KOSAKI Motohiro
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=508110C4.6030805@jp.fujitsu.com \
--to=kamezawa.hiroyu@jp.fujitsu.com \
--cc=akpm@linux-foundation.org \
--cc=bhutchings@solarflare.com \
--cc=davej@redhat.com \
--cc=hughd@google.com \
--cc=khlebnikov@openvz.org \
--cc=kosaki.motohiro@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=n-horiguchi@ah.jp.nec.com \
--cc=rientjes@google.com \
--cc=torvalds@linux-foundation.org \
/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.