linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2 v5][rfc] tmpfs not interleaving properly
@ 2012-07-03 19:44 Nathan Zimmer
  2012-07-03 19:44 ` [PATCH 1/2 v5][rfc] shmem: provide vm_ops when also providing a mem policy Nathan Zimmer
  0 siblings, 1 reply; 3+ messages in thread
From: Nathan Zimmer @ 2012-07-03 19:44 UTC (permalink / raw)
  To: linux-mm, linux-kernel; +Cc: Nathan Zimmer

When tmpfs has the memory policy interleaved it always starts allocating at each
file at node 0.  When there are many small files the lower nodes fill up
disproportionately.
This patch spreads out node usage by starting files at nodes other then 0.
The tmpfs superblock grants an offset for each inode as they are created. Each
then uses that offset to proved a prefered first node for its interleave in
the shmem_interleave.

v2: passed preferred node via addr.
v3: using current->cpuset_mem_spread_rotor instead of random_node.
v4: Switching the rotor and attempting to provide an interleave function.
Also splitting the patch into two sections.
v5: Corrected unsigned to long.

Nathan Zimmer (2):
  shmem: provide vm_ops when also providing a mem policy
  tmpfs: interleave the starting node of /dev/shmem

 include/linux/mm.h       |    7 +++++++
 include/linux/shmem_fs.h |    3 +++
 mm/mempolicy.c           |    4 ++++
 mm/shmem.c               |   35 ++++++++++++++++++++++++++++++++---
 4 files changed, 46 insertions(+), 3 deletions(-)

--
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>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 1/2 v5][rfc] shmem: provide vm_ops when also providing a mem policy
  2012-07-03 19:44 [PATCH 0/2 v5][rfc] tmpfs not interleaving properly Nathan Zimmer
@ 2012-07-03 19:44 ` Nathan Zimmer
  2012-07-03 19:44   ` [PATCH 2/2 v5][rfc] tmpfs: interleave the starting node of /dev/shmem Nathan Zimmer
  0 siblings, 1 reply; 3+ messages in thread
From: Nathan Zimmer @ 2012-07-03 19:44 UTC (permalink / raw)
  To: linux-mm, linux-kernel
  Cc: Nathan Zimmer, Christoph Lameter, Nick Piggin, Hugh Dickins,
	Lee Schermerhorn, KOSAKI Motohiro, Rik van Riel

Updating shmem_get_policy to use the vma_policy if provided.
This is to allows us to safely provide shmem_vm_ops to the vma when the vm_file
has not been setup which is the case on the pseudo vmas.

Cc: Christoph Lameter <cl@linux.com>
Cc: Nick Piggin <npiggin@gmail.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Lee Schermerhorn <lee.schermerhorn@hp.com>
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: Rik van Riel <riel@redhat.com>
Signed-off-by: Nathan Zimmer <nzimmer@sgi.com>
---
 mm/shmem.c |   18 +++++++++++++++---
 1 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/mm/shmem.c b/mm/shmem.c
index a15a466..d073252 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -921,8 +921,11 @@ static struct page *shmem_swapin(swp_entry_t swap, gfp_t gfp,
 	/* Create a pseudo vma that just contains the policy */
 	pvma.vm_start = 0;
 	pvma.vm_pgoff = index;
-	pvma.vm_ops = NULL;
 	pvma.vm_policy = spol;
+	if (pvma.vm_policy)
+		pvma.vm_ops = &shmem_vm_ops;
+	else
+		pvma.vm_ops = NULL;
 	return swapin_readahead(swap, gfp, &pvma, 0);
 }
 
@@ -934,8 +937,11 @@ static struct page *shmem_alloc_page(gfp_t gfp,
 	/* Create a pseudo vma that just contains the policy */
 	pvma.vm_start = 0;
 	pvma.vm_pgoff = index;
-	pvma.vm_ops = NULL;
 	pvma.vm_policy = mpol_shared_policy_lookup(&info->policy, index);
+	if (pvma.vm_policy)
+		pvma.vm_ops = &shmem_vm_ops;
+	else
+		pvma.vm_ops = NULL;
 
 	/*
 	 * alloc_page_vma() will drop the shared policy reference
@@ -1296,8 +1302,14 @@ static int shmem_set_policy(struct vm_area_struct *vma, struct mempolicy *mpol)
 static struct mempolicy *shmem_get_policy(struct vm_area_struct *vma,
 					  unsigned long addr)
 {
-	struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
 	pgoff_t index;
+	struct inode *inode;
+
+	/* If the vma knows what policy it wants use that one. */
+	if (vma->vm_policy)
+		return vma->vm_policy;
+
+	inode = vma->vm_file->f_path.dentry->d_inode;
 
 	index = ((addr - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
 	return mpol_shared_policy_lookup(&SHMEM_I(inode)->policy, index);
-- 
1.6.0.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>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 2/2 v5][rfc] tmpfs: interleave the starting node of /dev/shmem
  2012-07-03 19:44 ` [PATCH 1/2 v5][rfc] shmem: provide vm_ops when also providing a mem policy Nathan Zimmer
@ 2012-07-03 19:44   ` Nathan Zimmer
  0 siblings, 0 replies; 3+ messages in thread
From: Nathan Zimmer @ 2012-07-03 19:44 UTC (permalink / raw)
  To: linux-mm, linux-kernel
  Cc: Nathan Zimmer, Christoph Lameter, Nick Piggin, Hugh Dickins,
	Lee Schermerhorn, KOSAKI Motohiro, Rik van Riel

The tmpfs superblock grants an offset for each inode as they are created. Each
inode then uses that offset to provide a preferred first node for its interleave
in the newly provided shmem_interleave.

Cc: Christoph Lameter <cl@linux.com>
Cc: Nick Piggin <npiggin@gmail.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Lee Schermerhorn <lee.schermerhorn@hp.com>
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: Rik van Riel <riel@redhat.com>
Signed-off-by: Nathan Zimmer <nzimmer@sgi.com>
---
 include/linux/mm.h       |    7 +++++++
 include/linux/shmem_fs.h |    3 +++
 mm/mempolicy.c           |    4 ++++
 mm/shmem.c               |   17 +++++++++++++++++
 4 files changed, 31 insertions(+), 0 deletions(-)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index b36d08c..651109e 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -238,6 +238,13 @@ struct vm_operations_struct {
 	 */
 	struct mempolicy *(*get_policy)(struct vm_area_struct *vma,
 					unsigned long addr);
+
+	/*
+	 * If the policy is interleave allow the vma to suggest a node.
+	 */
+	unsigned long (*interleave)(struct vm_area_struct *vma,
+					unsigned long addr);
+
 	int (*migrate)(struct vm_area_struct *vma, const nodemask_t *from,
 		const nodemask_t *to, unsigned long flags);
 #endif
diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h
index bef2cf0..6995556 100644
--- a/include/linux/shmem_fs.h
+++ b/include/linux/shmem_fs.h
@@ -17,6 +17,7 @@ struct shmem_inode_info {
 		char		*symlink;	/* unswappable short symlink */
 	};
 	struct shared_policy	policy;		/* NUMA memory alloc policy */
+	unsigned long           node_offset;	/* bias for interleaved nodes */
 	struct list_head	swaplist;	/* chain of maybes on swap */
 	struct list_head	xattr_list;	/* list of shmem_xattr */
 	struct inode		vfs_inode;
@@ -32,6 +33,8 @@ struct shmem_sb_info {
 	kgid_t gid;		    /* Mount gid for root directory */
 	umode_t mode;		    /* Mount mode for root directory */
 	struct mempolicy *mpol;     /* default memory policy for mappings */
+	unsigned long next_pref_node;
+			 /* next interleave bias to suggest for inodes */
 };
 
 static inline struct shmem_inode_info *SHMEM_I(struct inode *inode)
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 1d771e4..e2cbe9e 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -1663,6 +1663,10 @@ static inline unsigned interleave_nid(struct mempolicy *pol,
 {
 	if (vma) {
 		unsigned long off;
+		if (vma->vm_ops && vma->vm_ops->interleave) {
+			off = vma->vm_ops->interleave(vma, addr);
+			return offset_il_node(pol, vma, off);
+		}
 
 		/*
 		 * for small pages, there is no difference between
diff --git a/mm/shmem.c b/mm/shmem.c
index d073252..e569338 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -922,6 +922,7 @@ static struct page *shmem_swapin(swp_entry_t swap, gfp_t gfp,
 	pvma.vm_start = 0;
 	pvma.vm_pgoff = index;
 	pvma.vm_policy = spol;
+	pvma.vm_private_data = (void *) info->node_offset;
 	if (pvma.vm_policy)
 		pvma.vm_ops = &shmem_vm_ops;
 	else
@@ -938,6 +939,7 @@ static struct page *shmem_alloc_page(gfp_t gfp,
 	pvma.vm_start = 0;
 	pvma.vm_pgoff = index;
 	pvma.vm_policy = mpol_shared_policy_lookup(&info->policy, index);
+	pvma.vm_private_data = (void *) info->node_offset;
 	if (pvma.vm_policy)
 		pvma.vm_ops = &shmem_vm_ops;
 	else
@@ -1314,6 +1316,19 @@ static struct mempolicy *shmem_get_policy(struct vm_area_struct *vma,
 	index = ((addr - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
 	return mpol_shared_policy_lookup(&SHMEM_I(inode)->policy, index);
 }
+
+static unsigned long shmem_interleave(struct vm_area_struct *vma,
+					unsigned long addr)
+{
+	unsigned long offset;
+
+	/* Use the vm_files prefered node as the initial offset. */
+	offset = (unsigned long *) vma->vm_private_data;
+
+	offset += ((addr - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
+
+	return offset;
+}
 #endif
 
 int shmem_lock(struct file *file, int lock, struct user_struct *user)
@@ -1386,6 +1401,7 @@ static struct inode *shmem_get_inode(struct super_block *sb, const struct inode
 			inode->i_fop = &shmem_file_operations;
 			mpol_shared_policy_init(&info->policy,
 						 shmem_get_sbmpol(sbinfo));
+			info->node_offset = ++(sbinfo->next_pref_node);
 			break;
 		case S_IFDIR:
 			inc_nlink(inode);
@@ -2871,6 +2887,7 @@ static const struct super_operations shmem_ops = {
 static const struct vm_operations_struct shmem_vm_ops = {
 	.fault		= shmem_fault,
 #ifdef CONFIG_NUMA
+	.interleave	= shmem_interleave,
 	.set_policy     = shmem_set_policy,
 	.get_policy     = shmem_get_policy,
 #endif
-- 
1.6.0.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>

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2012-07-03 19:44 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-03 19:44 [PATCH 0/2 v5][rfc] tmpfs not interleaving properly Nathan Zimmer
2012-07-03 19:44 ` [PATCH 1/2 v5][rfc] shmem: provide vm_ops when also providing a mem policy Nathan Zimmer
2012-07-03 19:44   ` [PATCH 2/2 v5][rfc] tmpfs: interleave the starting node of /dev/shmem Nathan Zimmer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox