2012-08-24 14:34:13

by Wanpeng Li

[permalink] [raw]
Subject: [PATCH 1/5] mm/memblock: truncate memblock if necessary

From: Gavin Shan <[email protected]>

While enforcing memory limit on current memblock layout, it is
possible that we don't have to change the current memblock layout.
For example, the enforced limited size is bigger than the maximal
address of memory regions. Also, we don't have to change the memory
layout while the enforced limited size is more than the accumulative
size of all memory regions.

The patch checks them and won't change current memblock layout for
those cases, thus to reduce some overhead.

Signed-off-by: Gavin Shan <[email protected]>
Signed-off-by: Wanpeng Li <[email protected]>
---
mm/memblock.c | 12 ++++++++----
1 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/mm/memblock.c b/mm/memblock.c
index 4d9393c..c1fbb12 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -844,14 +844,14 @@ void __init memblock_enforce_memory_limit(phys_addr_t limit)
unsigned long i;
phys_addr_t max_addr = (phys_addr_t)ULLONG_MAX;

- if (!limit)
+ if (!limit || limit >= memblock_end_of_DRAM())
return;

/* find out max address */
for (i = 0; i < memblock.memory.cnt; i++) {
struct memblock_region *r = &memblock.memory.regions[i];

- if (limit <= r->size) {
+ if (limit < r->size) {
max_addr = r->base + limit;
break;
}
@@ -859,8 +859,12 @@ void __init memblock_enforce_memory_limit(phys_addr_t limit)
}

/* truncate both memory and reserved regions */
- __memblock_remove(&memblock.memory, max_addr, (phys_addr_t)ULLONG_MAX);
- __memblock_remove(&memblock.reserved, max_addr, (phys_addr_t)ULLONG_MAX);
+ if (max_addr < (phys_addr_t)ULLONG_MAX) {
+ __memblock_remove(&memblock.memory, max_addr,
+ (phys_addr_t)ULLONG_MAX);
+ __memblock_remove(&memblock.reserved, max_addr,
+ (phys_addr_t)ULLONG_MAX);
+ }
}

static int __init_memblock memblock_search(struct memblock_type *type, phys_addr_t addr)
--
1.7.5.4


2012-08-24 14:34:38

by Wanpeng Li

[permalink] [raw]
Subject: [PATCH 2/5] mm/memblock: rename get_allocated_memblock_reserved_regions_info()

From: Wanpeng Li <[email protected]>

Rename get_allocated_memblock_reserved_regions_info() to
memblock_reserved_regions_info() so that the function name
looks more short and has prefix "memblock".

Signed-off-by: Wanpeng Li <[email protected]>
---
include/linux/memblock.h | 2 +-
mm/memblock.c | 2 +-
mm/nobootmem.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index 569d67d..ab7b887 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -50,7 +50,7 @@ phys_addr_t memblock_find_in_range_node(phys_addr_t start, phys_addr_t end,
phys_addr_t size, phys_addr_t align, int nid);
phys_addr_t memblock_find_in_range(phys_addr_t start, phys_addr_t end,
phys_addr_t size, phys_addr_t align);
-phys_addr_t get_allocated_memblock_reserved_regions_info(phys_addr_t *addr);
+phys_addr_t memblock_reserved_regions_info(phys_addr_t *addr);
void memblock_allow_resize(void);
int memblock_add_node(phys_addr_t base, phys_addr_t size, int nid);
int memblock_add(phys_addr_t base, phys_addr_t size);
diff --git a/mm/memblock.c b/mm/memblock.c
index c1fbb12..2feff8d 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -160,7 +160,7 @@ static void __init_memblock memblock_remove_region(struct memblock_type *type, u
}
}

-phys_addr_t __init_memblock get_allocated_memblock_reserved_regions_info(
+phys_addr_t __init_memblock memblock_reserved_regions_info(
phys_addr_t *addr)
{
if (memblock.reserved.regions == memblock_reserved_init_regions)
diff --git a/mm/nobootmem.c b/mm/nobootmem.c
index bd82f6b..7e95953 100644
--- a/mm/nobootmem.c
+++ b/mm/nobootmem.c
@@ -130,7 +130,7 @@ unsigned long __init free_low_memory_core_early(int nodeid)
count += __free_memory_core(start, end);

/* free range that is used for reserved array if we allocate it */
- size = get_allocated_memblock_reserved_regions_info(&start);
+ size = memblock_reserved_regions_info(&start);
if (size)
count += __free_memory_core(start, start + size);

--
1.7.5.4

2012-08-24 14:34:56

by Wanpeng Li

[permalink] [raw]
Subject: [PATCH 3/5] mm/memblock: reduce overhead in binary search

From: Wanpeng Li <[email protected]>

When checking the indicated address belongs to the memory
or reserved region, the memory or reserved regions are checked
one by one through binary search, which would be a little
time consuming. If the indicated address isn't in memory
region, then we needn't do the time-sonsuming search. The
patch adds more check on the indicated address for that purpose.

Signed-off-by: Wanpeng Li <[email protected]>
---
mm/memblock.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/mm/memblock.c b/mm/memblock.c
index 2feff8d..880e461 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -871,6 +871,10 @@ static int __init_memblock memblock_search(struct memblock_type *type, phys_addr
{
unsigned int left = 0, right = type->cnt;

+ if (unlikely(addr < memblock_start_of_DRAM() ||
+ addr >= memblock_end_of_DRAM()))
+ return 0;
+
do {
unsigned int mid = (right + left) / 2;

--
1.7.5.4

2012-08-24 14:35:35

by Wanpeng Li

[permalink] [raw]
Subject: [PATCH 4/5] mm/memblock: use existing interface to set nid

From: Wanpeng Li <[email protected]>

Use existing interface (function) to set NUMA node ID (NID) for
the regions, either memory or reserved region.

Signed-off-by: Wanpeng Li <[email protected]>
---
mm/memblock.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/mm/memblock.c b/mm/memblock.c
index 880e461..3620493 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -756,7 +756,7 @@ int __init_memblock memblock_set_node(phys_addr_t base, phys_addr_t size,
return ret;

for (i = start_rgn; i < end_rgn; i++)
- type->regions[i].nid = nid;
+ memblock_set_region_node(&type->regions[i], nid);

memblock_merge_regions(type);
return 0;
--
1.7.5.4

2012-08-24 14:36:01

by Wanpeng Li

[permalink] [raw]
Subject: [PATCH 5/5] mm/memblock: cleanup early_node_map[] related comments

From: Wanpeng Li <[email protected]>

Commit 0ee332c14518699 ("memblock: Kill early_node_map[]") removed
early_node_map[], the patch does cleanup on comments to comply with
that change.

Signed-off-by: Wanpeng Li <[email protected]>
---
include/linux/memblock.h | 3 +--
mm/nobootmem.c | 2 --
mm/page_alloc.c | 2 +-
3 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index d3d53aa..ab7b887 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -70,8 +70,7 @@ void __next_mem_pfn_range(int *idx, int nid, unsigned long *out_start_pfn,
* @p_end: ptr to ulong for end pfn of the range, can be %NULL
* @p_nid: ptr to int for nid of the range, can be %NULL
*
- * Walks over configured memory ranges. Available after early_node_map is
- * populated.
+ * Walks over configured memory ranges.
*/
#define for_each_mem_pfn_range(i, nid, p_start, p_end, p_nid) \
for (i = -1, __next_mem_pfn_range(&i, nid, p_start, p_end, p_nid); \
diff --git a/mm/nobootmem.c b/mm/nobootmem.c
index 8ec48484..7e95953 100644
--- a/mm/nobootmem.c
+++ b/mm/nobootmem.c
@@ -162,8 +162,6 @@ unsigned long __init free_all_bootmem(void)
* We need to use MAX_NUMNODES instead of NODE_DATA(0)->node_id
* because in some case like Node0 doesn't have RAM installed
* low ram will be on Node1
- * Use MAX_NUMNODES will make sure all ranges in early_node_map[]
- * will be used instead of only Node0 related
*/
return free_low_memory_core_early(MAX_NUMNODES);
}
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 009ac28..c1e2949 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -4873,7 +4873,7 @@ void __init free_area_init_nodes(unsigned long *max_zone_pfn)
zone_movable_pfn[i] << PAGE_SHIFT);
}

- /* Print out the early_node_map[] */
+ /* Print out the early node map */
printk("Early memory node ranges\n");
for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, &nid)
printk(" node %3d: [mem %#010lx-%#010lx]\n", nid,
--
1.7.7.6

2012-08-24 15:39:08

by Sam Ravnborg

[permalink] [raw]
Subject: Re: [PATCH 2/5] mm/memblock: rename get_allocated_memblock_reserved_regions_info()

On Fri, Aug 24, 2012 at 10:33:37PM +0800, Wanpeng Li wrote:
> From: Wanpeng Li <[email protected]>
>
> Rename get_allocated_memblock_reserved_regions_info() to
> memblock_reserved_regions_info() so that the function name
> looks more short and has prefix "memblock".
>
> Signed-off-by: Wanpeng Li <[email protected]>
> ---
> include/linux/memblock.h | 2 +-
> mm/memblock.c | 2 +-
> mm/nobootmem.c | 2 +-
> 3 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/include/linux/memblock.h b/include/linux/memblock.h
> index 569d67d..ab7b887 100644
> --- a/include/linux/memblock.h
> +++ b/include/linux/memblock.h
> @@ -50,7 +50,7 @@ phys_addr_t memblock_find_in_range_node(phys_addr_t start, phys_addr_t end,
> phys_addr_t size, phys_addr_t align, int nid);
> phys_addr_t memblock_find_in_range(phys_addr_t start, phys_addr_t end,
> phys_addr_t size, phys_addr_t align);
> -phys_addr_t get_allocated_memblock_reserved_regions_info(phys_addr_t *addr);
> +phys_addr_t memblock_reserved_regions_info(phys_addr_t *addr);
When you anyway change the prototype a description of what this function
is supposed to be used for would be good.
Many memblock function lacks this :-(

Sam