Memory-Hotplug: Fix the bug on interface /dev/mem for 64-bit kernel
Subsystems (3)
PATCH RESEND v4 1/1 Memory-Hotplug: Fix the bug on interface /dev/mem for 64-bit kernel
Send the v4 patch to mailing list.
changelog:
v1: add memory range to e820 table, and update the varibles max_pfn/max_low_pfn/high_memory
Peter[hpa]: memory hotplug make sense on 32-bit kernel for virtual environment.
Andi[ak]: No VM supports it currently, and 64bit is the important part for hotplug Fengguang[wfg]: some review comments on function naming
v2: rename function update_pfn to update_end_of_memory_vars
KAMEZAWA[kame]: e820map is considerted to be stable, read-only after boot.
Fengguang[wfg]: rewrite function page_is_ram, make it friendly for hotplug.
v3: keep the old e820map, update the varible max_pfn, high_memory only
KAMEZAWA[kame]: suggest to use memory hotplug notifier. If it's allowed, it will
be cleaner.
Fengguang[wfg]: notifier is for _outsider_ subsystems. It smells a bit overkill to do
notifier _inside_ the hotplug code.
Fengguang[wfg]: suggest to update max_pfn/max_low_pfn/high_memory in arch/x86/mm/init_64.c:
arch_add_memory() now, for X86_64.
Later on we can add code to arch/x86/mm/init_32.c:arch_add_memory() for X86_32.
v4: update max_pfn/max_low_pfn/high_memory in arch/x86/mm/init_64.c:arch_add_memory() for x86_64,
and resent it to mailing list, since fengguang's page_is_ram patch was accepted,
Memory-Hotplug: Fix the bug on interface /dev/mem for 64-bit kernel
The new added memory can not be access by interface /dev/mem, because we do not
update the variables high_memory, max_pfn and max_low_pfn.
Add a function update_end_of_memory_vars to update these variables for 64-bit kernel.
arch/x86/mm/init_64.c +16 -1
@@ -49,6 +49,7 @@#include <asm/numa.h> #include <asm/cacheflush.h> #include <asm/init.h> +#include <linux/bootmem.h> static unsigned long dma_reserve__initdata ;
@@ -614,6 +615,21 @@ void __init paging_init(void)* Memory hotplug specific functions */ #ifdef CONFIG_MEMORY_HOTPLUG +/** +* After memory hotplug, the variable max_pfn, max_low_pfn and high_memory will +* be affected, it will be updated in this function. +*/ +static inline void __meminit update_end_of_memory_vars (u64 start, +u64 size) +{ +unsigned long end_pfn =PFN_UP (start + size); + +if (end_pfn > max_pfn) { + max_low_pfn = max_pfn = end_pfn; + high_memory = (void *)__va (max_pfn *PAGE_SIZE -1 ) +1 ; + } +} +/* * Memory is added always to NORMAL zone. This means you will never get * additional DMA/DMA32 memory.
@@ -633,6 +649,9 @@ int arch_add_memory(int nid, u64 start, u64 size) ret =__add_pages (nid, zone, start_pfn, nr_pages);WARN_ON_ONCE (ret); --
Thanks & Regards,
Shaohuki
Memory-Hotplug: Fix the bug on interface /dev/mem for 64-bit kernel
The new added memory can not be access by interface /dev/mem, because we do not
update the variables high_memory, max_pfn and max_low_pfn.
Add a function update_end_of_memory_vars to update these variables for 64-bit kernel.
arch/x86/mm/init_64.c +19 -0
@@ -49,6 +49,7 @@#include <asm/numa.h> #include <asm/cacheflush.h> #include <asm/init.h> +#include <linux/bootmem.h> static unsigned long dma_reserve__initdata ;
@@ -614,6 +615,21 @@ void __init paging_init(void)* Memory hotplug specific functions */ #ifdef CONFIG_MEMORY_HOTPLUG +/** +* After memory hotplug, the variable max_pfn, max_low_pfn and high_memory will +* be affected, it will be updated in this function. +*/ +static inline void __meminit update_end_of_memory_vars (u64 start, +u64 size) +{ +unsigned long end_pfn =PFN_UP (start + size); + +if (end_pfn > max_pfn) { + max_low_pfn = max_pfn = end_pfn; + high_memory = (void *)__va (max_pfn *PAGE_SIZE -1 ) +1 ; + } +} +/* * Memory is added always to NORMAL zone. This means you will never get * additional DMA/DMA32 memory.
@@ -633,6 +649,9 @@ int arch_add_memory(int nid, u64 start, u64 size) ret =__add_pages (nid, zone, start_pfn, nr_pages);WARN_ON_ONCE (ret); +/* update max_pfn, max_low_pfn and high_memory */ +update_end_of_memory_vars (start, size); +return ret; }EXPORT_SYMBOL_GPL (arch_add_memory);
Shaohui,
Some style nitpicks..
Quoted 2 lines
#ifdef
CONFIG_MEMORY_HOTPLUG
+/**
Should use /* here.
Quoted 4 lines
+ * After memory hotplug, the variable
max_pfn,max_low_pfnandhigh_memorywill
+ * be affected, it will be updated in this function.
+ */
+static inline void__meminitupdate_end_of_memory_vars(u64 start,
The "inline" and "__meminit" are both redundant here.
Review
Quoted 1 line
(quoted diff) +1
-0+ max_low_pfn = max_pfn = end_pfn;
One assignment per line is preferred.
Thanks,
Fengguang
Shaohui Zheng
Reviewed-by Wu Fengguang Reviewed-by KAMEZAWA Hiroyuki Reviewed-by Wu Fengguang Reviewed-by KAMEZAWA HiroyukiQuoted 8 lines · Wu Fengguang
Shaohui,
Some style nitpicks..
Quoted 2 lines
#ifdef
CONFIG_MEMORY_HOTPLUG
+/**Should use /* here.
Agree.
Quoted 7 lines
Quoted 5 lines
+ * After memory hotplug, the variable
max_pfn,max_low_pfnandhigh_memorywill
+ * be affected, it will be updated in this function.
+ */
+static inline void__meminitupdate_end_of_memory_vars(u64 start,The "inline" and "
__meminit" are both redundant here.
will remove both.
Quoted 4 lines
Review
Quoted 2 lines
(quoted diff) +1
-0+ max_low_pfn = max_pfn = end_pfn;One assignment per line is preferred.
will change to 2 statements.
Quoted 3 lines
Thanks,
Fengguang
Memory-Hotplug: Fix the bug on interface /dev/mem for 64-bit kernel
The new added memory can not be access by interface /dev/mem, because we do not
update the variables high_memory, max_pfn and max_low_pfn.
Add a function update_end_of_memory_vars to update these variables for 64-bit kernel.
arch/x86/mm/init_64.c +19 -0
@@ -49,6 +49,7 @@#include <asm/numa.h> #include <asm/cacheflush.h> #include <asm/init.h> +#include <linux/bootmem.h> static unsigned long dma_reserve__initdata ;
@@ -616,6 +617,21 @@ void __init paging_init(void)*/ #ifdef CONFIG_MEMORY_HOTPLUG /* +* After memory hotplug, the variables max_pfn, max_low_pfn and high_memory will +* be affected, they will be updated in this function. +*/ +static void update_end_of_memory_vars (u64 start,u64 size) +{ +unsigned long end_pfn =PFN_UP (start + size); + +if (end_pfn > max_pfn) { + max_pfn = end_pfn; + max_low_pfn = end_pfn; + high_memory = (void *)__va (max_pfn *PAGE_SIZE -1 ) +1 ; + } +} + +/* * Memory is added always to NORMAL zone. This means you will never get * additional DMA/DMA32 memory. */
@@ -634,6 +650,9 @@ int arch_add_memory(int nid, u64 start, u64 size) ret =__add_pages (nid, zone, start_pfn, nr_pages);WARN_ON_ONCE (ret); +/* update max_pfn, max_low_pfn and high_memory */ +update_end_of_memory_vars (start, size); +return ret; }EXPORT_SYMBOL_GPL (arch_add_memory);
Signature · 2 lines
Thanks & Regards, Shaohui
Memory-Hotplug: Fix the bug on interface /dev/mem for 64-bit kernel
The new added memory can not be access by interface /dev/mem, because we do not
update the variables high_memory, max_pfn and max_low_pfn.
Add a function update_end_of_memory_vars to update these variables for 64-bit kernel.
arch/x86/mm/init_64.c +19 -0
@@ -49,6 +49,7 @@#include <asm/numa.h> #include <asm/cacheflush.h> #include <asm/init.h> +#include <linux/bootmem.h> static unsigned long dma_reserve__initdata ;
@@ -616,6 +617,21 @@ void __init paging_init(void)*/ #ifdef CONFIG_MEMORY_HOTPLUG /* +* After memory hotplug, the variables max_pfn, max_low_pfn and high_memory will +* be affected, they will be updated in this function. +*/ +static void update_end_of_memory_vars (u64 start,u64 size) +{ +unsigned long end_pfn =PFN_UP (start + size); + +if (end_pfn > max_pfn) { + max_pfn = end_pfn; + max_low_pfn = end_pfn; + high_memory = (void *)__va (max_pfn *PAGE_SIZE -1 ) +1 ; + } +} + +/* * Memory is added always to NORMAL zone. This means you will never get * additional DMA/DMA32 memory. */
@@ -634,6 +650,9 @@ int arch_add_memory(int nid, u64 start, u64 size) ret =__add_pages (nid, zone, start_pfn, nr_pages);WARN_ON_ONCE (ret); +/* update max_pfn, max_low_pfn and high_memory */ +update_end_of_memory_vars (start, size); +return ret; }EXPORT_SYMBOL_GPL (arch_add_memory);