Hello Tejun, Is it safe for us to task_get_css() every task in the tset in ->can_attach() and then put_css() in ->attach() and ->cancel_attach()? In other words: if we have a ref to a task's css, are we guaranteed that the task_css() will return the same thing every time? Here's what I'm currently doing: static int pids_can_attach(struct cgroup_subsys_state *css, struct cgroup_taskset *tset) { struct pids_cgroup *pids = css_pids(css); struct task_struct *task, *fail_task; int err; cgroup_taskset_for_each(task, tset) { struct cgroup_subsys_state *old_css; struct pids_cgroup *old_pids; old_css = task_get_css(task, pids_cgrp_id); old_pids = css_pids(old_css); err = pids_try_charge(pids, 1); if (err) goto out_fail; pids_uncharge(old_pids, 1); continue; out_fail: fail_task = task; goto err_revert; } return 0; err_revert: cgroup_taskset_for_each(task, tset) { css_put(task_css(task, pids_cgrp_id)); if (task == fail_task) break; pids_uncharge(pids, 1); } return err; } static void pids_cancel_attach(struct cgroup_subsys_state *css, struct cgroup_taskset *tset) { struct pids_cgroup *pids = css_pids(css); struct task_struct *task; cgroup_taskset_for_each(task, tset) { struct cgroup_subsys_state *old_css; struct pids_cgroup *old_pids; old_css = task_css(task, pids_cgrp_id); old_pids = css_pids(old_css); pids_charge(old_pids, 1); pids_uncharge(pids, 1); css_put(old_css); } } static void pids_attach(struct cgroup_subsys_state *css, struct cgroup_taskset *tset) { struct task_struct *task; cgroup_taskset_for_each(task, tset) css_put(task_css(task, pids_cgrp_id)); } -- Aleksa Sarai (cyphar) www.cyphar.com -- To unsubscribe from this list: send the line "unsubscribe cgroups" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html