[RFC PATCH 05/17] ARM: kernel: save/restore kernel IF

Frank Hofmann frank.hofmann at tomtom.com
Mon Jul 11 10:31:30 EDT 2011



On Mon, 11 Jul 2011, Lorenzo Pieralisi wrote:

> On Fri, Jul 08, 2011 at 05:12:22PM +0100, Frank Hofmann wrote:
>> Hi Lorenzo,
>>
>> only a few comments at this stage.
>>
>> The sr_entry.S code is both exclusively .arm (using conditionals and
>> long-distance adr, i.e. not Thumb2-clean), and it uses post-armv5
>> instructions (like wfi). Same for the other *.S code in the patch series.
>> It's non-generic assembly within arch/arch/kernel/, wouldn't one better
>> place this into arch/arm/mm/...-v[67].S ?
>>
>
> Yes, it is certainly something I should improve to make it more generic.
>
>>
>> Then, sr_suspend/sr_resume; these functions are "C-exported" and are
>> directly calling cpu_do_suspend/do_resume to pass a supplied buffer; I've
>> done that for one iteration of the hibernation patch, yes, but that was a
>> bit sneaky and Russell stated then the interface is cpu_suspend/cpu_resume
>> not the proc funcs directly. Unless _those_ have been changed they're also
>> unsafe to call from C funcs (clobber all regs). Couldn't you simply use
>> cpu_suspend/resume directly ?
>>
>
> Well, short answer is no. On SMP we do need to save CPU registers
> but if just one single cpu is shutdown L2 is still on.
> cpu_suspend saves regs on the stack that has to be cleaned from
> L2 before shutting a CPU down which make things more complicated than
> they should. That's why I use cpu_do_{suspend,resume}, so that I can choose
> the memory used to save registers (uncached), but that's an abuse of
> API.

There's the option to use a switch_stack() as Will Deacon has provided via 
his kexec series. Agreed not mainline yet but good for ideas. Will's diff 
is here:

http://www.spinics.net/lists/arm-kernel/msg127951.html

and that one restores the original sp after the "stack switched" function 
returns.

If you use that to switch to a different (uncached) stack before doing 
cpu_suspend (and the 'idle' finisher through that), wouldn't that solve 
the problem ? When the suspend returns, the above would restore your 
cached stackpointer.

> I agree this is sneaky, but I wanted to avoid duplicating code that
> just saves registers. Maybe moving to an uncached stack might solve this
> problem if we want to reuse cpu_suspend from cpu idle, which is still an
> open point.

(me speedtyping above ...) As you say ;-)

>
>> How much memory do all the pagedirs require that are being kept around ?
>> Why does each core need a separate one, what would happen to just use a
>> single "identity table" for all ?
>> I understand you can't use swapper_pg_dir for idle, so a separate one has
>> to be allocated, yet the question remains why per-cpu required ?
>>
>>
>
> I just allocate a 1:1 mapping once cloned from init_mm, reused for all CPUs,
> with an additional mapping.

Have started to wonder whether this facility (a 1:1-mapped pagedir for 
kernel text/data, or maybe even "non-user text/data") could/should be made 
available on a global scale; after all, both kexec, reset, hibernate, some 
forms of idle/suspend do require "some sort of that" to go through MMU 
reinitialization. I'm unfortunately not deep enough in the VM subsystem to 
say how exactly this best would have to look like.

Merely mentioning this because it looks while everyone creates 1:1 
mappings, there's ever so slight differences between how the 1:1 
mapping(s) are created; we've seen:

 	* (re)using current->active_mm->pgd
 	* (re)using swapper_pg_dir (different lengths for the 1:1 section)
 	* using a separately-allocated/initialized pgdir

Such proliferation usually means there's a justified need to do that kind 
of thing. Just the gritty details haven't been sorted how everyone with 
that need could do _the same_ thing instead of reinventing various square 
wheels.

The main reason why I've used swapper_pg_dir in the hibernation patch is 
because it's the only static one in the system (the hibernation hooks are 
in irqs-off codepaths and pgd_alloc isn't a good idea then), and happens 
to have "clear" lower sections (in the user area) so that one's not 
actually substituting anything when creating 1:1 mappings (and getting rid 
of them restores the "pristine" state). But this assumption only holds as 
long as swapper_pg_dir's use isn't changed. So a little creepy feeling 
remains.

A generic "reset_mmu_pg_dir", wouldn't that be a good thing to have ?

> The array of pointers is there to save pgdir on idle entry, one per-cpu.

If you're going through cpu_{do_}suspend/resume, the TTBRs are 
saved/restored anyway, what do you need to keep the virtual addresses 
around for ?


>
>>
>> I'm currently transitioning between jobs; will re-subscribe to arm-kernel
>> under a different email address soon, this one is likely to stop working
>> in August. Sorry the inconvenience and high-latency responses till then :(
>>
>> FrankH.
>
> May I thank you very much for the review in the interim,

You're welcome.
FrankH.

>
> Lorenzo
>
>



More information about the linux-arm-kernel mailing list