ARM: kernel: fix MPIDR cpu_{suspend}/{resume} usage
authorLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Fri, 4 May 2012 16:20:44 +0000 (17:20 +0100)
committerJon Medhurst <tixy@linaro.org>
Mon, 1 Jul 2013 10:05:11 +0000 (11:05 +0100)
commit5276597a467415e7d56034ba587925385f78662c
tree28966fbc39fa2ccb27aa6ae89d7999e3d4802179
parent8bb495e3f02401ee6f76d1b1d77f3ac9f079e376
ARM: kernel: fix MPIDR cpu_{suspend}/{resume} usage

The current version of cpu_{suspend}/{resume} relies on the 8 LSBs of
the MPIDR register to index the context pointer saved and restored on
CPU shutdown. This approach breaks as soon as platforms with populated
MPIDR affinity levels 1 and 2 are deployed, since the MPIDR cannot be
considered a linear index anymore.

There are multiple solutions to this problem, each with pros and cons.

This patch changes cpu_{suspend}/{resume} so that the CPU logical id
is used to retrieve an index into the context pointers array.

Performance is impacted on both save and restore paths. On save path
the CPU logical id has to be retrieved from thread_info; since caches
are on, the performance hit should be neglectable. In the resume code
path the MMU is off and so are the caches. The patch adds a trivial for
loop that polls the cpu_logical_map array scanning the present MPIDRs and
retrieves the actual CPU logical index. Since everything runs out of
strongly ordered memory the perfomance hit in the resume code path must
be measured and thought over; it worsens as the number of CPUs increases
since it is a linear search (but can be improved).

On the up side, the logical index approach is by far the easiest solution in
terms of coding and make dynamic changes to the cpu mapping trivial at
run-time.

Any change to the cpu_logical_map (ie in-kernel switcher) at run time must be
cleaned from the caches since this data has to be retrieved with the MMU
off, when caches are not searched.

Tested on TC2 and fast models.
arch/arm/kernel/sleep.S