Commit e73d2c61d1fcbd3621688ae457b49509c8d4c601
Committed by
Linus Torvalds
1 parent
418d7d875c
Exists in
master
and in
4 other branches
CGroups _s64 files: add cgroups read_s64/write_s64 file methods
These patches add cgroups read_s64 and write_s64 control file methods (the signed equivalent of read_u64/write_u64) and use them to implement the cpu.rt_runtime_us control file in the CFS cgroup subsystem. This patch: These are the signed equivalents of the read_u64/write_u64 methods Signed-off-by: Paul Menage <menage@google.com> Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Ingo Molnar <mingo@elte.hu> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 2 changed files with 36 additions and 10 deletions Side-by-side Diff
include/linux/cgroup.h
... | ... | @@ -216,6 +216,10 @@ |
216 | 216 | */ |
217 | 217 | u64 (*read_u64) (struct cgroup *cgrp, struct cftype *cft); |
218 | 218 | /* |
219 | + * read_s64() is a signed version of read_u64() | |
220 | + */ | |
221 | + s64 (*read_s64) (struct cgroup *cgrp, struct cftype *cft); | |
222 | + /* | |
219 | 223 | * read_map() is used for defining a map of key/value |
220 | 224 | * pairs. It should call cb->fill(cb, key, value) for each |
221 | 225 | * entry. The key/value pairs (and their ordering) should not |
... | ... | @@ -234,6 +238,10 @@ |
234 | 238 | * userspace. Use in place of write(); return 0 or error. |
235 | 239 | */ |
236 | 240 | int (*write_u64) (struct cgroup *cgrp, struct cftype *cft, u64 val); |
241 | + /* | |
242 | + * write_s64() is a signed version of write_u64() | |
243 | + */ | |
244 | + int (*write_s64) (struct cgroup *cgrp, struct cftype *cft, s64 val); | |
237 | 245 | |
238 | 246 | int (*release) (struct inode *inode, struct file *file); |
239 | 247 | }; |
kernel/cgroup.c
... | ... | @@ -1299,14 +1299,13 @@ |
1299 | 1299 | FILE_RELEASE_AGENT, |
1300 | 1300 | }; |
1301 | 1301 | |
1302 | -static ssize_t cgroup_write_u64(struct cgroup *cgrp, struct cftype *cft, | |
1302 | +static ssize_t cgroup_write_X64(struct cgroup *cgrp, struct cftype *cft, | |
1303 | 1303 | struct file *file, |
1304 | 1304 | const char __user *userbuf, |
1305 | 1305 | size_t nbytes, loff_t *unused_ppos) |
1306 | 1306 | { |
1307 | 1307 | char buffer[64]; |
1308 | 1308 | int retval = 0; |
1309 | - u64 val; | |
1310 | 1309 | char *end; |
1311 | 1310 | |
1312 | 1311 | if (!nbytes) |
... | ... | @@ -1318,12 +1317,17 @@ |
1318 | 1317 | |
1319 | 1318 | buffer[nbytes] = 0; /* nul-terminate */ |
1320 | 1319 | strstrip(buffer); |
1321 | - val = simple_strtoull(buffer, &end, 0); | |
1322 | - if (*end) | |
1323 | - return -EINVAL; | |
1324 | - | |
1325 | - /* Pass to subsystem */ | |
1326 | - retval = cft->write_u64(cgrp, cft, val); | |
1320 | + if (cft->write_u64) { | |
1321 | + u64 val = simple_strtoull(buffer, &end, 0); | |
1322 | + if (*end) | |
1323 | + return -EINVAL; | |
1324 | + retval = cft->write_u64(cgrp, cft, val); | |
1325 | + } else { | |
1326 | + s64 val = simple_strtoll(buffer, &end, 0); | |
1327 | + if (*end) | |
1328 | + return -EINVAL; | |
1329 | + retval = cft->write_s64(cgrp, cft, val); | |
1330 | + } | |
1327 | 1331 | if (!retval) |
1328 | 1332 | retval = nbytes; |
1329 | 1333 | return retval; |
... | ... | @@ -1404,8 +1408,8 @@ |
1404 | 1408 | return -ENODEV; |
1405 | 1409 | if (cft->write) |
1406 | 1410 | return cft->write(cgrp, cft, file, buf, nbytes, ppos); |
1407 | - if (cft->write_u64) | |
1408 | - return cgroup_write_u64(cgrp, cft, file, buf, nbytes, ppos); | |
1411 | + if (cft->write_u64 || cft->write_s64) | |
1412 | + return cgroup_write_X64(cgrp, cft, file, buf, nbytes, ppos); | |
1409 | 1413 | return -EINVAL; |
1410 | 1414 | } |
1411 | 1415 | |
... | ... | @@ -1421,6 +1425,18 @@ |
1421 | 1425 | return simple_read_from_buffer(buf, nbytes, ppos, tmp, len); |
1422 | 1426 | } |
1423 | 1427 | |
1428 | +static ssize_t cgroup_read_s64(struct cgroup *cgrp, struct cftype *cft, | |
1429 | + struct file *file, | |
1430 | + char __user *buf, size_t nbytes, | |
1431 | + loff_t *ppos) | |
1432 | +{ | |
1433 | + char tmp[64]; | |
1434 | + s64 val = cft->read_s64(cgrp, cft); | |
1435 | + int len = sprintf(tmp, "%lld\n", (long long) val); | |
1436 | + | |
1437 | + return simple_read_from_buffer(buf, nbytes, ppos, tmp, len); | |
1438 | +} | |
1439 | + | |
1424 | 1440 | static ssize_t cgroup_common_file_read(struct cgroup *cgrp, |
1425 | 1441 | struct cftype *cft, |
1426 | 1442 | struct file *file, |
... | ... | @@ -1477,6 +1493,8 @@ |
1477 | 1493 | return cft->read(cgrp, cft, file, buf, nbytes, ppos); |
1478 | 1494 | if (cft->read_u64) |
1479 | 1495 | return cgroup_read_u64(cgrp, cft, file, buf, nbytes, ppos); |
1496 | + if (cft->read_s64) | |
1497 | + return cgroup_read_s64(cgrp, cft, file, buf, nbytes, ppos); | |
1480 | 1498 | return -EINVAL; |
1481 | 1499 | } |
1482 | 1500 |