generic hotplug friendly page_is_ram()
cover generic hotplug friendly page_is_ram()
Hi,
This introduces a generic iomem_resource based page_is_ram() and removes the x86 page_is_ram().
The resource based page_is_ram() is more hotplug friendly, because memory hotplug only updates resource and leave e820 unchanged.
The first patch changes generic code, however due to tight dependency, I'd recommend it be included in x86 tree together with the other two.
Thanks,
Fengguang
PATCH 1/3 resources: introduce generic page_is_ram()
It's based on walk_system_ram_range(), for archs that don't have their own page_is_ram().
The static verions in MIPS and SCORE are also made global.
--- arch/mips/mm/init.c | 2 +- arch/score/mm/init.c | 2 +- include/linux/ioport.h | 2 ++ kernel/resource.c | 11 +++++++++++ 4 files changed, 15 insertions(+), 2 deletions(-)
kernel/resource.c +11 -0
@@ -327,6 +327,17 @@ int walk_system_ram_range(unsigned long#endif +#define PAGE_IS_RAM 24 +static int __is_ram (unsigned long pfn,unsigned long nr_pages,void *arg) +{ +return PAGE_IS_RAM ; +} +int __attribute__((weak))page_is_ram (unsigned long pfn) +{ +return PAGE_IS_RAM ==walk_system_ram_range (pfn,1 ,NULL , __is_ram); +} +#undef PAGE_IS_RAM +/* * Find empty slot in the resource tree given range and alignment. */
include/linux/ioport.h +2 -0
@@ -191,5 +191,7 @@ extern int walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages, void *arg, int (*func)(unsigned long, unsigned long, void *)); +extern int page_is_ram (unsigned long pfn); +#endif /* __ASSEMBLY__ */ #endif /* _LINUX_IOPORT_H */
arch/score/mm/init.c +1 -1
@@ -59,7 +59,7 @@ static unsigned long setup_zero_page(voi }#ifndef CONFIG_NEED_MULTIPLE_NODES -static int __init page_is_ram (unsigned long pagenr) +int page_is_ram (unsigned long pagenr) {if (pagenr >= min_low_pfn && pagenr < max_low_pfn)return 1 ;
arch/mips/mm/init.c +1 -1
@@ -298,7 +298,7 @@ void __init fixrange_init(unsigned long }#ifndef CONFIG_NEED_MULTIPLE_NODES -static int __init page_is_ram (unsigned long pagenr) +int page_is_ram (unsigned long pagenr) {int i;
Re: [PATCH 1/3] resources: introduce generic page_is_ram()
Quoted 5 lines · On Fri, 22 Jan 2010 11:21:03 +0800 Wu Fengguang <[email protected]> wrote:
It's based on
walk_system_ram_range(), for archs that don't have their ownpage_is_ram().The static verions in MIPS and SCORE are also made global.
Quoted 8 lines
CC Chen Liqin <[email protected]>CC Lennox Wu <[email protected]>CC Ralf Baechle <[email protected]>CC Am辿rico Wang <[email protected]>CC KAMEZAWA Hiroyuki <[email protected]>CC Yinghai Lu <[email protected]>Signed-off-by Wu Fengguang <[email protected]>
Maybe adding comment like this is good for reviewers..
"This page_is_ram() returns true if specified address is registered
as System RAM in io_resource list."
AFAIK, this "System RAM" information has been used for kdump to grab valid memory area and seems good for the kernel itself.
Thanks,
-Kame
Quoted 62 lines
--- arch/mips/mm/init.c | 2 +- arch/score/mm/init.c | 2 +- include/linux/ioport.h | 2 ++ kernel/resource.c | 11 +++++++++++ 4 files changed, 15 insertions(+), 2 deletions(-)kernel/resource.c +11
-0@@ -327,6 +327,17 @@ int walk_system_ram_range(unsigned long#endif +#define PAGE_IS_RAM 24 +static int __is_ram (unsigned long pfn,unsigned long nr_pages,void *arg) +{ +return PAGE_IS_RAM ; +} +int __attribute__((weak))page_is_ram (unsigned long pfn) +{ +return PAGE_IS_RAM ==walk_system_ram_range (pfn,1 ,NULL , __is_ram); +} +#undef PAGE_IS_RAM +/* * Find empty slot in the resource tree given range and alignment. */ include/linux/ioport.h +2
-0@@ -191,5 +191,7 @@ extern int walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages, void *arg, int (*func)(unsigned long, unsigned long, void *)); +extern int page_is_ram (unsigned long pfn); +#endif /* __ASSEMBLY__ */ #endif /* _LINUX_IOPORT_H */ arch/score/mm/init.c +1
-1@@ -59,7 +59,7 @@ static unsigned long setup_zero_page(voi }#ifndef CONFIG_NEED_MULTIPLE_NODES -static int __init page_is_ram (unsigned long pagenr) +int page_is_ram (unsigned long pagenr) {if (pagenr >= min_low_pfn && pagenr < max_low_pfn)return 1 ;arch/mips/mm/init.c +1
-1@@ -298,7 +298,7 @@ void __init fixrange_init(unsigned long }#ifndef CONFIG_NEED_MULTIPLE_NODES -static int __init page_is_ram (unsigned long pagenr) +int page_is_ram (unsigned long pagenr) {int i;
PATCH v3 1/3 resources: introduce generic page_is_ram()
Quoted 19 lines · KAMEZAWA Hiroyuki
Quoted 5 lines · On Fri, 22 Jan 2010 11:21:03 +0800 Wu Fengguang <[email protected]> wrote:
It's based on
walk_system_ram_range(), for archs that don't have their ownpage_is_ram().The static verions in MIPS and SCORE are also made global.
Quoted 8 lines
CC Chen Liqin <[email protected]>CC Lennox Wu <[email protected]>CC Ralf Baechle <[email protected]>CC Am辿rico Wang <[email protected]>CC KAMEZAWA Hiroyuki <[email protected]>CC Yinghai Lu <[email protected]>Signed-off-by Wu Fengguang <[email protected]>Reviewed-by KAMEZAWA Hiroyuki <[email protected]>
Quoted 7 lines
Maybe adding comment like this is good for reviewers..
"This
page_is_ram()returns true if specified address is registered
as System RAM inio_resourcelist."AFAIK, this "System RAM" information has been used for kdump to grab valid memory area and seems good for the kernel itself.
Thanks! Patch updated as follows.
---
resources: introduce generic page_is_ram()
It's based on walk_system_ram_range(), for archs that don't have their own page_is_ram().
The static verions in MIPS and SCORE are also made global.
v3: add comment (KAMEZAWA Hiroyuki)
v2: add PAGE_IS_RAM macro (Américo Wang)
--- arch/mips/mm/init.c | 2 +- arch/score/mm/init.c | 2 +- include/linux/ioport.h | 2 ++ kernel/resource.c | 15 +++++++++++++++ 4 files changed, 19 insertions(+), 2 deletions(-)
kernel/resource.c +15 -0
@@ -327,6 +327,21 @@ int walk_system_ram_range(unsigned long#endif +#define PAGE_IS_RAM 24 +static int __is_ram (unsigned long pfn,unsigned long nr_pages,void *arg) +{ +return PAGE_IS_RAM ; +} +/* +* This generic page_is_ram() returns true if specified address is +* registered as "System RAM" in iomem_resource list. +*/ +int __attribute__((weak))page_is_ram (unsigned long pfn) +{ +return PAGE_IS_RAM ==walk_system_ram_range (pfn,1 ,NULL , __is_ram); +} +#undef PAGE_IS_RAM +/* * Find empty slot in the resource tree given range and alignment. */
include/linux/ioport.h +2 -0
@@ -191,5 +191,7 @@ extern int walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages, void *arg, int (*func)(unsigned long, unsigned long, void *)); +extern int page_is_ram (unsigned long pfn); +#endif /* __ASSEMBLY__ */ #endif /* _LINUX_IOPORT_H */
arch/score/mm/init.c +1 -1
@@ -59,7 +59,7 @@ static unsigned long setup_zero_page(voi }#ifndef CONFIG_NEED_MULTIPLE_NODES -static int __init page_is_ram (unsigned long pagenr) +int page_is_ram (unsigned long pagenr) {if (pagenr >= min_low_pfn && pagenr < max_low_pfn)return 1 ;
arch/mips/mm/init.c +1 -1
@@ -298,7 +298,7 @@ void __init fixrange_init(unsigned long }#ifndef CONFIG_NEED_MULTIPLE_NODES -static int __init page_is_ram (unsigned long pagenr) +int page_is_ram (unsigned long pagenr) {int i;
Re: [PATCH 1/3] resources: introduce generic page_is_ram()
In reply to Wu FengguangQuoted 27 lines · Wu Fengguang
It's based on
walk_system_ram_range(), for archs that don't have their ownpage_is_ram().The static verions in MIPS and SCORE are also made global.
CC Chen Liqin <[email protected]>CC Lennox Wu <[email protected]>CC Ralf Baechle <[email protected]>CC Américo Wang <[email protected]>CC KAMEZAWA Hiroyuki <[email protected]>CC Yinghai Lu <[email protected]>Signed-off-by Wu Fengguang <[email protected]>---
arch/mips/mm/init.c | 2 +-
arch/score/mm/init.c | 2 +-
include/linux/ioport.h | 2 ++
kernel/resource.c | 11 +++++++++++4 files changed, 15 insertions(+), 2 deletions(-)kernel/resource.c 2010-01-22 11:20:35.000000000 +0800 renamed from kernel/resource.c 2010-01-22 11:20:34.000000000 +0800 +1
-0@@ -327,6 +327,17 @@ int walk_system_ram_range(unsigned long #endif +#define PAGE_IS_RAM 24
kernel/resource.c 2010-01-22 11:20:35.000000000 +0800 int walk_system_ram_range(unsigned long · line 340
Quoted 10 lines
kernel/resource.c 2010-01-22 11:20:35.000000000 +0800 renamed from kernel/resource.c 2010-01-22 11:20:34.000000000 +0800 +10
-0+static int __is_ram(unsigned long pfn, unsigned long nr_pages, void *arg) +{ + return PAGE_IS_RAM; +} +int __attribute__((weak)) page_is_ram(unsigned long pfn) +{ + return PAGE_IS_RAM == walk_system_ram_range(pfn, 1, NULL, __is_ram); +} +#undef PAGE_IS_RAM +
I'm not sure, but any build test for powerpc/mips/score? walk_system_ram_range is defined when CONFIG_ARCH_HAS_WALK_MEMORY is not set. Is it safe when CONFIG_ARCH_HAS_WALK_MEMORY is set for some powerpc archs?
Quoted 43 lines
kernel/resource.c 2010-01-22 11:20:35.000000000 +0800 renamed from kernel/resource.c 2010-01-22 11:20:34.000000000 +0800 +0
-0/* * Find empty slot in the resource tree given range and alignment. */include/linux/ioport.h 2010-01-22 11:20:35.000000000 +0800 renamed from include/linux/ioport.h 2010-01-22 11:20:34.000000000 +0800 +2
-0@@ -191,5 +191,7 @@ extern int walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages, void *arg, int (*func)(unsigned long, unsigned long, void *)); +extern int page_is_ram(unsigned long pfn); + #endif /* __ASSEMBLY__ */ #endif /* _LINUX_IOPORT_H */arch/score/mm/init.c 2010-01-22 11:20:35.000000000 +0800 renamed from arch/score/mm/init.c 2010-01-22 11:20:34.000000000 +0800 +1
-1@@ -59,7 +59,7 @@ static unsigned long setup_zero_page(voi } #ifndef CONFIG_NEED_MULTIPLE_NODES -static int __init page_is_ram(unsigned long pagenr) +int page_is_ram(unsigned long pagenr) { if (pagenr >= min_low_pfn && pagenr < max_low_pfn) return 1;arch/mips/mm/init.c 2010-01-22 11:20:35.000000000 +0800 renamed from arch/mips/mm/init.c 2010-01-22 11:20:34.000000000 +0800 +1
-2@@ -298,7 +298,7 @@ void __init fixrange_init(unsigned long } #ifndef CONFIG_NEED_MULTIPLE_NODES -static int __init page_is_ram(unsigned long pagenr) +int page_is_ram(unsigned long pagenr) { int i; --To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 1/3] resources: introduce generic page_is_ram()
Quoted 27 lines · Xiaotian Feng
Quoted 26 lines · Wu Fengguang
It's based on
walk_system_ram_range(), for archs that don't have their ownpage_is_ram().The static verions in MIPS and SCORE are also made global.
CC Chen Liqin <[email protected]>CC Lennox Wu <[email protected]>CC Ralf Baechle <[email protected]>CC Américo Wang <[email protected]>CC KAMEZAWA Hiroyuki <[email protected]>CC Yinghai Lu <[email protected]>Signed-off-by Wu Fengguang <[email protected]>---
arch/mips/mm/init.c | 2 +-
arch/score/mm/init.c | 2 +-
include/linux/ioport.h | 2 ++
kernel/resource.c | 11 +++++++++++4 files changed, 15 insertions(+), 2 deletions(-)kernel/resource.c 2010-01-22 11:20:35.000000000 +0800 renamed from kernel/resource.c 2010-01-22 11:20:34.000000000 +0800 +0
-0@@ -327,6 +327,17 @@ int walk_system_ram_range(unsigned long #endif
Quoted 13 lines
kernel/resource.c 2010-01-22 11:20:35.000000000 +0800 int walk_system_ram_range(unsigned long · line 340
Quoted 11 lines
kernel/resource.c 2010-01-22 11:20:35.000000000 +0800 renamed from kernel/resource.c 2010-01-22 11:20:34.000000000 +0800 +11
-0+#define PAGE_IS_RAM 24 +static int __is_ram(unsigned long pfn, unsigned long nr_pages, void *arg) +{ + return PAGE_IS_RAM; +} +int __attribute__((weak)) page_is_ram(unsigned long pfn) +{ + return PAGE_IS_RAM == walk_system_ram_range(pfn, 1, NULL, __is_ram); +} +#undef PAGE_IS_RAM +I'm not sure, but any build test for powerpc/mips/score?
Sorry, no build tests yet:
/bin/sh: score-linux-gcc: command not found
I just make the mips/score page_is_ram() non-static and assume that will make it compile.
Quoted 2 lines
walk_system_ram_rangeis defined whenCONFIG_ARCH_HAS_WALK_MEMORYis not set. Is it safe whenCONFIG_ARCH_HAS_WALK_MEMORYis set for some powerpc archs?
Good question. Grep shows that CONFIG_ARCH_HAS_WALK_MEMORY is only defined for powerpc, and it has its own page_is_ram() as well as walk_system_ram_range().
walk_system_ram_range() must be defined somewhere because it is expected to be generic routine: exported and called from both in-kernel and out-of-tree code.
Thanks,
Fengguang
Re: [PATCH 1/3] resources: introduce generic page_is_ram()
Quoted 52 lines · Wu Fengguang
Quoted 27 lines · Xiaotian Feng
Quoted 26 lines · Wu Fengguang
It's based on
walk_system_ram_range(), for archs that don't have their ownpage_is_ram().The static verions in MIPS and SCORE are also made global.
CC Chen Liqin <[email protected]>CC Lennox Wu <[email protected]>CC Ralf Baechle <[email protected]>CC Américo Wang <[email protected]>CC KAMEZAWA Hiroyuki <[email protected]>CC Yinghai Lu <[email protected]>Signed-off-by Wu Fengguang <[email protected]>---
arch/mips/mm/init.c | 2 +-
arch/score/mm/init.c | 2 +-
include/linux/ioport.h | 2 ++
kernel/resource.c | 11 +++++++++++4 files changed, 15 insertions(+), 2 deletions(-)kernel/resource.c 2010-01-22 11:20:35.000000000 +0800 renamed from kernel/resource.c 2010-01-22 11:20:34.000000000 +0800 +0
-0@@ -327,6 +327,17 @@ int walk_system_ram_range(unsigned long #endifQuoted 13 lines
kernel/resource.c 2010-01-22 11:20:35.000000000 +0800 int walk_system_ram_range(unsigned long · line 340
Quoted 11 lines
kernel/resource.c 2010-01-22 11:20:35.000000000 +0800 renamed from kernel/resource.c 2010-01-22 11:20:34.000000000 +0800 +11
-0+#define PAGE_IS_RAM 24 +static int __is_ram(unsigned long pfn, unsigned long nr_pages, void *arg) +{ + return PAGE_IS_RAM; +} +int __attribute__((weak)) page_is_ram(unsigned long pfn) +{ + return PAGE_IS_RAM == walk_system_ram_range(pfn, 1, NULL, __is_ram); +} +#undef PAGE_IS_RAM +I'm not sure, but any build test for powerpc/mips/score?
Sorry, no build tests yet:
/bin/sh: score-linux-gcc: command not found
I just make the mips/score
page_is_ram()non-static and assume that will make it compile.Quoted 2 lines
walk_system_ram_rangeis defined whenCONFIG_ARCH_HAS_WALK_MEMORYis not set. Is it safe whenCONFIG_ARCH_HAS_WALK_MEMORYis set for some powerpc archs?
Quoted 8 lines
Good question. Grep shows that
CONFIG_ARCH_HAS_WALK_MEMORYis only defined for powerpc, and it has its ownpage_is_ram()as well aswalk_system_ram_range().
walk_system_ram_range()must be defined somewhere because it is expected to be generic routine: exported and called from both in-kernel and out-of-tree code.
Yes, powerpc has its own walk_system_ram_range() and page_is_ram() ;-)
Would it be better if moving the weak attribute page_is_ram() into #if !defined(CONFIG_ARCH_HAS_WALK_MEMORY) ?
Quoted 3 lines
Thanks,
Fengguang
Re: [PATCH 1/3] resources: introduce generic page_is_ram()
Quoted 62 lines · Xiaotian Feng
Quoted 52 lines · Wu Fengguang
Quoted 27 lines · Xiaotian Feng
Quoted 26 lines · Wu Fengguang
It's based on
walk_system_ram_range(), for archs that don't have their ownpage_is_ram().The static verions in MIPS and SCORE are also made global.
CC Chen Liqin <[email protected]>CC Lennox Wu <[email protected]>CC Ralf Baechle <[email protected]>CC Américo Wang <[email protected]>CC KAMEZAWA Hiroyuki <[email protected]>CC Yinghai Lu <[email protected]>Signed-off-by Wu Fengguang <[email protected]>---
arch/mips/mm/init.c | 2 +-
arch/score/mm/init.c | 2 +-
include/linux/ioport.h | 2 ++
kernel/resource.c | 11 +++++++++++4 files changed, 15 insertions(+), 2 deletions(-)kernel/resource.c 2010-01-22 11:20:35.000000000 +0800 renamed from kernel/resource.c 2010-01-22 11:20:34.000000000 +0800 +0
-0@@ -327,6 +327,17 @@ int walk_system_ram_range(unsigned long #endifQuoted 13 lines
kernel/resource.c 2010-01-22 11:20:35.000000000 +0800 int walk_system_ram_range(unsigned long · line 340
Quoted 11 lines
kernel/resource.c 2010-01-22 11:20:35.000000000 +0800 renamed from kernel/resource.c 2010-01-22 11:20:34.000000000 +0800 +11
-0+#define PAGE_IS_RAM 24 +static int __is_ram(unsigned long pfn, unsigned long nr_pages, void *arg) +{ + return PAGE_IS_RAM; +} +int __attribute__((weak)) page_is_ram(unsigned long pfn) +{ + return PAGE_IS_RAM == walk_system_ram_range(pfn, 1, NULL, __is_ram); +} +#undef PAGE_IS_RAM +I'm not sure, but any build test for powerpc/mips/score?
Sorry, no build tests yet:
/bin/sh: score-linux-gcc: command not found
I just make the mips/score
page_is_ram()non-static and assume that will make it compile.Quoted 2 lines
walk_system_ram_rangeis defined whenCONFIG_ARCH_HAS_WALK_MEMORYis not set. Is it safe whenCONFIG_ARCH_HAS_WALK_MEMORYis set for some powerpc archs?Quoted 8 lines
Good question. Grep shows that
CONFIG_ARCH_HAS_WALK_MEMORYis only defined for powerpc, and it has its ownpage_is_ram()as well aswalk_system_ram_range().
walk_system_ram_range()must be defined somewhere because it is expected to be generic routine: exported and called from both in-kernel and out-of-tree code.
Quoted 4 lines
Yes, powerpc has its own
walk_system_ram_range()andpage_is_ram();-)Would it be better if moving the weak attribute
page_is_ram()into #if !defined(CONFIG_ARCH_HAS_WALK_MEMORY) ?
Only several archs defined page_is_ram(), so that would not be feasible for doing a _generic_ page_is_ram().
Thanks,
Fengguang
H. Peter Anvin
reviewerRe: [PATCH 1/3] resources: introduce generic page_is_ram()
In reply to Wu FengguangQuoted 7 lines · Wu Fengguang
kernel/resource.c +1
-0@@ -327,6 +327,17 @@ int walk_system_ram_range(unsigned long#endif +#define PAGE_IS_RAM 24
kernel/resource.c int walk_system_ram_range(unsigned long · line 340
Quoted 10 lines
kernel/resource.c +10
-0+static int __is_ram (unsigned long pfn,unsigned long nr_pages,void *arg) +{ +return PAGE_IS_RAM ; +} +int __attribute__((weak))page_is_ram (unsigned long pfn) +{ +return PAGE_IS_RAM ==walk_system_ram_range (pfn,1 ,NULL , __is_ram); +} +#undef PAGE_IS_RAM +
Stylistic nitpick:
The use of the magic number "24" here is pretty ugly; it seems to imply that there is something peculiar with this number and that it is trying to avoid an overlap, whereas in fact any number but 0 and -1 would do.
I would rather see just returning 1 and do:
return walk_system_ram_range(pfn, 1, NULL, __is_ram) == 1;
(walk_system_ram_range() returning -1 on error, and 0 means continue.)
Note also that we don't write "constant == expression"; although some schools teach it as a way to avoid the "=" versus "==" beginner C mistake, it makes the code less intuitive to read.
Other than that, the patchset looks good; if Ingo doesn't beat me to it I'll put it in tomorrow (need sleep right now.)
-hpa
Signature · 2 lines
H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf.
PATCH v4 1/3 resources: introduce generic page_is_ram()
Quoted 21 lines · H. Peter Anvin
Quoted 7 lines · Wu Fengguang
kernel/resource.c +1
-0@@ -327,6 +327,17 @@ int walk_system_ram_range(unsigned long#endif +#define PAGE_IS_RAM 24kernel/resource.c int walk_system_ram_range(unsigned long · line 340
Quoted 10 lines
kernel/resource.c +10
-0+static int __is_ram (unsigned long pfn,unsigned long nr_pages,void *arg) +{ +return PAGE_IS_RAM ; +} +int __attribute__((weak))page_is_ram (unsigned long pfn) +{ +return PAGE_IS_RAM ==walk_system_ram_range (pfn,1 ,NULL , __is_ram); +} +#undef PAGE_IS_RAM +Stylistic nitpick:
Quoted 3 lines
The use of the magic number "24" here is pretty ugly; it seems to imply that there is something peculiar with this number and that it is trying to avoid an overlap, whereas in fact any number but 0 and -1 would do.
Yes, exactly.
Quoted 5 lines
I would rather see just returning 1 and do:
return walk_system_ram_range(pfn, 1, NULL, __is_ram) == 1;(
walk_system_ram_range()returning -1 on error, and 0 means continue.)
Good suggestion.
Quoted 3 lines
Note also that we don't write "constant == expression"; although some schools teach it as a way to avoid the "=" versus "==" beginner C mistake, it makes the code less intuitive to read.
Yeah.
Quoted 2 lines
Other than that, the patchset looks good; if Ingo doesn't beat me to it I'll put it in tomorrow (need sleep right now.)
OK, thanks! Here is the updated patch.
---
resources: introduce generic page_is_ram()
It's based on walk_system_ram_range(), for archs that don't have their own page_is_ram().
The static verions in MIPS and SCORE are also made global.
v4: prefer plain 1 instead of PAGE_IS_RAM (H. Peter Anvin)
v3: add comment (KAMEZAWA Hiroyuki)
"AFAIK, this "System RAM" information has been used for kdump to grab valid memory area and seems good for the kernel itself."
v2: add PAGE_IS_RAM macro (Américo Wang)
--- arch/mips/mm/init.c | 2 +- arch/score/mm/init.c | 2 +- include/linux/ioport.h | 2 ++ kernel/resource.c | 13 +++++++++++++ 4 files changed, 17 insertions(+), 2 deletions(-)
kernel/resource.c +13 -0
@@ -327,6 +327,19 @@ int walk_system_ram_range(unsigned long#endif +static int __is_ram (unsigned long pfn,unsigned long nr_pages,void *arg) +{ +return 1 ; +} +/* +* This generic page_is_ram() returns true if specified address is +* registered as "System RAM" in iomem_resource list. +*/ +int __attribute__((weak))page_is_ram (unsigned long pfn) +{ +return walk_system_ram_range (pfn,1 ,NULL , __is_ram) ==1 ; +} +/* * Find empty slot in the resource tree given range and alignment. */
include/linux/ioport.h +2 -0
@@ -191,5 +191,7 @@ extern int walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages, void *arg, int (*func)(unsigned long, unsigned long, void *)); +extern int page_is_ram (unsigned long pfn); +#endif /* __ASSEMBLY__ */ #endif /* _LINUX_IOPORT_H */
arch/score/mm/init.c +1 -1
@@ -59,7 +59,7 @@ static unsigned long setup_zero_page(voi }#ifndef CONFIG_NEED_MULTIPLE_NODES -static int __init page_is_ram (unsigned long pagenr) +int page_is_ram (unsigned long pagenr) {if (pagenr >= min_low_pfn && pagenr < max_low_pfn)return 1 ;
arch/mips/mm/init.c +1 -1
@@ -298,7 +298,7 @@ void __init fixrange_init(unsigned long }#ifndef CONFIG_NEED_MULTIPLE_NODES -static int __init page_is_ram (unsigned long pagenr) +int page_is_ram (unsigned long pagenr) {int i;
Andrew Morton
maintainerRe: [PATCH 1/3 v4] resources: introduce generic page_is_ram()
Quoted 35 lines · On Fri, 22 Jan 2010 16:16:19 +0800 Wu Fengguang <[email protected]> wrote:
It's based on
walk_system_ram_range(), for archs that don't have their ownpage_is_ram().The static verions in MIPS and SCORE are also made global.
v4: prefer plain 1 instead of
PAGE_IS_RAM(H. Peter Anvin)
v3: add comment (KAMEZAWA Hiroyuki)
"AFAIK, this "System RAM" information has been used for kdump to grab valid memory area and seems good for the kernel itself."
v2: addPAGE_IS_RAMmacro (Am__ricoWang)CC Chen Liqin <[email protected]>CC Lennox Wu <[email protected]>CC Ralf Baechle <[email protected]>CC Am__rico Wang <[email protected]>CC Yinghai Lu <[email protected]>Reviewed-by KAMEZAWA Hiroyuki <[email protected]>Signed-off-by Wu Fengguang <[email protected]>--- arch/mips/mm/init.c | 2 +- arch/score/mm/init.c | 2 +- include/linux/ioport.h | 2 ++ kernel/resource.c | 13 +++++++++++++ 4 files changed, 17 insertions(+), 2 deletions(-)kernel/resource.c +2
-0@@ -327,6 +327,19 @@ int walk_system_ram_range(unsigned long#endif +static int __is_ram (unsigned long pfn,unsigned long nr_pages,void *arg) +{
kernel/resource.c int walk_system_ram_range(unsigned long · line 341
Quoted 10 lines
kernel/resource.c +10
-0+return 1 ; +} +/* +* This generic page_is_ram() returns true if specified address is +* registered as "System RAM" in iomem_resource list. +*/ +int __attribute__((weak))page_is_ram (unsigned long pfn) +{ +return walk_system_ram_range (pfn,1 ,NULL , __is_ram) ==1 ; +}
I'll switch this to use __weak.
include/linux/ioport.h extern int · line 194
Quoted 10 lines
kernel/resource.c +0
-0/* * Find empty slot in the resource tree given range and alignment. */ include/linux/ioport.h +1
-0@@ -191,5 +191,7 @@ extern int walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages, void *arg, int (*func)(unsigned long, unsigned long, void *)); +extern int page_is_ram (unsigned long pfn);
Is it appropriate that this function be declared in ioport.h? It's a pretty general function. Dunno.
Quoted 16 lines
include/linux/ioport.h +0
-0#endif /* __ASSEMBLY__ */ #endif /* _LINUX_IOPORT_H */ arch/score/mm/init.c +1
-1@@ -59,7 +59,7 @@ static unsigned long setup_zero_page(voi }#ifndef CONFIG_NEED_MULTIPLE_NODES -static int __init page_is_ram (unsigned long pagenr) +int page_is_ram (unsigned long pagenr) {if (pagenr >= min_low_pfn && pagenr < max_low_pfn)return 1 ;
arch/mips/mm/init.c void __init fixrange_init(unsigned long · line 303
Quoted 7 lines
arch/mips/mm/init.c +1
-1@@ -298,7 +298,7 @@ void __init fixrange_init(unsigned long }#ifndef CONFIG_NEED_MULTIPLE_NODES -static int __init page_is_ram (unsigned long pagenr) +int page_is_ram (unsigned long pagenr) {int i;
hm, so we lose the __init.
Re: [PATCH 1/3 v4] resources: introduce generic page_is_ram()
Quoted 6 lines · Andrew Morton
Review
Quoted 4 lines
(quoted diff) +4
-0+int __attribute__((weak)) page_is_ram(unsigned long pfn) +{ + return walk_system_ram_range(pfn, 1, NULL, __is_ram) == 1; +}I'll switch this to use
__weak.
Thanks.
Quoted 9 lines
Quoted 9 lines
/*
* Find empty slot in the resource tree given range and alignment. */include/linux/ioport.h +0
-0@@ -191,5 +191,7 @@ extern int walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages, void *arg, int (*func)(unsigned long, unsigned long, void *));
Quoted 4 lines
include/linux/ioport.h extern int · line 194
Quoted 1 line
include/linux/ioport.h +1
-0+extern int page_is_ram (unsigned long pfn);Is it appropriate that this function be declared in
ioport.h? It's a pretty general function. Dunno.
Good suggestion. The following patch moves it to mm.h.
Quoted 18 lines
Quoted 18 lines
include/linux/ioport.h +0
-0#endif /* __ASSEMBLY__ */ #endif /* _LINUX_IOPORT_H */ arch/score/mm/init.c +1
-1@@ -59,7 +59,7 @@ static unsigned long setup_zero_page(voi }#ifndef CONFIG_NEED_MULTIPLE_NODES -static int __init page_is_ram (unsigned long pagenr) +int page_is_ram (unsigned long pagenr) {if (pagenr >= min_low_pfn && pagenr < max_low_pfn)return 1 ;arch/mips/mm/init.c +0
-0@@ -298,7 +298,7 @@ void __init fixrange_init(unsigned long }
Quoted 7 lines
arch/mips/mm/init.c void __init fixrange_init(unsigned long · line 303
Quoted 5 lines
arch/mips/mm/init.c +1
-1#ifndef CONFIG_NEED_MULTIPLE_NODES -static int __init page_is_ram (unsigned long pagenr) +int page_is_ram (unsigned long pagenr) {int i;hm, so we lose the
__init.
Maybe Ralf Baechle knows whether MIPS can switch to the (smaller) generic page_is_ram().
Thanks,
Fengguang
---
move page_is_ram() declaration to mm.h
--- include/linux/ioport.h | 2 -- include/linux/mm.h | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-)
include/linux/ioport.h +0 -2
@@ -191,7 +191,5 @@ extern int walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages, void *arg, int (*func)(unsigned long, unsigned long, void *)); -extern int page_is_ram (unsigned long pfn); -#endif /* __ASSEMBLY__ */ #endif /* _LINUX_IOPORT_H */
include/linux/mm.h +2 -0
@@ -265,6 +265,8 @@ static inline int get_page_unless_zero(sreturn atomic_inc_not_zero (&page->_count); } +extern int page_is_ram (unsigned long pfn); +/* Support for virtually mapped pages */ struct page *vmalloc_to_page (const void *addr);unsigned long vmalloc_to_pfn (const void *addr);
[tip:x86/mm] Move page_is_ram() declaration to mm.h
Commit-ID: 53df8fdc15fb646b0219e43c989c2cdab1ab100c Gitweb: http://git.kernel.org/tip/53df8fdc15fb646b0219e43c989c2cdab1ab100c Author: Wu Fengguang <[email protected]> AuthorDate: Wed, 27 Jan 2010 11:06:39 +0800 Committer: H. Peter Anvin <[email protected]> CommitDate: Mon, 1 Feb 2010 16:58:17 -0800
Move page_is_ram() declaration to mm.h
Move page_is_ram() declaration to mm.h, it makes no sense in <linux/ioport.h>.
LKML-Reference: <20100127030639.GD8132@localhost>
--- include/linux/ioport.h | 2 -- include/linux/mm.h | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-)
include/linux/ioport.h +0 -2
@@ -188,7 +188,5 @@ extern int walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages, void *arg, int (*func)(unsigned long, unsigned long, void *)); -extern int page_is_ram (unsigned long pfn); -#endif /* __ASSEMBLY__ */ #endif /* _LINUX_IOPORT_H */
include/linux/mm.h +2 -0
@@ -265,6 +265,8 @@ static inline int get_page_unless_zero(struct page *page)return atomic_inc_not_zero (&page->_count); } +extern int page_is_ram (unsigned long pfn); +/* Support for virtually mapped pages */ struct page *vmalloc_to_page (const void *addr);unsigned long vmalloc_to_pfn (const void *addr);
PATCH 2/3 x86: remove bios data range from e820
In reply to Wu FengguangFrom: Yinghai Lu <[email protected]>
To prepare move page_is_ram() as generic one.
--- arch/x86/kernel/e820.c | 8 ++++++++ arch/x86/kernel/setup.c | 19 ++++++++++++++++++- arch/x86/mm/ioremap.c | 16 ---------------- 3 files changed, 26 insertions(+), 17 deletions(-)
arch/x86/kernel/setup.c +18 -1
@@ -659,6 +659,23 @@ static struct dmi_system_id __initdata b {} }; +static void __init trim_bios_range (void ) +{ +/* +* A special case is the first 4Kb of memory; +* This is a BIOS owned area, not kernel ram, but generally +* not listed as such in the E820 table. +*/ +e820_update_range (0 ,PAGE_SIZE ,E820_RAM ,E820_RESERVED ); +/* +* special case: Some BIOSen report the PC BIOS +* area (640->1Mb) as ram even though it is not. +* take them out. +*/ +e820_remove_range (BIOS_BEGIN ,BIOS_END -BIOS_BEGIN ,E820_RAM ,1 ); +sanitize_e820_map (e820.map,ARRAY_SIZE (e820.map), &e820.nr_map); +} +/* * Determine if we were loaded by an EFI loader. If so, then we have also been * passed the efi memmap, systab, etc., so we should use these data structures
@@ -822,7 +839,7 @@ void __init setup_arch(char **cmdline_p)insert_resource (&iomem_resource, &data_resource);insert_resource (&iomem_resource, &bss_resource); - +trim_bios_range ();#ifdef CONFIG_X86_32 if (ppro_with_ram_bug ()) { e820_update_range(0x70000000ULL, 0x40000ULL, E820_RAM,
arch/x86/kernel/e820.c +8 -0
@@ -517,11 +517,19 @@ u64 __init e820_remove_range(u64 start, int checktype) {int i; +u64 end;u64 real_removed_size =0 ;if (size > (ULLONG_MAX - start)) size =ULLONG_MAX - start; + end = start + size; +printk (KERN_DEBUG "e820 remove range: %016Lx - %016Lx " , + (unsigned long long ) start, + (unsigned long long ) end); +e820_print_type (old_type); +printk (KERN_CONT "\n" ); +for (i =0 ; i < e820.nr_map; i++) {struct e820entry *ei = &e820.map[i];u64 final_start, final_end;
arch/x86/mm/ioremap.c +0 -16
@@ -29,22 +29,6 @@ int page_is_ram(unsigned long pagenr)resource_size_t addr, end;int i; -/* -* A special case is the first 4Kb of memory; -* This is a BIOS owned area, not kernel ram, but generally -* not listed as such in the E820 table. -*/ -if (pagenr ==0 ) -return 0 ; - -/* -* Second special case: Some BIOSen report the PC BIOS -* area (640->1Mb) as ram even though it is not. -*/ -if (pagenr >= (BIOS_BEGIN >>PAGE_SHIFT ) && - pagenr < (BIOS_END >>PAGE_SHIFT )) -return 0 ; -for (i =0 ; i < e820.nr_map; i++) {/* * Not usable memory:
Re: [PATCH 2/3] x86: remove bios data range from e820
Quoted 3 lines · Fengguang
From: Yinghai Lu <[email protected]>
To prepare move
page_is_ram()as generic one.
Yinghai,
The following two chunks cannot apply because the lines they remove don't exist in linux-next. Because this patchset is targeted for 2.6.34, I just remove the chunks.
===================================================================
arch/x86/kernel/head32.c +0 -2
@@ -29,8 +29,6 @@ static void __init i386_default_early_sevoid __init i386_start_kernel (void ) { -reserve_early_overlap_ok (0 ,PAGE_SIZE ,"BIOS data page" ); -#ifdef CONFIG_X86_TRAMPOLINE /* * But first pinch a few for the stack/trampoline stuff
arch/x86/kernel/head64.c +0 -2
@@ -98,8 +98,6 @@ void __init x86_64_start_reservations(ch {copy_bootdata (__va (real_mode_data)); -reserve_early_overlap_ok (0 ,PAGE_SIZE ,"BIOS data page" ); -reserve_early (__pa_symbol (&_text),__pa_symbol (&__bss_stop),"TEXT DATA BSS" );#ifdef CONFIG_BLK_DEV_INITRD
Thanks,
Fengguang
Andrew Morton
maintainerRe: [PATCH 2/3] x86: remove bios data range from e820
In reply to Wu FengguangQuoted 6 lines · On Fri, 22 Jan 2010 11:21:04 +0800 Wu Fengguang <[email protected]> wrote:
From: Yinghai Lu <[email protected]>
To prepare move
page_is_ram()as generic one.Tested-by Wu Fengguang <[email protected]>Signed-off-by Yinghai Lu <[email protected]>
This should have included Signed-off-by:you, as you were on the patch delivery path. I shall add that.
[tip:x86/mm] x86: Remove BIOS data range from e820
In reply to Wu FengguangCommit-ID: 1b5576e69a5fe168c08a159685ac366316ac9bbc Gitweb: http://git.kernel.org/tip/1b5576e69a5fe168c08a159685ac366316ac9bbc Author: Yinghai Lu <[email protected]> AuthorDate: Fri, 22 Jan 2010 11:21:04 +0800 Committer: H. Peter Anvin <[email protected]> CommitDate: Mon, 1 Feb 2010 16:58:17 -0800
x86: Remove BIOS data range from e820
In preparation for moving to the generic page_is_ram(), make explicit what we expect to be reserved and not reserved.
LKML-Reference: <[email protected]>
--- arch/x86/kernel/e820.c | 8 ++++++++ arch/x86/kernel/setup.c | 19 ++++++++++++++++++- arch/x86/mm/ioremap.c | 16 ---------------- 3 files changed, 26 insertions(+), 17 deletions(-)
arch/x86/kernel/e820.c +8 -0
@@ -517,11 +517,19 @@ u64 __init e820_remove_range(u64 start, u64 size, unsigned old_type, int checktype) {int i; +u64 end;u64 real_removed_size =0 ;if (size > (ULLONG_MAX - start)) size =ULLONG_MAX - start; + end = start + size; +printk (KERN_DEBUG "e820 remove range: %016Lx - %016Lx " , + (unsigned long long ) start, + (unsigned long long ) end); +e820_print_type (old_type); +printk (KERN_CONT "\n" ); +for (i =0 ; i < e820.nr_map; i++) {struct e820entry *ei = &e820.map[i];u64 final_start, final_end;
arch/x86/kernel/setup.c +18 -1
@@ -650,6 +650,23 @@ static struct dmi_system_id __initdata bad_bios_dmi_table[] = { {} }; +static void __init trim_bios_range (void ) +{ +/* +* A special case is the first 4Kb of memory; +* This is a BIOS owned area, not kernel ram, but generally +* not listed as such in the E820 table. +*/ +e820_update_range (0 ,PAGE_SIZE ,E820_RAM ,E820_RESERVED ); +/* +* special case: Some BIOSen report the PC BIOS +* area (640->1Mb) as ram even though it is not. +* take them out. +*/ +e820_remove_range (BIOS_BEGIN ,BIOS_END -BIOS_BEGIN ,E820_RAM ,1 ); +sanitize_e820_map (e820.map,ARRAY_SIZE (e820.map), &e820.nr_map); +} +/* * Determine if we were loaded by an EFI loader. If so, then we have also been * passed the efi memmap, systab, etc., so we should use these data structures
@@ -813,7 +830,7 @@ void __init setup_arch(char **cmdline_p)insert_resource (&iomem_resource, &data_resource);insert_resource (&iomem_resource, &bss_resource); - +trim_bios_range ();#ifdef CONFIG_X86_32 if (ppro_with_ram_bug ()) { e820_update_range(0x70000000ULL, 0x40000ULL, E820_RAM,
arch/x86/mm/ioremap.c +0 -16
@@ -29,22 +29,6 @@ int page_is_ram(unsigned long pagenr)resource_size_t addr, end;int i; -/* -* A special case is the first 4Kb of memory; -* This is a BIOS owned area, not kernel ram, but generally -* not listed as such in the E820 table. -*/ -if (pagenr ==0 ) -return 0 ; - -/* -* Second special case: Some BIOSen report the PC BIOS -* area (640->1Mb) as ram even though it is not. -*/ -if (pagenr >= (BIOS_BEGIN >>PAGE_SHIFT ) && - pagenr < (BIOS_END >>PAGE_SHIFT )) -return 0 ; -for (i =0 ; i < e820.nr_map; i++) {/* * Not usable memory:
PATCH 3/3 x86: use the generic page_is_ram()
In reply to Wu FengguangThe generic resource based page_is_ram() works better with memory hotplug/hotremove. So switch the x86 e820map based code to it.
--- arch/x86/include/asm/page_types.h | 1 - arch/x86/mm/ioremap.c | 21 --------------------- 2 files changed, 22 deletions(-)
arch/x86/include/asm/page_types.h +0 -1
@@ -40,7 +40,6 @@#ifndef __ASSEMBLY__ -extern int page_is_ram (unsigned long pagenr);extern int devmem_is_allowed (unsigned long pagenr);extern unsigned long max_low_pfn_mapped;
arch/x86/mm/ioremap.c +0 -21
@@ -24,27 +24,6 @@#include "physaddr.h" -int page_is_ram (unsigned long pagenr) -{ -resource_size_t addr, end; -int i; - -for (i =0 ; i < e820.nr_map; i++) { -/* -* Not usable memory: -*/ -if (e820.map[i].type !=E820_RAM ) -continue ; - addr = (e820.map[i].addr +PAGE_SIZE -1 ) >>PAGE_SHIFT ; - end = (e820.map[i].addr + e820.map[i].size) >>PAGE_SHIFT ; - - -if ((pagenr >= addr) && (pagenr < end)) -return 1 ; - } -return 0 ; -} -/* * Fix up the linear direct mapping of the kernel to avoid cache attribute * conflicts.
[tip:x86/mm] x86: Use the generic page_is_ram()
Commit-ID: 13ca0fcaa33f6b1984c4111b6ec5df42689fea6f Gitweb: http://git.kernel.org/tip/13ca0fcaa33f6b1984c4111b6ec5df42689fea6f Author: Wu Fengguang <[email protected]> AuthorDate: Fri, 22 Jan 2010 11:21:05 +0800 Committer: H. Peter Anvin <[email protected]> CommitDate: Mon, 1 Feb 2010 16:58:17 -0800
x86: Use the generic page_is_ram()
The generic resource based page_is_ram() works better with memory hotplug/hotremove. So switch the x86 e820map based code to it.
LKML-Reference: <[email protected]>
--- arch/x86/include/asm/page_types.h | 1 - arch/x86/mm/ioremap.c | 21 --------------------- 2 files changed, 0 insertions(+), 22 deletions(-)
arch/x86/include/asm/page_types.h +0 -1
@@ -40,7 +40,6 @@#ifndef __ASSEMBLY__ -extern int page_is_ram (unsigned long pagenr);extern int devmem_is_allowed (unsigned long pagenr);extern unsigned long max_low_pfn_mapped;
arch/x86/mm/ioremap.c +0 -21
@@ -24,27 +24,6 @@#include "physaddr.h" -int page_is_ram (unsigned long pagenr) -{ -resource_size_t addr, end; -int i; - -for (i =0 ; i < e820.nr_map; i++) { -/* -* Not usable memory: -*/ -if (e820.map[i].type !=E820_RAM ) -continue ; - addr = (e820.map[i].addr +PAGE_SIZE -1 ) >>PAGE_SHIFT ; - end = (e820.map[i].addr + e820.map[i].size) >>PAGE_SHIFT ; - - -if ((pagenr >= addr) && (pagenr < end)) -return 1 ; - } -return 0 ; -} -/* * Fix up the linear direct mapping of the kernel to avoid cache attribute * conflicts.