Commit e37123953292146445c8629b3950d0513fd10ae2
Committed by
Linus Torvalds
1 parent
af351026aa
Exists in
master
and in
4 other branches
cgroup files: remove cpuset_common_file_write()
This patch tweaks the signatures of the update_cpumask() and update_nodemask() functions so that they can be called directly as handlers for the new cgroups write_string() method. This allows cpuset_common_file_write() to be removed. Signed-off-by: Paul Menage <menage@google.com> Cc: Paul Jackson <pj@sgi.com> Cc: Pavel Emelyanov <xemul@openvz.org> Cc: Balbir Singh <balbir@in.ibm.com> Cc: Serge Hallyn <serue@us.ibm.com> Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 1 changed file with 35 additions and 74 deletions Side-by-side Diff
kernel/cpuset.c
... | ... | @@ -227,10 +227,6 @@ |
227 | 227 | * The task_struct fields mems_allowed and mems_generation may only |
228 | 228 | * be accessed in the context of that task, so require no locks. |
229 | 229 | * |
230 | - * The cpuset_common_file_write handler for operations that modify | |
231 | - * the cpuset hierarchy holds cgroup_mutex across the entire operation, | |
232 | - * single threading all such cpuset modifications across the system. | |
233 | - * | |
234 | 230 | * The cpuset_common_file_read() handlers only hold callback_mutex across |
235 | 231 | * small pieces of code, such as when reading out possibly multi-word |
236 | 232 | * cpumasks and nodemasks. |
... | ... | @@ -772,7 +768,7 @@ |
772 | 768 | * @cs: the cpuset to consider |
773 | 769 | * @buf: buffer of cpu numbers written to this cpuset |
774 | 770 | */ |
775 | -static int update_cpumask(struct cpuset *cs, char *buf) | |
771 | +static int update_cpumask(struct cpuset *cs, const char *buf) | |
776 | 772 | { |
777 | 773 | struct cpuset trialcs; |
778 | 774 | struct cgroup_scanner scan; |
... | ... | @@ -792,7 +788,6 @@ |
792 | 788 | * that parsing. The validate_change() call ensures that cpusets |
793 | 789 | * with tasks have cpus. |
794 | 790 | */ |
795 | - buf = strstrip(buf); | |
796 | 791 | if (!*buf) { |
797 | 792 | cpus_clear(trialcs.cpus_allowed); |
798 | 793 | } else { |
... | ... | @@ -902,7 +897,7 @@ |
902 | 897 | |
903 | 898 | static void *cpuset_being_rebound; |
904 | 899 | |
905 | -static int update_nodemask(struct cpuset *cs, char *buf) | |
900 | +static int update_nodemask(struct cpuset *cs, const char *buf) | |
906 | 901 | { |
907 | 902 | struct cpuset trialcs; |
908 | 903 | nodemask_t oldmem; |
... | ... | @@ -929,7 +924,6 @@ |
929 | 924 | * that parsing. The validate_change() call ensures that cpusets |
930 | 925 | * with tasks have memory. |
931 | 926 | */ |
932 | - buf = strstrip(buf); | |
933 | 927 | if (!*buf) { |
934 | 928 | nodes_clear(trialcs.mems_allowed); |
935 | 929 | } else { |
936 | 930 | |
937 | 931 | |
... | ... | @@ -1256,72 +1250,14 @@ |
1256 | 1250 | FILE_SPREAD_SLAB, |
1257 | 1251 | } cpuset_filetype_t; |
1258 | 1252 | |
1259 | -static ssize_t cpuset_common_file_write(struct cgroup *cont, | |
1260 | - struct cftype *cft, | |
1261 | - struct file *file, | |
1262 | - const char __user *userbuf, | |
1263 | - size_t nbytes, loff_t *unused_ppos) | |
1264 | -{ | |
1265 | - struct cpuset *cs = cgroup_cs(cont); | |
1266 | - cpuset_filetype_t type = cft->private; | |
1267 | - char *buffer; | |
1268 | - int retval = 0; | |
1269 | - | |
1270 | - /* Crude upper limit on largest legitimate cpulist user might write. */ | |
1271 | - if (nbytes > 100U + 6 * max(NR_CPUS, MAX_NUMNODES)) | |
1272 | - return -E2BIG; | |
1273 | - | |
1274 | - /* +1 for nul-terminator */ | |
1275 | - buffer = kmalloc(nbytes + 1, GFP_KERNEL); | |
1276 | - if (!buffer) | |
1277 | - return -ENOMEM; | |
1278 | - | |
1279 | - if (copy_from_user(buffer, userbuf, nbytes)) { | |
1280 | - retval = -EFAULT; | |
1281 | - goto out1; | |
1282 | - } | |
1283 | - buffer[nbytes] = 0; /* nul-terminate */ | |
1284 | - | |
1285 | - cgroup_lock(); | |
1286 | - | |
1287 | - if (cgroup_is_removed(cont)) { | |
1288 | - retval = -ENODEV; | |
1289 | - goto out2; | |
1290 | - } | |
1291 | - | |
1292 | - switch (type) { | |
1293 | - case FILE_CPULIST: | |
1294 | - retval = update_cpumask(cs, buffer); | |
1295 | - break; | |
1296 | - case FILE_MEMLIST: | |
1297 | - retval = update_nodemask(cs, buffer); | |
1298 | - break; | |
1299 | - default: | |
1300 | - retval = -EINVAL; | |
1301 | - goto out2; | |
1302 | - } | |
1303 | - | |
1304 | - if (retval == 0) | |
1305 | - retval = nbytes; | |
1306 | -out2: | |
1307 | - cgroup_unlock(); | |
1308 | -out1: | |
1309 | - kfree(buffer); | |
1310 | - return retval; | |
1311 | -} | |
1312 | - | |
1313 | 1253 | static int cpuset_write_u64(struct cgroup *cgrp, struct cftype *cft, u64 val) |
1314 | 1254 | { |
1315 | 1255 | int retval = 0; |
1316 | 1256 | struct cpuset *cs = cgroup_cs(cgrp); |
1317 | 1257 | cpuset_filetype_t type = cft->private; |
1318 | 1258 | |
1319 | - cgroup_lock(); | |
1320 | - | |
1321 | - if (cgroup_is_removed(cgrp)) { | |
1322 | - cgroup_unlock(); | |
1259 | + if (!cgroup_lock_live_group(cgrp)) | |
1323 | 1260 | return -ENODEV; |
1324 | - } | |
1325 | 1261 | |
1326 | 1262 | switch (type) { |
1327 | 1263 | case FILE_CPU_EXCLUSIVE: |
1328 | 1264 | |
... | ... | @@ -1367,12 +1303,9 @@ |
1367 | 1303 | struct cpuset *cs = cgroup_cs(cgrp); |
1368 | 1304 | cpuset_filetype_t type = cft->private; |
1369 | 1305 | |
1370 | - cgroup_lock(); | |
1371 | - | |
1372 | - if (cgroup_is_removed(cgrp)) { | |
1373 | - cgroup_unlock(); | |
1306 | + if (!cgroup_lock_live_group(cgrp)) | |
1374 | 1307 | return -ENODEV; |
1375 | - } | |
1308 | + | |
1376 | 1309 | switch (type) { |
1377 | 1310 | case FILE_SCHED_RELAX_DOMAIN_LEVEL: |
1378 | 1311 | retval = update_relax_domain_level(cs, val); |
... | ... | @@ -1386,6 +1319,32 @@ |
1386 | 1319 | } |
1387 | 1320 | |
1388 | 1321 | /* |
1322 | + * Common handling for a write to a "cpus" or "mems" file. | |
1323 | + */ | |
1324 | +static int cpuset_write_resmask(struct cgroup *cgrp, struct cftype *cft, | |
1325 | + const char *buf) | |
1326 | +{ | |
1327 | + int retval = 0; | |
1328 | + | |
1329 | + if (!cgroup_lock_live_group(cgrp)) | |
1330 | + return -ENODEV; | |
1331 | + | |
1332 | + switch (cft->private) { | |
1333 | + case FILE_CPULIST: | |
1334 | + retval = update_cpumask(cgroup_cs(cgrp), buf); | |
1335 | + break; | |
1336 | + case FILE_MEMLIST: | |
1337 | + retval = update_nodemask(cgroup_cs(cgrp), buf); | |
1338 | + break; | |
1339 | + default: | |
1340 | + retval = -EINVAL; | |
1341 | + break; | |
1342 | + } | |
1343 | + cgroup_unlock(); | |
1344 | + return retval; | |
1345 | +} | |
1346 | + | |
1347 | +/* | |
1389 | 1348 | * These ascii lists should be read in a single call, by using a user |
1390 | 1349 | * buffer large enough to hold the entire map. If read in smaller |
1391 | 1350 | * chunks, there is no guarantee of atomicity. Since the display format |
1392 | 1351 | |
... | ... | @@ -1504,14 +1463,16 @@ |
1504 | 1463 | { |
1505 | 1464 | .name = "cpus", |
1506 | 1465 | .read = cpuset_common_file_read, |
1507 | - .write = cpuset_common_file_write, | |
1466 | + .write_string = cpuset_write_resmask, | |
1467 | + .max_write_len = (100U + 6 * NR_CPUS), | |
1508 | 1468 | .private = FILE_CPULIST, |
1509 | 1469 | }, |
1510 | 1470 | |
1511 | 1471 | { |
1512 | 1472 | .name = "mems", |
1513 | 1473 | .read = cpuset_common_file_read, |
1514 | - .write = cpuset_common_file_write, | |
1474 | + .write_string = cpuset_write_resmask, | |
1475 | + .max_write_len = (100U + 6 * MAX_NUMNODES), | |
1515 | 1476 | .private = FILE_MEMLIST, |
1516 | 1477 | }, |
1517 | 1478 |