diff options
-rw-r--r-- | Documentation/cgroups.txt | 22 | ||||
-rw-r--r-- | kernel/cgroup.c | 36 |
2 files changed, 35 insertions, 23 deletions
diff --git a/Documentation/cgroups.txt b/Documentation/cgroups.txt index 98a26f81fa75..42d7c4cb39cd 100644 --- a/Documentation/cgroups.txt +++ b/Documentation/cgroups.txt | |||
@@ -456,7 +456,7 @@ methods are create/destroy. Any others that are null are presumed to | |||
456 | be successful no-ops. | 456 | be successful no-ops. |
457 | 457 | ||
458 | struct cgroup_subsys_state *create(struct cgroup *cont) | 458 | struct cgroup_subsys_state *create(struct cgroup *cont) |
459 | LL=cgroup_mutex | 459 | (cgroup_mutex held by caller) |
460 | 460 | ||
461 | Called to create a subsystem state object for a cgroup. The | 461 | Called to create a subsystem state object for a cgroup. The |
462 | subsystem should allocate its subsystem state object for the passed | 462 | subsystem should allocate its subsystem state object for the passed |
@@ -471,14 +471,19 @@ it's the root of the hierarchy) and may be an appropriate place for | |||
471 | initialization code. | 471 | initialization code. |
472 | 472 | ||
473 | void destroy(struct cgroup *cont) | 473 | void destroy(struct cgroup *cont) |
474 | LL=cgroup_mutex | 474 | (cgroup_mutex held by caller) |
475 | 475 | ||
476 | The cgroup system is about to destroy the passed cgroup; the | 476 | The cgroup system is about to destroy the passed cgroup; the subsystem |
477 | subsystem should do any necessary cleanup | 477 | should do any necessary cleanup and free its subsystem state |
478 | object. By the time this method is called, the cgroup has already been | ||
479 | unlinked from the file system and from the child list of its parent; | ||
480 | cgroup->parent is still valid. (Note - can also be called for a | ||
481 | newly-created cgroup if an error occurs after this subsystem's | ||
482 | create() method has been called for the new cgroup). | ||
478 | 483 | ||
479 | int can_attach(struct cgroup_subsys *ss, struct cgroup *cont, | 484 | int can_attach(struct cgroup_subsys *ss, struct cgroup *cont, |
480 | struct task_struct *task) | 485 | struct task_struct *task) |
481 | LL=cgroup_mutex | 486 | (cgroup_mutex held by caller) |
482 | 487 | ||
483 | Called prior to moving a task into a cgroup; if the subsystem | 488 | Called prior to moving a task into a cgroup; if the subsystem |
484 | returns an error, this will abort the attach operation. If a NULL | 489 | returns an error, this will abort the attach operation. If a NULL |
@@ -489,25 +494,20 @@ remain valid while the caller holds cgroup_mutex. | |||
489 | 494 | ||
490 | void attach(struct cgroup_subsys *ss, struct cgroup *cont, | 495 | void attach(struct cgroup_subsys *ss, struct cgroup *cont, |
491 | struct cgroup *old_cont, struct task_struct *task) | 496 | struct cgroup *old_cont, struct task_struct *task) |
492 | LL=cgroup_mutex | ||
493 | |||
494 | 497 | ||
495 | Called after the task has been attached to the cgroup, to allow any | 498 | Called after the task has been attached to the cgroup, to allow any |
496 | post-attachment activity that requires memory allocations or blocking. | 499 | post-attachment activity that requires memory allocations or blocking. |
497 | 500 | ||
498 | void fork(struct cgroup_subsy *ss, struct task_struct *task) | 501 | void fork(struct cgroup_subsy *ss, struct task_struct *task) |
499 | LL=callback_mutex, maybe read_lock(tasklist_lock) | ||
500 | 502 | ||
501 | Called when a task is forked into a cgroup. Also called during | 503 | Called when a task is forked into a cgroup. Also called during |
502 | registration for all existing tasks. | 504 | registration for all existing tasks. |
503 | 505 | ||
504 | void exit(struct cgroup_subsys *ss, struct task_struct *task) | 506 | void exit(struct cgroup_subsys *ss, struct task_struct *task) |
505 | LL=callback_mutex | ||
506 | 507 | ||
507 | Called during task exit | 508 | Called during task exit |
508 | 509 | ||
509 | int populate(struct cgroup_subsys *ss, struct cgroup *cont) | 510 | int populate(struct cgroup_subsys *ss, struct cgroup *cont) |
510 | LL=none | ||
511 | 511 | ||
512 | Called after creation of a cgroup to allow a subsystem to populate | 512 | Called after creation of a cgroup to allow a subsystem to populate |
513 | the cgroup directory with file entries. The subsystem should make | 513 | the cgroup directory with file entries. The subsystem should make |
@@ -524,7 +524,7 @@ example in cpusets, no task may attach before 'cpus' and 'mems' are set | |||
524 | up. | 524 | up. |
525 | 525 | ||
526 | void bind(struct cgroup_subsys *ss, struct cgroup *root) | 526 | void bind(struct cgroup_subsys *ss, struct cgroup *root) |
527 | LL=callback_mutex | 527 | (cgroup_mutex held by caller) |
528 | 528 | ||
529 | Called when a cgroup subsystem is rebound to a different hierarchy | 529 | Called when a cgroup subsystem is rebound to a different hierarchy |
530 | and root cgroup. Currently this will only involve movement between | 530 | and root cgroup. Currently this will only involve movement between |
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 7d207414f2c7..b0fee0c61445 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -591,6 +591,7 @@ static void cgroup_diput(struct dentry *dentry, struct inode *inode) | |||
591 | /* is dentry a directory ? if so, kfree() associated cgroup */ | 591 | /* is dentry a directory ? if so, kfree() associated cgroup */ |
592 | if (S_ISDIR(inode->i_mode)) { | 592 | if (S_ISDIR(inode->i_mode)) { |
593 | struct cgroup *cgrp = dentry->d_fsdata; | 593 | struct cgroup *cgrp = dentry->d_fsdata; |
594 | struct cgroup_subsys *ss; | ||
594 | BUG_ON(!(cgroup_is_removed(cgrp))); | 595 | BUG_ON(!(cgroup_is_removed(cgrp))); |
595 | /* It's possible for external users to be holding css | 596 | /* It's possible for external users to be holding css |
596 | * reference counts on a cgroup; css_put() needs to | 597 | * reference counts on a cgroup; css_put() needs to |
@@ -599,6 +600,23 @@ static void cgroup_diput(struct dentry *dentry, struct inode *inode) | |||
599 | * queue the cgroup to be handled by the release | 600 | * queue the cgroup to be handled by the release |
600 | * agent */ | 601 | * agent */ |
601 | synchronize_rcu(); | 602 | synchronize_rcu(); |
603 | |||
604 | mutex_lock(&cgroup_mutex); | ||
605 | /* | ||
606 | * Release the subsystem state objects. | ||
607 | */ | ||
608 | for_each_subsys(cgrp->root, ss) { | ||
609 | if (cgrp->subsys[ss->subsys_id]) | ||
610 | ss->destroy(ss, cgrp); | ||
611 | } | ||
612 | |||
613 | cgrp->root->number_of_cgroups--; | ||
614 | mutex_unlock(&cgroup_mutex); | ||
615 | |||
616 | /* Drop the active superblock reference that we took when we | ||
617 | * created the cgroup */ | ||
618 | deactivate_super(cgrp->root->sb); | ||
619 | |||
602 | kfree(cgrp); | 620 | kfree(cgrp); |
603 | } | 621 | } |
604 | iput(inode); | 622 | iput(inode); |
@@ -1330,6 +1348,10 @@ static ssize_t cgroup_common_file_write(struct cgroup *cgrp, | |||
1330 | 1348 | ||
1331 | mutex_lock(&cgroup_mutex); | 1349 | mutex_lock(&cgroup_mutex); |
1332 | 1350 | ||
1351 | /* | ||
1352 | * This was already checked for in cgroup_file_write(), but | ||
1353 | * check again now we're holding cgroup_mutex. | ||
1354 | */ | ||
1333 | if (cgroup_is_removed(cgrp)) { | 1355 | if (cgroup_is_removed(cgrp)) { |
1334 | retval = -ENODEV; | 1356 | retval = -ENODEV; |
1335 | goto out2; | 1357 | goto out2; |
@@ -1370,7 +1392,7 @@ static ssize_t cgroup_file_write(struct file *file, const char __user *buf, | |||
1370 | struct cftype *cft = __d_cft(file->f_dentry); | 1392 | struct cftype *cft = __d_cft(file->f_dentry); |
1371 | struct cgroup *cgrp = __d_cgrp(file->f_dentry->d_parent); | 1393 | struct cgroup *cgrp = __d_cgrp(file->f_dentry->d_parent); |
1372 | 1394 | ||
1373 | if (!cft) | 1395 | if (!cft || cgroup_is_removed(cgrp)) |
1374 | return -ENODEV; | 1396 | return -ENODEV; |
1375 | if (cft->write) | 1397 | if (cft->write) |
1376 | return cft->write(cgrp, cft, file, buf, nbytes, ppos); | 1398 | return cft->write(cgrp, cft, file, buf, nbytes, ppos); |
@@ -1440,7 +1462,7 @@ static ssize_t cgroup_file_read(struct file *file, char __user *buf, | |||
1440 | struct cftype *cft = __d_cft(file->f_dentry); | 1462 | struct cftype *cft = __d_cft(file->f_dentry); |
1441 | struct cgroup *cgrp = __d_cgrp(file->f_dentry->d_parent); | 1463 | struct cgroup *cgrp = __d_cgrp(file->f_dentry->d_parent); |
1442 | 1464 | ||
1443 | if (!cft) | 1465 | if (!cft || cgroup_is_removed(cgrp)) |
1444 | return -ENODEV; | 1466 | return -ENODEV; |
1445 | 1467 | ||
1446 | if (cft->read) | 1468 | if (cft->read) |
@@ -2120,7 +2142,6 @@ static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry) | |||
2120 | struct cgroup *cgrp = dentry->d_fsdata; | 2142 | struct cgroup *cgrp = dentry->d_fsdata; |
2121 | struct dentry *d; | 2143 | struct dentry *d; |
2122 | struct cgroup *parent; | 2144 | struct cgroup *parent; |
2123 | struct cgroup_subsys *ss; | ||
2124 | struct super_block *sb; | 2145 | struct super_block *sb; |
2125 | struct cgroupfs_root *root; | 2146 | struct cgroupfs_root *root; |
2126 | 2147 | ||
@@ -2145,11 +2166,6 @@ static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry) | |||
2145 | return -EBUSY; | 2166 | return -EBUSY; |
2146 | } | 2167 | } |
2147 | 2168 | ||
2148 | for_each_subsys(root, ss) { | ||
2149 | if (cgrp->subsys[ss->subsys_id]) | ||
2150 | ss->destroy(ss, cgrp); | ||
2151 | } | ||
2152 | |||
2153 | spin_lock(&release_list_lock); | 2169 | spin_lock(&release_list_lock); |
2154 | set_bit(CGRP_REMOVED, &cgrp->flags); | 2170 | set_bit(CGRP_REMOVED, &cgrp->flags); |
2155 | if (!list_empty(&cgrp->release_list)) | 2171 | if (!list_empty(&cgrp->release_list)) |
@@ -2164,15 +2180,11 @@ static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry) | |||
2164 | 2180 | ||
2165 | cgroup_d_remove_dir(d); | 2181 | cgroup_d_remove_dir(d); |
2166 | dput(d); | 2182 | dput(d); |
2167 | root->number_of_cgroups--; | ||
2168 | 2183 | ||
2169 | set_bit(CGRP_RELEASABLE, &parent->flags); | 2184 | set_bit(CGRP_RELEASABLE, &parent->flags); |
2170 | check_for_release(parent); | 2185 | check_for_release(parent); |
2171 | 2186 | ||
2172 | mutex_unlock(&cgroup_mutex); | 2187 | mutex_unlock(&cgroup_mutex); |
2173 | /* Drop the active superblock reference that we took when we | ||
2174 | * created the cgroup */ | ||
2175 | deactivate_super(sb); | ||
2176 | return 0; | 2188 | return 0; |
2177 | } | 2189 | } |
2178 | 2190 | ||