From: Scott Wood <hidden> Date: 2014-08-02 03:07:59
This silences a section mismatch warning. early_alloc_pgtable() is
called from map_kernel_page() which cannot be __init, but only when
slab_is_available() returns false which can only happen during early
boot.
Signed-off-by: Scott Wood <redacted>
---
arch/powerpc/mm/pgtable_64.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
From: Scott Wood <hidden> Date: 2014-08-02 03:08:01
__early_init_mmu() does some things that are really only needed by the
boot cpu. On FSL booke, This includes calling
memblock_enforce_memory_limit(), which is labelled __init. Secondary
cpu init code can't be __init as that would break CPU hotplug.
While it's probably a bug that memblock_enforce_memory_limit() isn't
__init_memblock instead, there's no reason why we should be doing this
stuff for secondary cpus in the first place.
Signed-off-by: Scott Wood <redacted>
---
arch/powerpc/mm/tlb_nohash.c | 90 ++++++++++++++++++++++----------------------
1 file changed, 46 insertions(+), 44 deletions(-)
@@ -581,42 +581,10 @@ static void setup_mmu_htw(void)/**EarlyinitializationoftheMMUTLBcode*/-staticvoid__early_init_mmu(intboot_cpu)+staticvoidearly_init_mmu_allcpus(void){unsignedintmas4;-/* XXX This will have to be decided at runtime, but right-*nowourbootandTLBmisscodehardwiresit.Ideally-*weshouldfindoutasuitablepagesizeandpatchthe-*TLBmisscode(eitherthatorusethePACAtostore-*thevaluewewant)-*/-mmu_linear_psize=MMU_PAGE_1G;--/* XXX This should be decided at runtime based on supported-*pagesizesintheTLB,butfornowlet'sassume16Mis-*alwaysthereandagoodfit(whichitprobablyis)-*-*Freescalebookeonlysupports4KpagesinTLB0,sousethat.-*/-if(mmu_has_feature(MMU_FTR_TYPE_FSL_E))-mmu_vmemmap_psize=MMU_PAGE_4K;-else-mmu_vmemmap_psize=MMU_PAGE_16M;--/* XXX This code only checks for TLB 0 capabilities and doesn't-*checkwhatpagesizecombosaresupportedbytheHW.It-*alsodoesn'thandlethecasewhereaseparatearrayholds-*theINDentriesfromthearrayloadedbythePT.-*/-if(boot_cpu){-/* Look for supported page sizes */-setup_page_sizes();--/* Look for HW tablewalk support */-setup_mmu_htw();-}-/* Set MAS4 based on page table setting */mas4=0x4<<MAS4_WIMGED_SHIFT;
@@ -650,11 +618,6 @@ static void __early_init_mmu(int boot_cpu)}mtspr(SPRN_MAS4,mas4);-/* Set the global containing the top of the linear mapping-*forusebytheTLBmisscode-*/-linear_map_top=memblock_end_of_DRAM();-#ifdef CONFIG_PPC_FSL_BOOK3Eif(mmu_has_feature(MMU_FTR_TYPE_FSL_E)){unsignedintnum_cams;
@@ -662,7 +625,51 @@ static void __early_init_mmu(int boot_cpu)/* use a quarter of the TLBCAM for bolted linear map */num_cams=(mfspr(SPRN_TLB1CFG)&TLBnCFG_N_ENTRY)/4;linear_map_top=map_mem_in_cams(linear_map_top,num_cams);+}+#endif+}+void__initearly_init_mmu(void)+{+/* XXX This will have to be decided at runtime, but right+*nowourbootandTLBmisscodehardwiresit.Ideally+*weshouldfindoutasuitablepagesizeandpatchthe+*TLBmisscode(eitherthatorusethePACAtostore+*thevaluewewant)+*/+mmu_linear_psize=MMU_PAGE_1G;++/* XXX This should be decided at runtime based on supported+*pagesizesintheTLB,butfornowlet'sassume16Mis+*alwaysthereandagoodfit(whichitprobablyis)+*+*Freescalebookeonlysupports4KpagesinTLB0,sousethat.+*/+if(mmu_has_feature(MMU_FTR_TYPE_FSL_E))+mmu_vmemmap_psize=MMU_PAGE_4K;+else+mmu_vmemmap_psize=MMU_PAGE_16M;++/* XXX This code only checks for TLB 0 capabilities and doesn't+*checkwhatpagesizecombosaresupportedbytheHW.It+*alsodoesn'thandlethecasewhereaseparatearrayholds+*theINDentriesfromthearrayloadedbythePT.+*/+/* Look for supported page sizes */+setup_page_sizes();++/* Look for HW tablewalk support */+setup_mmu_htw();++/* Set the global containing the top of the linear mapping+*forusebytheTLBmisscode+*/+linear_map_top=memblock_end_of_DRAM();++early_init_mmu_allcpus();++#ifdef CONFIG_PPC_FSL_BOOK3E+if(mmu_has_feature(MMU_FTR_TYPE_FSL_E)){/* limit memory so we dont have linear faults */memblock_enforce_memory_limit(linear_map_top);
Small nit, it took me 30s too long to figure out what you were doing due
to the naming above :)
Call the latter early_init_this_mmu() and keep the global one separate
such that early_init_mmu() does:
early_init_mmu_common();
early_init_this_mmu();
Cheers,
Ben.
Small nit, it took me 30s too long to figure out what you were doing due
to the naming above :)
Call the latter early_init_this_mmu() and keep the global one separate
such that early_init_mmu() does:
early_init_mmu_common();
early_init_this_mmu();
I'll do s/mmu_allcpus/this_mmu/ but early_init_mmu() needs to do things
both before and after early_init_mmu_common(). Do you want two new
functions (before and after) or is it OK to just rename
early_init_mmu_allcpus() and put a comment before early_init_mmu()
saying it's just for the boot cpu?
-Scott
From: Benjamin Herrenschmidt <benh@kernel.crashing.org> Date: 2014-08-06 04:59:09
On Tue, 2014-08-05 at 19:48 -0500, Scott Wood wrote:
I'll do s/mmu_allcpus/this_mmu/ but early_init_mmu() needs to do things
both before and after early_init_mmu_common(). Do you want two new
functions (before and after) or is it OK to just rename
early_init_mmu_allcpus() and put a comment before early_init_mmu()
saying it's just for the boot cpu?
Do we really need that before/after ? The "after" code is the linear
mapping setup but does it rely on the MAS4 setting done above ?
Otherwise you can do before/after using a separate function
mmu_set_linear_map()
Always nicer to break down too large functions anyway.
Cheers,
Ben.
From: Scott Wood <hidden> Date: 2014-08-06 20:09:27
On Wed, 2014-08-06 at 14:58 +1000, Benjamin Herrenschmidt wrote:
On Tue, 2014-08-05 at 19:48 -0500, Scott Wood wrote:
quoted
I'll do s/mmu_allcpus/this_mmu/ but early_init_mmu() needs to do things
both before and after early_init_mmu_common(). Do you want two new
functions (before and after) or is it OK to just rename
early_init_mmu_allcpus() and put a comment before early_init_mmu()
saying it's just for the boot cpu?
Do we really need that before/after ? The "after" code is the linear
mapping setup but does it rely on the MAS4 setting done above ?
No, but it relies on the call to map_mem_in_cams() to determine how much
memory was able to be mapped.
Otherwise you can do before/after using a separate function
mmu_set_linear_map()
OK.
Always nicer to break down too large functions anyway.
Usually yes, but it doesn't necessarily help when it's an arbitrary
division of a function that is a list of simple things (as opposed to
e.g. factoring out the #ifdef CONFIG_PPC_FSL_BOOK3E block into its own
function).
BTW, is there a particular reason why we need to use
memblock_enforce_memory_limit() on FSL_BOOK3E, rather than relying on
memblock_set_current_limit()? I see that when
memblock_enforce_memory_limit() was added to __early_init_mmu(),
memblock_set_current_limit() did not exist. On 32-bit fsl booke uses
memblock_set_current_limit() for this.
-Scott
From: Benjamin Herrenschmidt <benh@kernel.crashing.org> Date: 2014-08-06 20:46:25
On Wed, 2014-08-06 at 15:09 -0500, Scott Wood wrote:
BTW, is there a particular reason why we need to use
memblock_enforce_memory_limit() on FSL_BOOK3E, rather than relying on
memblock_set_current_limit()? I see that when
memblock_enforce_memory_limit() was added to __early_init_mmu(),
memblock_set_current_limit() did not exist. On 32-bit fsl booke uses
memblock_set_current_limit() for this.
I don't remember. I don't even know what the difference is, I can
have a look later if you want but I'd rather you did :-)
Cheers,
Ben.