When combined with 'MIPS: Changed current_thread_info() to an equivalent ...'
(http://www.linux-mips.org/archives/linux-mips/2015-01/msg00070.html) and the
target independent LLVMLinux patches, this patch series makes it possible to
compile a working kernel for MIPS using Clang.
The patches aren't inter-dependent so they can be merged individually or I can
split the series into individual submissions if that's preferred.
Daniel Sanders (2):
slab: Correct size_index table before replacing the bootstrap
kmem_cache_node.
MIPS: LLVMLinux: Fix an 'inline asm input/output type mismatch' error.
Toma Tabacu (2):
MIPS: LLVMLinux: Fix a 'cast to type not present in union' error.
MIPS: LLVMLinux: Silence variable self-assignment warnings.
This series previously included a 5th patch ('MIPS: LLVMLinux: Silence unicode
warnings when preprocessing assembly.'. This patch has been dropped from this
series while we work on preventing the warnings in a different way.
arch/mips/include/asm/checksum.h | 6 ++++--
arch/mips/kernel/branch.c | 6 ++++--
arch/mips/math-emu/dp_add.c | 5 -----
arch/mips/math-emu/dp_sub.c | 5 -----
arch/mips/math-emu/sp_add.c | 5 -----
arch/mips/math-emu/sp_sub.c | 5 -----
mm/slab.c | 1 +
mm/slab.h | 1 +
mm/slab_common.c | 36 +++++++++++++++++++++---------------
mm/slub.c | 1 +
10 files changed, 32 insertions(+), 39 deletions(-)
Signed-off-by: Toma Tabacu <[email protected]>
Signed-off-by: Daniel Sanders <[email protected]>
Cc: "Steven J. Hill" <[email protected]>
Cc: Andreas Herrmann <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Christoph Lameter <[email protected]>
Cc: David Daney <[email protected]>
Cc: David Rientjes <[email protected]>
Cc: Jim Quinlan <[email protected]>
Cc: Joonsoo Kim <[email protected]>
Cc: Leonid Yegoshin <[email protected]>
Cc: Manuel Lauss <[email protected]>
Cc: Markos Chandras <[email protected]>
Cc: Paul Bolle <[email protected]>
Cc: Paul Burton <[email protected]>
Cc: Pekka Enberg <[email protected]>
Cc: Ralf Baechle <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
--
2.1.4
This patch moves the initialization of the size_index table slightly
earlier so that the first few kmem_cache_node's can be safely allocated
when KMALLOC_MIN_SIZE is large.
There are currently two ways to generate indices into kmalloc_caches
(via kmalloc_index() and via the size_index table in slab_common.c)
and on some arches (possibly only MIPS) they potentially disagree with
each other until create_kmalloc_caches() has been called. It seems
that the intention is that the size_index table is a fast equivalent
to kmalloc_index() and that create_kmalloc_caches() patches the table
to return the correct value for the cases where kmalloc_index()'s
if-statements apply.
The failing sequence was:
* kmalloc_caches contains NULL elements
* kmem_cache_init initialises the element that 'struct
kmem_cache_node' will be allocated to. For 32-bit Mips, this is a
56-byte struct and kmalloc_index returns KMALLOC_SHIFT_LOW (7).
* init_list is called which calls kmalloc_node to allocate a 'struct
kmem_cache_node'.
* kmalloc_slab selects the kmem_caches element using
size_index[size_index_elem(size)]. For MIPS, size is 56, and the
expression returns 6.
* This element of kmalloc_caches is NULL and allocation fails.
* If it had not already failed, it would have called
create_kmalloc_caches() at this point which would have changed
size_index[size_index_elem(size)] to 7.
Signed-off-by: Daniel Sanders <[email protected]>
Acked-by: Pekka Enberg <[email protected]>
Cc: Christoph Lameter <[email protected]>
Cc: Pekka Enberg <[email protected]>
Cc: David Rientjes <[email protected]>
Cc: Joonsoo Kim <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: [email protected]
Cc: [email protected]
---
v2 renamed correct_kmalloc_cache_index_table() to
setup_kmalloc_cache_index_table() as requested.
v3 has no code changes but adds this background information:
I don't believe the bug to be LLVM specific but GCC doesn't normally encounter
the problem. I haven't been able to identify exactly what GCC is doing better
(probably inlining) but it seems that GCC is managing to optimize to the point
that it eliminates the problematic allocations. This theory is supported by the
fact that GCC can be made to fail in the same way by changing inline, __inline,
__inline__, and __always_inline in include/linux/compiler-gcc.h such that they
don't actually inline things.
v4 refreshes the patch and adds an Acked-by.
mm/slab.c | 1 +
mm/slab.h | 1 +
mm/slab_common.c | 36 +++++++++++++++++++++---------------
mm/slub.c | 1 +
4 files changed, 24 insertions(+), 15 deletions(-)
diff --git a/mm/slab.c b/mm/slab.c
index c4b89ea..79efb3e 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -1440,6 +1440,7 @@ void __init kmem_cache_init(void)
kmalloc_caches[INDEX_NODE] = create_kmalloc_cache("kmalloc-node",
kmalloc_size(INDEX_NODE), ARCH_KMALLOC_FLAGS);
slab_state = PARTIAL_NODE;
+ setup_kmalloc_cache_index_table();
slab_early_init = 0;
diff --git a/mm/slab.h b/mm/slab.h
index 4c3ac12..8da63e4 100644
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -71,6 +71,7 @@ unsigned long calculate_alignment(unsigned long flags,
#ifndef CONFIG_SLOB
/* Kmalloc array related functions */
+void setup_kmalloc_cache_index_table(void);
void create_kmalloc_caches(unsigned long);
/* Find the kmalloc slab corresponding for a certain size */
diff --git a/mm/slab_common.c b/mm/slab_common.c
index 999bb34..c7c6c33 100644
--- a/mm/slab_common.c
+++ b/mm/slab_common.c
@@ -784,25 +784,20 @@ struct kmem_cache *kmalloc_slab(size_t size, gfp_t flags)
}
/*
- * Create the kmalloc array. Some of the regular kmalloc arrays
- * may already have been created because they were needed to
- * enable allocations for slab creation.
+ * Patch up the size_index table if we have strange large alignment
+ * requirements for the kmalloc array. This is only the case for
+ * MIPS it seems. The standard arches will not generate any code here.
+ *
+ * Largest permitted alignment is 256 bytes due to the way we
+ * handle the index determination for the smaller caches.
+ *
+ * Make sure that nothing crazy happens if someone starts tinkering
+ * around with ARCH_KMALLOC_MINALIGN
*/
-void __init create_kmalloc_caches(unsigned long flags)
+void __init setup_kmalloc_cache_index_table(void)
{
int i;
- /*
- * Patch up the size_index table if we have strange large alignment
- * requirements for the kmalloc array. This is only the case for
- * MIPS it seems. The standard arches will not generate any code here.
- *
- * Largest permitted alignment is 256 bytes due to the way we
- * handle the index determination for the smaller caches.
- *
- * Make sure that nothing crazy happens if someone starts tinkering
- * around with ARCH_KMALLOC_MINALIGN
- */
BUILD_BUG_ON(KMALLOC_MIN_SIZE > 256 ||
(KMALLOC_MIN_SIZE & (KMALLOC_MIN_SIZE - 1)));
@@ -833,6 +828,17 @@ void __init create_kmalloc_caches(unsigned long flags)
for (i = 128 + 8; i <= 192; i += 8)
size_index[size_index_elem(i)] = 8;
}
+}
+
+/*
+ * Create the kmalloc array. Some of the regular kmalloc arrays
+ * may already have been created because they were needed to
+ * enable allocations for slab creation.
+ */
+void __init create_kmalloc_caches(unsigned long flags)
+{
+ int i;
+
for (i = KMALLOC_SHIFT_LOW; i <= KMALLOC_SHIFT_HIGH; i++) {
if (!kmalloc_caches[i]) {
kmalloc_caches[i] = create_kmalloc_cache(NULL,
diff --git a/mm/slub.c b/mm/slub.c
index 6832c4e..a6363ba 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -3700,6 +3700,7 @@ void __init kmem_cache_init(void)
kmem_cache_node = bootstrap(&boot_kmem_cache_node);
/* Now we can use the kmem_cache to allocate kmalloc slabs */
+ setup_kmalloc_cache_index_table();
create_kmalloc_caches(0);
#ifdef CONFIG_SMP
--
2.1.4
From: Toma Tabacu <[email protected]>
Remove a cast to the 'mips16e_instruction' union inside an if
condition and instead do an assignment to a local
'union mips16e_instruction' variable's 'full' member before the if
statement and use this variable in the if condition.
This is the error message reported by clang:
arch/mips/kernel/branch.c:38:8: error: cast to union type from type 'unsigned short' not present in union
if (((union mips16e_instruction)inst).ri.opcode
^ ~~~~
The changed code can be compiled successfully by both gcc and clang.
Signed-off-by: Toma Tabacu <[email protected]>
Signed-off-by: Daniel Sanders <[email protected]>
Cc: Ralf Baechle <[email protected]>
Cc: Andreas Herrmann <[email protected]>
Cc: David Daney <[email protected]>
Cc: Manuel Lauss <[email protected]>
Cc: [email protected]
Cc: [email protected]
---
v2 refreshes the patch.
arch/mips/kernel/branch.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c
index c2e0f45..c0c5e59 100644
--- a/arch/mips/kernel/branch.c
+++ b/arch/mips/kernel/branch.c
@@ -36,8 +36,10 @@ int __isa_exception_epc(struct pt_regs *regs)
return epc;
}
if (cpu_has_mips16) {
- if (((union mips16e_instruction)inst).ri.opcode
- == MIPS16e_jal_op)
+ union mips16e_instruction inst_mips16e;
+
+ inst_mips16e.full = inst;
+ if (inst_mips16e.ri.opcode == MIPS16e_jal_op)
epc += 4;
else
epc += 2;
--
2.1.4
Replace incorrect matching constraint that caused the error with an alternative
that still has the required constraints on the inline assembly.
This is the error message reported by clang:
arch/mips/include/asm/checksum.h:285:27: error: unsupported inline asm: input with type '__be32' (aka 'unsigned int') matching output with type 'unsigned short'
"0" (htonl(len)), "1" (htonl(proto)), "r" (sum));
^~~~~~~~~~~~
The changed code can be compiled successfully by both gcc and clang.
Signed-off-by: Daniel Sanders <[email protected]>
Signed-off-by: Toma Tabacu <[email protected]>
Suggested-by: Maciej W. Rozycki <[email protected]>
Cc: Ralf Baechle <[email protected]>
Cc: Markos Chandras <[email protected]>
Cc: Leonid Yegoshin <[email protected]>
Cc: [email protected]
Cc: [email protected]
---
v2 replaced the patch following Maciej's suggestion where he observed that
the assembly was somewhat strange and suggested correcting the
constraints and using a local of matching type.
v3 fixed a small whitespace issue.
v4 refreshes the patch.
arch/mips/include/asm/checksum.h | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/mips/include/asm/checksum.h b/arch/mips/include/asm/checksum.h
index 5c585c5..3ceacde 100644
--- a/arch/mips/include/asm/checksum.h
+++ b/arch/mips/include/asm/checksum.h
@@ -218,6 +218,8 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
__u32 len, unsigned short proto,
__wsum sum)
{
+ __wsum tmp;
+
__asm__(
" .set push # csum_ipv6_magic\n"
" .set noreorder \n"
@@ -270,9 +272,9 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
" addu %0, $1 # Add final carry\n"
" .set pop"
- : "=r" (sum), "=r" (proto)
+ : "=&r" (sum), "=&r" (tmp)
: "r" (saddr), "r" (daddr),
- "0" (htonl(len)), "1" (htonl(proto)), "r" (sum));
+ "0" (htonl(len)), "r" (htonl(proto)), "r" (sum));
return csum_fold(sum);
}
--
2.1.4
From: Toma Tabacu <[email protected]>
Remove variable self-assignments.
This silences a bunch of -Wself-assign warnings reported by clang.
The changed code can be compiled without warnings by both gcc and clang.
Signed-off-by: Toma Tabacu <[email protected]>
Signed-off-by: Daniel Sanders <[email protected]>
Cc: Ralf Baechle <[email protected]>
Cc: [email protected]
Cc: [email protected]
---
v2 refreshes the patch.
arch/mips/math-emu/dp_add.c | 5 -----
arch/mips/math-emu/dp_sub.c | 5 -----
arch/mips/math-emu/sp_add.c | 5 -----
arch/mips/math-emu/sp_sub.c | 5 -----
4 files changed, 20 deletions(-)
diff --git a/arch/mips/math-emu/dp_add.c b/arch/mips/math-emu/dp_add.c
index 7f64577..58b2795 100644
--- a/arch/mips/math-emu/dp_add.c
+++ b/arch/mips/math-emu/dp_add.c
@@ -150,8 +150,6 @@ union ieee754dp ieee754dp_add(union ieee754dp x, union ieee754dp y)
* leaving result in xm, xs and xe.
*/
xm = xm + ym;
- xe = xe;
- xs = xs;
if (xm >> (DP_FBITS + 1 + 3)) { /* carry out */
xm = XDPSRS1(xm);
@@ -160,11 +158,8 @@ union ieee754dp ieee754dp_add(union ieee754dp x, union ieee754dp y)
} else {
if (xm >= ym) {
xm = xm - ym;
- xe = xe;
- xs = xs;
} else {
xm = ym - xm;
- xe = xe;
xs = ys;
}
if (xm == 0)
diff --git a/arch/mips/math-emu/dp_sub.c b/arch/mips/math-emu/dp_sub.c
index 7a17402..2eb87cd2 100644
--- a/arch/mips/math-emu/dp_sub.c
+++ b/arch/mips/math-emu/dp_sub.c
@@ -153,8 +153,6 @@ union ieee754dp ieee754dp_sub(union ieee754dp x, union ieee754dp y)
/* generate 28 bit result of adding two 27 bit numbers
*/
xm = xm + ym;
- xe = xe;
- xs = xs;
if (xm >> (DP_FBITS + 1 + 3)) { /* carry out */
xm = XDPSRS1(xm); /* shift preserving sticky */
@@ -163,11 +161,8 @@ union ieee754dp ieee754dp_sub(union ieee754dp x, union ieee754dp y)
} else {
if (xm >= ym) {
xm = xm - ym;
- xe = xe;
- xs = xs;
} else {
xm = ym - xm;
- xe = xe;
xs = ys;
}
if (xm == 0) {
diff --git a/arch/mips/math-emu/sp_add.c b/arch/mips/math-emu/sp_add.c
index 2d84d46..7a33af4 100644
--- a/arch/mips/math-emu/sp_add.c
+++ b/arch/mips/math-emu/sp_add.c
@@ -148,8 +148,6 @@ union ieee754sp ieee754sp_add(union ieee754sp x, union ieee754sp y)
* leaving result in xm, xs and xe.
*/
xm = xm + ym;
- xe = xe;
- xs = xs;
if (xm >> (SP_FBITS + 1 + 3)) { /* carry out */
SPXSRSX1();
@@ -157,11 +155,8 @@ union ieee754sp ieee754sp_add(union ieee754sp x, union ieee754sp y)
} else {
if (xm >= ym) {
xm = xm - ym;
- xe = xe;
- xs = xs;
} else {
xm = ym - xm;
- xe = xe;
xs = ys;
}
if (xm == 0)
diff --git a/arch/mips/math-emu/sp_sub.c b/arch/mips/math-emu/sp_sub.c
index 8592e49..1189bc5 100644
--- a/arch/mips/math-emu/sp_sub.c
+++ b/arch/mips/math-emu/sp_sub.c
@@ -148,8 +148,6 @@ union ieee754sp ieee754sp_sub(union ieee754sp x, union ieee754sp y)
/* generate 28 bit result of adding two 27 bit numbers
*/
xm = xm + ym;
- xe = xe;
- xs = xs;
if (xm >> (SP_FBITS + 1 + 3)) { /* carry out */
SPXSRSX1(); /* shift preserving sticky */
@@ -157,11 +155,8 @@ union ieee754sp ieee754sp_sub(union ieee754sp x, union ieee754sp y)
} else {
if (xm >= ym) {
xm = xm - ym;
- xe = xe;
- xs = xs;
} else {
xm = ym - xm;
- xe = xe;
xs = ys;
}
if (xm == 0) {
--
2.1.4
This patch moves the initialization of the size_index table slightly
earlier so that the first few kmem_cache_node's can be safely allocated
when KMALLOC_MIN_SIZE is large.
There are currently two ways to generate indices into kmalloc_caches
(via kmalloc_index() and via the size_index table in slab_common.c)
and on some arches (possibly only MIPS) they potentially disagree with
each other until create_kmalloc_caches() has been called. It seems
that the intention is that the size_index table is a fast equivalent
to kmalloc_index() and that create_kmalloc_caches() patches the table
to return the correct value for the cases where kmalloc_index()'s
if-statements apply.
The failing sequence was:
* kmalloc_caches contains NULL elements
* kmem_cache_init initialises the element that 'struct
kmem_cache_node' will be allocated to. For 32-bit Mips, this is a
56-byte struct and kmalloc_index returns KMALLOC_SHIFT_LOW (7).
* init_list is called which calls kmalloc_node to allocate a 'struct
kmem_cache_node'.
* kmalloc_slab selects the kmem_caches element using
size_index[size_index_elem(size)]. For MIPS, size is 56, and the
expression returns 6.
* This element of kmalloc_caches is NULL and allocation fails.
* If it had not already failed, it would have called
create_kmalloc_caches() at this point which would have changed
size_index[size_index_elem(size)] to 7.
Signed-off-by: Daniel Sanders <[email protected]>
Acked-by: Pekka Enberg <[email protected]>
Cc: Christoph Lameter <[email protected]>
Cc: Pekka Enberg <[email protected]>
Cc: David Rientjes <[email protected]>
Cc: Joonsoo Kim <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: [email protected]
Cc: [email protected]
---
v2 renamed correct_kmalloc_cache_index_table() to
setup_kmalloc_cache_index_table() as requested.
v3 has no changes but adds this background information:
I don't believe the bug to be LLVM specific but GCC doesn't normally encounter
the problem. I haven't been able to identify exactly what GCC is doing better
(probably inlining) but it seems that GCC is managing to optimize to the point
that it eliminates the problematic allocations. This theory is supported by the
fact that GCC can be made to fail in the same way by changing inline, __inline,
__inline__, and __always_inline in include/linux/compiler-gcc.h such that they
don't actually inline things.
v4 refreshes the patch.
v5 refreshes the patch and drops the '1/4' from the subject since the other
patches in the series have been merged.
mm/slab.c | 1 +
mm/slab.h | 1 +
mm/slab_common.c | 36 +++++++++++++++++++++---------------
mm/slub.c | 1 +
4 files changed, 24 insertions(+), 15 deletions(-)
diff --git a/mm/slab.c b/mm/slab.c
index 7eb38dd..200e224 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -1454,6 +1454,7 @@ void __init kmem_cache_init(void)
kmalloc_caches[INDEX_NODE] = create_kmalloc_cache("kmalloc-node",
kmalloc_size(INDEX_NODE), ARCH_KMALLOC_FLAGS);
slab_state = PARTIAL_NODE;
+ setup_kmalloc_cache_index_table();
slab_early_init = 0;
diff --git a/mm/slab.h b/mm/slab.h
index 4c3ac12..8da63e4 100644
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -71,6 +71,7 @@ unsigned long calculate_alignment(unsigned long flags,
#ifndef CONFIG_SLOB
/* Kmalloc array related functions */
+void setup_kmalloc_cache_index_table(void);
void create_kmalloc_caches(unsigned long);
/* Find the kmalloc slab corresponding for a certain size */
diff --git a/mm/slab_common.c b/mm/slab_common.c
index 999bb34..c7c6c33 100644
--- a/mm/slab_common.c
+++ b/mm/slab_common.c
@@ -784,25 +784,20 @@ struct kmem_cache *kmalloc_slab(size_t size, gfp_t flags)
}
/*
- * Create the kmalloc array. Some of the regular kmalloc arrays
- * may already have been created because they were needed to
- * enable allocations for slab creation.
+ * Patch up the size_index table if we have strange large alignment
+ * requirements for the kmalloc array. This is only the case for
+ * MIPS it seems. The standard arches will not generate any code here.
+ *
+ * Largest permitted alignment is 256 bytes due to the way we
+ * handle the index determination for the smaller caches.
+ *
+ * Make sure that nothing crazy happens if someone starts tinkering
+ * around with ARCH_KMALLOC_MINALIGN
*/
-void __init create_kmalloc_caches(unsigned long flags)
+void __init setup_kmalloc_cache_index_table(void)
{
int i;
- /*
- * Patch up the size_index table if we have strange large alignment
- * requirements for the kmalloc array. This is only the case for
- * MIPS it seems. The standard arches will not generate any code here.
- *
- * Largest permitted alignment is 256 bytes due to the way we
- * handle the index determination for the smaller caches.
- *
- * Make sure that nothing crazy happens if someone starts tinkering
- * around with ARCH_KMALLOC_MINALIGN
- */
BUILD_BUG_ON(KMALLOC_MIN_SIZE > 256 ||
(KMALLOC_MIN_SIZE & (KMALLOC_MIN_SIZE - 1)));
@@ -833,6 +828,17 @@ void __init create_kmalloc_caches(unsigned long flags)
for (i = 128 + 8; i <= 192; i += 8)
size_index[size_index_elem(i)] = 8;
}
+}
+
+/*
+ * Create the kmalloc array. Some of the regular kmalloc arrays
+ * may already have been created because they were needed to
+ * enable allocations for slab creation.
+ */
+void __init create_kmalloc_caches(unsigned long flags)
+{
+ int i;
+
for (i = KMALLOC_SHIFT_LOW; i <= KMALLOC_SHIFT_HIGH; i++) {
if (!kmalloc_caches[i]) {
kmalloc_caches[i] = create_kmalloc_cache(NULL,
diff --git a/mm/slub.c b/mm/slub.c
index 54c0876..816df00 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -3700,6 +3700,7 @@ void __init kmem_cache_init(void)
kmem_cache_node = bootstrap(&boot_kmem_cache_node);
/* Now we can use the kmem_cache to allocate kmalloc slabs */
+ setup_kmalloc_cache_index_table();
create_kmalloc_caches(0);
#ifdef CONFIG_SMP
--
2.1.4
On Mon, 20 Apr 2015, Daniel Sanders wrote:
> This patch moves the initialization of the size_index table slightly
> earlier so that the first few kmem_cache_node's can be safely allocated
> when KMALLOC_MIN_SIZE is large.
I have seen this patch and acked it before.
Acked-by: Christoph Lameter <[email protected]>
> -----Original Message-----
> From: Christoph Lameter [mailto:[email protected]]
> Sent: 20 April 2015 16:43
> To: Daniel Sanders
> Cc: Pekka Enberg; David Rientjes; Joonsoo Kim; Andrew Morton; linux-
> [email protected]; [email protected]
> Subject: Re: [PATCH v5] slab: Correct size_index table before replacing the
> bootstrap kmem_cache_node.
>
> On Mon, 20 Apr 2015, Daniel Sanders wrote:
>
> > This patch moves the initialization of the size_index table slightly
> > earlier so that the first few kmem_cache_node's can be safely allocated
> > when KMALLOC_MIN_SIZE is large.
>
> I have seen this patch and acked it before.
>
> Acked-by: Christoph Lameter <[email protected]>
Sorry, I must have forgotten to add it to the commit in my repo. Thanks for looking at the patch again.