Thread (29 messages) 29 messages, 3 authors, 2012-03-23

Re: Q: cgroup: Questions about possible issues in cgroup locking

From: Mandeep Singh Baines <hidden>
Date: 2012-01-12 00:31:19
Also in: lkml

Hi Oleg,

Oleg Nesterov (oleg-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org) wrote:
On 01/06, Mandeep Singh Baines wrote:
quoted
Oleg Nesterov (oleg-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org) wrote:
quoted
quoted
quoted
in particular, http://marc.info/?l=linux-kernel&m=127714242731448
I think this should work, but then we should do something with the
users like zap_threads().
With that patch, won't you potentially miss the exec thread if an exec
occurs while you're iterating over the list? Is that OK?
Of course it is not OK ;) Note the "we should do something with" above.
So requirements should be something like this:
(I assume, you mean the lockless case)
Correct.
quoted
* Any task alive for the duration of the iteration MUST be visited
* No task should be visited more than once
* Any task born or exiting after starting the iteration MAY be skipped
* You can start at any task in the thread group
Well yes, but it is not easy to exactly define what after/before
means in this case.
quoted
Would something like this work:

#define while_each_thread(g, t, o) \
	while (t->group_leader == o && (t = next_thread(t)) != g)

Where o should have the value of g->group_leader.
I don't understand how this helps... and how this can work even
ignoring the barriers.

OK, we have the main thream M and the sub-thread T, we are doing

	do {
		do_something(t);
	} while_each_thread(M, t, M);

why we can't miss T if it does exec?
So for:

struct task *M; /* assuming this is passed in to us */
struct task *L = M->group_leader;
struct task *I = M;

do {
	do_something(T);
} while_each_thread(M, T, L);

Here is my thinking.

If some thread K does exec, you won't miss it because:

1) Ignoring the group_leader check, you'll visit K just by following
   next_thread(). That's the case today and is what you except
   when iterating over an rcu_list.
2) (t->group_leader == o) will fail iff t is the exec thread.
   Since we test t->group_leader before re-assigning it (t=next_thread()),
   the test will fail only after visiting the exec thread. So you'll
   visit the exec thread and then terminate the loop.

I realize its a klutzy interface (requires 3 variables) but it seems
correct (ignoring barriers) and meets all the requirements. I'm hoping
it inspires a solution which is less klutzy and meet its all the
requirements.

Regards,
Mandeep
Oleg.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help