x86, ACPI, numa: Parse numa info early
Subsystems (8)
cover x86, ACPI, numa: Parse numa info early
One commit that tried to parse SRAT early get reverted before v3.9-rc1.
| commit e8d1955258091e4c92d5a975ebd7fd8a98f5d30f | Author: Tang Chen <[email protected]> | Date: Fri Feb 22 16:33:44 2013 -0800 | | acpi, memory-hotplug: parse SRAT before memblock is ready
It broke several several things, like acpi override and fall back path etc.
This patchset is clean implementation that will parse numa info early.
1. keep the acpi table initrd override working by split finding with copying. finding is done at head_32.S and head64.c stage, that mimics microcode updating. copying is just after memblock is setup.
2. keep fallback path working. numaq and ACPI and amd_nmua and dummy. seperate initmem_init to two stages. early_initmem_init will only extract numa info early into numa_meminfo.
3. keep other old code flow untouched like relocate_initrd and initmem_init.
4. last patch will try to put page table on local node, so that memory hotplug will be happy.
In short, early_initmem_init will parse numa info early and call init_mem_mapping to set page table for every nodes's mem.
could be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/yinghai/linux-yinghai.git for-x86-mm
and it is based on today's Linus tree that merges x86_urgent.
Tested on x86 32bit non-numa/numa, 64bit non-numa/numa configurations.
Thanks
Yinghai
Yinghai Lu (14):
x86, ACPI, mm: Kill max_low_pfn_mapped
x86, ACPI: Split find/copy from acpi_initrd_override x86, ACPI: store override acpi tables phys addr
x86, ACPI: make acpi override finding work with 32bit flat mode x86, ACPI: Find acpi tables in initrd early at head_32.S/head64.c x86, mm, numa: Move successful path handling code later x86, mm, numa: call numa_meminfo_cover_memory() early x86, mm, numa: use numa_meminfo to check node_map_pfn alignment x86, mm, numa: set memblock nid later
x86, mm, numa: Move emulation handling down.
x86, acpi, numa: split SLIT handling out
x86, mm, numa: Add early_initmem_init() stub
x86, mm: Parse numa info early
x86, mm: Put pagetable on local node ram
arch/x86/include/asm/acpi.h | 3 +- arch/x86/include/asm/page_types.h | 2 +- arch/x86/include/asm/pgtable.h | 2 +- arch/x86/include/asm/setup.h | 2 + arch/x86/kernel/head64.c | 2 + arch/x86/kernel/head_32.S | 4 + arch/x86/kernel/setup.c | 56 +++++--- arch/x86/mm/init.c | 87 ++++++------ arch/x86/mm/init_32.c | 11 ++ arch/x86/mm/init_64.c | 12 ++ arch/x86/mm/numa.c | 236 +++++++++++++++++++++++++------- arch/x86/mm/numa_emulation.c | 2 +- arch/x86/mm/numa_internal.h | 2 + arch/x86/mm/srat.c | 8 +- drivers/acpi/numa.c | 22 ++- drivers/acpi/osl.c | 122 +++++++++++------ drivers/gpu/drm/i915/i915_gem_stolen.c | 2 +- include/linux/acpi.h | 18 +-- include/linux/mm.h | 3 - mm/page_alloc.c | 52 +------ 20 files changed, 425 insertions(+), 223 deletions(-)
Signature · 1 line
1.7.10.4
PATCH 1/14 x86, ACPI, mm: Kill max_low_pfn_mapped
Now we have arch_pfn_mapped array, and max_low_pfn_mapped should not be used anymore.
Only user is ACPI_OVERRIDE, and it should not use that, as later accessing is using early_remap. Change to try to 4G below and then 4G above.
Other user is in drm/i915, but it is commented out.
Should use arch_pfn_mapped or just 1<<(32-PAGE_SHIFT) instead.
--- arch/x86/include/asm/page_types.h | 1 - arch/x86/kernel/setup.c | 4 +--- arch/x86/mm/init.c | 4 ---- drivers/acpi/osl.c | 9 ++++++--- drivers/gpu/drm/i915/i915_gem_stolen.c | 2 +- 5 files changed, 8 insertions(+), 12 deletions(-)
arch/x86/include/asm/page_types.h +0 -1
@@ -43,7 +43,6 @@extern int devmem_is_allowed (unsigned long pagenr); -extern unsigned long max_low_pfn_mapped;extern unsigned long max_pfn_mapped;static inline phys_addr_t get_max_mapped (void )
arch/x86/kernel/setup.c +1 -3
@@ -113,13 +113,11 @@#include <asm/prom.h> /* -* max_low_pfn_mapped: highest direct mapped pfn under 4GB -* max_pfn_mapped: highest direct mapped pfn over 4GB +* max_pfn_mapped: highest direct mapped pfn * * The direct mapping only covers E820_RAM regions, so the ranges and gaps are * represented by pfn_mapped */ -unsigned long max_low_pfn_mapped;unsigned long max_pfn_mapped;#ifdef CONFIG_DMI
arch/x86/mm/init.c +0 -4
@@ -313,10 +313,6 @@ static void add_pfn_range_mapped(unsigned long start_pfn, unsigned long end_pfn) nr_pfn_mapped =clean_sort_range (pfn_mapped,E820_X_MAX ); max_pfn_mapped =max (max_pfn_mapped, end_pfn); - -if (start_pfn < (1UL <<(32 -PAGE_SHIFT ))) - max_low_pfn_mapped =max (max_low_pfn_mapped, -min (end_pfn,1UL <<(32 -PAGE_SHIFT ))); }bool pfn_range_is_mapped (unsigned long start_pfn,unsigned long end_pfn)
drivers/acpi/osl.c +6 -3
@@ -624,9 +624,12 @@ void __init acpi_initrd_override(void *data, size_t size)if (table_nr ==0 )return ; - acpi_tables_addr = -memblock_find_in_range (0 , max_low_pfn_mapped <<PAGE_SHIFT , - all_tables_size,PAGE_SIZE ); +/* under 4G at first, then above 4G */ + acpi_tables_addr =memblock_find_in_range (0 ,1ULL <<32 , + all_tables_size,PAGE_SIZE ); +if (!acpi_tables_addr) + acpi_tables_addr =memblock_find_in_range (1ULL <<32 ,-1ULL , + all_tables_size,PAGE_SIZE );if (!acpi_tables_addr) {WARN_ON (1 );return ;
drivers/gpu/drm/i915/i915_gem_stolen.c +1 -1
@@ -81,7 +81,7 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) base -= dev_priv->mm.gtt->stolen_size; }else {/* Stolen is immediately above Top of Memory */ - base = max_low_pfn_mapped <<PAGE_SHIFT ; + base = __REMOVED_CRAZY__ <<PAGE_SHIFT ;#endif }
Signature · 1 line
1.7.10.4
Re: [PATCH 01/14] x86, ACPI, mm: Kill max_low_pfn_mapped
drivers/gpu/drm/i915/i915_gem_stolen.c static unsigned long i915_stolen_to_physical(struct drm_device *dev) · line 84
Quoted 10 lines · Yinghai Lu
drivers/gpu/drm/i915/i915_gem_stolen.c +1
-1@@ -81,7 +81,7 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) base -= dev_priv->mm.gtt->stolen_size; }else {/* Stolen is immediately above Top of Memory */ - base = max_low_pfn_mapped <<PAGE_SHIFT ; + base = __REMOVED_CRAZY__ <<PAGE_SHIFT ;
Huh?
Signature · 1 line
tejun
Re: [PATCH 01/14] x86, ACPI, mm: Kill max_low_pfn_mapped
Quoted 13 lines · Tejun Heo
drivers/gpu/drm/i915/i915_gem_stolen.c static unsigned long i915_stolen_to_physical(struct drm_device *dev) · line 84
Quoted 10 lines · Yinghai Lu
drivers/gpu/drm/i915/i915_gem_stolen.c +1
-1@@ -81,7 +81,7 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) base -= dev_priv->mm.gtt->stolen_size; }else {/* Stolen is immediately above Top of Memory */ - base = max_low_pfn_mapped <<PAGE_SHIFT ; + base = __REMOVED_CRAZY__ <<PAGE_SHIFT ;Huh?
Whole function:
static unsigned long i915_stolen_to_physical(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct pci_dev *pdev = dev_priv->bridge_dev;
u32 base;
/* On the machines I have tested the Graphics Base of Stolen Memory
* is unreliable, so on those compute the base by subtracting the
* stolen memory from the Top of Low Usable DRAM which is where the
* BIOS places the graphics stolen memory.
*
* On gen2, the layout is slightly different with the Graphics Segment
* immediately following Top of Memory (or Top of Usable DRAM). Note
* it appears that TOUD is only reported by 865g, so we just use the
* top of memory as determined by the e820 probe.
*
* XXX gen2 requires an unavailable symbol and 945gm fails with
* its value of TOLUD.
*/
base = 0;
if (INTEL_INFO(dev)->gen >= 6) {
/* Read Base Data of Stolen Memory Register (BDSM) directly.
* Note that there is also a MCHBAR miror at 0x1080c0 or
* we could use device 2:0x5c instead.
*/
pci_read_config_dword(pdev, 0xB0, &base);
base &= ~4095; /* lower bits used for locking register */
} else if (INTEL_INFO(dev)->gen > 3 || IS_G33(dev)) {
/* Read Graphics Base of Stolen Memory directly */
pci_read_config_dword(pdev, 0xA4, &base);
#if 0
} else if (IS_GEN3(dev)) {
u8 val;
/* Stolen is immediately below Top of Low Usable DRAM */
pci_read_config_byte(pdev, 0x9c, &val);
base = val >> 3 << 27;
base -= dev_priv->mm.gtt->stolen_size;
} else {
/* Stolen is immediately above Top of Memory */
base = __REMOVED_CRAZY__ << PAGE_SHIFT;
#endif
}
return base;
}Re: [PATCH 01/14] x86, ACPI, mm: Kill max_low_pfn_mapped
Quoted 15 lines · Yinghai Lu
Quoted 13 lines · Tejun Heo
drivers/gpu/drm/i915/i915_gem_stolen.c static unsigned long i915_stolen_to_physical(struct drm_device *dev) · line 84
Quoted 10 lines · Yinghai Lu
drivers/gpu/drm/i915/i915_gem_stolen.c +1
-1@@ -81,7 +81,7 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) base -= dev_priv->mm.gtt->stolen_size; }else {/* Stolen is immediately above Top of Memory */ - base = max_low_pfn_mapped <<PAGE_SHIFT ; + base = __REMOVED_CRAZY__ <<PAGE_SHIFT ;Huh?
Quoted 1 line
Whole function:
Yeah, but can't we still just do 1LLU << 32 like other places? Or at least explain what was there before? It's gonna confuse the hell out of future readers of the code.
Signature · 1 line
tejun
Re: [PATCH 01/14] x86, ACPI, mm: Kill max_low_pfn_mapped
Quoted 16 lines · Tejun Heo
Quoted 15 lines · Yinghai Lu
Quoted 13 lines · Tejun Heo
drivers/gpu/drm/i915/i915_gem_stolen.c static unsigned long i915_stolen_to_physical(struct drm_device *dev) · line 84
Quoted 10 lines · Yinghai Lu
drivers/gpu/drm/i915/i915_gem_stolen.c +1
-1@@ -81,7 +81,7 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) base -= dev_priv->mm.gtt->stolen_size; }else {/* Stolen is immediately above Top of Memory */ - base = max_low_pfn_mapped <<PAGE_SHIFT ; + base = __REMOVED_CRAZY__ <<PAGE_SHIFT ;Huh?
Quoted 5 lines
Quoted 1 line
Whole function:
Yeah, but can't we still just do 1LLU << 32 like other places? Or at least explain what was there before? It's gonna confuse the hell out of future readers of the code.
They are not using memblock_find_in_range(), so 1ULL<< will not help.
Really hope i915 drm guys could clean that hacks.
Thanks
Yinghai
Re: [PATCH 01/14] x86, ACPI, mm: Kill max_low_pfn_mapped
Quoted 3 lines · Yinghai Lu
They are not using
memblock_find_in_range(), so 1ULL<< will not help.Really hope i915 drm guys could clean that hacks.
The code isn't being used. Just leave it alone. Maybe add a comment.
The change is just making things more confusing.
Signature · 1 line
tejun
H. Peter Anvin
reviewerRe: [PATCH 01/14] x86, ACPI, mm: Kill max_low_pfn_mapped
Quoted 8 lines · Tejun Heo
Quoted 3 lines · Yinghai Lu
They are not using
memblock_find_in_range(), so 1ULL<< will not help.Really hope i915 drm guys could clean that hacks.
The code isn't being used. Just leave it alone. Maybe add a comment.
The change is just making things more confusing.
Indeed, but...
Daniel: can you guys clean this up or can we just remove the #if 0 clause?
-hpa
Signature · 2 lines
H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf.
Re: [PATCH 01/14] x86, ACPI, mm: Kill max_low_pfn_mapped
Quoted 6 lines · H. Peter Anvin
Quoted 5 lines · Tejun Heo
Quoted 3 lines · Yinghai Lu
They are not using
memblock_find_in_range(), so 1ULL<< will not help.Really hope i915 drm guys could clean that hacks.
Quoted 7 lines
Quoted 3 lines
The code isn't being used. Just leave it alone. Maybe add a comment.
The change is just making things more confusing.Indeed, but...
Daniel: can you guys clean this up or can we just remove the #if 0 clause?
I guess we could just put this into a comment explaining where stolen memory for the gfx devices is at on gen2. But tbh I don't mind if we just keep the #if 0 code around. For all newer platforms we can get at that offset through mch bar registers, so I don't really care. -Daniel
Signature · 3 lines
Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch
Re: [PATCH 01/14] x86, ACPI, mm: Kill max_low_pfn_mapped
Quoted 11 lines · Daniel Vetter
Quoted 10 lines · H. Peter Anvin
Quoted 8 lines · Tejun Heo
Quoted 3 lines · Yinghai Lu
They are not using
memblock_find_in_range(), so 1ULL<< will not help.Really hope i915 drm guys could clean that hacks.
The code isn't being used. Just leave it alone. Maybe add a comment.
The change is just making things more confusing.
Quoted 8 lines
Quoted 3 lines
Indeed, but...
Daniel: can you guys clean this up or can we just remove the #if 0 clause?
I guess we could just put this into a comment explaining where stolen memory for the gfx devices is at on gen2. But tbh I don't mind if we just keep the #if 0 code around. For all newer platforms we can get at that offset through mch bar registers, so I don't really care.
If you want to keep the comment accurate s/max_low_pfn_mapped/max_pfn_mapped/ as the machines in question don't support more than 4GiB anyway. Or you can help address the underlying issue of figuring out how we can derive the location of the stolen memory which is reserved by the BIOS but not communicated to the OS. -Chris
Signature · 1 line
Chris Wilson, Intel Open Source Technology Centre
H. Peter Anvin
reviewerRe: [PATCH 01/14] x86, ACPI, mm: Kill max_low_pfn_mapped
In reply to Daniel VetterThe problem is that the code will be broken, and so it makes no sense. The #if 0 is really confusing.
Quoted 25 lines · Daniel Vetter
Quoted 2 lines · H. Peter Anvin
Quoted 1 line · Tejun Heo
On Thu, Mar 7, 2013 at 9:27 PM, Yinghai Lu <[email protected]>
Quoted 1 line · wrote:
Quoted 1 line
Quoted 1 line
They are not using
memblock_find_in_range(), so 1ULL<< will nothelp.
Quoted 4 lines
Quoted 4 lines
Quoted 2 lines
Really hope i915 drm guys could clean that hacks.
The code isn't being used. Just leave it alone. Maybe add a
comment.
Quoted 6 lines
Quoted 2 lines
The change is just making things more confusing.
Indeed, but...
Daniel: can you guys clean this up or can we just remove the #if 0
clause?
I guess we could just put this into a comment explaining where stolen memory for the gfx devices is at on gen2. But tbh I don't mind if we just
keep the #if 0 code around. For all newer platforms we can get at that offset through mch bar registers, so I don't really care. -Daniel
Signature · 1 line
Sent from my mobile phone. Please excuse brevity and lack of formatting.
PATCH 2/14 x86, ACPI: Split find/copy from acpi_initrd_override
In reply to Yinghai LuTo parse srat early, we will need to move acpi table probing early. and to keep acpi_initrd_table_override working, we need to move it ahead.
But current that is called after init_mem_mapping and relocate_initrd().
Copying need to be after memblock is ready, because it need to allocate some buffer for acpi tables.
Finding will be moved into head_32.S and head64.c, just like microcode early scanning.
So split them at first.
Also move down functions declaration to avoid #ifdef in setup.c
--- arch/x86/kernel/setup.c | 6 +++--- drivers/acpi/osl.c | 32 +++++++++++++++++++------------- include/linux/acpi.h | 16 ++++++++-------- 3 files changed, 30 insertions(+), 24 deletions(-)
arch/x86/kernel/setup.c +3 -3
@@ -1092,9 +1092,9 @@ void __init setup_arch(char **cmdline_p)reserve_initrd (); -#if defined(CONFIG_ACPI ) && defined(CONFIG_BLK_DEV_INITRD ) -acpi_initrd_override ((void *)initrd_start, initrd_end - initrd_start); -#endif +acpi_initrd_override_find ((void *)initrd_start, + initrd_end - initrd_start); +acpi_initrd_override_copy ();reserve_crashkernel ();
drivers/acpi/osl.c +19 -13
@@ -539,6 +539,7 @@ acpi_os_predefined_override(const struct acpi_predefined_names *init_val,static u64 acpi_tables_addr;static int all_tables_size; +static int table_nr;/* Copied from acpica/tbutils.c:acpi_tb_checksum() */ u8 __init acpi_table_checksum (u8 *buffer,u32 length)
@@ -569,18 +570,16 @@ static const char * const table_sigs[] = {#define ACPI_HEADER_SIZE sizeof(struct acpi_table_header) -/* Must not increase 10 or needs code modification below */ -#define ACPI_OVERRIDE_TABLES 10 +#define ACPI_OVERRIDE_TABLES 64 +static struct cpio_data __initdata early_initrd_files[ACPI_OVERRIDE_TABLES ]; -void __init acpi_initrd_override (void *data,size_t size) +void __init acpi_initrd_override_find (void *data,size_t size) { -int sig, no, table_nr =0 , total_offset =0 ; +int sig, no;long offset =0 ;struct acpi_table_header *table;char cpio_path[32 ] ="kernel/firmware/acpi/" ;struct cpio_data file; -struct cpio_data early_initrd_files[ACPI_OVERRIDE_TABLES ]; -char *p;if (data ==NULL || size ==0 )return ;
@@ -621,7 +620,14 @@ void __init acpi_initrd_override(void *data, size_t size) early_initrd_files[table_nr].size = file.size; table_nr++; } -if (table_nr ==0 ) +} + +void __init acpi_initrd_override_copy (void ) +{ +int no, total_offset =0 ; +char *p; + +if (!table_nr)return ;/* under 4G at first, then above 4G */
@@ -647,14 +653,14 @@ void __init acpi_initrd_override(void *data, size_t size)memblock_reserve (acpi_tables_addr, acpi_tables_addr + all_tables_size);arch_reserve_mem_area (acpi_tables_addr, all_tables_size); - p =early_ioremap (acpi_tables_addr, all_tables_size); -for (no =0 ; no < table_nr; no++) { -memcpy (p + total_offset, early_initrd_files[no].data, - early_initrd_files[no].size); - total_offset += early_initrd_files[no].size; +size_t size = early_initrd_files[no].size; + + p =early_ioremap (acpi_tables_addr + total_offset, size); +memcpy (p, early_initrd_files[no].data, size); +early_iounmap (p, size); + total_offset += size; } - early_iounmap(p, all_tables_size); }#endif /* CONFIG_ACPI_INITRD_TABLE_OVERRIDE */
include/linux/acpi.h +8 -8
@@ -79,14 +79,6 @@ typedef int (*acpi_tbl_table_handler)(struct acpi_table_header *table);typedef int (*acpi_tbl_entry_handler )(struct acpi_subtable_header *header,const unsigned long end); -#ifdef CONFIG_ACPI_INITRD_TABLE_OVERRIDE -void acpi_initrd_override (void *data,size_t size); -#else -static inline void acpi_initrd_override (void *data,size_t size) -{ -} -#endif -char *__acpi_map_table (unsigned long phys_addr,unsigned long size);void __acpi_unmap_table (char *map,unsigned long size);int early_acpi_boot_init (void );
@@ -485,6 +477,14 @@ static inline bool acpi_driver_match_device(struct device *dev,#endif /* !CONFIG_ACPI */ +#ifdef CONFIG_ACPI_INITRD_TABLE_OVERRIDE +void acpi_initrd_override_find (void *data,size_t size); +void acpi_initrd_override_copy (void ); +#else +static inline void acpi_initrd_override_find (void *data,size_t size) { } +static inline void acpi_initrd_override_copy (void ) { } +#endif +#ifdef CONFIG_ACPI void acpi_os_set_prepare_sleep (int (*func)(u8 sleep_state,u32 pm1a_ctrl,u32 pm1b_ctrl));
Signature · 1 line
1.7.10.4
Re: [PATCH 02/14] x86, ACPI: Split find/copy from acpi_initrd_override
Quoted 22 lines · Yinghai Lu
To parse srat early, we will need to move acpi table probing early. and to keep
acpi_initrd_table_overrideworking, we need to move it ahead.But current that is called after
init_mem_mappingandrelocate_initrd().Copying need to be after memblock is ready, because it need to allocate some buffer for acpi tables.
Finding will be moved into
head_32.Sandhead64.c, just like microcode early scanning.So split them at first.
Also move down functions declaration to avoid #ifdef in
setup.cSigned-off-by Yinghai <[email protected]>Cc Thomas Renninger <[email protected]>Cc Pekka Enberg <[email protected]>Cc Jacob Shin <[email protected]>Cc Rafael J. Wysocki <[email protected]>
...
drivers/acpi/osl.c acpi_os_predefined_override(const struct acpi_predefined_names *init_val, · line 542
Quoted 9 lines
drivers/acpi/osl.c +1
-0@@ -539,6 +539,7 @@ acpi_os_predefined_override(const struct acpi_predefined_names *init_val,static u64 acpi_tables_addr;static int all_tables_size; +static int table_nr;
Not particularly good choice of name for static variable visible to multiple functions. all_tables_size isn't a stellar choice either but no need to continue the tradition. Maybe acpi_nr_initrd_files? Also, why is this one defined here away from the actual table?
drivers/acpi/osl.c static const char * const table_sigs[] = { · line 573
Quoted 3 lines
drivers/acpi/osl.c +1
-2-/* Must not increase 10 or needs code modification below */ -#define ACPI_OVERRIDE_TABLES 10 +#define ACPI_OVERRIDE_TABLES 64
What's up with the silent bumping of table size?
drivers/acpi/osl.c static const char * const table_sigs[] = { · line 574
Quoted 1 line
drivers/acpi/osl.c +1
-0+static struct cpio_data __initdata early_initrd_files[ACPI_OVERRIDE_TABLES ];
acpi_initrd_files[]? Do we really need the "early" designation together with initrd?
Quoted 8 lines
drivers/acpi/osl.c +0
-3@@ -647,14 +653,14 @@ void __init acpi_initrd_override(void *data, size_t size)memblock_reserve (acpi_tables_addr, acpi_tables_addr + all_tables_size);arch_reserve_mem_area (acpi_tables_addr, all_tables_size); - p =early_ioremap (acpi_tables_addr, all_tables_size); -for (no =0 ; no < table_nr; no++) { - memcpy(p + total_offset, early_initrd_files[no].data,
drivers/acpi/osl.c void __init acpi_initrd_override(void *data, size_t size) · line 657
Quoted 10 lines
drivers/acpi/osl.c +6
-3- early_initrd_files[no].size); - total_offset += early_initrd_files[no].size; +size_t size = early_initrd_files[no].size; + + p =early_ioremap (acpi_tables_addr + total_offset, size); +memcpy (p, early_initrd_files[no].data, size); +early_iounmap (p, size); + total_offset += size; } -early_iounmap (p, all_tables_size);
Why is this necessary? Why no explanation in the description?
Quoted 18 lines
include/linux/acpi.h +0
-8@@ -79,14 +79,6 @@ typedef int (*acpi_tbl_table_handler)(struct acpi_table_header *table);typedef int (*acpi_tbl_entry_handler )(struct acpi_subtable_header *header,const unsigned long end); -#ifdef CONFIG_ACPI_INITRD_TABLE_OVERRIDE -void acpi_initrd_override (void *data,size_t size); -#else -static inline void acpi_initrd_override (void *data,size_t size) -{ -} -#endif -char *__acpi_map_table (unsigned long phys_addr,unsigned long size);void __acpi_unmap_table (char *map,unsigned long size);int early_acpi_boot_init (void );
include/linux/acpi.h static inline bool acpi_driver_match_device(struct device *dev, · line 486
Quoted 10 lines
include/linux/acpi.h +7
-0@@ -485,6 +477,14 @@ static inline bool acpi_driver_match_device(struct device *dev,#endif /* !CONFIG_ACPI */ +#ifdef CONFIG_ACPI_INITRD_TABLE_OVERRIDE +void acpi_initrd_override_find (void *data,size_t size); +void acpi_initrd_override_copy (void ); +#else +static inline void acpi_initrd_override_find (void *data,size_t size) { } +static inline void acpi_initrd_override_copy (void ) { } +#endif
I don't get this part either. Why is it necessary to move the prototypes to avoid #ifdefs in setup.c? Ah, okay, you're brining it outside CONFIG_ACPI so that they're defined regardless of that config option. Can you please add why you're moving the prototype in the descriptoin? Having "what" is nice but "why" is much nicer. :)
Thanks.
Signature · 1 line
tejun
Re: [PATCH 02/14] x86, ACPI: Split find/copy from acpi_initrd_override
Quoted 7 lines · Tejun Heo
Quoted 6 lines · Yinghai Lu
drivers/acpi/osl.c +0
-0@@ -539,6 +539,7 @@ acpi_os_predefined_override(const struct acpi_predefined_names *init_val,
Quoted 8 lines
drivers/acpi/osl.c acpi_os_predefined_override(const struct acpi_predefined_names *init_val, · line 542
Quoted 3 lines
drivers/acpi/osl.c +1
-0static u64 acpi_tables_addr;static int all_tables_size; +static int table_nr;Not particularly good choice of name for static variable visible to multiple functions.
all_tables_sizeisn't a stellar choice either but no need to continue the tradition. Maybeacpi_nr_initrd_files? Also, why is this one defined here away from the actual table?
ok, acpi_nr_initrd_files.
will check if it could be killed.
Quoted 5 lines
drivers/acpi/osl.c static const char * const table_sigs[] = { · line 573
Quoted 3 lines
drivers/acpi/osl.c +1
-2-/* Must not increase 10 or needs code modification below */ -#define ACPI_OVERRIDE_TABLES 10 +#define ACPI_OVERRIDE_TABLES 64What's up with the silent bumping of table size?
will mention that in change log.
Quoted 5 lines
drivers/acpi/osl.c static const char * const table_sigs[] = { · line 574
Quoted 2 lines
drivers/acpi/osl.c +1
-0+static struct cpio_data __initdata early_initrd_files[ACPI_OVERRIDE_TABLES ];acpi_initrd_files[]? Do we really need the "early" designation together with initrd?
just move it out from acpi_initrd_override.
Quoted 5 lines
Quoted 5 lines
drivers/acpi/osl.c +0
-0@@ -647,14 +653,14 @@ void __init acpi_initrd_override(void *data, size_t size)memblock_reserve (acpi_tables_addr, acpi_tables_addr + all_tables_size);arch_reserve_mem_area (acpi_tables_addr, all_tables_size);
Quoted 16 lines
Quoted 4 lines
drivers/acpi/osl.c +0
-3- p =early_ioremap (acpi_tables_addr, all_tables_size); -for (no =0 ; no < table_nr; no++) { - memcpy(p + total_offset, early_initrd_files[no].data,drivers/acpi/osl.c void __init acpi_initrd_override(void *data, size_t size) · line 657
Quoted 10 lines
drivers/acpi/osl.c +6
-3- early_initrd_files[no].size); - total_offset += early_initrd_files[no].size; +size_t size = early_initrd_files[no].size; + + p =early_ioremap (acpi_tables_addr + total_offset, size); +memcpy (p, early_initrd_files[no].data, size); +early_iounmap (p, size); + total_offset += size; } -early_iounmap (p, all_tables_size);Why is this necessary? Why no explanation in the description?
actually it is the reason for bump table_nr to 64.
early_ioremap only can map 256k one time, so there will have limit for overall size.
If map one by one, then we could increase the number of limit.
Quoted 22 lines
Quoted 22 lines
include/linux/acpi.h +0
-8@@ -79,14 +79,6 @@ typedef int (*acpi_tbl_table_handler)(struct acpi_table_header *table);typedef int (*acpi_tbl_entry_handler )(struct acpi_subtable_header *header,const unsigned long end); -#ifdef CONFIG_ACPI_INITRD_TABLE_OVERRIDE -void acpi_initrd_override (void *data,size_t size); -#else -static inline void acpi_initrd_override (void *data,size_t size) -{ -} -#endif -char *__acpi_map_table (unsigned long phys_addr,unsigned long size);void __acpi_unmap_table (char *map,unsigned long size);int early_acpi_boot_init (void );@@ -485,6 +477,14 @@ static inline bool acpi_driver_match_device(struct device *dev,#endif /* !CONFIG_ACPI */
Quoted 13 lines
include/linux/acpi.h static inline bool acpi_driver_match_device(struct device *dev, · line 486
Quoted 7 lines
include/linux/acpi.h +7
-0+#ifdef CONFIG_ACPI_INITRD_TABLE_OVERRIDE +void acpi_initrd_override_find (void *data,size_t size); +void acpi_initrd_override_copy (void ); +#else +static inline void acpi_initrd_override_find (void *data,size_t size) { } +static inline void acpi_initrd_override_copy (void ) { } +#endif I don't get this part either. Why is it necessary to move the prototypes to avoid #ifdefs in
setup.c? Ah, okay, you're brining it outsideCONFIG_ACPIso that they're defined regardless of that config option. Can you please add why you're moving the prototype in the descriptoin? Having "what" is nice but "why" is much nicer. :)
I think i have that in the log.
more detail is : ACPI_INITRD_TABLE_OVERRIDE depends one ACPI and BLK_DEV_INITRD.
So could move it out safely.
Thanks
Yinghai
PATCH 3/14 x86, ACPI: store override acpi tables phys addr
In reply to Yinghai LuAs later 32bit only find table with phys address during 32bit flat mode in head_32.S.
To keep 32bit and 64 bit consistent, use phys_addr for all.
Use early_ioremap to access during copying.
--- drivers/acpi/osl.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/acpi/osl.c +7 -4
@@ -616,7 +616,7 @@ void __init acpi_initrd_override_find(void *data, size_t size) table->signature, cpio_path, file.name, table->length); all_tables_size += table->length; - early_initrd_files[table_nr].data = file.data; + early_initrd_files[table_nr].data = (void *)__pa (file.data); early_initrd_files[table_nr].size = file.size; table_nr++; }
@@ -625,7 +625,7 @@ void __init acpi_initrd_override_find(void *data, size_t size)void __init acpi_initrd_override_copy (void ) {int no, total_offset =0 ; -char *p; +char *p, *q;if (!table_nr)return ;
@@ -654,10 +654,13 @@ void __init acpi_initrd_override_copy(void)arch_reserve_mem_area (acpi_tables_addr, all_tables_size);for (no =0 ; no < table_nr; no++) { -size_t size = early_initrd_files[no].size; +unsigned long size = early_initrd_files[no].size; p =early_ioremap (acpi_tables_addr + total_offset, size); -memcpy (p, early_initrd_files[no].data, size); + q =early_ioremap ((unsigned long )early_initrd_files[no].data, + size); +memcpy (p, q, size); +early_iounmap (q, size);early_iounmap (p, size); total_offset += size; }
Signature · 1 line
1.7.10.4
Re: [PATCH 03/14] x86, ACPI: store override acpi tables phys addr
Quoted 15 lines · Yinghai Lu
As later 32bit only find table with phys address during 32bit flat mode in
head_32.S.To keep 32bit and 64 bit consistent, use
phys_addrfor all.Use
early_ioremapto access during copying.Signed-off-by Yinghai Lu <[email protected]>Cc Thomas Renninger <[email protected]>Cc Rafael J. Wysocki <[email protected]>---
drivers/acpi/osl.c +0
-0@@ -654,10 +654,13 @@ void __init acpi_initrd_override_copy(void)arch_reserve_mem_area (acpi_tables_addr, all_tables_size);
drivers/acpi/osl.c void __init acpi_initrd_override_copy(void) · line 663
Quoted 10 lines
drivers/acpi/osl.c +5
-2for (no =0 ; no < table_nr; no++) { -size_t size = early_initrd_files[no].size; +unsigned long size = early_initrd_files[no].size; p =early_ioremap (acpi_tables_addr + total_offset, size); -memcpy (p, early_initrd_files[no].data, size); + q =early_ioremap ((unsigned long )early_initrd_files[no].data, + size); +memcpy (p, q, size); +early_iounmap (q, size);
Ah, okay, so the loop change in the previous patch was for this, I suppose? That chunk probably should either be a separate patch or rolled into this one.
Thanks.
Signature · 1 line
tejun
Re: [PATCH 03/14] x86, ACPI: store override acpi tables phys addr
Quoted 20 lines · Tejun Heo
Quoted 19 lines · Yinghai Lu
As later 32bit only find table with phys address during 32bit flat mode in
head_32.S.To keep 32bit and 64 bit consistent, use
phys_addrfor all.Use
early_ioremapto access during copying.Signed-off-by Yinghai Lu <[email protected]>Cc Thomas Renninger <[email protected]>Cc Rafael J. Wysocki <[email protected]>---
drivers/acpi/osl.c +1
-1@@ -654,10 +654,13 @@ void __init acpi_initrd_override_copy(void)arch_reserve_mem_area (acpi_tables_addr, all_tables_size);for (no =0 ; no < table_nr; no++) { -size_t size = early_initrd_files[no].size; +unsigned long size = early_initrd_files[no].size;
Quoted 10 lines
drivers/acpi/osl.c void __init acpi_initrd_override_copy(void) · line 663
Quoted 6 lines
drivers/acpi/osl.c +4
-1p =early_ioremap (acpi_tables_addr + total_offset, size); -memcpy (p, early_initrd_files[no].data, size); + q =early_ioremap ((unsigned long )early_initrd_files[no].data, + size); +memcpy (p, q, size); +early_iounmap (q, size);Ah, okay, so the loop change in the previous patch was for this, I suppose? That chunk probably should either be a separate patch or rolled into this one.
merge two patches?
Re: [PATCH 03/14] x86, ACPI: store override acpi tables phys addr
Quoted 18 lines · Yinghai Lu
Quoted 7 lines
Quoted 7 lines
drivers/acpi/osl.c +1
-1@@ -654,10 +654,13 @@ void __init acpi_initrd_override_copy(void)arch_reserve_mem_area (acpi_tables_addr, all_tables_size);for (no =0 ; no < table_nr; no++) { -size_t size = early_initrd_files[no].size; +unsigned long size = early_initrd_files[no].size;Quoted 10 lines
drivers/acpi/osl.c void __init acpi_initrd_override_copy(void) · line 663
Quoted 6 lines
drivers/acpi/osl.c +4
-1p =early_ioremap (acpi_tables_addr + total_offset, size); -memcpy (p, early_initrd_files[no].data, size); + q =early_ioremap ((unsigned long )early_initrd_files[no].data, + size); +memcpy (p, q, size); +early_iounmap (q, size);Ah, okay, so the loop change in the previous patch was for this, I suppose? That chunk probably should either be a separate patch or rolled into this one.
Quoted 1 line
merge two patches?
Hmm... probably better to just move the related chunks from the previous patch to this one with better explanation on what's going on.
Thanks.
Signature · 1 line
tejun
PATCH 4/14 x86, ACPI: make acpi override finding work with 32bit flat mode
In reply to Yinghai LuWe will find acpi tables in initrd during head_32.S in 32bit flat mode.
So need acpi_initrd_override_find could take phys directly.
--- arch/x86/kernel/setup.c | 2 +- drivers/acpi/osl.c | 84 +++++++++++++++++++++++++++++++---------------- include/linux/acpi.h | 4 +-- 3 files changed, 58 insertions(+), 32 deletions(-)
arch/x86/kernel/setup.c +1 -1
@@ -1093,7 +1093,7 @@ void __init setup_arch(char **cmdline_p)reserve_initrd ();acpi_initrd_override_find ((void *)initrd_start, - initrd_end - initrd_start); + initrd_end - initrd_start, false);acpi_initrd_override_copy ();reserve_crashkernel ();
drivers/acpi/osl.c +55 -29
136 lines not on this page · raw message
include/linux/acpi.h +2 -2
@@ -478,10 +478,10 @@ static inline bool acpi_driver_match_device(struct device *dev,#endif /* !CONFIG_ACPI */ #ifdef CONFIG_ACPI_INITRD_TABLE_OVERRIDE -void acpi_initrd_override_find (void *data,size_t size); +void acpi_initrd_override_find (void *data,size_t size,bool is_phys);void acpi_initrd_override_copy (void );#else -static inline void acpi_initrd_override_find (void *data,size_t size) { } +static inline void acpi_initrd_override_find (void *data,size_t size,bool is_phys) { }static inline void acpi_initrd_override_copy (void ) { }#endif
Signature · 1 line
1.7.10.4
Re: [PATCH 04/14] x86, ACPI: make acpi override finding work with 32bit flat mode
Quoted 3 lines · Yinghai Lu
We will find acpi tables in initrd during
head_32.Sin 32bit flat mode.So need
acpi_initrd_override_findcould take phys directly.
The patch description doesn't explain even half of what's going on.
Quoted 5 lines
drivers/acpi/osl.c +0
-1@@ -552,38 +552,47 @@ u8 __init acpi_table_checksum(u8 *buffer, u32 length)return sum; } -/* All but ACPI_SIG_RSDP and ACPI_SIG_FACS: */
drivers/acpi/osl.c u8 __init acpi_table_checksum(u8 *buffer, u32 length) · line 565
Quoted 10 lines
drivers/acpi/osl.c +0
-10-static const char *const table_sigs[] = { -ACPI_SIG_BERT ,ACPI_SIG_CPEP ,ACPI_SIG_ECDT ,ACPI_SIG_EINJ , -ACPI_SIG_ERST ,ACPI_SIG_HEST ,ACPI_SIG_MADT ,ACPI_SIG_MSCT , -ACPI_SIG_SBST ,ACPI_SIG_SLIT ,ACPI_SIG_SRAT ,ACPI_SIG_ASF , -ACPI_SIG_BOOT ,ACPI_SIG_DBGP ,ACPI_SIG_DMAR ,ACPI_SIG_HPET , -ACPI_SIG_IBFT ,ACPI_SIG_IVRS ,ACPI_SIG_MCFG ,ACPI_SIG_MCHI , -ACPI_SIG_SLIC ,ACPI_SIG_SPCR ,ACPI_SIG_SPMI ,ACPI_SIG_TCPA , -ACPI_SIG_UEFI ,ACPI_SIG_WAET ,ACPI_SIG_WDAT ,ACPI_SIG_WDDT , -ACPI_SIG_WDRT ,ACPI_SIG_DSDT ,ACPI_SIG_FADT ,ACPI_SIG_PSDT , -ACPI_SIG_RSDT ,ACPI_SIG_XSDT ,ACPI_SIG_SSDT ,NULL };
Why is this table made a stack variable? What's the benefit of doing that?
drivers/acpi/osl.c u8 __init acpi_table_checksum(u8 *buffer, u32 length) · line 557
Quoted 4 lines
drivers/acpi/osl.c +1
-1/* Non-fatal errors: Affected tables/files are ignored */ #define INVALID_TABLE (x, path, name) \ - { pr_err("ACPI OVERRIDE: " x " [%s%s]\n", path, name); continue; } + do { pr_err("ACPI OVERRIDE: " x " [%s%s]\n", path, name); } while (0)
Might as well rename the macro to something which indicates it's just printing error message. Urgh... who thought embedding control flow directive like continue inside a macro was a good idea? :(
drivers/acpi/osl.c u8 __init acpi_table_checksum(u8 *buffer, u32 length) · line 564
Quoted 2 lines
drivers/acpi/osl.c +1
-1-void __init acpi_initrd_override_find (void *data,size_t size) +void __init acpi_initrd_override_find (void *data,size_t size,bool is_phys)
Is it really necessary to make the function take both virtual and physical addresses? Can't we just make the function take phys_addr_t and update everyone to call with physaddr? Also @is_phys isn't simple address switch. It also changes error reporting. If you're gonna keep @is_phys, let's at least write up a function comment explaining what's going on and why we need it. But, really, if at all possible, let's change the function to take single type of argument and predicate error message printing on something else (e.g. early printk initialized or whatever).
drivers/acpi/osl.c void __init acpi_initrd_override_copy(void) · line 680
Quoted 5 lines
drivers/acpi/osl.c +1
-0@@ -654,11 +677,14 @@ void __init acpi_initrd_override_copy(void)arch_reserve_mem_area (acpi_tables_addr, all_tables_size);for (no =0 ; no < table_nr; no++) { +unsigned long phys_addr = (unsigned long )early_initrd_files[no].data;
Can we please use phys_addr_t for physical addresses?
drivers/acpi/osl.c void __init acpi_initrd_override_copy(void) · line 686
Quoted 6 lines
drivers/acpi/osl.c +4
-0unsigned long size = early_initrd_files[no].size; + q =early_ioremap (phys_addr, size); +pr_info ("%4.4s ACPI table found in initrd [%#010lx-%#010lx]\n" , + ((struct acpi_table_header *)q)->signature, + phys_addr, phys_addr + size -1 );
Maybe putting pr_info after ioremapping both p and q would be easier on the eyes?
drivers/acpi/osl.c void __init acpi_initrd_override_copy(void) · line 690
Quoted 6 lines
drivers/acpi/osl.c +0
-2p =early_ioremap (acpi_tables_addr + total_offset, size); - q =early_ioremap ((unsigned long )early_initrd_files[no].data, - size);memcpy (p, q, size);early_iounmap (q, size);early_iounmap (p, size);
Thanks.
Signature · 1 line
tejun
Re: [PATCH 04/14] x86, ACPI: make acpi override finding work with 32bit flat mode
Quoted 6 lines · Tejun Heo
Quoted 3 lines · Yinghai Lu
We will find acpi tables in initrd during
head_32.Sin 32bit flat mode.So need
acpi_initrd_override_findcould take phys directly.The patch description doesn't explain even half of what's going on.
hope HPA could understand.
Access initrd before relocate_initrd and init_memory mapping.
Quoted 5 lines
Quoted 5 lines
drivers/acpi/osl.c +0
-0@@ -552,38 +552,47 @@ u8 __init acpi_table_checksum(u8 *buffer, u32 length)return sum; }
Quoted 14 lines
drivers/acpi/osl.c u8 __init acpi_table_checksum(u8 *buffer, u32 length) · line 565
Quoted 11 lines
drivers/acpi/osl.c +0
-11-/* All but ACPI_SIG_RSDP and ACPI_SIG_FACS: */ -static const char *const table_sigs[] = { -ACPI_SIG_BERT ,ACPI_SIG_CPEP ,ACPI_SIG_ECDT ,ACPI_SIG_EINJ , -ACPI_SIG_ERST ,ACPI_SIG_HEST ,ACPI_SIG_MADT ,ACPI_SIG_MSCT , -ACPI_SIG_SBST ,ACPI_SIG_SLIT ,ACPI_SIG_SRAT ,ACPI_SIG_ASF , -ACPI_SIG_BOOT ,ACPI_SIG_DBGP ,ACPI_SIG_DMAR ,ACPI_SIG_HPET , -ACPI_SIG_IBFT ,ACPI_SIG_IVRS ,ACPI_SIG_MCFG ,ACPI_SIG_MCHI , -ACPI_SIG_SLIC ,ACPI_SIG_SPCR ,ACPI_SIG_SPMI ,ACPI_SIG_TCPA , -ACPI_SIG_UEFI ,ACPI_SIG_WAET ,ACPI_SIG_WDAT ,ACPI_SIG_WDDT , -ACPI_SIG_WDRT ,ACPI_SIG_DSDT ,ACPI_SIG_FADT ,ACPI_SIG_PSDT , -ACPI_SIG_RSDT ,ACPI_SIG_XSDT ,ACPI_SIG_SSDT ,NULL };Why is this table made a stack variable? What's the benefit of doing that?
so I do need to switch global variables to phys and access it.
Quoted 9 lines
drivers/acpi/osl.c u8 __init acpi_table_checksum(u8 *buffer, u32 length) · line 557
Quoted 5 lines
drivers/acpi/osl.c +1
-1/* Non-fatal errors: Affected tables/files are ignored */ #define INVALID_TABLE (x, path, name) \ - { pr_err("ACPI OVERRIDE: " x " [%s%s]\n", path, name); continue; } + do { pr_err("ACPI OVERRIDE: " x " [%s%s]\n", path, name); } while (0)Might as well rename the macro to something which indicates it's just printing error message. Urgh... who thought embedding control flow directive like continue inside a macro was a good idea? :(
so I removed it.
Quoted 13 lines
drivers/acpi/osl.c u8 __init acpi_table_checksum(u8 *buffer, u32 length) · line 564
Quoted 3 lines
drivers/acpi/osl.c +1
-1-void __init acpi_initrd_override_find (void *data,size_t size) +void __init acpi_initrd_override_find (void *data,size_t size,bool is_phys)Is it really necessary to make the function take both virtual and physical addresses? Can't we just make the function take
phys_addr_tand update everyone to call with physaddr? Also @is_phys isn't simple address switch. It also changes error reporting. If you're gonna keep @is_phys, let's at least write up a function comment explaining what's going on and why we need it. But, really, if at all possible, let's change the function to take single type of argument and predicate error message printing on something else (e.g. early printk initialized or whatever).
yes, one for 32bit from head_32.S, phys.
one for 64bit from head64.c. with _va.
Not sure if I could use early_printk from head_32.S, as Fenghua does not print out
from microcode updating early in the same parts.
Will check that.
Quoted 8 lines
drivers/acpi/osl.c void __init acpi_initrd_override_copy(void) · line 680
Quoted 6 lines
drivers/acpi/osl.c +1
-0@@ -654,11 +677,14 @@ void __init acpi_initrd_override_copy(void)arch_reserve_mem_area (acpi_tables_addr, all_tables_size);for (no =0 ; no < table_nr; no++) { +unsigned long phys_addr = (unsigned long )early_initrd_files[no].data;Can we please use
phys_addr_tfor physical addresses?
ok.
Quoted 10 lines
drivers/acpi/osl.c void __init acpi_initrd_override_copy(void) · line 686
Quoted 7 lines
drivers/acpi/osl.c +4
-0unsigned long size = early_initrd_files[no].size; + q =early_ioremap (phys_addr, size); +pr_info ("%4.4s ACPI table found in initrd [%#010lx-%#010lx]\n" , + ((struct acpi_table_header *)q)->signature, + phys_addr, phys_addr + size -1 );Maybe putting
pr_infoafter ioremapping both p and q would be easier on the eyes?
ok.
Quoted 7 lines
drivers/acpi/osl.c void __init acpi_initrd_override_copy(void) · line 690
Quoted 7 lines
drivers/acpi/osl.c +0
-2p =early_ioremap (acpi_tables_addr + total_offset, size); - q =early_ioremap ((unsigned long )early_initrd_files[no].data, - size);memcpy (p, q, size);early_iounmap (q, size);early_iounmap (p, size);
Thanks
Yinghai
Re: [PATCH 04/14] x86, ACPI: make acpi override finding work with 32bit flat mode
Hello, Yinghai.
Quoted 11 lines · Yinghai Lu
Quoted 6 lines · Tejun Heo
Quoted 3 lines · Yinghai Lu
We will find acpi tables in initrd during
head_32.Sin 32bit flat mode.So need
acpi_initrd_override_findcould take phys directly.The patch description doesn't explain even half of what's going on.
hope HPA could understand.
Access initrd before
relocate_initrdandinit_memorymapping.
I really hope the changelogs were better. Eh well...
Quoted 15 lines
Quoted 6 lines
Quoted 6 lines
drivers/acpi/osl.c +0
-6-/* All but ACPI_SIG_RSDP and ACPI_SIG_FACS: */ -static const char *const table_sigs[] = { -ACPI_SIG_BERT ,ACPI_SIG_CPEP ,ACPI_SIG_ECDT ,ACPI_SIG_EINJ , -ACPI_SIG_ERST ,ACPI_SIG_HEST ,ACPI_SIG_MADT ,ACPI_SIG_MSCT , -ACPI_SIG_SBST ,ACPI_SIG_SLIT ,ACPI_SIG_SRAT ,ACPI_SIG_ASF , -ACPI_SIG_BOOT ,ACPI_SIG_DBGP ,ACPI_SIG_DMAR ,ACPI_SIG_HPET ,Quoted 8 lines
drivers/acpi/osl.c u8 __init acpi_table_checksum(u8 *buffer, u32 length) · line 565
Quoted 5 lines
drivers/acpi/osl.c +0
-5-ACPI_SIG_IBFT ,ACPI_SIG_IVRS ,ACPI_SIG_MCFG ,ACPI_SIG_MCHI , -ACPI_SIG_SLIC ,ACPI_SIG_SPCR ,ACPI_SIG_SPMI ,ACPI_SIG_TCPA , -ACPI_SIG_UEFI ,ACPI_SIG_WAET ,ACPI_SIG_WDAT ,ACPI_SIG_WDDT , -ACPI_SIG_WDRT ,ACPI_SIG_DSDT ,ACPI_SIG_FADT ,ACPI_SIG_PSDT , - ACPI_SIG_RSDT, ACPI_SIG_XSDT, ACPI_SIG_SSDT, NULL };Why is this table made a stack variable? What's the benefit of doing that?
Quoted 1 line
so I do need to switch global variables to phys and access it.
I can't really understand what your response means. Can you please elaborate?
Quoted 10 lines
Quoted 9 lines
Is it really necessary to make the function take both virtual and physical addresses? Can't we just make the function take
phys_addr_tand update everyone to call with physaddr? Also @is_phys isn't simple address switch. It also changes error reporting. If you're gonna keep @is_phys, let's at least write up a function comment explaining what's going on and why we need it. But, really, if at all possible, let's change the function to take single type of argument and predicate error message printing on something else (e.g. early printk initialized or whatever).
Quoted 2 lines
yes, one for 32bit from
head_32.S, phys.
one for 64bit fromhead64.c. with_va.
head64.c can't call with phys? Why not?
Quoted 3 lines
Not sure if I could use
early_printkfromhead_32.S, as Fenghua does not print out
from microcode updating early in the same parts.
ISTR it works but it doens't have to (although it would be much nicer if it did). You can test whether printk is online and skip if it isn't online yet.
Thanks.
Signature · 1 line
tejun
Re: [PATCH 04/14] x86, ACPI: make acpi override finding work with 32bit flat mode
Quoted 32 lines · Tejun Heo
Hello, Yinghai.
Quoted 11 lines · Yinghai Lu
Quoted 6 lines · Tejun Heo
Quoted 3 lines · Yinghai Lu
We will find acpi tables in initrd during
head_32.Sin 32bit flat mode.So need
acpi_initrd_override_findcould take phys directly.The patch description doesn't explain even half of what's going on.
hope HPA could understand.
Access initrd before
relocate_initrdandinit_memorymapping.I really hope the changelogs were better. Eh well...
Quoted 15 lines
Quoted 14 lines
drivers/acpi/osl.c u8 __init acpi_table_checksum(u8 *buffer, u32 length) · line 565
Quoted 11 lines
drivers/acpi/osl.c +0
-11-/* All but ACPI_SIG_RSDP and ACPI_SIG_FACS: */ -static const char *const table_sigs[] = { -ACPI_SIG_BERT ,ACPI_SIG_CPEP ,ACPI_SIG_ECDT ,ACPI_SIG_EINJ , -ACPI_SIG_ERST ,ACPI_SIG_HEST ,ACPI_SIG_MADT ,ACPI_SIG_MSCT , -ACPI_SIG_SBST ,ACPI_SIG_SLIT ,ACPI_SIG_SRAT ,ACPI_SIG_ASF , -ACPI_SIG_BOOT ,ACPI_SIG_DBGP ,ACPI_SIG_DMAR ,ACPI_SIG_HPET , -ACPI_SIG_IBFT ,ACPI_SIG_IVRS ,ACPI_SIG_MCFG ,ACPI_SIG_MCHI , -ACPI_SIG_SLIC ,ACPI_SIG_SPCR ,ACPI_SIG_SPMI ,ACPI_SIG_TCPA , -ACPI_SIG_UEFI ,ACPI_SIG_WAET ,ACPI_SIG_WDAT ,ACPI_SIG_WDDT , -ACPI_SIG_WDRT ,ACPI_SIG_DSDT ,ACPI_SIG_FADT ,ACPI_SIG_PSDT , -ACPI_SIG_RSDT ,ACPI_SIG_XSDT ,ACPI_SIG_SSDT ,NULL };Why is this table made a stack variable? What's the benefit of doing that?
Quoted 4 lines
Quoted 1 line
so I do need to switch global variables to phys and access it.
I can't really understand what your response means. Can you please elaborate?
sorry, I missed NOT.
so I do NOT need to switch global variables from kernel virtual addr to phys address and access it
in 32bit flat mode.
Quoted 11 lines
Quoted 11 lines
Quoted 10 lines
Is it really necessary to make the function take both virtual and physical addresses? Can't we just make the function take
phys_addr_tand update everyone to call with physaddr? Also @is_phys isn't simple address switch. It also changes error reporting. If you're gonna keep @is_phys, let's at least write up a function comment explaining what's going on and why we need it. But, really, if at all possible, let's change the function to take single type of argument and predicate error message printing on something else (e.g. early printk initialized or whatever).
Quoted 4 lines
Quoted 2 lines
yes, one for 32bit from
head_32.S, phys.
one for 64bit fromhead64.c. with_va.
head64.ccan't call with phys? Why not?
HPA's #PF set up page table only handle kernel low mapping address.
and after reset_early_page_tables, only kernel high mapping address is there. and other low mapping will be supported via #PF handler.
Quoted 8 lines
Quoted 4 lines
Not sure if I could use
early_printkfromhead_32.S, as Fenghua does not print out
from microcode updating early in the same parts.ISTR it works but it doens't have to (although it would be much nicer if it did). You can test whether printk is online and skip if it isn't online yet.
ok, will give it try.
Thanks
Yinghai
Re: [PATCH 04/14] x86, ACPI: make acpi override finding work with 32bit flat mode
Quoted 5 lines · Yinghai Lu
Quoted 5 lines
Quoted 4 lines
Quoted 2 lines
Why is this table made a stack variable? What's the benefit of doing that?
so I do need to switch global variables to phys and access it.
Quoted 8 lines
Quoted 2 lines
I can't really understand what your response means. Can you please elaborate?
sorry, I missed NOT.
so I do NOT need to switch global variables from kernel virtual addr to phys address and access it
in 32bit flat mode.
Ah, okay, so the function is called with a completely different address mode and so you actually want to build the table on stack so that you don't have to flip the address mode for the global address.
Quoted 9 lines
Quoted 4 lines
Quoted 2 lines
yes, one for 32bit from
head_32.S, phys.
one for 64bit fromhead64.c. with_va.
head64.ccan't call with phys? Why not?HPA's #PF set up page table only handle kernel low mapping address.
and after
reset_early_page_tables, only kernel high mapping address is there. and other low mapping will be supported via #PF handler.
Okay, it now makes sense. Ah.... You'll definitely need a lot of documentation explanining what's going on.
Thanks.
Signature · 1 line
tejun
Andrew Morton
maintainerRe: [PATCH 04/14] x86, ACPI: make acpi override finding work with 32bit flat mode
In reply to Yinghai LuQuoted 20 lines · On Thu, 7 Mar 2013 22:57:21 -0800 Yinghai Lu <[email protected]> wrote:
Quoted 5 lines
Quoted 5 lines
drivers/acpi/osl.c +0
-0@@ -552,38 +552,47 @@ u8 __init acpi_table_checksum(u8 *buffer, u32 length)return sum; }Quoted 14 lines
drivers/acpi/osl.c u8 __init acpi_table_checksum(u8 *buffer, u32 length) · line 565
Quoted 11 lines
drivers/acpi/osl.c +0
-11-/* All but ACPI_SIG_RSDP and ACPI_SIG_FACS: */ -static const char *const table_sigs[] = { -ACPI_SIG_BERT ,ACPI_SIG_CPEP ,ACPI_SIG_ECDT ,ACPI_SIG_EINJ , -ACPI_SIG_ERST ,ACPI_SIG_HEST ,ACPI_SIG_MADT ,ACPI_SIG_MSCT , -ACPI_SIG_SBST ,ACPI_SIG_SLIT ,ACPI_SIG_SRAT ,ACPI_SIG_ASF , -ACPI_SIG_BOOT ,ACPI_SIG_DBGP ,ACPI_SIG_DMAR ,ACPI_SIG_HPET , -ACPI_SIG_IBFT ,ACPI_SIG_IVRS ,ACPI_SIG_MCFG ,ACPI_SIG_MCHI , -ACPI_SIG_SLIC ,ACPI_SIG_SPCR ,ACPI_SIG_SPMI ,ACPI_SIG_TCPA , -ACPI_SIG_UEFI ,ACPI_SIG_WAET ,ACPI_SIG_WDAT ,ACPI_SIG_WDDT , -ACPI_SIG_WDRT ,ACPI_SIG_DSDT ,ACPI_SIG_FADT ,ACPI_SIG_PSDT , -ACPI_SIG_RSDT ,ACPI_SIG_XSDT ,ACPI_SIG_SSDT ,NULL };Why is this table made a stack variable? What's the benefit of doing that?
Quoted 1 line
so I do need to switch global variables to phys and access it.
What Tejun means is that it should be marked "static" within acpi_initrd_override(), so we don't have to build a copy on the stack at runtime each time acpi_initrd_override() is called.
While we're there, it should be __initdata also.
Re: [PATCH 04/14] x86, ACPI: make acpi override finding work with 32bit flat mode
In reply to Yinghai LuYinghai,
Quoted 9 lines · Yinghai Lu
Quoted 6 lines · Tejun Heo
Quoted 3 lines · Yinghai Lu
We will find acpi tables in initrd during
head_32.Sin 32bit flat mode.So need
acpi_initrd_override_findcould take phys directly.The patch description doesn't explain even half of what's going on.
hope HPA could understand.
What the heck? Is HPA your personal decryptor?
I'm really tired of this nonsense. There is a track record of people complaining about your completely useless and sloppy changelogs and your unwillingness to properly explain and discuss your patches.
Just to make it clear. We all are able and willing to cope with developers who are not native english speakers and have limited language skills. I'm rewriting changelogs on a regular base without complaining about that.
But that's not the problem at hand. I met you personally at KS and found out that your english skills are not those of the random Chinese person. You just prefer to hide your excellent language skills behind your Chinese name.
That's an utter waste of time and resources!
Please grow up and use your language and technical skills in a way which does not offend the people you need to interact with.
Seriously, if you can't convince yourself that a proper communication with maintainers and other developers is a primary task, please don't be surprised if you end up on the /dev/null filters and auto-NAK bots of quite a bunch of affected people.
That would be a sad outcome, really. But that's solely your decision.
Thanks,
tglx
PATCH 5/14 x86, ACPI: Find acpi tables in initrd early at head_32.S/head64.c
In reply to Yinghai Luhead64.c could use #PF handler set page table to access initrd before mapping and relocating.
head_32.S could use 32bit flat mode to access initrd before mapping and relocating.
--- arch/x86/include/asm/setup.h | 2 ++ arch/x86/kernel/head64.c | 2 ++ arch/x86/kernel/head_32.S | 4 ++++ arch/x86/kernel/setup.c | 28 ++++++++++++++++++++++++++-- 4 files changed, 34 insertions(+), 2 deletions(-)
arch/x86/include/asm/setup.h +2 -0
@@ -42,6 +42,8 @@ extern void visws_early_detect(void);static inline void visws_early_detect (void ) { }#endif +void x86_acpi_override_find (void ); +extern unsigned long saved_video_mode;extern void reserve_standard_io_resources (void );
arch/x86/kernel/head64.c +2 -0
@@ -174,6 +174,8 @@ void __init x86_64_start_kernel(char * real_mode_data)if (console_loglevel ==10 )early_printk ("Kernel alive\n" ); +x86_acpi_override_find (); +clear_page (init_level4_pgt);/* set init_level4_pgt kernel high mapping*/ init_level4_pgt[511 ] = early_level4_pgt[511 ];
arch/x86/kernel/head_32.S +4 -0
@@ -149,6 +149,10 @@ ENTRY(startup_32) call load_ucode_bsp #endif +#ifdef CONFIG_ACPI_INITRD_TABLE_OVERRIDE + call x86_acpi_override_find +#endif + /* * Initialize page tables. This creates a PDE and a set of page * tables, which are located immediately beyond __brk_base. The variable
arch/x86/kernel/setup.c +26 -2
@@ -424,6 +424,32 @@ static void __init reserve_initrd(void) }#endif /* CONFIG_BLK_DEV_INITRD */ +#ifdef CONFIG_ACPI_INITRD_TABLE_OVERRIDE +void __init x86_acpi_override_find (void ) +{ +unsigned long ramdisk_image, ramdisk_size; +unsigned char *p =NULL ; + +#ifdef CONFIG_X86_32 +struct boot_params *boot_params_p; + + boot_params_p = (struct boot_params *)__pa_symbol (&boot_params); + ramdisk_image = boot_params_p->hdr.ramdisk_image; + ramdisk_size = boot_params_p->hdr.ramdisk_size; + p = (unsigned char *)ramdisk_image; +acpi_initrd_override_find (p, ramdisk_size, true); +#else + ramdisk_image =get_ramdisk_image (); + ramdisk_size =get_ramdisk_size (); +if (ramdisk_image) + p =__va (ramdisk_image); +acpi_initrd_override_find (p, ramdisk_size, false); +#endif +} +#else +void __init x86_acpi_override_find (void ) { } +#endif +static void __init parse_setup_data (void ) {struct setup_data *data;
@@ -1092,8 +1118,6 @@ void __init setup_arch(char **cmdline_p)reserve_initrd (); -acpi_initrd_override_find ((void *)initrd_start, - initrd_end - initrd_start, false);acpi_initrd_override_copy ();reserve_crashkernel ();
Signature · 1 line
1.7.10.4
Re: [PATCH 05/14] x86, ACPI: Find acpi tables in initrd early at head_32.S/head64.c
arch/x86/kernel/head_32.S ENTRY(startup_32) · line 154
Quoted 11 lines · Yinghai Lu
arch/x86/kernel/head_32.S +3
-0@@ -149,6 +149,10 @@ ENTRY(startup_32) call load_ucode_bsp #endif +#ifdef CONFIG_ACPI_INITRD_TABLE_OVERRIDE + call x86_acpi_override_find +#endif
The function is always defined. We can probalby lose ifdef here?
Also, does it really have to be called from head_32.S? No way this can be done after entering C code? It would be great if you can explain overall design choices in the head message (and important patches).
Quoted 22 lines
arch/x86/kernel/setup.c +14
-0@@ -424,6 +424,32 @@ static void __init reserve_initrd(void) }#endif /* CONFIG_BLK_DEV_INITRD */ +#ifdef CONFIG_ACPI_INITRD_TABLE_OVERRIDE +void __init x86_acpi_override_find (void ) +{ +unsigned long ramdisk_image, ramdisk_size; +unsigned char *p =NULL ; + +#ifdef CONFIG_X86_32 +struct boot_params *boot_params_p; + + boot_params_p = (struct boot_params *)__pa_symbol (&boot_params); + ramdisk_image = boot_params_p->hdr.ramdisk_image; + ramdisk_size = boot_params_p->hdr.ramdisk_size; + p = (unsigned char *)ramdisk_image; +acpi_initrd_override_find (p, ramdisk_size, true);
arch/x86/kernel/setup.c static void __init reserve_initrd(void) · line 450
Quoted 10 lines
arch/x86/kernel/setup.c +10
-0+#else + ramdisk_image =get_ramdisk_image (); + ramdisk_size =get_ramdisk_size (); +if (ramdisk_image) + p =__va (ramdisk_image); +acpi_initrd_override_find (p, ramdisk_size, false); +#endif +} +#else +void __init x86_acpi_override_find (void ) { }
And add a comment here why we're not doing static inline for the dummy function?
Thanks.
Signature · 1 line
tejun
Re: [PATCH 05/14] x86, ACPI: Find acpi tables in initrd early at head_32.S/head64.c
Quoted 9 lines · Tejun Heo
Quoted 8 lines · Yinghai Lu
arch/x86/kernel/head_32.S +0
-0@@ -149,6 +149,10 @@ ENTRY(startup_32) call load_ucode_bsp #endif
Quoted 5 lines
arch/x86/kernel/head_32.S ENTRY(startup_32) · line 154
Quoted 3 lines
arch/x86/kernel/head_32.S +3
-0+#ifdef CONFIG_ACPI_INITRD_TABLE_OVERRIDE + call x86_acpi_override_find +#endifThe function is always defined. We can probalby lose ifdef here?
just mimic microcode updating again.
Quoted 5 lines
Also, does it really have to be called from
head_32.S? No way this can be done after entering C code? It would be great if you can explain overall design choices in the head message (and important patches).
have to be with head_32.S and it is with 32bit flat mode, so could access 4G blow without setting page table.
Will try add to more in the change log.
Quoted 36 lines
Quoted 23 lines
arch/x86/kernel/setup.c +14
-0@@ -424,6 +424,32 @@ static void __init reserve_initrd(void) }#endif /* CONFIG_BLK_DEV_INITRD */ +#ifdef CONFIG_ACPI_INITRD_TABLE_OVERRIDE +void __init x86_acpi_override_find (void ) +{ +unsigned long ramdisk_image, ramdisk_size; +unsigned char *p =NULL ; + +#ifdef CONFIG_X86_32 +struct boot_params *boot_params_p; + + boot_params_p = (struct boot_params *)__pa_symbol (&boot_params); + ramdisk_image = boot_params_p->hdr.ramdisk_image; + ramdisk_size = boot_params_p->hdr.ramdisk_size; + p = (unsigned char *)ramdisk_image; +acpi_initrd_override_find (p, ramdisk_size, true);arch/x86/kernel/setup.c static void __init reserve_initrd(void) · line 450
Quoted 10 lines
arch/x86/kernel/setup.c +10
-0+#else + ramdisk_image =get_ramdisk_image (); + ramdisk_size =get_ramdisk_size (); +if (ramdisk_image) + p =__va (ramdisk_image); +acpi_initrd_override_find (p, ramdisk_size, false); +#endif +} +#else +void __init x86_acpi_override_find (void ) { }And add a comment here why we're not doing static inline for the dummy function?
...
Re: [PATCH 05/14] x86, ACPI: Find acpi tables in initrd early at head_32.S/head64.c
Quoted 9 lines · Yinghai Lu
Quoted 4 lines
Also, does it really have to be called from
head_32.S? No way this can be done after entering C code? It would be great if you can explain overall design choices in the head message (and important patches).have to be with
head_32.Sand it is with 32bit flat mode, so could access 4G blow without setting page table.Will try add to more in the change log.
Yes, please. In the comment too.
Signature · 1 line
tejun
PATCH 6/14 x86, mm, numa: Move successful path handling code later
In reply to Yinghai LuWe could move setup_node_data() and numa_init_array() calling out numa_init() to make numa_init() small.
Those functions only need to be called for success path, and only call them one time in x86_numa_init().
So later we could split parse numa info to two stages. early one will be before init_mem_mapping.
--- arch/x86/mm/numa.c | 68 ++++++++++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 31 deletions(-)
arch/x86/mm/numa.c +37 -31
@@ -480,7 +480,7 @@ static bool __init numa_meminfo_cover_memory(const struct numa_meminfo *mi)static int __init numa_register_memblks (struct numa_meminfo *mi) {unsigned long uninitialized_var (pfn_align ); -int i, nid; +int i;/* Account for nodes with cpus and no memory */ node_possible_map = numa_nodes_parsed;
@@ -509,24 +509,6 @@ static int __init numa_register_memblks(struct numa_meminfo *mi)if (!numa_meminfo_cover_memory (mi))return -EINVAL ; -/* Finally register nodes. */ -for_each_node_mask (nid, node_possible_map) { -u64 start =PFN_PHYS (max_pfn); -u64 end =0 ; - -for (i =0 ; i < mi->nr_blks; i++) { -if (nid != mi->blk[i].nid) -continue ; - start =min (mi->blk[i].start, start); - end =max (mi->blk[i].end, end); - } - -if (start < end) -setup_node_data (nid, start, end); - } - -/* Dump memblock with node info and return. */ -memblock_dump_all ();return 0 ; }
@@ -580,15 +562,6 @@ static int __init numa_init(int (*init_func)(void))if (ret <0 )return ret; -for (i =0 ; i < nr_cpu_ids; i++) { -int nid =early_cpu_to_node (i); - -if (nid ==NUMA_NO_NODE ) -continue ; -if (!node_online (nid)) -numa_clear_node (i); - } -numa_init_array ();return 0 ; }
@@ -623,22 +596,55 @@ static int __init dummy_numa_init(void)*/ void __init x86_numa_init (void ) { +int i, nid; +struct numa_meminfo *mi = &numa_meminfo; +if (!numa_off) {#ifdef CONFIG_X86_NUMAQ if (!numa_init (numaq_numa_init)) -return ; + goto out;#endif #ifdef CONFIG_ACPI_NUMA if (!numa_init (x86_acpi_numa_init)) -return ; + goto out;#endif #ifdef CONFIG_AMD_NUMA if (!numa_init (amd_numa_init)) -return ; + goto out;#endif }numa_init (dummy_numa_init); + +out: +/* Finally register nodes. */ +for_each_node_mask (nid, node_possible_map) { +u64 start =PFN_PHYS (max_pfn); +u64 end =0 ; + +for (i =0 ; i < mi->nr_blks; i++) { +if (nid != mi->blk[i].nid) +continue ; + start =min (mi->blk[i].start, start); + end =max (mi->blk[i].end, end); + } + +if (start < end) +setup_node_data (nid, start, end); + } + +/* Dump memblock with node info */ +memblock_dump_all (); + +for (i =0 ; i < nr_cpu_ids; i++) { +int nid =early_cpu_to_node (i); + +if (nid ==NUMA_NO_NODE ) +continue ; +if (!node_online (nid)) +numa_clear_node (i); + } +numa_init_array (); }static __init int find_near_online_node (int node)
Signature · 1 line
1.7.10.4
Re: [PATCH 06/14] x86, mm, numa: Move successful path handling code later
Quoted 1 line
static int
__initnuma_register_memblks(struct numa_meminfo *mi)
After this patch, the above name is a bit misleading, I think.
Quoted 1 line
+out:
Maybe register: would fit better?
arch/x86/mm/numa.c static int __init dummy_numa_init(void) · line 622
Quoted 3 lines
arch/x86/mm/numa.c +3
-0+/* Finally register nodes. */ +for_each_node_mask (nid, node_possible_map) { +u64 start =PFN_PHYS (max_pfn);
Thanks.
Signature · 1 line
tejun
Re: [PATCH 06/14] x86, mm, numa: Move successful path handling code later
Quoted 3 lines · Tejun Heo
Quoted 1 line
static int
__initnuma_register_memblks(struct numa_meminfo *mi)After this patch, the above name is a bit misleading, I think.
later i changed it to numa_check_memblks()
Thanks
Yinghai
PATCH 7/14 x86, mm, numa: call numa_meminfo_cover_memory() early
In reply to Yinghai LuWe do not need to use nid in memblock to find out absent pages.
So could move that numa_meminfo_cover_memory() early before set memblock nid.
Also could make __absent_pages_in_range() to static and use absent_pages_in_range() directly.
Later will only set memblock nid one time on successful path.
--- arch/x86/mm/numa.c | 7 ++++--- include/linux/mm.h | 2 -- mm/page_alloc.c | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-)
arch/x86/mm/numa.c +4 -3
@@ -460,7 +460,7 @@ static bool __init numa_meminfo_cover_memory(const struct numa_meminfo *mi)u64 s = mi->blk[i].start >>PAGE_SHIFT ;u64 e = mi->blk[i].end >>PAGE_SHIFT ; numaram += e - s; - numaram -=__absent_pages_in_range (mi->blk[i].nid, s, e); + numaram -=absent_pages_in_range (s, e);if ((s64 )numaram <0 ) numaram =0 ; }
@@ -488,6 +488,9 @@ static int __init numa_register_memblks(struct numa_meminfo *mi)if (WARN_ON (nodes_empty (node_possible_map)))return -EINVAL ; +if (!numa_meminfo_cover_memory (mi)) +return -EINVAL ; +for (i =0 ; i < mi->nr_blks; i++) {struct numa_memblk *mb = &mi->blk[i];memblock_set_node (mb->start, mb->end - mb->start, mb->nid);
@@ -506,8 +509,6 @@ static int __init numa_register_memblks(struct numa_meminfo *mi) return -EINVAL; }#endif -if (!numa_meminfo_cover_memory (mi)) -return -EINVAL ;return 0 ; }
include/linux/mm.h +0 -2
@@ -1324,8 +1324,6 @@ extern void free_initmem(void);*/ extern void free_area_init_nodes (unsigned long *max_zone_pfn);unsigned long node_map_pfn_alignment (void ); -unsigned long __absent_pages_in_range (int nid,unsigned long start_pfn, -unsigned long end_pfn);extern unsigned long absent_pages_in_range (unsigned long start_pfn,unsigned long end_pfn); extern void get_pfn_range_for_nid(unsigned int nid,
mm/page_alloc.c +1 -1
@@ -4356,7 +4356,7 @@ static unsigned long __meminit zone_spanned_pages_in_node(int nid,* Return the number of holes in a range on a node. If nid is MAX_NUMNODES, * then all holes in the requested range will be accounted for. */ -unsigned long __meminit __absent_pages_in_range (int nid, +static unsigned long __meminit __absent_pages_in_range (int nid,unsigned long range_start_pfn,unsigned long range_end_pfn) {
Signature · 1 line
1.7.10.4
PATCH 8/14 x86, mm, numa: use numa_meminfo to check node_map_pfn alignment
In reply to Yinghai LuWe could use numa_meminfo directly instead of memblock nid.
So we could move down set memblock nid down and only do it one time for successful path
Move node_map_pfn_alignment() to arch/x86/mm as no other user for it.
--- arch/x86/mm/numa.c | 76 +++++++++++++++++++++++++++++++++++++++++++++------- include/linux/mm.h | 1 - mm/page_alloc.c | 50 ---------------------------------- 3 files changed, 67 insertions(+), 60 deletions(-)
arch/x86/mm/numa.c +67 -9
@@ -477,9 +477,69 @@ static bool __init numa_meminfo_cover_memory(const struct numa_meminfo *mi)return true; } +/** +* node_map_pfn_alignment - determine the maximum internode alignment +* +* This function should be called after node map is populated and sorted. +* It calculates the maximum power of two alignment which can distinguish +* all the nodes. +* +* For example, if all nodes are 1GiB and aligned to 1GiB, the return value +* would indicate 1GiB alignment with (1 << (30 - PAGE_SHIFT)). If the +* nodes are shifted by 256MiB, 256MiB. Note that if only the last node is +* shifted, 1GiB is enough and this function will indicate so. +* +* This is used to test whether pfn -> nid mapping of the chosen memory +* model has fine enough granularity to avoid incorrect mapping for the +* populated node map. +* +* Returns the determined alignment in pfn's. 0 if there is no alignment +* requirement (single node). +*/ +#ifdef NODE_NOT_IN_PAGE_FLAGS +static unsigned long __init node_map_pfn_alignment (struct numa_meminfo *mi) +{ +unsigned long accl_mask =0 , last_end =0 ; +unsigned long start, end, mask; +int last_nid =-1 ; +int i, nid; + +for (i =0 ; i < mi->nr_blks; i++) { + start = mi->blk[i].start >>PAGE_SHIFT ; + end = mi->blk[i].end >>PAGE_SHIFT ; + nid = mi->blk[i].nid; +if (!start || last_nid <0 || last_nid == nid) { + last_nid = nid; + last_end = end; +continue ; + } + +/* +* Start with a mask granular enough to pin-point to the +* start pfn and tick off bits one-by-one until it becomes +* too coarse to separate the current node from the last. +*/ + mask = ~((1 <<__ffs (start)) -1 ); +while (mask && last_end <= (start & (mask <<1 ))) + mask <<=1 ; + +/* accumulate all internode masks */ + accl_mask |= mask; + } + +/* convert mask to number of pages */ +return ~accl_mask +1 ; +} +#else +static unsigned long __init node_map_pfn_alignment (struct numa_meminfo *mi) +{ +return 0 ; +} +#endif +static int __init numa_register_memblks (struct numa_meminfo *mi) { -unsigned long uninitialized_var (pfn_align ); +unsigned long pfn_align;int i;/* Account for nodes with cpus and no memory */
@@ -491,24 +551,22 @@ static int __init numa_register_memblks(struct numa_meminfo *mi)if (!numa_meminfo_cover_memory (mi))return -EINVAL ; -for (i =0 ; i < mi->nr_blks; i++) { -struct numa_memblk *mb = &mi->blk[i]; -memblock_set_node (mb->start, mb->end - mb->start, mb->nid); - } -/* * If sections array is gonna be used for pfn -> nid mapping, check * whether its granularity is fine enough. */ -#ifdef NODE_NOT_IN_PAGE_FLAGS - pfn_align =node_map_pfn_alignment (); + pfn_align =node_map_pfn_alignment (mi);if (pfn_align && pfn_align <PAGES_PER_SECTION ) {printk (KERN_WARNING "Node alignment %LuMB < min %LuMB, rejecting NUMA config\n" ,PFN_PHYS (pfn_align) >>20 ,PFN_PHYS (PAGES_PER_SECTION ) >>20 );return -EINVAL ; } -#endif + +for (i =0 ; i < mi->nr_blks; i++) { +struct numa_memblk *mb = &mi->blk[i]; +memblock_set_node (mb->start, mb->end - mb->start, mb->nid); + }return 0 ; }
include/linux/mm.h +0 -1
@@ -1323,7 +1323,6 @@ extern void free_initmem(void);* CONFIG_HAVE_MEMBLOCK_NODE_MAP. */ extern void free_area_init_nodes (unsigned long *max_zone_pfn); -unsigned long node_map_pfn_alignment (void );extern unsigned long absent_pages_in_range (unsigned long start_pfn,unsigned long end_pfn); extern void get_pfn_range_for_nid(unsigned int nid,
mm/page_alloc.c +0 -50
56 lines not on this page · raw message
Signature · 1 line
1.7.10.4
Re: [PATCH 08/14] x86, mm, numa: use numa_meminfo to check node_map_pfn alignment
Quoted 6 lines · Yinghai Lu
We could use
numa_meminfodirectly instead of memblock nid.So we could move down set memblock nid down and only do it one time for successful path
Move
node_map_pfn_alignment()toarch/x86/mmas no other user for it.
Please don't move and update in the same patch. It makes it difficult to review what's really changing.
Thanks.
Signature · 1 line
tejun
Re: [PATCH 08/14] x86, mm, numa: use numa_meminfo to check node_map_pfn alignment
Quoted 10 lines · Tejun Heo
Quoted 6 lines · Yinghai Lu
We could use
numa_meminfodirectly instead of memblock nid.So we could move down set memblock nid down and only do it one time for successful path
Move
node_map_pfn_alignment()toarch/x86/mmas no other user for it.Please don't move and update in the same patch. It makes it difficult to review what's really changing.
ok, will make it two patches, one for moving and one for changing to numa_meminfo.
Thanks
Yinghai
PATCH 9/14 x86, mm, numa: set memblock nid later
In reply to Yinghai LuOnly set memblock nid one time.
Also rename numa_register_memblks to numa_check_memblks() after move set memblock nid out.
--- arch/x86/mm/numa.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-)
arch/x86/mm/numa.c +7 -9
@@ -537,10 +537,9 @@ static unsigned long __init node_map_pfn_alignment(struct numa_meminfo *mi) }#endif -static int __init numa_register_memblks (struct numa_meminfo *mi) +static int __init numa_check_memblks (struct numa_meminfo *mi) {unsigned long pfn_align; -int i;/* Account for nodes with cpus and no memory */ node_possible_map = numa_nodes_parsed;
@@ -563,11 +562,6 @@ static int __init numa_register_memblks(struct numa_meminfo *mi)return -EINVAL ; } -for (i =0 ; i < mi->nr_blks; i++) { -struct numa_memblk *mb = &mi->blk[i]; -memblock_set_node (mb->start, mb->end - mb->start, mb->nid); - } -return 0 ; }
@@ -605,7 +599,6 @@ static int __init numa_init(int (*init_func)(void))nodes_clear (node_possible_map);nodes_clear (node_online_map);memset (&numa_meminfo,0 ,sizeof (numa_meminfo)); -WARN_ON (memblock_set_node (0 ,ULLONG_MAX ,MAX_NUMNODES ));numa_reset_distance (); ret =init_func ();
@@ -617,7 +610,7 @@ static int __init numa_init(int (*init_func)(void))numa_emulation (&numa_meminfo, numa_distance_cnt); - ret =numa_register_memblks (&numa_meminfo); + ret =numa_check_memblks (&numa_meminfo);if (ret <0 )return ret;
@@ -676,6 +669,11 @@ void __init x86_numa_init(void)numa_init (dummy_numa_init); out: +for (i =0 ; i < mi->nr_blks; i++) { +struct numa_memblk *mb = &mi->blk[i]; +memblock_set_node (mb->start, mb->end - mb->start, mb->nid); + } +/* Finally register nodes. */ for_each_node_mask (nid, node_possible_map) {u64 start =PFN_PHYS (max_pfn);
Signature · 1 line
1.7.10.4
Re: [PATCH 09/14] x86, mm, numa: set memblock nid later
Quoted 1 line · Yinghai Lu
Only set memblock nid one time.
Would be awesome if the description explains why we're doing this and why we're allowed to do this now.
Quoted 2 lines
Also rename
numa_register_memblkstonuma_check_memblks()after move set memblock nid out.
Ah... so, it's getting renamed here.
Signature · 1 line
tejun
Re: [PATCH 09/14] x86, mm, numa: set memblock nid later
Quoted 5 lines · Tejun Heo
Quoted 1 line · Yinghai Lu
Only set memblock nid one time.
Would be awesome if the description explains why we're doing this and why we're allowed to do this now.
will add more:
set memblock nid will cause membock layout change like array could be doubled. and we do not have current memblock limit set, so will put down under 1M and could
use too much under 1M.
And for fallback path, we can avoid restore memblock and remerge action.
After We use numa_meminfo nid for checking, we don't need to send it again.
Thanks
Yinghai
PATCH 10/14 x86, mm, numa: Move emulation handling down.
In reply to Yinghai LuIt will need to allocate buffer for new numa_meminfo and distance matrix, so move it down.
Also we change the behavoir:
before this patch, if user input wrong data in command line, it will fall back to next numa or disabling numa.
after this patch, if user input wrong data in command line, it will stay with numa info from probing before, like acpi srat or amd_numa.
--- arch/x86/mm/numa.c | 15 +++++++++------ arch/x86/mm/numa_emulation.c | 2 +- arch/x86/mm/numa_internal.h | 2 ++ 3 files changed, 12 insertions(+), 7 deletions(-)
arch/x86/mm/numa.c +9 -6
@@ -537,14 +537,16 @@ static unsigned long __init node_map_pfn_alignment(struct numa_meminfo *mi) }#endif -static int __init numa_check_memblks (struct numa_meminfo *mi) + +int __init numa_check_memblks (struct numa_meminfo *mi) { +nodemask_t tmp_node_map;unsigned long pfn_align;/* Account for nodes with cpus and no memory */ - node_possible_map = numa_nodes_parsed; -numa_nodemask_from_meminfo (&node_possible_map, mi); -if (WARN_ON (nodes_empty (node_possible_map))) + tmp_node_map = numa_nodes_parsed; +numa_nodemask_from_meminfo (&tmp_node_map, mi); +if (WARN_ON (nodes_empty (tmp_node_map)))return -EINVAL ;if (!numa_meminfo_cover_memory (mi))
@@ -562,6 +564,7 @@ static int __init numa_check_memblks(struct numa_meminfo *mi)return -EINVAL ; } + node_possible_map = tmp_node_map;return 0 ; }
@@ -608,8 +611,6 @@ static int __init numa_init(int (*init_func)(void))if (ret <0 )return ret; -numa_emulation (&numa_meminfo, numa_distance_cnt); - ret =numa_check_memblks (&numa_meminfo);if (ret <0 )return ret;
@@ -669,6 +670,8 @@ void __init x86_numa_init(void)numa_init (dummy_numa_init); out: +numa_emulation (&numa_meminfo, numa_distance_cnt); +for (i =0 ; i < mi->nr_blks; i++) {struct numa_memblk *mb = &mi->blk[i];memblock_set_node (mb->start, mb->end - mb->start, mb->nid);
arch/x86/mm/numa_emulation.c +1 -1
@@ -348,7 +348,7 @@ void __init numa_emulation(struct numa_meminfo *numa_meminfo, int numa_dist_cnt)if (ret <0 ) goto no_emu; -if (numa_cleanup_meminfo (&ei) <0 ) { +if (numa_cleanup_meminfo (&ei) <0 ||numa_check_memblks (&ei) <0 ) {pr_warning ("NUMA: Warning: constructed meminfo invalid, disabling emulation\n" ); goto no_emu; }
arch/x86/mm/numa_internal.h +2 -0
@@ -21,6 +21,8 @@ void __init numa_reset_distance(void);void __init x86_numa_init (void ); +int __init numa_check_memblks (struct numa_meminfo *mi); +#ifdef CONFIG_NUMA_EMU void __init numa_emulation (struct numa_meminfo *numa_meminfo,int numa_dist_cnt);
Signature · 1 line
1.7.10.4
Re: [PATCH 10/14] x86, mm, numa: Move emulation handling down.
Quoted 18 lines · Yinghai Lu
arch/x86/mm/numa.c +6
-4-static int __init numa_check_memblks (struct numa_meminfo *mi) + +int __init numa_check_memblks (struct numa_meminfo *mi) { +nodemask_t tmp_node_map;unsigned long pfn_align;/* Account for nodes with cpus and no memory */ - node_possible_map = numa_nodes_parsed; -numa_nodemask_from_meminfo (&node_possible_map, mi); -if (WARN_ON (nodes_empty (node_possible_map))) + tmp_node_map = numa_nodes_parsed; +numa_nodemask_from_meminfo (&tmp_node_map, mi); +if (WARN_ON (nodes_empty (tmp_node_map)))return -EINVAL ;if (!numa_meminfo_cover_memory (mi))
arch/x86/mm/numa.c static int __init numa_check_memblks(struct numa_meminfo *mi) · line 567
Quoted 4 lines
arch/x86/mm/numa.c +1
-0@@ -562,6 +564,7 @@ static int __init numa_check_memblks(struct numa_meminfo *mi)return -EINVAL ; } + node_possible_map = tmp_node_map;
Hmmm.... it's kinda nasty to have a side effect like the above for a function named numa_check_memblks(). Maybe we can move this to the caller or name the function to make it clear that some global state is being updated?
Quoted 23 lines
arch/x86/mm/numa.c +2
-2@@ -608,8 +611,6 @@ static int __init numa_init(int (*init_func)(void))if (ret <0 )return ret; -numa_emulation (&numa_meminfo, numa_distance_cnt); - ret =numa_check_memblks (&numa_meminfo);if (ret <0 )return ret;@@ -669,6 +670,8 @@ void __init x86_numa_init(void)numa_init (dummy_numa_init); out: +numa_emulation (&numa_meminfo, numa_distance_cnt); +for (i =0 ; i < mi->nr_blks; i++) {struct numa_memblk *mb = &mi->blk[i];memblock_set_node (mb->start, mb->end - mb->start, mb->nid);arch/x86/mm/numa_emulation.c +0
-0
arch/x86/mm/numa_emulation.c void __init numa_emulation(struct numa_meminfo *numa_meminfo, int numa_dist_cnt) · line 354
Quoted 8 lines
arch/x86/mm/numa_emulation.c +1
-1@@ -348,7 +348,7 @@ void __init numa_emulation(struct numa_meminfo *numa_meminfo, int numa_dist_cnt)if (ret <0 ) goto no_emu; -if (numa_cleanup_meminfo (&ei) <0 ) { +if (numa_cleanup_meminfo (&ei) <0 ||numa_check_memblks (&ei) <0 ) {pr_warning ("NUMA: Warning: constructed meminfo invalid, disabling emulation\n" ); goto no_emu; }
Given that acpi is the only mechanism which matters in any modern NUMA machines, I think the re-ordering should be fine.
Thanks.
Signature · 1 line
tejun
Re: [PATCH 10/14] x86, mm, numa: Move emulation handling down.
Quoted 22 lines · Tejun Heo
Quoted 21 lines · Yinghai Lu
arch/x86/mm/numa.c +6
-4-static int __init numa_check_memblks (struct numa_meminfo *mi) + +int __init numa_check_memblks (struct numa_meminfo *mi) { +nodemask_t tmp_node_map;unsigned long pfn_align;/* Account for nodes with cpus and no memory */ - node_possible_map = numa_nodes_parsed; -numa_nodemask_from_meminfo (&node_possible_map, mi); -if (WARN_ON (nodes_empty (node_possible_map))) + tmp_node_map = numa_nodes_parsed; +numa_nodemask_from_meminfo (&tmp_node_map, mi); +if (WARN_ON (nodes_empty (tmp_node_map)))return -EINVAL ;if (!numa_meminfo_cover_memory (mi))@@ -562,6 +564,7 @@ static int __init numa_check_memblks(struct numa_meminfo *mi)return -EINVAL ; }
Quoted 6 lines
arch/x86/mm/numa.c static int __init numa_check_memblks(struct numa_meminfo *mi) · line 567
Quoted 1 line
arch/x86/mm/numa.c +1
-0+ node_possible_map = tmp_node_map;Hmmm.... it's kinda nasty to have a side effect like the above for a function named
numa_check_memblks(). Maybe we can move this to the caller or name the function to make it clear that some global state is being updated?
ok, will split it out for node_possibe_map updating.
Quoted 27 lines
Quoted 27 lines
arch/x86/mm/numa.c +2
-2@@ -608,8 +611,6 @@ static int __init numa_init(int (*init_func)(void))if (ret <0 )return ret; -numa_emulation (&numa_meminfo, numa_distance_cnt); - ret =numa_check_memblks (&numa_meminfo);if (ret <0 )return ret;@@ -669,6 +670,8 @@ void __init x86_numa_init(void)numa_init (dummy_numa_init); out: +numa_emulation (&numa_meminfo, numa_distance_cnt); +for (i =0 ; i < mi->nr_blks; i++) {struct numa_memblk *mb = &mi->blk[i];memblock_set_node (mb->start, mb->end - mb->start, mb->nid);arch/x86/mm/numa_emulation.c +0
-0@@ -348,7 +348,7 @@ void __init numa_emulation(struct numa_meminfo *numa_meminfo, int numa_dist_cnt)if (ret <0 ) goto no_emu;
Quoted 8 lines
arch/x86/mm/numa_emulation.c void __init numa_emulation(struct numa_meminfo *numa_meminfo, int numa_dist_cnt) · line 354
Quoted 5 lines
arch/x86/mm/numa_emulation.c +1
-1-if (numa_cleanup_meminfo (&ei) <0 ) { +if (numa_cleanup_meminfo (&ei) <0 ||numa_check_memblks (&ei) <0 ) {pr_warning ("NUMA: Warning: constructed meminfo invalid, disabling emulation\n" ); goto no_emu; }Given that acpi is the only mechanism which matters in any modern NUMA machines, I think the re-ordering should be fine.
Good.
PATCH 11/14 x86, acpi, numa: split SLIT handling out
In reply to Yinghai LuWe need to handle slit later, as it need to allocate buffer.
Also we only need srat info before init_mem_mapping.
x86_acpi_numa_init become x86_acpi_numa_init_only_slit x86_acpi_numa_init_no_slit.
--- arch/x86/include/asm/acpi.h | 3 ++- arch/x86/mm/numa.c | 13 ++++++++++++- arch/x86/mm/srat.c | 8 ++++++-- drivers/acpi/numa.c | 22 +++++++++++++++++++--- include/linux/acpi.h | 2 ++ 5 files changed, 41 insertions(+), 7 deletions(-)
arch/x86/include/asm/acpi.h +2 -1
@@ -178,7 +178,8 @@ static inline void disable_acpi(void) { }#ifdef CONFIG_ACPI_NUMA extern int acpi_numa; -extern int x86_acpi_numa_init (void ); +int x86_acpi_numa_init_no_slit (void ); +void x86_acpi_numa_init_only_slit (void );#endif /* CONFIG_ACPI_NUMA */ #define acpi_unlazy_tlb (x) leave_mm(x)
arch/x86/mm/numa.c +12 -1
@@ -640,6 +640,10 @@ static int __init dummy_numa_init(void)return 0 ; } +#ifdef CONFIG_ACPI_NUMA +static bool srat_used__initdata ; +#endif +/** * x86_numa_init - Initialize NUMA *
@@ -658,8 +662,10 @@ void __init x86_numa_init(void) goto out;#endif #ifdef CONFIG_ACPI_NUMA -if (!numa_init (x86_acpi_numa_init)) +if (!numa_init (x86_acpi_numa_init_no_slit)) { + srat_used = true; goto out; + }#endif #ifdef CONFIG_AMD_NUMA if (!numa_init (amd_numa_init))
@@ -670,6 +676,11 @@ void __init x86_numa_init(void)numa_init (dummy_numa_init); out: +#ifdef CONFIG_ACPI_NUMA +if (srat_used) +x86_acpi_numa_init_only_slit (); +#endif +numa_emulation (&numa_meminfo, numa_distance_cnt);for (i =0 ; i < mi->nr_blks; i++) {
arch/x86/mm/srat.c +6 -2
@@ -187,11 +187,15 @@ out_err:void __init acpi_numa_arch_fixup (void ) {} -int __init x86_acpi_numa_init (void ) +void __init x86_acpi_numa_init_only_slit (void ) +{ +acpi_numa_init_only_slit (); +} +int __init x86_acpi_numa_init_no_slit (void ) {int ret; - ret =acpi_numa_init (); + ret =acpi_numa_init_no_slit ();if (ret <0 )return ret;return srat_disabled () ? -EINVAL :0 ;
drivers/acpi/numa.c +19 -3
@@ -282,7 +282,13 @@ acpi_table_parse_srat(enum acpi_srat_type id, handler, max_entries); } -int __init acpi_numa_init (void ) +void __init acpi_numa_init_only_slit (void ) +{ +/* SLIT: System Locality Information Table */ +acpi_table_parse (ACPI_SIG_SLIT , acpi_parse_slit); +} + +static int __init __acpi_numa_init (bool with_slit) {int cnt =0 ;
@@ -303,8 +309,8 @@ int __init acpi_numa_init(void) NR_NODE_MEMBLKS); } -/* SLIT: System Locality Information Table */ -acpi_table_parse (ACPI_SIG_SLIT , acpi_parse_slit); +if (with_slit) +acpi_numa_init_only_slit ();acpi_numa_arch_fixup ();
@@ -315,6 +321,16 @@ int __init acpi_numa_init(void)return 0 ; } +int __init acpi_numa_init (void ) +{ +return __acpi_numa_init (true); +} + +int __init acpi_numa_init_no_slit (void ) +{ +return __acpi_numa_init (false); +} +int acpi_get_pxm (acpi_handle h) {unsigned long long pxm;
include/linux/acpi.h +2 -0
@@ -86,6 +86,8 @@ int acpi_boot_init (void);void acpi_boot_table_init (void );int acpi_mps_check (void );int acpi_numa_init (void ); +int acpi_numa_init_no_slit (void ); +void acpi_numa_init_only_slit (void );int acpi_table_init (void );int acpi_table_parse (char *id,acpi_tbl_table_handler handler);
Signature · 1 line
1.7.10.4
Re: [PATCH 11/14] x86, acpi, numa: split SLIT handling out
drivers/acpi/numa.c acpi_table_parse_srat(enum acpi_srat_type id, · line 293
Quoted 9 lines · Yinghai Lu
drivers/acpi/numa.c +7
-0+void __init acpi_numa_init_only_slit (void ) +{ +/* SLIT: System Locality Information Table */ +acpi_table_parse (ACPI_SIG_SLIT , acpi_parse_slit); +} + +static int __init __acpi_numa_init (bool with_slit) {int cnt =0 ;
Hmmm.... how about just having the following two functions
acpi_numa_init_srat(); acpi_numa_init_slit();
and update both x86 and ia64 to use the two functions?
Signature · 1 line
tejun
Re: [PATCH 11/14] x86, acpi, numa: split SLIT handling out
Quoted 13 lines · Tejun Heo
drivers/acpi/numa.c acpi_table_parse_srat(enum acpi_srat_type id, · line 293
Quoted 9 lines · Yinghai Lu
drivers/acpi/numa.c +7
-0+void __init acpi_numa_init_only_slit (void ) +{ +/* SLIT: System Locality Information Table */ +acpi_table_parse (ACPI_SIG_SLIT , acpi_parse_slit); +} + +static int __init __acpi_numa_init (bool with_slit) {int cnt =0 ;Hmmm.... how about just having the following two functions
Quoted 2 lines
acpi_numa_init_srat();
acpi_numa_init_slit();ok.
Quoted 1 line
and update both x86 and ia64 to use the two functions?
ia64 like to call in this seqenceacpi_numa_init()
parse srat
parse slit
thenacpi_numa_arch_fixup()
in this arch_fixup, it will try to fill dummy distance_matrix.
so would to keep acpi_numa_init ...
Re: [PATCH 11/14] x86, acpi, numa: split SLIT handling out
Quoted 10 lines · Yinghai Lu
ia64 like to call in this seqence
acpi_numa_init()
parse srat
parse slit
thenacpi_numa_arch_fixup()in this
arch_fixup, it will try to fill dummydistance_matrix.so would to keep
acpi_numa_init...
Can't it just call acpi_numa_init_srat() and then init_slit()? What am I missing?
Signature · 1 line
tejun
Re: [PATCH 11/14] x86, acpi, numa: split SLIT handling out
Quoted 8 lines · Tejun Heo
Quoted 7 lines · Yinghai Lu
ia64 like to call in this seqence
acpi_numa_init()
parse srat
parse slit
thenacpi_numa_arch_fixup()
Quoted 6 lines
Quoted 3 lines
in this
arch_fixup, it will try to fill dummydistance_matrix.so would to keep
acpi_numa_init...Can't it just call
acpi_numa_init_srat()and theninit_slit()? What am I missing?
Yes, but need to break acpi_numa_init calling
in arch/ia64/kernel/setup.c
withacpi_numa_init_srat()acpi_numa_init_slit()acpi_numa_arch_fixup()
current code isacpi_numa_init calling arch_numa_arch_fixup()
Thanks
Yinghai
PATCH 12/14 x86, mm, numa: Add early_initmem_init() stub
In reply to Yinghai Luearly_initmem_init() will call early_x86_numa_init().
later will call init_mem_mapping for nodes in it.
--- arch/x86/include/asm/page_types.h | 1 + arch/x86/kernel/setup.c | 1 + arch/x86/mm/init_32.c | 3 +++ arch/x86/mm/init_64.c | 3 +++ arch/x86/mm/numa.c | 23 +++++++++++++++-------- 5 files changed, 23 insertions(+), 8 deletions(-)
arch/x86/include/asm/page_types.h +1 -0
@@ -55,6 +55,7 @@ bool pfn_range_is_mapped(unsigned long start_pfn, unsigned long end_pfn);extern unsigned long init_memory_mapping (unsigned long start,unsigned long end); +void early_initmem_init (void );extern void initmem_init (void );#endif /* !__ASSEMBLY__ */
arch/x86/kernel/setup.c +1 -0
@@ -1133,6 +1133,7 @@ void __init setup_arch(char **cmdline_p)early_acpi_boot_init (); +early_initmem_init ();initmem_init ();memblock_find_dma_reserve ();
arch/x86/mm/init_32.c +3 -0
@@ -660,6 +660,9 @@ void __init find_low_pfn_range(void) }#ifndef CONFIG_NEED_MULTIPLE_NODES +void __init early_initmem_init (void ) +{ +}void __init initmem_init (void ) {#ifdef CONFIG_HIGHMEM
arch/x86/mm/init_64.c +3 -0
@@ -640,6 +640,9 @@ kernel_physical_mapping_init(unsigned long start, }#ifndef CONFIG_NUMA +void __init early_initmem_init (void ) +{ +}void __init initmem_init (void ) {memblock_set_node (0 , (phys_addr_t )ULLONG_MAX ,0 );
arch/x86/mm/numa.c +15 -8
@@ -651,31 +651,38 @@ static bool srat_used __initdata;* last fallback is dummy single node config encomapssing whole memory and * never fails. */ -void __init x86_numa_init (void ) +static void __init early_x86_numa_init (void ) { -int i, nid; -struct numa_meminfo *mi = &numa_meminfo; -if (!numa_off) {#ifdef CONFIG_X86_NUMAQ if (!numa_init (numaq_numa_init)) - goto out; +return ;#endif #ifdef CONFIG_ACPI_NUMA if (!numa_init (x86_acpi_numa_init_no_slit)) { srat_used = true; - goto out; +return ; }#endif #ifdef CONFIG_AMD_NUMA if (!numa_init (amd_numa_init)) - goto out; +return ;#endif }numa_init (dummy_numa_init); +} + +void __init early_initmem_init (void ) +{ +early_x86_numa_init (); +} + +void __init x86_numa_init (void ) +{ +int i, nid; +struct numa_meminfo *mi = &numa_meminfo; -out:#ifdef CONFIG_ACPI_NUMA if (srat_used)x86_acpi_numa_init_only_slit ();
Signature · 1 line
1.7.10.4
PATCH 13/14 x86, mm: Parse numa info early
In reply to Yinghai LuParse numa info at first and store info into numa_meminfo.
call early_initmem_init before init_memory_mapping(), will have numa info ready at first, and will still keep numaq, acpi_numa, amd_numa, dummy fall back sequence.
SLIT and numa emulation handling are still left in initmem_init().
--- arch/x86/kernel/setup.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-)
arch/x86/kernel/setup.c +10 -14
@@ -1096,13 +1096,21 @@ void __init setup_arch(char **cmdline_p)trim_platform_memory_ranges ();trim_low_memory_range (); +/* +* Parse the ACPI tables for possible boot-time SMP configuration. +*/ +acpi_initrd_override_copy (); +acpi_boot_table_init (); +early_acpi_boot_init (); +early_initmem_init ();init_mem_mapping (); - + memblock.current_limit =get_max_mapped ();early_trap_pf_init (); +reserve_initrd (); +setup_real_mode (); - memblock.current_limit =get_max_mapped ();dma_contiguous_reserve (0 );/*
@@ -1116,24 +1124,12 @@ void __init setup_arch(char **cmdline_p)/* Allocate bigger log buffer */ setup_log_buf (1 ); -reserve_initrd (); - -acpi_initrd_override_copy (); -reserve_crashkernel ();vsmp_init ();io_delay_init (); -/* -* Parse the ACPI tables for possible boot-time SMP configuration. -*/ -acpi_boot_table_init (); - -early_acpi_boot_init (); - -early_initmem_init ();initmem_init ();memblock_find_dma_reserve ();
Signature · 1 line
1.7.10.4
PATCH 14/14 x86, mm: Put pagetable on local node ram
In reply to Yinghai LuIf node with ram is hotplugable, local node mem for page table and vmemmap should be on that node ram.
This patch is some kind of refreshment of
| commit 1411e0ec3123ae4c4ead6bfc9fe3ee5a3ae5c327 | Date: Mon Dec 27 16:48:17 2010 -0800 | | x86-64, numa: Put pgtable to local node memory
That was reverted before.
We have reason to reintroduce it to make memory hotplug work.
Split calling of init_mem_mapping into early_initmem_info for nodes after we get numa info there.
First node will be low range.
Need to rework alloc_low_pages to alloc page table in following order:
BRK, local node, low range
Still only load_cr3 one time, otherwise we would break xen 64bit again.
--- arch/x86/include/asm/pgtable.h | 2 +- arch/x86/kernel/setup.c | 1 - arch/x86/mm/init.c | 83 ++++++++++++++++++++++------------------ arch/x86/mm/init_32.c | 8 ++++ arch/x86/mm/init_64.c | 9 +++++ arch/x86/mm/numa.c | 56 +++++++++++++++++++++++++++ 6 files changed, 119 insertions(+), 40 deletions(-)
arch/x86/include/asm/pgtable.h +1 -1
@@ -621,7 +621,7 @@ static inline int pgd_none(pgd_t pgd)#ifndef __ASSEMBLY__extern int direct_gbpages; -void init_mem_mapping (void ); +void init_mem_mapping (unsigned long begin,unsigned long end);void early_alloc_pgt_buf (void );/* local pte updates need not use xchg for locking */
arch/x86/kernel/setup.c +0 -1
@@ -1103,7 +1103,6 @@ void __init setup_arch(char **cmdline_p)acpi_boot_table_init ();early_acpi_boot_init ();early_initmem_init (); -init_mem_mapping (); memblock.current_limit =get_max_mapped ();early_trap_pf_init ();
arch/x86/mm/init.c +45 -38
129 lines not on this page · raw message
arch/x86/mm/init_32.c +8 -0
@@ -662,6 +662,14 @@ void __init find_low_pfn_range(void)#ifndef CONFIG_NEED_MULTIPLE_NODES void __init early_initmem_init (void ) { +init_mem_mapping (0 , max_low_pfn<<PAGE_SHIFT ); + +early_ioremap_page_table_range_init (); + +load_cr3 (swapper_pg_dir); +__flush_tlb_all (); + +early_memtest (0 , max_pfn_mapped<<PAGE_SHIFT ); }void __init initmem_init (void ) {
arch/x86/mm/init_64.c +9 -0
@@ -642,6 +642,15 @@ kernel_physical_mapping_init(unsigned long start,#ifndef CONFIG_NUMA void __init early_initmem_init (void ) { +init_mem_mapping (0 , max_pfn<<PAGE_SHIFT ); + +if (max_pfn > max_low_pfn) + max_low_pfn = max_pfn; + +load_cr3 (swapper_pg_dir); +__flush_tlb_all (); + +early_memtest (0 , max_pfn_mapped<<PAGE_SHIFT ); }void __init initmem_init (void ) {
arch/x86/mm/numa.c +56 -0
73 lines not on this page · raw message
Signature · 1 line
1.7.10.4
Re: [PATCH 14/14] x86, mm: Put pagetable on local node ram
Quoted 12 lines · Yinghai Lu
If node with ram is hotplugable, local node mem for page table and vmemmap should be on that node ram.
This patch is some kind of refreshment of
| commit 1411e0ec3123ae4c4ead6bfc9fe3ee5a3ae5c327 | Date: Mon Dec 27 16:48:17 2010 -0800 | | x86-64, numa: Put pgtable to local node memoryThat was reverted before.
We have reason to reintroduce it to make memory hotplug work.
Quoted 8 lines
Split calling of
init_mem_mappingintoearly_initmem_infofor nodes after we get numa info there.First node will be low range.
Need to reworkalloc_low_pagesto alloc page table in following order:
BRK, local node, low rangeStill only
load_cr3one time, otherwise we would break xen 64bit again.
Hmmm... can you please split this patch further? init_mem_mapping() change can be separated, no? Also, comments are disturbingly missing. How are other people reading the code supposed to know what it's trying to achieve why and how? Hmmm... we're also likely to end up with smaller mapping for misaligned NUMA configurations (I think my test machine is like that). Is it guaranteed that the top level ends up in the first node? It really needs documentation.
Thanks.
Signature · 1 line
tejun
Re: [PATCH 14/14] x86, mm: Put pagetable on local node ram
Quoted 16 lines · Tejun Heo
Quoted 15 lines · Yinghai Lu
If node with ram is hotplugable, local node mem for page table and vmemmap should be on that node ram.
This patch is some kind of refreshment of
| commit 1411e0ec3123ae4c4ead6bfc9fe3ee5a3ae5c327 | Date: Mon Dec 27 16:48:17 2010 -0800 | | x86-64, numa: Put pgtable to local node memoryThat was reverted before.
We have reason to reintroduce it to make memory hotplug work.
Split calling of
init_mem_mappingintoearly_initmem_infofor nodes after we get numa info there.
Quoted 8 lines
Quoted 5 lines
First node will be low range.
Need to reworkalloc_low_pagesto alloc page table in following order:
BRK, local node, low rangeStill only
load_cr3one time, otherwise we would break xen 64bit again.Hmmm... can you please split this patch further?
init_mem_mapping()change can be separated, no?
will try to split it out.
Quoted 6 lines
Also, comments are disturbingly missing.
How are other people reading the code supposed to know what it's trying to achieve why and how? Hmmm... we're also likely to end up with smaller mapping for misaligned NUMA configurations (I think my test machine is like that). Is it guaranteed that the top level ends up in the first node? It really needs documentation.
Yes. To really memory hotplug working, will need to trim the node alignment to be
1G in memblock and numa_meminfo.
also need to put pgd page in low range (first node) if 512G block is crossing node.
for example: if node2 is [256g, 1024g), pgd for 256g-512g, must be stay on node0 and 512g-1024g could stay on node2.
or just put all PGD pages on low range (first node).
Thanks
Yinghai
Re: [PATCH 14/14] x86, mm: Put pagetable on local node ram
In reply to Yinghai LuHi Yinghai,
On 03/08/2013 12:58 PM, Yinghai Lu wrote:
......
arch/x86/mm/init.c static unsigned long __init init_range_memory_mapping( · line 421
Quoted 3 lines
/* xen has big range in reserved near end of ram, skip it at first.*/
arch/x86/mm/init.c +1
-1- addr =memblock_find_in_range (ISA_END_ADDRESS , end,PMD_SIZE ,PMD_SIZE ); + addr =memblock_find_in_range (begin, end,PMD_SIZE ,PMD_SIZE );
Found that the latest code here is:
414 addr = memblock_find_in_range(ISA_END_ADDRESS, end, PMD_SIZE,
415 PAGE_SIZE);
^^^^^^^^^^^^The "align" is PAGE_SIZE, not PMD_SIZE. Not sure if it is a problem. :)
Thanks. :)
Re: [PATCH 14/14] x86, mm: Put pagetable on local node ram
Quoted 12 lines · Tang Chen
Hi Yinghai,
On 03/08/2013 12:58 PM, Yinghai Lu wrote:
......Quoted 5 lines
/* xen has big range in reserved near end of ram, skip it atfirst.*/
- addr = memblock_find_in_range(ISA_END_ADDRESS, end,PMD_SIZE,PMD_SIZE);
+ addr =memblock_find_in_range(begin, end, PMD_SIZE, PMD_SIZE);
Quoted 8 lines
Found that the latest code here is:
414 addr = memblock_find_in_range(ISA_END_ADDRESS, end,
PMD_SIZE,415 PAGE_SIZE); ^^^^^^^^^^^^The "align" is
PAGE_SIZE, notPMD_SIZE. Not sure if it is a problem. :)
Yes, it is PMD_SIZE.
Thanks
Yinghai