Re: [BUG] "sched: Remove rq->lock from the first half of ttwu()" locks up on ARM

Catalin Marinas
2011-05-29T10:21:32Z

On Fri, May 27, 2011 at 09:52:40PM +0100, Russell King - ARM Linux wrote:
> On Fri, May 27, 2011 at 02:06:29PM +0200, Ingo Molnar wrote:
> > The expectations are to have irqs off (we are holding the runqueue
> > lock if !__ARCH_WANT_INTERRUPTS_ON_CTXSW), so that's not workable i
> > suspect.
>
> Just a thought, but we _might_ be able to avoid a lot of this hastle if
> we had a new arch hook in finish_task_switch(), after finish_lock_switch()
> returns but before the old MM is dropped.
...
> We could change switch_mm() to only do:
>
> 1. flush branch predictor
> 2. set swapper_pg_dir tables
> 3. check ASID validity
> 4. set new ASID value

If we find that we ran out of ASIDs, we can't reset it across all the
other CPUs at this point as we have interrupts disabled. So here we
assume that we don't need to reset the ASIDs.

> At this point, we have no user mappings, and so nothing will be using the
> ASID at this point. Then in a new post-finish_lock_switch() arch hook:
>
> 5. check whether we need to do flushing as a result of ASID change
> 6. set new page tables

Can we actually not move points 1, 3 and 4 to the
post-finish_lock_switch() hook as well? We don't really care what's in
the ASID as long as we don't have any user mappings. The same goes for
the branch predictor (which may be wrongly placed already). This would
make the switch_mm() relatively simple and move the check_context() and
cpu_switch_mm() to the post-switch hook.

On A15, the ASID is part of TTBR0 so we set both of them at the same
time in the post-switch hook.

To avoid extra per-thread flags, we could set a per-cpu variable in
switch_mm() so that we know what to switch the page tables to in the
post-switch hook.

So I think this is feasible but it needs some intensive testing.

--
Catalin