From: Frederic Weisbecker <fweisbec@gmail.com>
To: Oleg Nesterov <oleg@redhat.com>
Cc: LKML <linux-kernel@vger.kernel.org>,
Andrew Morton <akpm@linux-foundation.org>,
Paul Menage <menage@google.com>, Li Zefan <lizf@cn.fujitsu.com>,
Johannes Weiner <hannes@cmpxchg.org>,
Aditya Kali <adityakali@google.com>
Subject: Re: [PATCH 7/8] cgroups: Add a task counter subsystem
Date: Tue, 9 Aug 2011 19:27:50 +0200 [thread overview]
Message-ID: <20110809172746.GA31645@somewhere.redhat.com> (raw)
In-Reply-To: <20110809151155.GA15311@redhat.com>
On Tue, Aug 09, 2011 at 05:11:55PM +0200, Oleg Nesterov wrote:
> On 07/29, Frederic Weisbecker wrote:
> >
> > +static int task_counter_can_attach_task(struct cgroup *cgrp, struct cgroup *old_cgrp,
> > + struct task_struct *tsk)
> > +{
> > + struct res_counter *res = cgroup_task_counter_res(cgrp);
> > + struct res_counter *old_res = cgroup_task_counter_res(old_cgrp);
> > + struct res_counter *limit_fail_at;
> > +
> > + common_ancestor = res_counter_common_ancestor(res, old_res);
> > +
> > + return res_counter_charge_until(res, common_ancestor, 1, &limit_fail_at);
> > +}
> >
> > ...
> >
> > +static void task_counter_attach_task(struct cgroup *cgrp, struct cgroup *old_cgrp,
> > + struct task_struct *tsk)
> > +{
> > + res_counter_uncharge_until(cgroup_task_counter_res(old_cgrp), common_ancestor, 1);
> > +}
>
> This doesn't look right or I missed something.
>
> What if tsk exits in between? Afaics this can happen with both
> cgroup_attach_task() and cgroup_attach_proc().
>
> Let's look at cgroup_attach_task(). Suppose that
> task_counter_can_attach_task() succeeds and charges the new cgrp,
> Then cgroup_task_migrate() returns -ESRCH. Who will uncharge the
> new cgrp?
>
I may totally be missing something but that looks safe to me.
If the task has exited then cgroup_task_migrate() fails then we
rollback with ->cancel_attach_task().
Let me enumerate the possible scenario (may not be exhaustive):
* The task exits (called cgroup_exit()) before we cgroup_task_migrate()
switch the cgroup. In this case we rollback the charge we pushed
on the new cgoup and we return an error.
* The task exits after cgroup_task_migrate(), in which case cgroup
called ->exit() on the task with the new cgroup, uncharging that
task from it. At the same time we call ->attach_task() to uncharge the
old cgroup, which is still what we want as we confirmed the cgroup
migration.
> cgroup_attach_proc() is different, it calls cgroup_task_migrate()
> after ->attach_task(). Cough.
That's bad. I need to fix that.
So if it returns -ESRCH, I shall not call attach_task() on it
but cancel_attach_task().
Other than that it should be safe as in the single task case.
> In this case old_cgrp can be uncharged twice, no? And again, nobody
> will uncharge the new cgrp?
(see above)
> ->attach_task() can be skipped if cgrp == oldcgrp... Probably this
> is fine, in this case can_attach_task() shouldn't actually charge.
In fact in this case it simply doesn't charge. res_counter_common_ancestor()
returns the res_counter for cgrp as a limit and thus charging stops as soon
as it starts.
>
> > @@ -1295,6 +1295,10 @@ static struct task_struct *copy_process(unsigned long clone_flags,
> > p->group_leader = p;
> > INIT_LIST_HEAD(&p->thread_group);
> >
> > + retval = cgroup_task_counter_fork(p);
> > + if (retval)
> > + goto bad_fork_free_pid;
> > +
>
> Well, imho this is not good. You are adding yet another cgroup hook.
> Why you can not reuse cgroup_fork_callbacks() ?
>
> Yes, it returns void. Can't we chane ->fork() to return the error and
> make it boolean?
That was my first proposition (minus the rollback with exit() that I forgot)
but Paul Menage said that added unnecessary complexity in the fork callbacks.
>
> Better yet,
>
> - cgroup_fork_callbacks(p);
> - cgroup_callbacks_done = 1;
> + failed_ss = cgroup_fork_callbacks(p);
> + if (failed_ss)
> + goto bad_fork_free_pid;
>
> ...
>
> - cgroup_exit(p, cgroup_callbacks_done);
> + cgroup_exit(p, failed_ss);
>
> What do you think?
I would personally prefer that.
> Oleg.
>
next prev parent reply other threads:[~2011-08-09 17:27 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-07-29 16:13 [PATCH 0/8 v3] cgroups: Task counter subsystem (was: New max number of tasks subsystem) Frederic Weisbecker
2011-07-29 16:13 ` [PATCH 1/8] cgroups: Add res_counter_write_u64() API Frederic Weisbecker
2011-08-09 15:17 ` Oleg Nesterov
2011-08-09 17:31 ` Frederic Weisbecker
2011-07-29 16:13 ` [PATCH 2/8] cgroups: New resource counter inheritance API Frederic Weisbecker
2011-07-29 16:13 ` [PATCH 3/8] cgroups: Add previous cgroup in can_attach_task/attach_task callbacks Frederic Weisbecker
2011-08-17 2:40 ` Li Zefan
2011-08-27 13:58 ` Frederic Weisbecker
2011-07-29 16:13 ` [PATCH 4/8] cgroups: New cancel_attach_task subsystem callback Frederic Weisbecker
2011-08-17 2:40 ` Li Zefan
2011-08-27 13:58 ` Frederic Weisbecker
2011-07-29 16:13 ` [PATCH 5/8] cgroups: Ability to stop res charge propagation on bounded ancestor Frederic Weisbecker
2011-08-17 2:41 ` Li Zefan
2011-08-27 13:59 ` Frederic Weisbecker
2011-07-29 16:13 ` [PATCH 6/8] cgroups: Add res counter common ancestor searching Frederic Weisbecker
2011-07-29 16:13 ` [PATCH 7/8] cgroups: Add a task counter subsystem Frederic Weisbecker
2011-08-01 23:13 ` Andrew Morton
2011-08-04 14:05 ` Frederic Weisbecker
2011-08-09 15:11 ` Oleg Nesterov
2011-08-09 17:27 ` Frederic Weisbecker [this message]
2011-08-09 17:57 ` Oleg Nesterov
2011-08-09 18:09 ` Frederic Weisbecker
2011-08-09 18:19 ` Oleg Nesterov
2011-08-09 18:34 ` Frederic Weisbecker
2011-08-09 18:39 ` Oleg Nesterov
2011-08-17 3:18 ` Li Zefan
2011-08-27 14:16 ` Frederic Weisbecker
2011-07-29 16:13 ` [PATCH 8/8] res_counter: Allow charge failure pointer to be null Frederic Weisbecker
2011-08-17 2:44 ` Li Zefan
2011-08-27 14:05 ` Frederic Weisbecker
2011-08-01 23:19 ` [PATCH 0/8 v3] cgroups: Task counter subsystem (was: New max number of tasks subsystem) Andrew Morton
2011-08-03 14:29 ` Frederic Weisbecker
2011-08-12 21:11 ` Tim Hockin
2011-08-16 16:01 ` Kay Sievers
2011-08-18 14:33 ` [RFD] Task counter: cgroup core feature or cgroup subsystem? (was Re: [PATCH 0/8 v3] cgroups: Task counter subsystem) Frederic Weisbecker
2011-08-23 16:07 ` Paul Menage
2011-08-24 17:54 ` Frederic Weisbecker
2011-08-26 7:28 ` Li Zefan
2011-08-26 14:58 ` Paul Menage
2011-09-06 9:06 ` Li Zefan
2011-08-26 15:16 ` Paul Menage
2011-08-27 13:40 ` Frederic Weisbecker
2011-08-31 22:36 ` Paul Menage
2011-08-31 21:54 ` Frederic Weisbecker
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20110809172746.GA31645@somewhere.redhat.com \
--to=fweisbec@gmail.com \
--cc=adityakali@google.com \
--cc=akpm@linux-foundation.org \
--cc=hannes@cmpxchg.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lizf@cn.fujitsu.com \
--cc=menage@google.com \
--cc=oleg@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.