<div dir="ltr">correct-size_index-table-before-replacing-the-bootst.patch does not apply cleanly to the upstream kernel. Tested with upstream ifc6410 target.<br><div><br></div><div>-Mark</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jan 9, 2015 at 6:20 AM, Daniel Sanders <span dir="ltr">&lt;<a href="mailto:daniel.sanders@imgtec.com" target="_blank">daniel.sanders@imgtec.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This patch should work for all arches but I&#39;ve only tested Mips so far.<br>
---<br>
<br>
I haven&#39;t submitted this one upstream yet since I&#39;d like to do one patch<br>
successfully before attempting to do multiple at once.<br>
<br>
 ...e_index-table-before-replacing-the-bootst.patch | 140 +++++++++++++++++++++<br>
 arch/all/patches/series                            |   1 +<br>
 .../mips-WIP-Fix-slab-allocator-bootstrap.patch    | 102 ---------------<br>
 3 files changed, 141 insertions(+), 102 deletions(-)<br>
 create mode 100644 arch/all/patches/correct-size_index-table-before-replacing-the-bootst.patch<br>
 delete mode 100644 arch/mips/patches/mips-WIP-Fix-slab-allocator-bootstrap.patch<br>
<br>
diff --git a/arch/all/patches/correct-size_index-table-before-replacing-the-bootst.patch b/arch/all/patches/correct-size_index-table-before-replacing-the-bootst.patch<br>
new file mode 100644<br>
index 0000000..fe2e904<br>
--- /dev/null<br>
+++ b/arch/all/patches/correct-size_index-table-before-replacing-the-bootst.patch<br>
@@ -0,0 +1,140 @@<br>
+From ef285703935fd863463f64eae490e8f1d880e50c Mon Sep 17 00:00:00 2001<br>
+From: Daniel Sanders &lt;<a href="mailto:daniel.sanders@imgtec.com">daniel.sanders@imgtec.com</a>&gt;<br>
+Date: Thu, 8 Jan 2015 14:38:02 +0000<br>
+Subject: [PATCH] Correct size_index table before replacing the bootstrap<br>
+ kmem_cache_node<br>
+<br>
+There are currently two ways to generate indices into kmalloc_caches<br>
+(via kmalloc_index() and via the size_index table in slab_common.c) and on some<br>
+arches (possibly only MIPS) they disagree with each other until<br>
+create_kmalloc_caches() has been called. This patch moves the initialization<br>
+of the size_index array slightly earlier so that the first few kmem_cache_node&#39;s<br>
+can be safely allocated.<br>
+<br>
+The failing sequence was:<br>
+* kmalloc_caches contains NULL elements<br>
+* kmem_cache_init initialises the element that &#39;struct kmem_cache_node&#39; will be<br>
+  allocated to. For 32-bit Mips, this is a 56-byte struct and kmalloc_index<br>
+  returns KMALLOC_SHIFT_LOW (7).<br>
+* init_list is called which calls kmalloc_node to allocate a &#39;struct<br>
+  kmem_cache_node&#39;.<br>
+* kmalloc_slab selects the kmem_caches element using<br>
+  size_index[size_index_elem(size)]. For MIPS, size is 56, and the expression<br>
+  returns 6.<br>
+* This element of kmalloc_caches is NULL and allocation fails.<br>
+* If it had not already failed, it would have called create_kmalloc_caches()<br>
+  at this point which would have changed size_index[size_index_elem(size)] to 7.<br>
+<br>
+Signed-off-by: Daniel Sanders &lt;<a href="mailto:daniel.sanders@imgtec.com">daniel.sanders@imgtec.com</a>&gt;<br>
+---<br>
+<br>
+This is needed to fix the boot when compiled with clang.  Interestingly, GCC<br>
+does not normally encounter this bug. I believe this is because it manages to<br>
+optimise the problematic allocation away. This theory is supported by GCC<br>
+encountering this bug when I disable inlining by changing the definitions of<br>
+inline, __inline, __inline__, and __always_inline in<br>
+include/linux/compiler-gcc.h.<br>
+<br>
+ mm/slab.c        |  1 +<br>
+ mm/slab.h        |  1 +<br>
+ mm/slab_common.c | 37 +++++++++++++++++++++----------------<br>
+ mm/slub.c        |  1 +<br>
+ 4 files changed, 24 insertions(+), 16 deletions(-)<br>
+<br>
+diff --git a/mm/slab.c b/mm/slab.c<br>
+index 65b5dcb..6c93f28 100644<br>
+--- a/mm/slab.c<br>
++++ b/mm/slab.c<br>
+@@ -1440,6 +1440,7 @@ void __init kmem_cache_init(void)<br>
+       kmalloc_caches[INDEX_NODE] = create_kmalloc_cache(&quot;kmalloc-node&quot;,<br>
+                               kmalloc_size(INDEX_NODE), ARCH_KMALLOC_FLAGS);<br>
+       slab_state = PARTIAL_NODE;<br>
++      correct_kmalloc_cache_index_table();<br>
+<br>
+       slab_early_init = 0;<br>
+<br>
+diff --git a/mm/slab.h b/mm/slab.h<br>
+index 1cf40054..036c08d 100644<br>
+--- a/mm/slab.h<br>
++++ b/mm/slab.h<br>
+@@ -71,6 +71,7 @@ unsigned long calculate_alignment(unsigned long flags,<br>
+<br>
+ #ifndef CONFIG_SLOB<br>
+ /* Kmalloc array related functions */<br>
++void correct_kmalloc_cache_index_table(void);<br>
+ void create_kmalloc_caches(unsigned long);<br>
+<br>
+ /* Find the kmalloc slab corresponding for a certain size */<br>
+diff --git a/mm/slab_common.c b/mm/slab_common.c<br>
+index e03dd6f..a4ac0d7 100644<br>
+--- a/mm/slab_common.c<br>
++++ b/mm/slab_common.c<br>
+@@ -675,25 +675,19 @@ struct kmem_cache *kmalloc_slab(size_t size, gfp_t flags)<br>
+ }<br>
+<br>
+ /*<br>
+- * Create the kmalloc array. Some of the regular kmalloc arrays<br>
+- * may already have been created because they were needed to<br>
+- * enable allocations for slab creation.<br>
++ * Patch up the size_index table if we have strange large alignment<br>
++ * requirements for the kmalloc array. This is only the case for<br>
++ * MIPS it seems. The standard arches will not generate any code here.<br>
++ *<br>
++ * Largest permitted alignment is 256 bytes due to the way we<br>
++ * handle the index determination for the smaller caches.<br>
++ *<br>
++ * Make sure that nothing crazy happens if someone starts tinkering<br>
++ * around with ARCH_KMALLOC_MINALIGN<br>
+  */<br>
+-void __init create_kmalloc_caches(unsigned long flags)<br>
+-{<br>
++void __init correct_kmalloc_cache_index_table(void) {<br>
+       int i;<br>
+<br>
+-      /*<br>
+-       * Patch up the size_index table if we have strange large alignment<br>
+-       * requirements for the kmalloc array. This is only the case for<br>
+-       * MIPS it seems. The standard arches will not generate any code here.<br>
+-       *<br>
+-       * Largest permitted alignment is 256 bytes due to the way we<br>
+-       * handle the index determination for the smaller caches.<br>
+-       *<br>
+-       * Make sure that nothing crazy happens if someone starts tinkering<br>
+-       * around with ARCH_KMALLOC_MINALIGN<br>
+-       */<br>
+       BUILD_BUG_ON(KMALLOC_MIN_SIZE &gt; 256 ||<br>
+               (KMALLOC_MIN_SIZE &amp; (KMALLOC_MIN_SIZE - 1)));<br>
+<br>
+@@ -724,6 +718,17 @@ void __init create_kmalloc_caches(unsigned long flags)<br>
+               for (i = 128 + 8; i &lt;= 192; i += 8)<br>
+                       size_index[size_index_elem(i)] = 8;<br>
+       }<br>
++}<br>
++<br>
++/*<br>
++ * Create the kmalloc array. Some of the regular kmalloc arrays<br>
++ * may already have been created because they were needed to<br>
++ * enable allocations for slab creation.<br>
++ */<br>
++void __init create_kmalloc_caches(unsigned long flags)<br>
++{<br>
++      int i;<br>
++<br>
+       for (i = KMALLOC_SHIFT_LOW; i &lt;= KMALLOC_SHIFT_HIGH; i++) {<br>
+               if (!kmalloc_caches[i]) {<br>
+                       kmalloc_caches[i] = create_kmalloc_cache(NULL,<br>
+diff --git a/mm/slub.c b/mm/slub.c<br>
+index fe376fe..2217761 100644<br>
+--- a/mm/slub.c<br>
++++ b/mm/slub.c<br>
+@@ -3604,6 +3604,7 @@ void __init kmem_cache_init(void)<br>
+       kmem_cache_node = bootstrap(&amp;boot_kmem_cache_node);<br>
+<br>
+       /* Now we can use the kmem_cache to allocate kmalloc slabs */<br>
++      correct_kmalloc_cache_index_table();<br>
+       create_kmalloc_caches(0);<br>
+<br>
+ #ifdef CONFIG_SMP<br>
+--<br>
+2.1.3<br>
+<br>
diff --git a/arch/all/patches/series b/arch/all/patches/series<br>
index b37fbe0..7f0e3b9 100644<br>
--- a/arch/all/patches/series<br>
+++ b/arch/all/patches/series<br>
@@ -25,3 +25,4 @@ vlais-wimax-i2400m.patch<br>
 compiler-gcc.patch<br>
 smaller.patch<br>
 lib-mpi-extern-inline.patch<br>
+correct-size_index-table-before-replacing-the-bootst.patch<br>
diff --git a/arch/mips/patches/mips-WIP-Fix-slab-allocator-bootstrap.patch b/arch/mips/patches/mips-WIP-Fix-slab-allocator-bootstrap.patch<br>
deleted file mode 100644<br>
index 8805e98..0000000<br>
--- a/arch/mips/patches/mips-WIP-Fix-slab-allocator-bootstrap.patch<br>
+++ /dev/null<br>
@@ -1,102 +0,0 @@<br>
-From 875ec57dd7258115829918ed10980e1ad6a975c4 Mon Sep 17 00:00:00 2001<br>
-From: Daniel Sanders &lt;<a href="mailto:daniel.sanders@imgtec.com">daniel.sanders@imgtec.com</a>&gt;<br>
-Date: Fri, 19 Dec 2014 13:48:06 +0000<br>
-Subject: [PATCH 1/2] [WIP] Fix slab allocator bootstrap.<br>
-<br>
-There are currently two functions that generate indices into kmalloc_caches and<br>
-they disagree with each other.  This patch fixes the bug to the point that the<br>
-LLVM-compiled kernel successfully boots for Mips but it will need further work<br>
-before upstreaming.<br>
-<br>
-The failing sequence is:<br>
-* kmalloc_caches contains NULL elements<br>
-* kmem_cache_init initialises the element that &#39;struct kmem_cache_node&#39; will be<br>
-  allocated to. For 32-bit Mips, this is a 56-byte struct and kmalloc_index<br>
-  selects element 7.<br>
-* init_list is called which calls kmalloc_node to allocate a &#39;struct<br>
-  kmem_cache_node&#39;.<br>
-* kmalloc_slab selects the kmem_caches element using<br>
-  size_index[size_index_elem(size)]. For Mips, size is 56, and the expression<br>
-  returns 6.<br>
-* This element of kmalloc_caches is NULL and allocation fails.<br>
-<br>
-GCC does not normally encounter this bug. I believe this is because it manages<br>
-to optimise the problematic allocation away. This theory is supported by GCC<br>
-encountering this bug when I disable inlining by changing the definitions of<br>
-inline, __inline, __inline__, and __always_inline in<br>
-include/linux/compiler-gcc.h.<br>
-<br>
-Signed-off-by: Daniel Sanders &lt;<a href="mailto:daniel.sanders@imgtec.com">daniel.sanders@imgtec.com</a>&gt;<br>
----<br>
- .../all/patches/fix-slab-allocator-bootstrap.patch | 49 ++++++++++++++++++++++<br>
- arch/all/patches/series                            |  1 +<br>
- 2 files changed, 50 insertions(+)<br>
- create mode 100644 arch/all/patches/fix-slab-allocator-bootstrap.patch<br>
-<br>
-diff --git a/arch/all/patches/fix-slab-allocator-bootstrap.patch b/arch/all/patches/fix-slab-allocator-bootstrap.patch<br>
-new file mode 100644<br>
-index 0000000..00d2abe<br>
---- /dev/null<br>
-+++ b/arch/all/patches/fix-slab-allocator-bootstrap.patch<br>
-@@ -0,0 +1,49 @@<br>
-+From e22638bbb262796ecb717e7cbc795aaad954a4ce Mon Sep 17 00:00:00 2001<br>
-+From: Daniel Sanders &lt;<a href="mailto:daniel.sanders@imgtec.com">daniel.sanders@imgtec.com</a>&gt;<br>
-+Date: Fri, 19 Dec 2014 13:16:19 +0000<br>
-+Subject: [PATCH 1/2] [WIP] Fix slab allocator bootstrap.<br>
-+<br>
-+There are currently two functions that generate indices into kmalloc_caches and<br>
-+they disagree with each other.  This patch fixes the bug to the point that the<br>
-+LLVM-compiled kernel successfully boots for Mips but it will need further work<br>
-+before upstreaming.<br>
-+<br>
-+The failing sequence is:<br>
-+* kmalloc_caches contains NULL elements<br>
-+* kmem_cache_init initialises the element that &#39;struct kmem_cache_node&#39; will be<br>
-+  allocated to. For 32-bit Mips, this is a 56-byte struct and kmalloc_index<br>
-+  selects element 7.<br>
-+* init_list is called which calls kmalloc_node to allocate a &#39;struct<br>
-+  kmem_cache_node&#39;.<br>
-+* kmalloc_slab selects the kmem_caches element using<br>
-+  size_index[size_index_elem(size)]. For Mips, size is 56, and the expression<br>
-+  returns 6.<br>
-+* This element of kmalloc_caches is NULL and allocation fails.<br>
-+<br>
-+GCC does not normally encounter this bug. I believe this is because it manages<br>
-+to optimise the problematic allocation away. This theory is supported by GCC<br>
-+encountering this bug when I disable inlining by changing the definitions of<br>
-+inline, __inline, __inline__, and __always_inline in<br>
-+include/linux/compiler-gcc.h.<br>
-+<br>
-+Signed-off-by: Daniel Sanders &lt;<a href="mailto:daniel.sanders@imgtec.com">daniel.sanders@imgtec.com</a>&gt;<br>
-+---<br>
-+ mm/slab_common.c | 2 +-<br>
-+ 1 file changed, 1 insertion(+), 1 deletion(-)<br>
-+<br>
-+diff --git a/mm/slab_common.c b/mm/slab_common.c<br>
-+index e03dd6f..459433f 100644<br>
-+--- a/mm/slab_common.c<br>
-++++ b/mm/slab_common.c<br>
-+@@ -620,7 +620,7 @@ static s8 size_index[24] = {<br>
-+      5,      /* 32 */<br>
-+      6,      /* 40 */<br>
-+      6,      /* 48 */<br>
-+-     6,      /* 56 */<br>
-++     7,      /* 56 */<br>
-+      6,      /* 64 */<br>
-+      1,      /* 72 */<br>
-+      1,      /* 80 */<br>
-+--<br>
-+2.1.3<br>
-+<br>
-diff --git a/arch/all/patches/series b/arch/all/patches/series<br>
-index b37fbe0..523c83d 100644<br>
---- a/arch/all/patches/series<br>
-+++ b/arch/all/patches/series<br>
-@@ -25,3 +25,4 @@ vlais-wimax-i2400m.patch<br>
- compiler-gcc.patch<br>
- smaller.patch<br>
- lib-mpi-extern-inline.patch<br>
-+fix-slab-allocator-bootstrap.patch<br>
---<br>
-2.1.3<br>
-<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.1.4<br>
<br>
_______________________________________________<br>
LLVMLinux mailing list<br>
<a href="mailto:LLVMLinux@lists.linuxfoundation.org">LLVMLinux@lists.linuxfoundation.org</a><br>
<a href="https://lists.linuxfoundation.org/mailman/listinfo/llvmlinux" target="_blank">https://lists.linuxfoundation.org/mailman/listinfo/llvmlinux</a><br>
</font></span></blockquote></div><br></div>