diff options
author | Lee Schermerhorn <lee.schermerhorn@hp.com> | 2008-04-28 05:13:23 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-28 11:58:24 -0400 |
commit | 095f1fc4ebf36c64fddf9b6db29b1ab5517378e6 (patch) | |
tree | 39aae9d5b05d8501d1794e92c6115331c0a40848 /mm/shmem.c | |
parent | 2291990ab36b4b2d8a81b1f92e7a046e51632a60 (diff) |
mempolicy: rework shmem mpol parsing and display
mm/shmem.c currently contains functions to parse and display memory policy
strings for the tmpfs 'mpol' mount option. Move this to mm/mempolicy.c with
the rest of the mempolicy support. With subsequent patches, we'll be able to
remove knowledge of the details [mode, flags, policy, ...] completely from
shmem.c
1) replace shmem_parse_mpol() in mm/shmem.c with mpol_parse_str() in
mm/mempolicy.c. Rework to use the policy_types[] array [used by
mpol_to_str()] to look up mode by name.
2) use mpol_to_str() to format policy for shmem_show_mpol(). mpol_to_str()
expects a pointer to a struct mempolicy, so temporarily construct one.
This will be replaced with a reference to a struct mempolicy in the tmpfs
superblock in a subsequent patch.
NOTE 1: I changed mpol_to_str() to use a colon ':' rather than an equal
sign '=' as the nodemask delimiter to match mpol_parse_str() and the
tmpfs/shmem mpol mount option formatting that now uses mpol_to_str(). This
is a user visible change to numa_maps, but then the addition of the mode
flags already changed the display. It makes sense to me to have the mounts
and numa_maps display the policy in the same format. However, if anyone
objects strongly, I can pass the desired nodemask delimeter as an arg to
mpol_to_str().
Note 2: Like show_numa_map(), I don't check the return code from
mpol_to_str(). I do use a longer buffer than the one provided by
show_numa_map(), which seems to have sufficed so far.
Signed-off-by: Lee Schermerhorn <lee.schermerhorn@hp.com>
Cc: Christoph Lameter <clameter@sgi.com>
Cc: David Rientjes <rientjes@google.com>
Cc: Mel Gorman <mel@csn.ul.ie>
Cc: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/shmem.c')
-rw-r--r-- | mm/shmem.c | 118 |
1 files changed, 13 insertions, 105 deletions
diff --git a/mm/shmem.c b/mm/shmem.c index 0b591c669b2d..3c620dc10135 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -1079,108 +1079,22 @@ redirty: | |||
1079 | 1079 | ||
1080 | #ifdef CONFIG_NUMA | 1080 | #ifdef CONFIG_NUMA |
1081 | #ifdef CONFIG_TMPFS | 1081 | #ifdef CONFIG_TMPFS |
1082 | static int shmem_parse_mpol(char *value, unsigned short *policy, | 1082 | static void shmem_show_mpol(struct seq_file *seq, unsigned short mode, |
1083 | unsigned short *mode_flags, nodemask_t *policy_nodes) | ||
1084 | { | ||
1085 | char *nodelist = strchr(value, ':'); | ||
1086 | char *flags = strchr(value, '='); | ||
1087 | int err = 1; | ||
1088 | |||
1089 | if (nodelist) { | ||
1090 | /* NUL-terminate policy string */ | ||
1091 | *nodelist++ = '\0'; | ||
1092 | if (nodelist_parse(nodelist, *policy_nodes)) | ||
1093 | goto out; | ||
1094 | if (!nodes_subset(*policy_nodes, node_states[N_HIGH_MEMORY])) | ||
1095 | goto out; | ||
1096 | } | ||
1097 | if (flags) | ||
1098 | *flags++ = '\0'; | ||
1099 | if (!strcmp(value, "default")) { | ||
1100 | *policy = MPOL_DEFAULT; | ||
1101 | /* Don't allow a nodelist */ | ||
1102 | if (!nodelist) | ||
1103 | err = 0; | ||
1104 | } else if (!strcmp(value, "prefer")) { | ||
1105 | *policy = MPOL_PREFERRED; | ||
1106 | /* Insist on a nodelist of one node only */ | ||
1107 | if (nodelist) { | ||
1108 | char *rest = nodelist; | ||
1109 | while (isdigit(*rest)) | ||
1110 | rest++; | ||
1111 | if (!*rest) | ||
1112 | err = 0; | ||
1113 | } | ||
1114 | } else if (!strcmp(value, "bind")) { | ||
1115 | *policy = MPOL_BIND; | ||
1116 | /* Insist on a nodelist */ | ||
1117 | if (nodelist) | ||
1118 | err = 0; | ||
1119 | } else if (!strcmp(value, "interleave")) { | ||
1120 | *policy = MPOL_INTERLEAVE; | ||
1121 | /* | ||
1122 | * Default to online nodes with memory if no nodelist | ||
1123 | */ | ||
1124 | if (!nodelist) | ||
1125 | *policy_nodes = node_states[N_HIGH_MEMORY]; | ||
1126 | err = 0; | ||
1127 | } | ||
1128 | |||
1129 | *mode_flags = 0; | ||
1130 | if (flags) { | ||
1131 | /* | ||
1132 | * Currently, we only support two mutually exclusive | ||
1133 | * mode flags. | ||
1134 | */ | ||
1135 | if (!strcmp(flags, "static")) | ||
1136 | *mode_flags |= MPOL_F_STATIC_NODES; | ||
1137 | else if (!strcmp(flags, "relative")) | ||
1138 | *mode_flags |= MPOL_F_RELATIVE_NODES; | ||
1139 | else | ||
1140 | err = 1; /* unrecognized flag */ | ||
1141 | } | ||
1142 | out: | ||
1143 | /* Restore string for error message */ | ||
1144 | if (nodelist) | ||
1145 | *--nodelist = ':'; | ||
1146 | if (flags) | ||
1147 | *--flags = '='; | ||
1148 | return err; | ||
1149 | } | ||
1150 | |||
1151 | static void shmem_show_mpol(struct seq_file *seq, unsigned short policy, | ||
1152 | unsigned short flags, const nodemask_t policy_nodes) | 1083 | unsigned short flags, const nodemask_t policy_nodes) |
1153 | { | 1084 | { |
1154 | char *policy_string; | 1085 | struct mempolicy temp; |
1155 | 1086 | char buffer[64]; | |
1156 | switch (policy) { | ||
1157 | case MPOL_PREFERRED: | ||
1158 | policy_string = "prefer"; | ||
1159 | break; | ||
1160 | case MPOL_BIND: | ||
1161 | policy_string = "bind"; | ||
1162 | break; | ||
1163 | case MPOL_INTERLEAVE: | ||
1164 | policy_string = "interleave"; | ||
1165 | break; | ||
1166 | default: | ||
1167 | /* MPOL_DEFAULT */ | ||
1168 | return; | ||
1169 | } | ||
1170 | 1087 | ||
1171 | seq_printf(seq, ",mpol=%s", policy_string); | 1088 | if (mode == MPOL_DEFAULT) |
1089 | return; /* show nothing */ | ||
1172 | 1090 | ||
1173 | if (policy != MPOL_INTERLEAVE || | 1091 | temp.mode = mode; |
1174 | !nodes_equal(policy_nodes, node_states[N_HIGH_MEMORY])) { | 1092 | temp.flags = flags; |
1175 | char buffer[64]; | 1093 | temp.v.nodes = policy_nodes; |
1176 | int len; | ||
1177 | 1094 | ||
1178 | len = nodelist_scnprintf(buffer, sizeof(buffer), policy_nodes); | 1095 | mpol_to_str(buffer, sizeof(buffer), &temp); |
1179 | if (len < sizeof(buffer)) | 1096 | |
1180 | seq_printf(seq, ":%s", buffer); | 1097 | seq_printf(seq, ",mpol=%s", buffer); |
1181 | else | ||
1182 | seq_printf(seq, ":?"); | ||
1183 | } | ||
1184 | } | 1098 | } |
1185 | #endif /* CONFIG_TMPFS */ | 1099 | #endif /* CONFIG_TMPFS */ |
1186 | 1100 | ||
@@ -1221,12 +1135,6 @@ static struct page *shmem_alloc_page(gfp_t gfp, | |||
1221 | } | 1135 | } |
1222 | #else /* !CONFIG_NUMA */ | 1136 | #else /* !CONFIG_NUMA */ |
1223 | #ifdef CONFIG_TMPFS | 1137 | #ifdef CONFIG_TMPFS |
1224 | static inline int shmem_parse_mpol(char *value, unsigned short *policy, | ||
1225 | unsigned short *mode_flags, nodemask_t *policy_nodes) | ||
1226 | { | ||
1227 | return 1; | ||
1228 | } | ||
1229 | |||
1230 | static inline void shmem_show_mpol(struct seq_file *seq, unsigned short policy, | 1138 | static inline void shmem_show_mpol(struct seq_file *seq, unsigned short policy, |
1231 | unsigned short flags, const nodemask_t policy_nodes) | 1139 | unsigned short flags, const nodemask_t policy_nodes) |
1232 | { | 1140 | { |
@@ -2231,8 +2139,8 @@ static int shmem_parse_options(char *options, struct shmem_sb_info *sbinfo, | |||
2231 | if (*rest) | 2139 | if (*rest) |
2232 | goto bad_val; | 2140 | goto bad_val; |
2233 | } else if (!strcmp(this_char,"mpol")) { | 2141 | } else if (!strcmp(this_char,"mpol")) { |
2234 | if (shmem_parse_mpol(value, &sbinfo->policy, | 2142 | if (mpol_parse_str(value, &sbinfo->policy, |
2235 | &sbinfo->flags, &sbinfo->policy_nodes)) | 2143 | &sbinfo->flags, &sbinfo->policy_nodes)) |
2236 | goto bad_val; | 2144 | goto bad_val; |
2237 | } else { | 2145 | } else { |
2238 | printk(KERN_ERR "tmpfs: Bad mount option %s\n", | 2146 | printk(KERN_ERR "tmpfs: Bad mount option %s\n", |