diff options
author | Paul Menage <menage@google.com> | 2008-05-06 23:42:41 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-05-08 13:46:56 -0400 |
commit | 5be7a4792a31df6f2cd44bfba8da467ea20a0642 (patch) | |
tree | 87ec7f4f59f52a729ab21aa6d6bf3d3e6cad9474 | |
parent | 4ea33e2dc2dab10960877e1649ee527c033f42c0 (diff) |
Fix cpuset sched_relax_domain_level control file
Due to a merge conflict, the sched_relax_domain_level control file was marked
as being handled by cpuset_read/write_u64, but the code to handle it was
actually in cpuset_common_file_read/write.
Since the value being written/read is in fact a signed integer, it should be
treated as such; this patch adds cpuset_read/write_s64 functions, and uses
them to handle the sched_relax_domain_level file.
With this patch, the sched_relax_domain_level can be read and written, and the
correct contents seen/updated.
Signed-off-by: Paul Menage <menage@google.com>
Cc: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Cc: Paul Jackson <pj@sgi.com>
Cc: Ingo Molnar <mingo@elte.hu>
Reviewed-by: Li Zefan <lizf@cn.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | kernel/cpuset.c | 52 |
1 files changed, 40 insertions, 12 deletions
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 8da627d33804..86ea9e34e326 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
@@ -1031,11 +1031,9 @@ int current_cpuset_is_being_rebound(void) | |||
1031 | return task_cs(current) == cpuset_being_rebound; | 1031 | return task_cs(current) == cpuset_being_rebound; |
1032 | } | 1032 | } |
1033 | 1033 | ||
1034 | static int update_relax_domain_level(struct cpuset *cs, char *buf) | 1034 | static int update_relax_domain_level(struct cpuset *cs, s64 val) |
1035 | { | 1035 | { |
1036 | int val = simple_strtol(buf, NULL, 10); | 1036 | if ((int)val < 0) |
1037 | |||
1038 | if (val < 0) | ||
1039 | val = -1; | 1037 | val = -1; |
1040 | 1038 | ||
1041 | if (val != cs->relax_domain_level) { | 1039 | if (val != cs->relax_domain_level) { |
@@ -1280,9 +1278,6 @@ static ssize_t cpuset_common_file_write(struct cgroup *cont, | |||
1280 | case FILE_MEMLIST: | 1278 | case FILE_MEMLIST: |
1281 | retval = update_nodemask(cs, buffer); | 1279 | retval = update_nodemask(cs, buffer); |
1282 | break; | 1280 | break; |
1283 | case FILE_SCHED_RELAX_DOMAIN_LEVEL: | ||
1284 | retval = update_relax_domain_level(cs, buffer); | ||
1285 | break; | ||
1286 | default: | 1281 | default: |
1287 | retval = -EINVAL; | 1282 | retval = -EINVAL; |
1288 | goto out2; | 1283 | goto out2; |
@@ -1348,6 +1343,30 @@ static int cpuset_write_u64(struct cgroup *cgrp, struct cftype *cft, u64 val) | |||
1348 | return retval; | 1343 | return retval; |
1349 | } | 1344 | } |
1350 | 1345 | ||
1346 | static int cpuset_write_s64(struct cgroup *cgrp, struct cftype *cft, s64 val) | ||
1347 | { | ||
1348 | int retval = 0; | ||
1349 | struct cpuset *cs = cgroup_cs(cgrp); | ||
1350 | cpuset_filetype_t type = cft->private; | ||
1351 | |||
1352 | cgroup_lock(); | ||
1353 | |||
1354 | if (cgroup_is_removed(cgrp)) { | ||
1355 | cgroup_unlock(); | ||
1356 | return -ENODEV; | ||
1357 | } | ||
1358 | switch (type) { | ||
1359 | case FILE_SCHED_RELAX_DOMAIN_LEVEL: | ||
1360 | retval = update_relax_domain_level(cs, val); | ||
1361 | break; | ||
1362 | default: | ||
1363 | retval = -EINVAL; | ||
1364 | break; | ||
1365 | } | ||
1366 | cgroup_unlock(); | ||
1367 | return retval; | ||
1368 | } | ||
1369 | |||
1351 | /* | 1370 | /* |
1352 | * These ascii lists should be read in a single call, by using a user | 1371 | * These ascii lists should be read in a single call, by using a user |
1353 | * buffer large enough to hold the entire map. If read in smaller | 1372 | * buffer large enough to hold the entire map. If read in smaller |
@@ -1406,9 +1425,6 @@ static ssize_t cpuset_common_file_read(struct cgroup *cont, | |||
1406 | case FILE_MEMLIST: | 1425 | case FILE_MEMLIST: |
1407 | s += cpuset_sprintf_memlist(s, cs); | 1426 | s += cpuset_sprintf_memlist(s, cs); |
1408 | break; | 1427 | break; |
1409 | case FILE_SCHED_RELAX_DOMAIN_LEVEL: | ||
1410 | s += sprintf(s, "%d", cs->relax_domain_level); | ||
1411 | break; | ||
1412 | default: | 1428 | default: |
1413 | retval = -EINVAL; | 1429 | retval = -EINVAL; |
1414 | goto out; | 1430 | goto out; |
@@ -1449,6 +1465,18 @@ static u64 cpuset_read_u64(struct cgroup *cont, struct cftype *cft) | |||
1449 | } | 1465 | } |
1450 | } | 1466 | } |
1451 | 1467 | ||
1468 | static s64 cpuset_read_s64(struct cgroup *cont, struct cftype *cft) | ||
1469 | { | ||
1470 | struct cpuset *cs = cgroup_cs(cont); | ||
1471 | cpuset_filetype_t type = cft->private; | ||
1472 | switch (type) { | ||
1473 | case FILE_SCHED_RELAX_DOMAIN_LEVEL: | ||
1474 | return cs->relax_domain_level; | ||
1475 | default: | ||
1476 | BUG(); | ||
1477 | } | ||
1478 | } | ||
1479 | |||
1452 | 1480 | ||
1453 | /* | 1481 | /* |
1454 | * for the common functions, 'private' gives the type of file | 1482 | * for the common functions, 'private' gives the type of file |
@@ -1499,8 +1527,8 @@ static struct cftype files[] = { | |||
1499 | 1527 | ||
1500 | { | 1528 | { |
1501 | .name = "sched_relax_domain_level", | 1529 | .name = "sched_relax_domain_level", |
1502 | .read_u64 = cpuset_read_u64, | 1530 | .read_s64 = cpuset_read_s64, |
1503 | .write_u64 = cpuset_write_u64, | 1531 | .write_s64 = cpuset_write_s64, |
1504 | .private = FILE_SCHED_RELAX_DOMAIN_LEVEL, | 1532 | .private = FILE_SCHED_RELAX_DOMAIN_LEVEL, |
1505 | }, | 1533 | }, |
1506 | 1534 | ||