Thread (13 messages) 13 messages, 3 authors, 2011-01-27

HIGHMEM is broken when working in SMP V6 mode

From: nico@fluxnic.net (Nicolas Pitre)
Date: 2011-01-27 19:45:52

On Thu, 27 Jan 2011, Russell King - ARM Linux wrote:
On Thu, Jan 27, 2011 at 01:40:37PM -0500, Nicolas Pitre wrote:
quoted
On Thu, 27 Jan 2011, Russell King - ARM Linux wrote:
quoted
On Mon, Jan 24, 2011 at 02:58:07PM -0500, Nicolas Pitre wrote:
quoted
 /*
+ * The reason for kmap_high_get() is to ensure that the currently kmap'd
+ * page usage count does not decrease to zero while we're using its
+ * existing virtual mapping in an atomic context.  With a VIVT cache this
+ * is essential to do, but with a VIPT cache this is only an optimization
+ * so not to pay the price of establishing a second mapping if an existing
+ * one can be used.  However, on platforms without hardware TLB maintainence
+ * broadcast, we simply cannot use ARCH_NEEDS_KMAP_HIGH_GET at all since
+ * the locking involved must also disable IRQs which is incompatible with
+ * the IPI mechanism used by global TLB operations.
+ */
+#define ARCH_NEEDS_KMAP_HIGH_GET
+#if defined(CONFIG_SMP) && defined(CONFIG_CPU_TLB_V6)
+#undef ARCH_NEEDS_KMAP_HIGH_GET
+#if defined(CONFIG_HIGHMEM) && defined(CONFIG_CPU_CACHE_VIVT)
+#error "The sum of feature in your kernel config cannot be supported together"
+#endif
This is wrong.  Take a moment to consider a kernel supporting an ARMv6
VIPT aliasing cache CPU and ARMv7 SMP.  Don't we need kmap_high_get()
for ARMv6 VIPT aliasing cache?
We don't support highmem on aliasing VIPT.  Highmem gets disabled at run 
time on aliasing VIPT platforms.
Correct.  But a kernel which has this configuration:

CONFIG_SMP=y
CONFIG_HIGHMEM=y
CONFIG_CPU_V6=y
CONFIG_CPU_V7=y
CONFIG_CPU_32v6=y
CONFIG_CPU_32v7=y
CONFIG_CPU_CACHE_V6=y
CONFIG_CPU_CACHE_VIPT=y
CONFIG_CPU_CACHE_V7=y
CONFIG_CPU_CACHE_VIPT=y
CONFIG_CPU_TLB_V6=y
CONFIG_CPU_TLB_V7=y

This disables ARCH_NEEDS_KMAP_HIGH_GET in this kernel, which can be used on
ARMv6 VIPT non-aliasing, VIPT aliasing, as well as SMP stuff.
Yes.

On a VIPT aliasing target, highmem gets disabled at run time.  So no 
issue there.

Otherwise, on VIPT, it is not essential to have 
ARCH_NEEDS_KMAP_HIGH_GET.
If we don't need ARCH_NEEDS_KMAP_HIGH_GET on V6 and V7, we should just not
enable it for those at all.
As I said in the patch comment, ARCH_NEEDS_KMAP_HIGH_GET is still a nice 
optimization on VIPT. It avoids the creation of a second mapping and TLB 
usage when an existing mapping from the pkmap array can be reused right 
away.  But if our kernel config indicates that we might run on a target 
lacking hw TLB broadcast then we have to compromize and give up on that 
optimization.


Nicolas
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help