Commit e73d2c61d1fcbd3621688ae457b49509c8d4c601

Authored by Paul Menage
Committed by Linus Torvalds
1 parent 418d7d875c

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 };
... ... @@ -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