aboutsummaryrefslogtreecommitdiffstats
path: root/mm/shmem.c
diff options
context:
space:
mode:
authorRobin Holt <holt@sgi.com>2006-01-14 16:20:48 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-14 21:27:07 -0500
commit7339ff8302fd70aabf5f1ae26e0c4905fa74a495 (patch)
tree38ee561d51b7e4db7c0d6dd9ebd9fc22c2b6ab88 /mm/shmem.c
parent852cf918dcf2ae46468b425e679fbcbf0ea8fdbb (diff)
[PATCH] Add tmpfs options for memory placement policies
Anything that writes into a tmpfs filesystem is liable to disproportionately decrease the available memory on a particular node. Since there's no telling what sort of application (e.g. dd/cp/cat) might be dropping large files there, this lets the admin choose the appropriate default behavior for their site's situation. Introduce a tmpfs mount option which allows specifying a memory policy and a second option to specify the nodelist for that policy. With the default policy, tmpfs will behave as it does today. This patch adds support for preferred, bind, and interleave policies. The default policy will cause pages to be added to tmpfs files on the node which is doing the writing. Some jobs expect a single process to create and manage the tmpfs files. This results in a node which has a significantly reduced number of free pages. With this patch, the administrator can specify the policy and nodes for that policy where they would prefer allocations. This patch was originally written by Brent Casavant and Hugh Dickins. I added support for the bind and preferred policies and the mpol_nodelist mount option. Signed-off-by: Brent Casavant <bcasavan@sgi.com> Signed-off-by: Hugh Dickins <hugh@veritas.com> Signed-off-by: Robin Holt <holt@sgi.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'mm/shmem.c')
-rw-r--r--mm/shmem.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/mm/shmem.c b/mm/shmem.c
index 343b3c0937e5..ce501bce1c2e 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1316,7 +1316,8 @@ shmem_get_inode(struct super_block *sb, int mode, dev_t dev)
1316 case S_IFREG: 1316 case S_IFREG:
1317 inode->i_op = &shmem_inode_operations; 1317 inode->i_op = &shmem_inode_operations;
1318 inode->i_fop = &shmem_file_operations; 1318 inode->i_fop = &shmem_file_operations;
1319 mpol_shared_policy_init(&info->policy); 1319 mpol_shared_policy_init(&info->policy, sbinfo->policy,
1320 &sbinfo->policy_nodes);
1320 break; 1321 break;
1321 case S_IFDIR: 1322 case S_IFDIR:
1322 inode->i_nlink++; 1323 inode->i_nlink++;
@@ -1330,7 +1331,8 @@ shmem_get_inode(struct super_block *sb, int mode, dev_t dev)
1330 * Must not load anything in the rbtree, 1331 * Must not load anything in the rbtree,
1331 * mpol_free_shared_policy will not be called. 1332 * mpol_free_shared_policy will not be called.
1332 */ 1333 */
1333 mpol_shared_policy_init(&info->policy); 1334 mpol_shared_policy_init(&info->policy, MPOL_DEFAULT,
1335 NULL);
1334 break; 1336 break;
1335 } 1337 }
1336 } else if (sbinfo->max_inodes) { 1338 } else if (sbinfo->max_inodes) {
@@ -1843,7 +1845,9 @@ static struct inode_operations shmem_symlink_inode_operations = {
1843 .put_link = shmem_put_link, 1845 .put_link = shmem_put_link,
1844}; 1846};
1845 1847
1846static int shmem_parse_options(char *options, int *mode, uid_t *uid, gid_t *gid, unsigned long *blocks, unsigned long *inodes) 1848static int shmem_parse_options(char *options, int *mode, uid_t *uid,
1849 gid_t *gid, unsigned long *blocks, unsigned long *inodes,
1850 int *policy, nodemask_t *policy_nodes)
1847{ 1851{
1848 char *this_char, *value, *rest; 1852 char *this_char, *value, *rest;
1849 1853
@@ -1897,6 +1901,19 @@ static int shmem_parse_options(char *options, int *mode, uid_t *uid, gid_t *gid,
1897 *gid = simple_strtoul(value,&rest,0); 1901 *gid = simple_strtoul(value,&rest,0);
1898 if (*rest) 1902 if (*rest)
1899 goto bad_val; 1903 goto bad_val;
1904 } else if (!strcmp(this_char,"mpol")) {
1905 if (!strcmp(value,"default"))
1906 *policy = MPOL_DEFAULT;
1907 else if (!strcmp(value,"preferred"))
1908 *policy = MPOL_PREFERRED;
1909 else if (!strcmp(value,"bind"))
1910 *policy = MPOL_BIND;
1911 else if (!strcmp(value,"interleave"))
1912 *policy = MPOL_INTERLEAVE;
1913 else
1914 goto bad_val;
1915 } else if (!strcmp(this_char,"mpol_nodelist")) {
1916 nodelist_parse(value, *policy_nodes);
1900 } else { 1917 } else {
1901 printk(KERN_ERR "tmpfs: Bad mount option %s\n", 1918 printk(KERN_ERR "tmpfs: Bad mount option %s\n",
1902 this_char); 1919 this_char);
@@ -1917,12 +1934,14 @@ static int shmem_remount_fs(struct super_block *sb, int *flags, char *data)
1917 struct shmem_sb_info *sbinfo = SHMEM_SB(sb); 1934 struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
1918 unsigned long max_blocks = sbinfo->max_blocks; 1935 unsigned long max_blocks = sbinfo->max_blocks;
1919 unsigned long max_inodes = sbinfo->max_inodes; 1936 unsigned long max_inodes = sbinfo->max_inodes;
1937 int policy = sbinfo->policy;
1938 nodemask_t policy_nodes = sbinfo->policy_nodes;
1920 unsigned long blocks; 1939 unsigned long blocks;
1921 unsigned long inodes; 1940 unsigned long inodes;
1922 int error = -EINVAL; 1941 int error = -EINVAL;
1923 1942
1924 if (shmem_parse_options(data, NULL, NULL, NULL, 1943 if (shmem_parse_options(data, NULL, NULL, NULL, &max_blocks,
1925 &max_blocks, &max_inodes)) 1944 &max_inodes, &policy, &policy_nodes))
1926 return error; 1945 return error;
1927 1946
1928 spin_lock(&sbinfo->stat_lock); 1947 spin_lock(&sbinfo->stat_lock);
@@ -1948,6 +1967,8 @@ static int shmem_remount_fs(struct super_block *sb, int *flags, char *data)
1948 sbinfo->free_blocks = max_blocks - blocks; 1967 sbinfo->free_blocks = max_blocks - blocks;
1949 sbinfo->max_inodes = max_inodes; 1968 sbinfo->max_inodes = max_inodes;
1950 sbinfo->free_inodes = max_inodes - inodes; 1969 sbinfo->free_inodes = max_inodes - inodes;
1970 sbinfo->policy = policy;
1971 sbinfo->policy_nodes = policy_nodes;
1951out: 1972out:
1952 spin_unlock(&sbinfo->stat_lock); 1973 spin_unlock(&sbinfo->stat_lock);
1953 return error; 1974 return error;
@@ -1972,6 +1993,8 @@ static int shmem_fill_super(struct super_block *sb,
1972 struct shmem_sb_info *sbinfo; 1993 struct shmem_sb_info *sbinfo;
1973 unsigned long blocks = 0; 1994 unsigned long blocks = 0;
1974 unsigned long inodes = 0; 1995 unsigned long inodes = 0;
1996 int policy = MPOL_DEFAULT;
1997 nodemask_t policy_nodes = node_online_map;
1975 1998
1976#ifdef CONFIG_TMPFS 1999#ifdef CONFIG_TMPFS
1977 /* 2000 /*
@@ -1984,8 +2007,8 @@ static int shmem_fill_super(struct super_block *sb,
1984 inodes = totalram_pages - totalhigh_pages; 2007 inodes = totalram_pages - totalhigh_pages;
1985 if (inodes > blocks) 2008 if (inodes > blocks)
1986 inodes = blocks; 2009 inodes = blocks;
1987 if (shmem_parse_options(data, &mode, &uid, &gid, 2010 if (shmem_parse_options(data, &mode, &uid, &gid, &blocks,
1988 &blocks, &inodes)) 2011 &inodes, &policy, &policy_nodes))
1989 return -EINVAL; 2012 return -EINVAL;
1990 } 2013 }
1991#else 2014#else
@@ -2003,6 +2026,8 @@ static int shmem_fill_super(struct super_block *sb,
2003 sbinfo->free_blocks = blocks; 2026 sbinfo->free_blocks = blocks;
2004 sbinfo->max_inodes = inodes; 2027 sbinfo->max_inodes = inodes;
2005 sbinfo->free_inodes = inodes; 2028 sbinfo->free_inodes = inodes;
2029 sbinfo->policy = policy;
2030 sbinfo->policy_nodes = policy_nodes;
2006 2031
2007 sb->s_fs_info = sbinfo; 2032 sb->s_fs_info = sbinfo;
2008 sb->s_maxbytes = SHMEM_MAX_BYTES; 2033 sb->s_maxbytes = SHMEM_MAX_BYTES;