Skip to content

Commit

Permalink
walk system ram range
Browse files Browse the repository at this point in the history
Originally, walk_memory_resource() was introduced to traverse all memory
of "System RAM" for detecting memory hotplug/unplug range.  For doing so,
flags of IORESOUCE_MEM|IORESOURCE_BUSY was used and this was enough for
memory hotplug.

But for using other purpose, /proc/kcore, this may includes some firmware
area marked as IORESOURCE_BUSY | IORESOUCE_MEM.  This patch makes the
check strict to find out busy "System RAM".

Note: PPC64 keeps their own walk_memory_resouce(), which walk through
ppc64's lmb informaton.  Because old kclist_add() is called per lmb, this
patch makes no difference in behavior, finally.

And this patch removes CONFIG_MEMORY_HOTPLUG check from this function.
Because pfn_valid() just show "there is memmap or not* and cannot be used
for "there is physical memory or not", this function is useful in generic
to scan physical memory range.

Signed-off-by: KAMEZAWA Hiroyuki <[email protected]>
Cc: Ralf Baechle <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Cc: WANG Cong <[email protected]>
Cc: Américo Wang <[email protected]>
Cc: David Rientjes <[email protected]>
Cc: Roland Dreier <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
hkamezawa authored and torvalds committed Sep 23, 2009
1 parent 9492587 commit 908eedc
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 23 deletions.
6 changes: 3 additions & 3 deletions arch/powerpc/mm/mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ int arch_add_memory(int nid, u64 start, u64 size)
* memory regions, find holes and callback for contiguous regions.
*/
int
walk_memory_resource(unsigned long start_pfn, unsigned long nr_pages, void *arg,
int (*func)(unsigned long, unsigned long, void *))
walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages,
void *arg, int (*func)(unsigned long, unsigned long, void *))
{
struct lmb_property res;
unsigned long pfn, len;
Expand All @@ -166,7 +166,7 @@ walk_memory_resource(unsigned long start_pfn, unsigned long nr_pages, void *arg,
}
return ret;
}
EXPORT_SYMBOL_GPL(walk_memory_resource);
EXPORT_SYMBOL_GPL(walk_system_ram_range);

/*
* Initialize the bootmem system and give it all the memory we
Expand Down
2 changes: 1 addition & 1 deletion drivers/infiniband/hw/ehca/ehca_mrmw.c
Original file line number Diff line number Diff line change
Expand Up @@ -2463,7 +2463,7 @@ int ehca_create_busmap(void)
int ret;

ehca_mr_len = 0;
ret = walk_memory_resource(0, 1ULL << MAX_PHYSMEM_BITS, NULL,
ret = walk_system_ram_range(0, 1ULL << MAX_PHYSMEM_BITS, NULL,
ehca_create_busmap_callback);
return ret;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ehea/ehea_qmr.c
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,7 @@ int ehea_create_busmap(void)

mutex_lock(&ehea_busmap_mutex);
ehea_mr_len = 0;
ret = walk_memory_resource(0, 1ULL << MAX_PHYSMEM_BITS, NULL,
ret = walk_system_ram_range(0, 1ULL << MAX_PHYSMEM_BITS, NULL,
ehea_create_busmap_callback);
mutex_unlock(&ehea_busmap_mutex);
return ret;
Expand Down
4 changes: 4 additions & 0 deletions include/linux/ioport.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,5 +184,9 @@ extern void __devm_release_region(struct device *dev, struct resource *parent,
extern int iomem_map_sanity_check(resource_size_t addr, unsigned long size);
extern int iomem_is_exclusive(u64 addr);

extern int
walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages,
void *arg, int (*func)(unsigned long, unsigned long, void *));

#endif /* __ASSEMBLY__ */
#endif /* _LINUX_IOPORT_H */
8 changes: 0 additions & 8 deletions include/linux/memory_hotplug.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,14 +191,6 @@ static inline void register_page_bootmem_info_node(struct pglist_data *pgdat)

#endif /* ! CONFIG_MEMORY_HOTPLUG */

/*
* Walk through all memory which is registered as resource.
* arg is (start_pfn, nr_pages, private_arg_pointer)
*/
extern int walk_memory_resource(unsigned long start_pfn,
unsigned long nr_pages, void *arg,
int (*func)(unsigned long, unsigned long, void *));

#ifdef CONFIG_MEMORY_HOTREMOVE

extern int is_mem_section_removable(unsigned long pfn, unsigned long nr_pages);
Expand Down
23 changes: 16 additions & 7 deletions kernel/resource.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,13 +223,13 @@ int release_resource(struct resource *old)

EXPORT_SYMBOL(release_resource);

#if defined(CONFIG_MEMORY_HOTPLUG) && !defined(CONFIG_ARCH_HAS_WALK_MEMORY)
#if !defined(CONFIG_ARCH_HAS_WALK_MEMORY)
/*
* Finds the lowest memory reosurce exists within [res->start.res->end)
* the caller must specify res->start, res->end, res->flags.
* the caller must specify res->start, res->end, res->flags and "name".
* If found, returns 0, res is overwritten, if not found, returns -1.
*/
static int find_next_system_ram(struct resource *res)
static int find_next_system_ram(struct resource *res, char *name)
{
resource_size_t start, end;
struct resource *p;
Expand All @@ -245,6 +245,8 @@ static int find_next_system_ram(struct resource *res)
/* system ram is just marked as IORESOURCE_MEM */
if (p->flags != res->flags)
continue;
if (name && strcmp(p->name, name))
continue;
if (p->start > end) {
p = NULL;
break;
Expand All @@ -262,19 +264,26 @@ static int find_next_system_ram(struct resource *res)
res->end = p->end;
return 0;
}
int
walk_memory_resource(unsigned long start_pfn, unsigned long nr_pages, void *arg,
int (*func)(unsigned long, unsigned long, void *))

/*
* This function calls callback against all memory range of "System RAM"
* which are marked as IORESOURCE_MEM and IORESOUCE_BUSY.
* Now, this function is only for "System RAM".
*/
int walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages,
void *arg, int (*func)(unsigned long, unsigned long, void *))
{
struct resource res;
unsigned long pfn, len;
u64 orig_end;
int ret = -1;

res.start = (u64) start_pfn << PAGE_SHIFT;
res.end = ((u64)(start_pfn + nr_pages) << PAGE_SHIFT) - 1;
res.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
orig_end = res.end;
while ((res.start < res.end) && (find_next_system_ram(&res) >= 0)) {
while ((res.start < res.end) &&
(find_next_system_ram(&res, "System RAM") >= 0)) {
pfn = (unsigned long)(res.start >> PAGE_SHIFT);
len = (unsigned long)((res.end + 1 - res.start) >> PAGE_SHIFT);
ret = (*func)(pfn, len, arg);
Expand Down
6 changes: 3 additions & 3 deletions mm/memory_hotplug.c
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ int online_pages(unsigned long pfn, unsigned long nr_pages)
if (!populated_zone(zone))
need_zonelists_rebuild = 1;

ret = walk_memory_resource(pfn, nr_pages, &onlined_pages,
ret = walk_system_ram_range(pfn, nr_pages, &onlined_pages,
online_pages_range);
if (ret) {
printk(KERN_DEBUG "online_pages %lx at %lx failed\n",
Expand Down Expand Up @@ -705,7 +705,7 @@ offline_isolated_pages_cb(unsigned long start, unsigned long nr_pages,
static void
offline_isolated_pages(unsigned long start_pfn, unsigned long end_pfn)
{
walk_memory_resource(start_pfn, end_pfn - start_pfn, NULL,
walk_system_ram_range(start_pfn, end_pfn - start_pfn, NULL,
offline_isolated_pages_cb);
}

Expand All @@ -731,7 +731,7 @@ check_pages_isolated(unsigned long start_pfn, unsigned long end_pfn)
long offlined = 0;
int ret;

ret = walk_memory_resource(start_pfn, end_pfn - start_pfn, &offlined,
ret = walk_system_ram_range(start_pfn, end_pfn - start_pfn, &offlined,
check_pages_isolated_cb);
if (ret < 0)
offlined = (long)ret;
Expand Down

0 comments on commit 908eedc

Please sign in to comment.