aboutsummaryrefslogtreecommitdiffstats
path: root/mm/shmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/shmem.c')
-rw-r--r--mm/shmem.c144
1 files changed, 43 insertions, 101 deletions
diff --git a/mm/shmem.c b/mm/shmem.c
index f514dd392cd9..e6d9298aa22a 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1079,104 +1079,47 @@ redirty:
1079 1079
1080#ifdef CONFIG_NUMA 1080#ifdef CONFIG_NUMA
1081#ifdef CONFIG_TMPFS 1081#ifdef CONFIG_TMPFS
1082static int shmem_parse_mpol(char *value, int *policy, nodemask_t *policy_nodes) 1082static void shmem_show_mpol(struct seq_file *seq, struct mempolicy *mpol)
1083{ 1083{
1084 char *nodelist = strchr(value, ':'); 1084 char buffer[64];
1085 int err = 1;
1086 1085
1087 if (nodelist) { 1086 if (!mpol || mpol->mode == MPOL_DEFAULT)
1088 /* NUL-terminate policy string */ 1087 return; /* show nothing */
1089 *nodelist++ = '\0';
1090 if (nodelist_parse(nodelist, *policy_nodes))
1091 goto out;
1092 if (!nodes_subset(*policy_nodes, node_states[N_HIGH_MEMORY]))
1093 goto out;
1094 }
1095 if (!strcmp(value, "default")) {
1096 *policy = MPOL_DEFAULT;
1097 /* Don't allow a nodelist */
1098 if (!nodelist)
1099 err = 0;
1100 } else if (!strcmp(value, "prefer")) {
1101 *policy = MPOL_PREFERRED;
1102 /* Insist on a nodelist of one node only */
1103 if (nodelist) {
1104 char *rest = nodelist;
1105 while (isdigit(*rest))
1106 rest++;
1107 if (!*rest)
1108 err = 0;
1109 }
1110 } else if (!strcmp(value, "bind")) {
1111 *policy = MPOL_BIND;
1112 /* Insist on a nodelist */
1113 if (nodelist)
1114 err = 0;
1115 } else if (!strcmp(value, "interleave")) {
1116 *policy = MPOL_INTERLEAVE;
1117 /*
1118 * Default to online nodes with memory if no nodelist
1119 */
1120 if (!nodelist)
1121 *policy_nodes = node_states[N_HIGH_MEMORY];
1122 err = 0;
1123 }
1124out:
1125 /* Restore string for error message */
1126 if (nodelist)
1127 *--nodelist = ':';
1128 return err;
1129}
1130
1131static void shmem_show_mpol(struct seq_file *seq, int policy,
1132 const nodemask_t policy_nodes)
1133{
1134 char *policy_string;
1135 1088
1136 switch (policy) { 1089 mpol_to_str(buffer, sizeof(buffer), mpol, 1);
1137 case MPOL_PREFERRED:
1138 policy_string = "prefer";
1139 break;
1140 case MPOL_BIND:
1141 policy_string = "bind";
1142 break;
1143 case MPOL_INTERLEAVE:
1144 policy_string = "interleave";
1145 break;
1146 default:
1147 /* MPOL_DEFAULT */
1148 return;
1149 }
1150 1090
1151 seq_printf(seq, ",mpol=%s", policy_string); 1091 seq_printf(seq, ",mpol=%s", buffer);
1152 1092}
1153 if (policy != MPOL_INTERLEAVE ||
1154 !nodes_equal(policy_nodes, node_states[N_HIGH_MEMORY])) {
1155 char buffer[64];
1156 int len;
1157 1093
1158 len = nodelist_scnprintf(buffer, sizeof(buffer), policy_nodes); 1094static struct mempolicy *shmem_get_sbmpol(struct shmem_sb_info *sbinfo)
1159 if (len < sizeof(buffer)) 1095{
1160 seq_printf(seq, ":%s", buffer); 1096 struct mempolicy *mpol = NULL;
1161 else 1097 if (sbinfo->mpol) {
1162 seq_printf(seq, ":?"); 1098 spin_lock(&sbinfo->stat_lock); /* prevent replace/use races */
1099 mpol = sbinfo->mpol;
1100 mpol_get(mpol);
1101 spin_unlock(&sbinfo->stat_lock);
1163 } 1102 }
1103 return mpol;
1164} 1104}
1165#endif /* CONFIG_TMPFS */ 1105#endif /* CONFIG_TMPFS */
1166 1106
1167static struct page *shmem_swapin(swp_entry_t entry, gfp_t gfp, 1107static struct page *shmem_swapin(swp_entry_t entry, gfp_t gfp,
1168 struct shmem_inode_info *info, unsigned long idx) 1108 struct shmem_inode_info *info, unsigned long idx)
1169{ 1109{
1110 struct mempolicy mpol, *spol;
1170 struct vm_area_struct pvma; 1111 struct vm_area_struct pvma;
1171 struct page *page; 1112 struct page *page;
1172 1113
1114 spol = mpol_cond_copy(&mpol,
1115 mpol_shared_policy_lookup(&info->policy, idx));
1116
1173 /* Create a pseudo vma that just contains the policy */ 1117 /* Create a pseudo vma that just contains the policy */
1174 pvma.vm_start = 0; 1118 pvma.vm_start = 0;
1175 pvma.vm_pgoff = idx; 1119 pvma.vm_pgoff = idx;
1176 pvma.vm_ops = NULL; 1120 pvma.vm_ops = NULL;
1177 pvma.vm_policy = mpol_shared_policy_lookup(&info->policy, idx); 1121 pvma.vm_policy = spol;
1178 page = swapin_readahead(entry, gfp, &pvma, 0); 1122 page = swapin_readahead(entry, gfp, &pvma, 0);
1179 mpol_free(pvma.vm_policy);
1180 return page; 1123 return page;
1181} 1124}
1182 1125
@@ -1184,27 +1127,21 @@ static struct page *shmem_alloc_page(gfp_t gfp,
1184 struct shmem_inode_info *info, unsigned long idx) 1127 struct shmem_inode_info *info, unsigned long idx)
1185{ 1128{
1186 struct vm_area_struct pvma; 1129 struct vm_area_struct pvma;
1187 struct page *page;
1188 1130
1189 /* Create a pseudo vma that just contains the policy */ 1131 /* Create a pseudo vma that just contains the policy */
1190 pvma.vm_start = 0; 1132 pvma.vm_start = 0;
1191 pvma.vm_pgoff = idx; 1133 pvma.vm_pgoff = idx;
1192 pvma.vm_ops = NULL; 1134 pvma.vm_ops = NULL;
1193 pvma.vm_policy = mpol_shared_policy_lookup(&info->policy, idx); 1135 pvma.vm_policy = mpol_shared_policy_lookup(&info->policy, idx);
1194 page = alloc_page_vma(gfp, &pvma, 0); 1136
1195 mpol_free(pvma.vm_policy); 1137 /*
1196 return page; 1138 * alloc_page_vma() will drop the shared policy reference
1139 */
1140 return alloc_page_vma(gfp, &pvma, 0);
1197} 1141}
1198#else /* !CONFIG_NUMA */ 1142#else /* !CONFIG_NUMA */
1199#ifdef CONFIG_TMPFS 1143#ifdef CONFIG_TMPFS
1200static inline int shmem_parse_mpol(char *value, int *policy, 1144static inline void shmem_show_mpol(struct seq_file *seq, struct mempolicy *p)
1201 nodemask_t *policy_nodes)
1202{
1203 return 1;
1204}
1205
1206static inline void shmem_show_mpol(struct seq_file *seq, int policy,
1207 const nodemask_t policy_nodes)
1208{ 1145{
1209} 1146}
1210#endif /* CONFIG_TMPFS */ 1147#endif /* CONFIG_TMPFS */
@@ -1222,6 +1159,13 @@ static inline struct page *shmem_alloc_page(gfp_t gfp,
1222} 1159}
1223#endif /* CONFIG_NUMA */ 1160#endif /* CONFIG_NUMA */
1224 1161
1162#if !defined(CONFIG_NUMA) || !defined(CONFIG_TMPFS)
1163static inline struct mempolicy *shmem_get_sbmpol(struct shmem_sb_info *sbinfo)
1164{
1165 return NULL;
1166}
1167#endif
1168
1225/* 1169/*
1226 * shmem_getpage - either get the page from swap or allocate a new one 1170 * shmem_getpage - either get the page from swap or allocate a new one
1227 * 1171 *
@@ -1576,8 +1520,8 @@ shmem_get_inode(struct super_block *sb, int mode, dev_t dev)
1576 case S_IFREG: 1520 case S_IFREG:
1577 inode->i_op = &shmem_inode_operations; 1521 inode->i_op = &shmem_inode_operations;
1578 inode->i_fop = &shmem_file_operations; 1522 inode->i_fop = &shmem_file_operations;
1579 mpol_shared_policy_init(&info->policy, sbinfo->policy, 1523 mpol_shared_policy_init(&info->policy,
1580 &sbinfo->policy_nodes); 1524 shmem_get_sbmpol(sbinfo));
1581 break; 1525 break;
1582 case S_IFDIR: 1526 case S_IFDIR:
1583 inc_nlink(inode); 1527 inc_nlink(inode);
@@ -1591,8 +1535,7 @@ shmem_get_inode(struct super_block *sb, int mode, dev_t dev)
1591 * Must not load anything in the rbtree, 1535 * Must not load anything in the rbtree,
1592 * mpol_free_shared_policy will not be called. 1536 * mpol_free_shared_policy will not be called.
1593 */ 1537 */
1594 mpol_shared_policy_init(&info->policy, MPOL_DEFAULT, 1538 mpol_shared_policy_init(&info->policy, NULL);
1595 NULL);
1596 break; 1539 break;
1597 } 1540 }
1598 } else 1541 } else
@@ -2207,8 +2150,7 @@ static int shmem_parse_options(char *options, struct shmem_sb_info *sbinfo,
2207 if (*rest) 2150 if (*rest)
2208 goto bad_val; 2151 goto bad_val;
2209 } else if (!strcmp(this_char,"mpol")) { 2152 } else if (!strcmp(this_char,"mpol")) {
2210 if (shmem_parse_mpol(value, &sbinfo->policy, 2153 if (mpol_parse_str(value, &sbinfo->mpol, 1))
2211 &sbinfo->policy_nodes))
2212 goto bad_val; 2154 goto bad_val;
2213 } else { 2155 } else {
2214 printk(KERN_ERR "tmpfs: Bad mount option %s\n", 2156 printk(KERN_ERR "tmpfs: Bad mount option %s\n",
@@ -2259,8 +2201,9 @@ static int shmem_remount_fs(struct super_block *sb, int *flags, char *data)
2259 sbinfo->free_blocks = config.max_blocks - blocks; 2201 sbinfo->free_blocks = config.max_blocks - blocks;
2260 sbinfo->max_inodes = config.max_inodes; 2202 sbinfo->max_inodes = config.max_inodes;
2261 sbinfo->free_inodes = config.max_inodes - inodes; 2203 sbinfo->free_inodes = config.max_inodes - inodes;
2262 sbinfo->policy = config.policy; 2204
2263 sbinfo->policy_nodes = config.policy_nodes; 2205 mpol_put(sbinfo->mpol);
2206 sbinfo->mpol = config.mpol; /* transfers initial ref */
2264out: 2207out:
2265 spin_unlock(&sbinfo->stat_lock); 2208 spin_unlock(&sbinfo->stat_lock);
2266 return error; 2209 return error;
@@ -2281,7 +2224,7 @@ static int shmem_show_options(struct seq_file *seq, struct vfsmount *vfs)
2281 seq_printf(seq, ",uid=%u", sbinfo->uid); 2224 seq_printf(seq, ",uid=%u", sbinfo->uid);
2282 if (sbinfo->gid != 0) 2225 if (sbinfo->gid != 0)
2283 seq_printf(seq, ",gid=%u", sbinfo->gid); 2226 seq_printf(seq, ",gid=%u", sbinfo->gid);
2284 shmem_show_mpol(seq, sbinfo->policy, sbinfo->policy_nodes); 2227 shmem_show_mpol(seq, sbinfo->mpol);
2285 return 0; 2228 return 0;
2286} 2229}
2287#endif /* CONFIG_TMPFS */ 2230#endif /* CONFIG_TMPFS */
@@ -2311,8 +2254,7 @@ static int shmem_fill_super(struct super_block *sb,
2311 sbinfo->mode = S_IRWXUGO | S_ISVTX; 2254 sbinfo->mode = S_IRWXUGO | S_ISVTX;
2312 sbinfo->uid = current->fsuid; 2255 sbinfo->uid = current->fsuid;
2313 sbinfo->gid = current->fsgid; 2256 sbinfo->gid = current->fsgid;
2314 sbinfo->policy = MPOL_DEFAULT; 2257 sbinfo->mpol = NULL;
2315 sbinfo->policy_nodes = node_states[N_HIGH_MEMORY];
2316 sb->s_fs_info = sbinfo; 2258 sb->s_fs_info = sbinfo;
2317 2259
2318#ifdef CONFIG_TMPFS 2260#ifdef CONFIG_TMPFS