aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Menage <menage@google.com>2008-02-07 03:13:45 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-07 11:42:18 -0500
commit8dc4f3e17dd5f7e59ce568155ccd8974af879315 (patch)
tree959b1197fea798c9daae4dd6c9596ab710d41fda
parent622d42cac9ed42098aa50c53994f625abfa3d473 (diff)
cgroups: move cgroups destroy() callbacks to cgroup_diput()
Move the calls to the cgroup subsystem destroy() methods from cgroup_rmdir() to cgroup_diput(). This allows control file reads and writes to access their subsystem state without having to be concerned with locking against cgroup destruction - the control file dentry will keep the cgroup and its subsystem state objects alive until the file is closed. The documentation is updated to reflect the changed semantics of destroy(); additionally the locking comments for destroy() and some other methods were clarified and decrustified. Signed-off-by: Paul Menage <menage@google.com> Cc: Paul Jackson <pj@sgi.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--Documentation/cgroups.txt22
-rw-r--r--kernel/cgroup.c36
2 files changed, 35 insertions, 23 deletions
diff --git a/Documentation/cgroups.txt b/Documentation/cgroups.txt
index 98a26f81fa7..42d7c4cb39c 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
456be successful no-ops. 456be successful no-ops.
457 457
458struct cgroup_subsys_state *create(struct cgroup *cont) 458struct cgroup_subsys_state *create(struct cgroup *cont)
459LL=cgroup_mutex 459(cgroup_mutex held by caller)
460 460
461Called to create a subsystem state object for a cgroup. The 461Called to create a subsystem state object for a cgroup. The
462subsystem should allocate its subsystem state object for the passed 462subsystem 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
471initialization code. 471initialization code.
472 472
473void destroy(struct cgroup *cont) 473void destroy(struct cgroup *cont)
474LL=cgroup_mutex 474(cgroup_mutex held by caller)
475 475
476The cgroup system is about to destroy the passed cgroup; the 476The cgroup system is about to destroy the passed cgroup; the subsystem
477subsystem should do any necessary cleanup 477should do any necessary cleanup and free its subsystem state
478object. By the time this method is called, the cgroup has already been
479unlinked from the file system and from the child list of its parent;
480cgroup->parent is still valid. (Note - can also be called for a
481newly-created cgroup if an error occurs after this subsystem's
482create() method has been called for the new cgroup).
478 483
479int can_attach(struct cgroup_subsys *ss, struct cgroup *cont, 484int can_attach(struct cgroup_subsys *ss, struct cgroup *cont,
480 struct task_struct *task) 485 struct task_struct *task)
481LL=cgroup_mutex 486(cgroup_mutex held by caller)
482 487
483Called prior to moving a task into a cgroup; if the subsystem 488Called prior to moving a task into a cgroup; if the subsystem
484returns an error, this will abort the attach operation. If a NULL 489returns 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
490void attach(struct cgroup_subsys *ss, struct cgroup *cont, 495void 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)
492LL=cgroup_mutex
493
494 497
495Called after the task has been attached to the cgroup, to allow any 498Called after the task has been attached to the cgroup, to allow any
496post-attachment activity that requires memory allocations or blocking. 499post-attachment activity that requires memory allocations or blocking.
497 500
498void fork(struct cgroup_subsy *ss, struct task_struct *task) 501void fork(struct cgroup_subsy *ss, struct task_struct *task)
499LL=callback_mutex, maybe read_lock(tasklist_lock)
500 502
501Called when a task is forked into a cgroup. Also called during 503Called when a task is forked into a cgroup. Also called during
502registration for all existing tasks. 504registration for all existing tasks.
503 505
504void exit(struct cgroup_subsys *ss, struct task_struct *task) 506void exit(struct cgroup_subsys *ss, struct task_struct *task)
505LL=callback_mutex
506 507
507Called during task exit 508Called during task exit
508 509
509int populate(struct cgroup_subsys *ss, struct cgroup *cont) 510int populate(struct cgroup_subsys *ss, struct cgroup *cont)
510LL=none
511 511
512Called after creation of a cgroup to allow a subsystem to populate 512Called after creation of a cgroup to allow a subsystem to populate
513the cgroup directory with file entries. The subsystem should make 513the 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
524up. 524up.
525 525
526void bind(struct cgroup_subsys *ss, struct cgroup *root) 526void bind(struct cgroup_subsys *ss, struct cgroup *root)
527LL=callback_mutex 527(cgroup_mutex held by caller)
528 528
529Called when a cgroup subsystem is rebound to a different hierarchy 529Called when a cgroup subsystem is rebound to a different hierarchy
530and root cgroup. Currently this will only involve movement between 530and root cgroup. Currently this will only involve movement between
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 7d207414f2c..b0fee0c6144 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