aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cgroup.c
diff options
context:
space:
mode:
authorPaul Menage <menage@google.com>2008-07-25 04:47:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-25 13:53:36 -0400
commitaf351026aafc8da16518a02b41c66d3e0c1cdef4 (patch)
treef294376157f2e1c91f5a4b6ff90b4183dc6f7969 /kernel/cgroup.c
parent6379c106152388f7ea45d6dda63edda0e9181fc8 (diff)
cgroup files: turn attach_task_by_pid directly into a cgroup write handler
This patch changes attach_task_by_pid() to take a u64 rather than a string; as a result it can be called directly as a control groups write_u64 handler, and cgroup_common_file_write() can 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>
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r--kernel/cgroup.c80
1 files changed, 14 insertions, 66 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index d597d3015786..86b71e714e13 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -504,10 +504,6 @@ static struct css_set *find_css_set(
504 * knows that the cgroup won't be removed, as cgroup_rmdir() 504 * knows that the cgroup won't be removed, as cgroup_rmdir()
505 * needs that mutex. 505 * needs that mutex.
506 * 506 *
507 * The cgroup_common_file_write handler for operations that modify
508 * the cgroup hierarchy holds cgroup_mutex across the entire operation,
509 * single threading all such cgroup modifications across the system.
510 *
511 * The fork and exit callbacks cgroup_fork() and cgroup_exit(), don't 507 * The fork and exit callbacks cgroup_fork() and cgroup_exit(), don't
512 * (usually) take cgroup_mutex. These are the two most performance 508 * (usually) take cgroup_mutex. These are the two most performance
513 * critical pieces of code here. The exception occurs on cgroup_exit(), 509 * critical pieces of code here. The exception occurs on cgroup_exit(),
@@ -1279,18 +1275,14 @@ int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
1279} 1275}
1280 1276
1281/* 1277/*
1282 * Attach task with pid 'pid' to cgroup 'cgrp'. Call with 1278 * Attach task with pid 'pid' to cgroup 'cgrp'. Call with cgroup_mutex
1283 * cgroup_mutex, may take task_lock of task 1279 * held. May take task_lock of task
1284 */ 1280 */
1285static int attach_task_by_pid(struct cgroup *cgrp, char *pidbuf) 1281static int attach_task_by_pid(struct cgroup *cgrp, u64 pid)
1286{ 1282{
1287 pid_t pid;
1288 struct task_struct *tsk; 1283 struct task_struct *tsk;
1289 int ret; 1284 int ret;
1290 1285
1291 if (sscanf(pidbuf, "%d", &pid) != 1)
1292 return -EIO;
1293
1294 if (pid) { 1286 if (pid) {
1295 rcu_read_lock(); 1287 rcu_read_lock();
1296 tsk = find_task_by_vpid(pid); 1288 tsk = find_task_by_vpid(pid);
@@ -1316,6 +1308,16 @@ static int attach_task_by_pid(struct cgroup *cgrp, char *pidbuf)
1316 return ret; 1308 return ret;
1317} 1309}
1318 1310
1311static int cgroup_tasks_write(struct cgroup *cgrp, struct cftype *cft, u64 pid)
1312{
1313 int ret;
1314 if (!cgroup_lock_live_group(cgrp))
1315 return -ENODEV;
1316 ret = attach_task_by_pid(cgrp, pid);
1317 cgroup_unlock();
1318 return ret;
1319}
1320
1319/* The various types of files and directories in a cgroup file system */ 1321/* The various types of files and directories in a cgroup file system */
1320enum cgroup_filetype { 1322enum cgroup_filetype {
1321 FILE_ROOT, 1323 FILE_ROOT,
@@ -1434,60 +1436,6 @@ static ssize_t cgroup_write_string(struct cgroup *cgrp, struct cftype *cft,
1434 return retval; 1436 return retval;
1435} 1437}
1436 1438
1437static ssize_t cgroup_common_file_write(struct cgroup *cgrp,
1438 struct cftype *cft,
1439 struct file *file,
1440 const char __user *userbuf,
1441 size_t nbytes, loff_t *unused_ppos)
1442{
1443 enum cgroup_filetype type = cft->private;
1444 char *buffer;
1445 int retval = 0;
1446
1447 if (nbytes >= PATH_MAX)
1448 return -E2BIG;
1449
1450 /* +1 for nul-terminator */
1451 buffer = kmalloc(nbytes + 1, GFP_KERNEL);
1452 if (buffer == NULL)
1453 return -ENOMEM;
1454
1455 if (copy_from_user(buffer, userbuf, nbytes)) {
1456 retval = -EFAULT;
1457 goto out1;
1458 }
1459 buffer[nbytes] = 0; /* nul-terminate */
1460 strstrip(buffer); /* strip -just- trailing whitespace */
1461
1462 mutex_lock(&cgroup_mutex);
1463
1464 /*
1465 * This was already checked for in cgroup_file_write(), but
1466 * check again now we're holding cgroup_mutex.
1467 */
1468 if (cgroup_is_removed(cgrp)) {
1469 retval = -ENODEV;
1470 goto out2;
1471 }
1472
1473 switch (type) {
1474 case FILE_TASKLIST:
1475 retval = attach_task_by_pid(cgrp, buffer);
1476 break;
1477 default:
1478 retval = -EINVAL;
1479 goto out2;
1480 }
1481
1482 if (retval == 0)
1483 retval = nbytes;
1484out2:
1485 mutex_unlock(&cgroup_mutex);
1486out1:
1487 kfree(buffer);
1488 return retval;
1489}
1490
1491static ssize_t cgroup_file_write(struct file *file, const char __user *buf, 1439static ssize_t cgroup_file_write(struct file *file, const char __user *buf,
1492 size_t nbytes, loff_t *ppos) 1440 size_t nbytes, loff_t *ppos)
1493{ 1441{
@@ -2265,7 +2213,7 @@ static struct cftype files[] = {
2265 .name = "tasks", 2213 .name = "tasks",
2266 .open = cgroup_tasks_open, 2214 .open = cgroup_tasks_open,
2267 .read = cgroup_tasks_read, 2215 .read = cgroup_tasks_read,
2268 .write = cgroup_common_file_write, 2216 .write_u64 = cgroup_tasks_write,
2269 .release = cgroup_tasks_release, 2217 .release = cgroup_tasks_release,
2270 .private = FILE_TASKLIST, 2218 .private = FILE_TASKLIST,
2271 }, 2219 },