mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
cpu/mem hotplug: add try_online_node() for cpu_up()
cpu_up() has #ifdef CONFIG_MEMORY_HOTPLUG code blocks, which call mem_online_node() to put its node online if offlined and then call build_all_zonelists() to initialize the zone list. These steps are specific to memory hotplug, and should be managed in mm/memory_hotplug.c. lock_memory_hotplug() should also be held for the whole steps. For this reason, this patch replaces mem_online_node() with try_online_node(), which performs the whole steps with lock_memory_hotplug() held. try_online_node() is named after try_offline_node() as they have similar purpose. There is no functional change in this patch. Signed-off-by: Toshi Kani <toshi.kani@hp.com> Reviewed-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
309d0b3917
commit
01b0f19707
@ -94,6 +94,8 @@ extern void __online_page_set_limits(struct page *page);
|
|||||||
extern void __online_page_increment_counters(struct page *page);
|
extern void __online_page_increment_counters(struct page *page);
|
||||||
extern void __online_page_free(struct page *page);
|
extern void __online_page_free(struct page *page);
|
||||||
|
|
||||||
|
extern int try_online_node(int nid);
|
||||||
|
|
||||||
#ifdef CONFIG_MEMORY_HOTREMOVE
|
#ifdef CONFIG_MEMORY_HOTREMOVE
|
||||||
extern bool is_pageblock_removable_nolock(struct page *page);
|
extern bool is_pageblock_removable_nolock(struct page *page);
|
||||||
extern int arch_remove_memory(u64 start, u64 size);
|
extern int arch_remove_memory(u64 start, u64 size);
|
||||||
@ -225,6 +227,11 @@ static inline void register_page_bootmem_info_node(struct pglist_data *pgdat)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int try_online_node(int nid)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void lock_memory_hotplug(void) {}
|
static inline void lock_memory_hotplug(void) {}
|
||||||
static inline void unlock_memory_hotplug(void) {}
|
static inline void unlock_memory_hotplug(void) {}
|
||||||
|
|
||||||
@ -256,7 +263,6 @@ static inline void remove_memory(int nid, u64 start, u64 size) {}
|
|||||||
|
|
||||||
extern int walk_memory_range(unsigned long start_pfn, unsigned long end_pfn,
|
extern int walk_memory_range(unsigned long start_pfn, unsigned long end_pfn,
|
||||||
void *arg, int (*func)(struct memory_block *, void *));
|
void *arg, int (*func)(struct memory_block *, void *));
|
||||||
extern int mem_online_node(int nid);
|
|
||||||
extern int add_memory(int nid, u64 start, u64 size);
|
extern int add_memory(int nid, u64 start, u64 size);
|
||||||
extern int arch_add_memory(int nid, u64 start, u64 size);
|
extern int arch_add_memory(int nid, u64 start, u64 size);
|
||||||
extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages);
|
extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages);
|
||||||
|
25
kernel/cpu.c
25
kernel/cpu.c
@ -437,11 +437,6 @@ int cpu_up(unsigned int cpu)
|
|||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
#ifdef CONFIG_MEMORY_HOTPLUG
|
|
||||||
int nid;
|
|
||||||
pg_data_t *pgdat;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!cpu_possible(cpu)) {
|
if (!cpu_possible(cpu)) {
|
||||||
printk(KERN_ERR "can't online cpu %d because it is not "
|
printk(KERN_ERR "can't online cpu %d because it is not "
|
||||||
"configured as may-hotadd at boot time\n", cpu);
|
"configured as may-hotadd at boot time\n", cpu);
|
||||||
@ -452,27 +447,9 @@ int cpu_up(unsigned int cpu)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_MEMORY_HOTPLUG
|
err = try_online_node(cpu_to_node(cpu));
|
||||||
nid = cpu_to_node(cpu);
|
|
||||||
if (!node_online(nid)) {
|
|
||||||
err = mem_online_node(nid);
|
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
|
||||||
|
|
||||||
pgdat = NODE_DATA(nid);
|
|
||||||
if (!pgdat) {
|
|
||||||
printk(KERN_ERR
|
|
||||||
"Can't online cpu %d due to NULL pgdat\n", cpu);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pgdat->node_zonelists->_zonerefs->zone == NULL) {
|
|
||||||
mutex_lock(&zonelists_mutex);
|
|
||||||
build_all_zonelists(NULL, NULL);
|
|
||||||
mutex_unlock(&zonelists_mutex);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
cpu_maps_update_begin();
|
cpu_maps_update_begin();
|
||||||
|
|
||||||
|
@ -1043,17 +1043,23 @@ static void rollback_node_hotadd(int nid, pg_data_t *pgdat)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
* try_online_node - online a node if offlined
|
||||||
|
*
|
||||||
* called by cpu_up() to online a node without onlined memory.
|
* called by cpu_up() to online a node without onlined memory.
|
||||||
*/
|
*/
|
||||||
int mem_online_node(int nid)
|
int try_online_node(int nid)
|
||||||
{
|
{
|
||||||
pg_data_t *pgdat;
|
pg_data_t *pgdat;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (node_online(nid))
|
||||||
|
return 0;
|
||||||
|
|
||||||
lock_memory_hotplug();
|
lock_memory_hotplug();
|
||||||
pgdat = hotadd_new_pgdat(nid, 0);
|
pgdat = hotadd_new_pgdat(nid, 0);
|
||||||
if (!pgdat) {
|
if (!pgdat) {
|
||||||
|
pr_err("Cannot online node %d due to NULL pgdat\n", nid);
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -1061,6 +1067,12 @@ int mem_online_node(int nid)
|
|||||||
ret = register_one_node(nid);
|
ret = register_one_node(nid);
|
||||||
BUG_ON(ret);
|
BUG_ON(ret);
|
||||||
|
|
||||||
|
if (pgdat->node_zonelists->_zonerefs->zone == NULL) {
|
||||||
|
mutex_lock(&zonelists_mutex);
|
||||||
|
build_all_zonelists(NULL, NULL);
|
||||||
|
mutex_unlock(&zonelists_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
unlock_memory_hotplug();
|
unlock_memory_hotplug();
|
||||||
return ret;
|
return ret;
|
||||||
|
Loading…
Reference in New Issue
Block a user