|
@@ -277,6 +277,10 @@ static struct cgroup_subsys_state *cgroup_e_css(struct cgroup *cgrp,
|
|
|
if (!(cgrp->root->subsys_mask & (1 << ss->id)))
|
|
|
return NULL;
|
|
|
|
|
|
+ /*
|
|
|
+ * This function is used while updating css associations and thus
|
|
|
+ * can't test the csses directly. Use ->child_subsys_mask.
|
|
|
+ */
|
|
|
while (cgroup_parent(cgrp) &&
|
|
|
!(cgroup_parent(cgrp)->child_subsys_mask & (1 << ss->id)))
|
|
|
cgrp = cgroup_parent(cgrp);
|
|
@@ -284,6 +288,39 @@ static struct cgroup_subsys_state *cgroup_e_css(struct cgroup *cgrp,
|
|
|
return cgroup_css(cgrp, ss);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * cgroup_get_e_css - get a cgroup's effective css for the specified subsystem
|
|
|
+ * @cgrp: the cgroup of interest
|
|
|
+ * @ss: the subsystem of interest
|
|
|
+ *
|
|
|
+ * Find and get the effective css of @cgrp for @ss. The effective css is
|
|
|
+ * defined as the matching css of the nearest ancestor including self which
|
|
|
+ * has @ss enabled. If @ss is not mounted on the hierarchy @cgrp is on,
|
|
|
+ * the root css is returned, so this function always returns a valid css.
|
|
|
+ * The returned css must be put using css_put().
|
|
|
+ */
|
|
|
+struct cgroup_subsys_state *cgroup_get_e_css(struct cgroup *cgrp,
|
|
|
+ struct cgroup_subsys *ss)
|
|
|
+{
|
|
|
+ struct cgroup_subsys_state *css;
|
|
|
+
|
|
|
+ rcu_read_lock();
|
|
|
+
|
|
|
+ do {
|
|
|
+ css = cgroup_css(cgrp, ss);
|
|
|
+
|
|
|
+ if (css && css_tryget_online(css))
|
|
|
+ goto out_unlock;
|
|
|
+ cgrp = cgroup_parent(cgrp);
|
|
|
+ } while (cgrp);
|
|
|
+
|
|
|
+ css = init_css_set.subsys[ss->id];
|
|
|
+ css_get(css);
|
|
|
+out_unlock:
|
|
|
+ rcu_read_unlock();
|
|
|
+ return css;
|
|
|
+}
|
|
|
+
|
|
|
/* convenient tests for these bits */
|
|
|
static inline bool cgroup_is_dead(const struct cgroup *cgrp)
|
|
|
{
|