x86-64, NUMA: Restructure initmem_init()
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 109 lines · tip-bot for Tejun Heo
arch/x86/mm/numa_64.c +42
-43@@ -580,65 +580,73 @@ static int __init numa_emulation(unsigned long start_pfn, }#endif /* CONFIG_NUMA_EMU */ -void __init initmem_init (void ) +static int dummy_numa_init (void ) { -int acpi =0 , amd =0 ; -int i; - -#ifdef CONFIG_ACPI_NUMA -/* -* Parse SRAT to discover nodes. -*/ - acpi = !x86_acpi_numa_init (); -#endif - -#ifdef CONFIG_AMD_NUMA -if (!acpi) - amd = !amd_numa_init (); -#endif - -nodes_clear (node_possible_map); -nodes_clear (node_online_map); - -#ifdef CONFIG_NUMA_EMU -setup_physnodes (0 , max_pfn <<PAGE_SHIFT , acpi, amd); -if (cmdline && !numa_emulation (0 , max_pfn, acpi, amd)) -return ; -setup_physnodes (0 , max_pfn <<PAGE_SHIFT , acpi, amd); -nodes_clear (node_possible_map); -nodes_clear (node_online_map); -#endif - -#ifdef CONFIG_ACPI_NUMA -if (!numa_off && acpi && !acpi_scan_nodes ()) -return ; -nodes_clear (node_possible_map); -nodes_clear (node_online_map); -#endif +return 0 ; +} -#ifdef CONFIG_AMD_NUMA -if (!numa_off && amd && !amd_scan_nodes ()) -return ; -nodes_clear (node_possible_map); -nodes_clear (node_online_map); -#endif +static int dummy_scan_nodes (void ) +{printk (KERN_INFO "%s\n" , numa_off ?"NUMA turned off" :"No NUMA configuration found" ); -printk (KERN_INFO "Faking a node at %016lx-%016lx\n" ,0LU , max_pfn <<PAGE_SHIFT ); +/* setup dummy node covering all memory */ memnode_shift =63 ; memnodemap = memnode.embedded_map; memnodemap[0 ] =0 ;node_set_online (0 );node_set (0 , node_possible_map); -for (i =0 ; i <MAX_LOCAL_APIC ; i++) -set_apicid_to_node (i,NUMA_NO_NODE );memblock_x86_register_active_regions (0 ,0 , max_pfn);init_memory_mapping_high ();setup_node_bootmem (0 ,0 , max_pfn <<PAGE_SHIFT );numa_init_array (); + +return 0 ; +} + +void __init initmem_init (void ) +{ +int (*numa_init[])(void ) = { [2 ] = dummy_numa_init }; +int (*scan_nodes[])(void ) = { [2 ] = dummy_scan_nodes }; +int i, j; + +if (!numa_off) { +#ifdef CONFIG_ACPI_NUMA + numa_init[0 ] = x86_acpi_numa_init; + scan_nodes[0 ] = acpi_scan_nodes; +#endif +#ifdef CONFIG_AMD_NUMA + numa_init[1 ] = amd_numa_init; + scan_nodes[1 ] = amd_scan_nodes; +#endif + } + +for (i =0 ; i <ARRAY_SIZE (numa_init); i++) { +if (!numa_init[i]) +continue ; + +for (j =0 ; j <MAX_LOCAL_APIC ; j++) +set_apicid_to_node (j,NUMA_NO_NODE ); + +nodes_clear (node_possible_map); +nodes_clear (node_online_map); + +if (numa_init[i]() <0 ) +continue ; +#ifdef CONFIG_NUMA_EMU +setup_physnodes (0 , max_pfn <<PAGE_SHIFT , i ==0 , i ==1 ); +if (cmdline && !numa_emulation (0 , max_pfn, i ==0 , i ==1 ))
arch/x86/mm/numa_64.c static int __init numa_emulation(unsigned long start_pfn, · line 650
Quoted 10 lines
arch/x86/mm/numa_64.c +9
-0+return ; +setup_physnodes (0 , max_pfn <<PAGE_SHIFT , i ==0 , i ==1 ); +nodes_clear (node_possible_map); +nodes_clear (node_online_map); +#endif +if (!scan_nodes[i]()) +return ; + } +BUG (); }
This doesn't look very clean, I think it would be much better to extract the iteration out to a function of its own which takes an init and scan function as arguments and then deal only with numa_off, CONFIG_ACPI_NUMA, and CONFIG_AMD_NUMA callers in initmem_init(). If that's done, it's clear that the dummy implementation will never fail and so the BUG() in this case is never possible (which is intended if all else fails).
Quoted 6 lines · David Rientjes
This doesn't look very clean, I think it would be much better to extract the iteration out to a function of its own which takes an init and scan function as arguments and then deal only with
numa_off,CONFIG_ACPI_NUMA, andCONFIG_AMD_NUMAcallers ininitmem_init(). If that's done, it's clear that the dummy implementation will never fail and so theBUG()in this case is never possible (which is intended if all else fails).
I don't know. Maybe. Care to send a patch?
Signature · 1 line
tejun
PATCH 1/1 x86, mm: Clean up initmem_init
This patch cleans initmem_init() so that it is more readable and doesn't use an unnecessary array of function pointers to convolute the flow of the code. It also makes it obvious that dummy_numa_init() will always succeed (and documents that requirement) so that the existing BUG() is never actually reached.
No functional change.
--- arch/x86/mm/numa_64.c | 92 ++++++++++++++++++++++++++++--------------------- 1 files changed, 53 insertions(+), 39 deletions(-)
arch/x86/mm/numa_64.c +53 -39
@@ -564,6 +564,13 @@ static int __init numa_register_memblks(struct numa_meminfo *mi)return 0 ; } +/* +* Used if there's no underlying NUMA architecture, NUMA initialization fails, +* or NUMA is disabled on the command line. +* +* Must online at least one node and add memory blocks that cover all allowed +* memory. +*/ static int __init dummy_numa_init (void ) { printk(KERN_INFO "%s\n",
@@ -577,57 +584,64 @@ static int __init dummy_numa_init(void)return 0 ; } -void __init initmem_init (void ) +static int __init numa_init (int (*init_func)(void )) { -int (*numa_init[])(void ) = { [2 ] = dummy_numa_init }; -int i, j; - -if (!numa_off) { -#ifdef CONFIG_ACPI_NUMA - numa_init[0 ] = x86_acpi_numa_init; -#endif -#ifdef CONFIG_AMD_NUMA - numa_init[1 ] = amd_numa_init; -#endif - } +int i; +int ret; -for (i =0 ; i <ARRAY_SIZE (numa_init); i++) { -if (!numa_init[i]) -continue ; +for (i =0 ; i <MAX_LOCAL_APIC ; i++) +set_apicid_to_node (i,NUMA_NO_NODE ); -for (j =0 ; j <MAX_LOCAL_APIC ; j++) -set_apicid_to_node (j,NUMA_NO_NODE ); +nodes_clear (numa_nodes_parsed); +nodes_clear (node_possible_map); +nodes_clear (node_online_map); +memset (&numa_meminfo,0 ,sizeof (numa_meminfo)); +remove_all_active_ranges (); +numa_reset_distance (); -nodes_clear (numa_nodes_parsed); -nodes_clear (node_possible_map); -nodes_clear (node_online_map); -memset (&numa_meminfo,0 ,sizeof (numa_meminfo)); -remove_all_active_ranges (); -numa_reset_distance (); + ret =init_func (); +if (ret <0 ) +return ret; + ret =numa_cleanup_meminfo (&numa_meminfo); +if (ret <0 ) +return ret; -if (numa_init[i]() <0 ) -continue ; +numa_emulation (&numa_meminfo, numa_distance_cnt); -if (numa_cleanup_meminfo (&numa_meminfo) <0 ) -continue ; + ret =numa_register_memblks (&numa_meminfo); +if (ret <0 ) +return ret; -numa_emulation (&numa_meminfo, numa_distance_cnt); +for (i =0 ; i < nr_cpu_ids; i++) { +int nid =early_cpu_to_node (i); -if (numa_register_memblks (&numa_meminfo) <0 ) +if (nid ==NUMA_NO_NODE )continue ; +if (!node_online (nid)) +numa_clear_node (i); + } +numa_init_array (); +return 0 ; +} -for (j =0 ; j < nr_cpu_ids; j++) { -int nid =early_cpu_to_node (j); +void __init initmem_init (void ) +{ +int ret; -if (nid ==NUMA_NO_NODE ) -continue ; -if (!node_online (nid)) -numa_clear_node (j); - } -numa_init_array (); -return ; +if (!numa_off) { +#ifdef CONFIG_ACPI_NUMA + ret =numa_init (x86_acpi_numa_init); +if (!ret) +return ; +#endif +#ifdef CONFIG_AMD_NUMA + ret =numa_init (amd_numa_init); +if (!ret) +return ; +#endif } -BUG (); + +numa_init (dummy_numa_init); }unsigned long __init numa_free_all_bootmem (void )
Re: [patch] x86, mm: Clean up initmem_init
Quoted 13 lines · David Rientjes
This patch cleans
initmem_init()so that it is more readable and doesn't use an unnecessary array of function pointers to convolute the flow of the code. It also makes it obvious thatdummy_numa_init()will always succeed (and documents that requirement) so that the existingBUG()is never actually reached.No functional change.
Signed-off-by David Rientjes <[email protected]>--- arch/x86/mm/numa_64.c | 92 ++++++++++++++++++++++++++++--------------------- 1 files changed, 53 insertions(+), 39 deletions(-)
...
Quoted 19 lines
arch/x86/mm/numa_64.c +11
-7+void __init initmem_init (void ) +{ +int ret; -if (nid ==NUMA_NO_NODE ) -continue ; -if (!node_online (nid)) -numa_clear_node (j); - } -numa_init_array (); -return ; +if (!numa_off) { +#ifdef CONFIG_ACPI_NUMA + ret =numa_init (x86_acpi_numa_init); +if (!ret) +return ; +#endif +#ifdef CONFIG_AMD_NUMA + ret =numa_init (amd_numa_init);
arch/x86/mm/numa_64.c static int __init dummy_numa_init(void) · line 647
Quoted 10 lines
arch/x86/mm/numa_64.c +5
-1+if (!ret) +return ; +#endif } -BUG (); + +numa_init (dummy_numa_init); }unsigned long __init numa_free_all_bootmem (void )
Divid, I suspect it's due to diff format and we still need "ret" here, right?
Signature · 1 line
Cyrill
Re: [patch] x86, mm: Clean up initmem_init
Quoted 42 lines · Cyrill Gorcunov
Quoted 13 lines
This patch cleans
initmem_init()so that it is more readable and doesn't use an unnecessary array of function pointers to convolute the flow of the code. It also makes it obvious thatdummy_numa_init()will always succeed (and documents that requirement) so that the existingBUG()is never actually reached.No functional change.
Signed-off-by David Rientjes <[email protected]>--- arch/x86/mm/numa_64.c | 92 ++++++++++++++++++++++++++++--------------------- 1 files changed, 53 insertions(+), 39 deletions(-)...
Quoted 28 lines
arch/x86/mm/numa_64.c +16
-8+void __init initmem_init (void ) +{ +int ret; -if (nid ==NUMA_NO_NODE ) -continue ; -if (!node_online (nid)) -numa_clear_node (j); - } -numa_init_array (); -return ; +if (!numa_off) { +#ifdef CONFIG_ACPI_NUMA + ret =numa_init (x86_acpi_numa_init); +if (!ret) +return ; +#endif +#ifdef CONFIG_AMD_NUMA + ret =numa_init (amd_numa_init); +if (!ret) +return ; +#endif } -BUG (); + +numa_init (dummy_numa_init); }
Quoted 4 lines
Quoted 1 line
unsigned long
__initnuma_free_all_bootmem(void)Divid, I suspect it's due to diff format and we still need "ret" here, right?
Not sure what you mean. "ret" is a temporary variable to test the return values of numa_init() and return from initmem_init() on success.
Re: [patch] x86, mm: Clean up initmem_init
On 03/03/2011 02:00 PM, David Rientjes wrote:
he want
Quoted 10 lines
+#ifdef
CONFIG_ACPI_NUMAQuoted 9 lines
arch/x86/mm/numa_64.c static int __init dummy_numa_init(void) · line 641
Quoted 9 lines
arch/x86/mm/numa_64.c +9
-0+ ret =numa_init (x86_acpi_numa_init); +if (!ret) +return ; +#endif +#ifdef CONFIG_AMD_NUMA + ret =numa_init (amd_numa_init); +if (!ret) +return ; +#endif
to be replaced by:
Quoted 8 lines
+#ifdef
CONFIG_ACPI_NUMAQuoted 7 lines
Quoted 7 lines
arch/x86/mm/numa_64.c +7
-0+if (!numa_init (x86_acpi_numa_init)) +return ; +#endif +#ifdef CONFIG_AMD_NUMA +if (!numa_init (amd_numa_init)) +return ; +#endif
Re: [patch] x86, mm: Clean up initmem_init
Quoted 4 lines · Yinghai Lu
On 03/03/2011 02:00 PM, David Rientjes wrote:
he want
yeah, if only i didn't miss something
Signature · 1 line
Cyrill
Re: [patch] x86, mm: Clean up initmem_init
In reply to Yinghai LuQuoted 15 lines · Yinghai Lu
he want
Quoted 10 lines
+#ifdef
CONFIG_ACPI_NUMAQuoted 9 lines
arch/x86/mm/numa_64.c static int __init dummy_numa_init(void) · line 641
Quoted 9 lines
arch/x86/mm/numa_64.c +9
-0+ ret =numa_init (x86_acpi_numa_init); +if (!ret) +return ; +#endif +#ifdef CONFIG_AMD_NUMA + ret =numa_init (amd_numa_init); +if (!ret) +return ; +#endif to be replaced by:
Quoted 8 lines
Quoted 8 lines
+#ifdef
CONFIG_ACPI_NUMAQuoted 7 lines
arch/x86/mm/numa_64.c static int __init dummy_numa_init(void) · line 641
Quoted 7 lines
arch/x86/mm/numa_64.c +7
-0+if (!numa_init (x86_acpi_numa_init)) +return ; +#endif +#ifdef CONFIG_AMD_NUMA +if (!numa_init (amd_numa_init)) +return ; +#endif
It's a matter of style and I think it's up to Ingo what he'd prefer to see.
Re: [patch] x86, mm: Clean up initmem_init
Quoted 18 lines · David Rientjes
Quoted 16 lines · Yinghai Lu
he want
Quoted 10 lines
+#ifdef
CONFIG_ACPI_NUMAQuoted 9 lines
arch/x86/mm/numa_64.c static int __init dummy_numa_init(void) · line 641
Quoted 9 lines
arch/x86/mm/numa_64.c +9
-0+ ret =numa_init (x86_acpi_numa_init); +if (!ret) +return ; +#endif +#ifdef CONFIG_AMD_NUMA + ret =numa_init (amd_numa_init); +if (!ret) +return ; +#endif to be replaced by:
Quoted 1 line
+#ifdef
CONFIG_ACPI_NUMA
Quoted 10 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
arch/x86/mm/numa_64.c static int __init dummy_numa_init(void) · line 641
Quoted 7 lines
arch/x86/mm/numa_64.c +7
-0+if (!numa_init (x86_acpi_numa_init)) +return ; +#endif +#ifdef CONFIG_AMD_NUMA +if (!numa_init (amd_numa_init)) +return ; +#endif It's a matter of style and I think it's up to Ingo what he'd prefer to see.
i'm fine with either, just though it would shrink the code a bit (since there is no need to track var witch i guess will be eliminated by gcc anyway).
nb: am i only the one who obtain bounce from [email protected] (so i'd to remove him from cc'ing)?
Signature · 1 line
Cyrill
Re: [patch] x86, mm: Clean up initmem_init
In reply to David RientjesQuoted 18 lines · David Rientjes
Quoted 16 lines · Yinghai Lu
he want
Quoted 10 lines
+#ifdef
CONFIG_ACPI_NUMAQuoted 9 lines
arch/x86/mm/numa_64.c static int __init dummy_numa_init(void) · line 641
Quoted 9 lines
arch/x86/mm/numa_64.c +9
-0+ ret =numa_init (x86_acpi_numa_init); +if (!ret) +return ; +#endif +#ifdef CONFIG_AMD_NUMA + ret =numa_init (amd_numa_init); +if (!ret) +return ; +#endif to be replaced by:
Quoted 1 line
+#ifdef
CONFIG_ACPI_NUMA
Quoted 10 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
arch/x86/mm/numa_64.c static int __init dummy_numa_init(void) · line 641
Quoted 7 lines
arch/x86/mm/numa_64.c +7
-0+if (!numa_init (x86_acpi_numa_init)) +return ; +#endif +#ifdef CONFIG_AMD_NUMA +if (!numa_init (amd_numa_init)) +return ; +#endif It's a matter of style and I think it's up to Ingo what he'd prefer to see.
I think your variant is cleaner: hiding function call side-effects in conditionscan be a fragile thing to do. We want constant expressions with no side-effects - so if functions are called they should be constant functions as well.
Code compactness isn't everything - if it was we'd be using C to the max to create unreadable compound expressions all the time.
Thanks,
Ingo
Re: [patch] x86, mm: Clean up initmem_init
On Fri, Mar 4, 2011 at 10:08 AM, Ingo Molnar <[email protected]> wrote:
...
Quoted 7 lines
Quoted 3 lines
It's a matter of style and I think it's up to Ingo what he'd prefer to see.
I think your variant is cleaner: hiding function call side-effects in conditionscan be a fragile thing to do. We want constant expressions with no side-effects - so if functions are called they should be constant functions as well.
Well, we do it a lot with say strcmp and others so I would use rather semantic argument,
but I agree that David's version is easier to read and mark same time that these functions
are important steps in bootup procedure. So I'm sorry for proposing this change in first place.
Quoted 8 lines
Code compactness isn't everything - if it was we'd be using C to the max to create unreadable compound expressions all the time.
Thanks,
Ingo
Re: [patch] x86, mm: Clean up initmem_init
In reply to David RientjesHello,
Quoted 9 lines · David Rientjes
This patch cleans
initmem_init()so that it is more readable and doesn't use an unnecessary array of function pointers to convolute the flow of the code. It also makes it obvious thatdummy_numa_init()will always succeed (and documents that requirement) so that the existingBUG()is never actually reached.No functional change.
Signed-off-by David Rientjes <[email protected]>
Just a nitpick.
Quoted 7 lines
+/*
+ * Used if there's no underlying NUMA architecture, NUMA initialization fails,
+ * or NUMA is disabled on the command line.
+ *
+ * Must online at least one node and add memory blocks that cover all allowed
+ * memory.
+ */
Can you please reformat to docbook style?
Thanks.
Signature · 1 line
tejun
PATCH 1/1 x86-64, NUMA: Clean up initmem_init()
Quoted 1 line
From
c09cedf4f75f1e47ea17f55e18e9cfb81bec8575Mon Sep 17 00:00:00 2001
From: David Rientjes <[email protected]>
Date: Fri, 4 Mar 2011 15:17:21 +0100
This patch cleans initmem_init() so that it is more readable and doesn't use an unnecessary array of function pointers to convolute the flow of the code. It also makes it obvious that dummy_numa_init() will always succeed (and documents that requirement) so that the existing BUG() is never actually reached.
No functional change.
-tj: Updated comment for dummy_numa_init() slightly.
---
Never mind the previous message. I just updated and applied it. Thanks.
arch/x86/mm/numa_64.c | 94 ++++++++++++++++++++++++++++-------------------- 1 files changed, 55 insertions(+), 39 deletions(-)
arch/x86/mm/numa_64.c +55 -39
@@ -562,6 +562,15 @@ static int __init numa_register_memblks(struct numa_meminfo *mi)return 0 ; } +/** +* dummy_numma_init - Fallback dummy NUMA init +* +* Used if there's no underlying NUMA architecture, NUMA initialization +* fails, or NUMA is disabled on the command line. +* +* Must online at least one node and add memory blocks that cover all +* allowed memory. This function must not fail. +*/ static int __init dummy_numa_init (void ) { printk(KERN_INFO "%s\n",
@@ -575,57 +584,64 @@ static int __init dummy_numa_init(void)return 0 ; } -void __init initmem_init (void ) +static int __init numa_init (int (*init_func)(void )) { -int (*numa_init[])(void ) = { [2 ] = dummy_numa_init }; -int i, j; - -if (!numa_off) { -#ifdef CONFIG_ACPI_NUMA - numa_init[0 ] = x86_acpi_numa_init; -#endif -#ifdef CONFIG_AMD_NUMA - numa_init[1 ] = amd_numa_init; -#endif - } +int i; +int ret; -for (i =0 ; i <ARRAY_SIZE (numa_init); i++) { -if (!numa_init[i]) -continue ; +for (i =0 ; i <MAX_LOCAL_APIC ; i++) +set_apicid_to_node (i,NUMA_NO_NODE ); -for (j =0 ; j <MAX_LOCAL_APIC ; j++) -set_apicid_to_node (j,NUMA_NO_NODE ); +nodes_clear (numa_nodes_parsed); +nodes_clear (node_possible_map); +nodes_clear (node_online_map); +memset (&numa_meminfo,0 ,sizeof (numa_meminfo)); +remove_all_active_ranges (); +numa_reset_distance (); -nodes_clear (numa_nodes_parsed); -nodes_clear (node_possible_map); -nodes_clear (node_online_map); -memset (&numa_meminfo,0 ,sizeof (numa_meminfo)); -remove_all_active_ranges (); -numa_reset_distance (); + ret =init_func (); +if (ret <0 ) +return ret; + ret =numa_cleanup_meminfo (&numa_meminfo); +if (ret <0 ) +return ret; -if (numa_init[i]() <0 ) -continue ; +numa_emulation (&numa_meminfo, numa_distance_cnt); -if (numa_cleanup_meminfo (&numa_meminfo) <0 ) -continue ; + ret =numa_register_memblks (&numa_meminfo); +if (ret <0 ) +return ret; -numa_emulation (&numa_meminfo, numa_distance_cnt); +for (i =0 ; i < nr_cpu_ids; i++) { +int nid =early_cpu_to_node (i); -if (numa_register_memblks (&numa_meminfo) <0 ) +if (nid ==NUMA_NO_NODE )continue ; +if (!node_online (nid)) +numa_clear_node (i); + } +numa_init_array (); +return 0 ; +} -for (j =0 ; j < nr_cpu_ids; j++) { -int nid =early_cpu_to_node (j); +void __init initmem_init (void ) +{ +int ret; -if (nid ==NUMA_NO_NODE ) -continue ; -if (!node_online (nid)) -numa_clear_node (j); - } -numa_init_array (); -return ; +if (!numa_off) { +#ifdef CONFIG_ACPI_NUMA + ret =numa_init (x86_acpi_numa_init); +if (!ret) +return ; +#endif +#ifdef CONFIG_AMD_NUMA + ret =numa_init (amd_numa_init); +if (!ret) +return ; +#endif } -BUG (); + +numa_init (dummy_numa_init); }unsigned long __init numa_free_all_bootmem (void )
Signature · 1 line
1.7.1