From: "Paul Menage" <menage@google.com>
To: "Paul Jackson" <pj@sgi.com>
Cc: "David Rientjes" <rientjes@google.com>,
akpm@linux-foundation.org, nickpiggin@yahoo.com.au,
a.p.zijlstra@chello.nl, serue@us.ibm.com, clg@fr.ibm.com,
linux-kernel@vger.kernel.org, ebiederm@xmission.com,
svaidy@linux.vnet.ibm.com, xemul@openvz.org,
containers@lists.osdl.org, balbir@linux.vnet.ibm.com
Subject: Re: [PATCH] task containersv11 add tasks file interface fix for cpusets
Date: Sat, 6 Oct 2007 14:09:52 -0700 [thread overview]
Message-ID: <6599ad830710061409p2dcaa1c8u8c6864beaaafb149@mail.gmail.com> (raw)
In-Reply-To: <20071006125904.a26ed99f.pj@sgi.com>
On 10/6/07, Paul Jackson <pj@sgi.com> wrote:
> David wrote:
> > It would probably be better to just save references to the tasks.
> >
> > struct cgroup_iter it;
> > struct task_struct *p, **tasks;
> > int i = 0;
> >
> > cgroup_iter_start(cs->css.cgroup, &it);
> > while ((p = cgroup_iter_next(cs->css.cgroup, &it))) {
> > get_task_struct(p);
> > tasks[i++] = p;
> > }
> > cgroup_iter_end(cs->css.cgroup, &it);
>
> Hmmm ... guess I'd have to loop over the cgroup twice, once to count
> them (the 'count' field is not claimed to be accurate) and then again,
> after I've kmalloc'd the tasks[] array, filling in the tasks[] array.
>
> On a big cgroup on a big system, this could easily be thousands of
> iteration loops.
But if userspace has to do it, the effect will be far more expensive.
>
> If I need to close the window all the way, completely solving the race
> condition, then I have the code in kernel/cpuset.c:update_nodemask(),
> which builds an mmarray[] using two loops and some retries if newly
> forked tasks are showing up too rapidly at the same time. The first of
> the two loops is hidden in the cgroup_task_count() call.
In general, the loop inside cgroup_task_count() will only have a
single iteration. (It's iterating across the shared css_set objects,
not across member tasks.
What's wrong with:
allocate a page of task_struct pointers
again:
need_repeat = false;
cgroup_iter_start();
while (cgroup_iter_next()) {
if (p->cpus_allowed != new_cpumask) {
store p;
if (page is full) {
need_repeat = true;
break;
}
}
}
for each saved task p {
set_cpus_allowed(p, new_cpumask);
release p;
}
if (need_repeat)
goto again;
Advantages:
- no vmalloc needed
- just one iteration in the case where a cgroup has fewer than 512 members
- additional iterations only need to deal with tasks that don't have
the right cpu mask
- automatically handles fork races
Another option would be to have a cpuset fork callback that forces
p->cpus_allowed to its cpuset's cpus_allowed if another thread is in
the middle of update_cpumask(). Then you don't need to worry about
fork races at all, since all new threads will get the right cpumask.
> Or, if there is a good reason that must remain a spinlock, then the
> smallest amount of new code, and the easiest code to write, would
> perhaps be adding another cgroup callback, called only by cgroup attach
> () requests back to the same group. Then code that wants to do
> something odd, such as cpusets, for what seems like a no-op, can do so.
I'd much rather not perpetuate that broken API requirement. The fact
that cpusets wants this odd behaviour is based on a nasty hack.
Paul
next prev parent reply other threads:[~2007-10-06 21:10 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-10-03 8:42 Paul Jackson
2007-10-03 15:51 ` Paul Menage
2007-10-03 17:58 ` Paul Jackson
2007-10-03 18:10 ` Paul Menage
2007-10-03 18:25 ` Paul Menage
2007-10-03 20:16 ` Paul Jackson
2007-10-03 20:31 ` Paul Menage
2007-10-03 20:52 ` Paul Jackson
2007-10-03 20:58 ` Paul Menage
2007-10-06 8:24 ` Paul Jackson
2007-10-06 17:54 ` David Rientjes
2007-10-06 19:59 ` Paul Jackson
2007-10-06 21:09 ` Paul Menage [this message]
2007-10-06 21:41 ` Paul Jackson
2007-10-11 22:03 ` Paul Jackson
2007-10-11 23:20 ` Eric W. Biederman
2007-10-12 1:23 ` Paul Jackson
2007-10-07 6:13 ` David Rientjes
2007-10-06 21:11 ` Paul Menage
2007-10-07 6:15 ` David Rientjes
2007-10-10 20:46 ` Paul Menage
2007-10-10 20:59 ` David Rientjes
2007-10-11 23:15 ` Paul Jackson
2007-10-12 15:13 ` David Rientjes
2007-10-06 20:53 ` Paul Menage
2007-10-03 20:56 ` Paul Jackson
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=6599ad830710061409p2dcaa1c8u8c6864beaaafb149@mail.gmail.com \
--to=menage@google.com \
--cc=a.p.zijlstra@chello.nl \
--cc=akpm@linux-foundation.org \
--cc=balbir@linux.vnet.ibm.com \
--cc=clg@fr.ibm.com \
--cc=containers@lists.osdl.org \
--cc=ebiederm@xmission.com \
--cc=linux-kernel@vger.kernel.org \
--cc=nickpiggin@yahoo.com.au \
--cc=pj@sgi.com \
--cc=rientjes@google.com \
--cc=serue@us.ibm.com \
--cc=svaidy@linux.vnet.ibm.com \
--cc=xemul@openvz.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®