mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-19 18:53:52 +08:00
mm, memory_hotplug: reorganize new pgdat initialization
When a !node_online node is brought up it needs a hotplug specific initialization because the node could be either uninitialized yet or it could have been recycled after previous hotremove. hotadd_init_pgdat is responsible for that. Internal pgdat state is initialized at two places currently - hotadd_init_pgdat - free_area_init_core_hotplug There is no real clear cut what should go where but this patch's chosen to move the whole internal state initialization into free_area_init_core_hotplug. hotadd_init_pgdat is still responsible to pull all the parts together - most notably to initialize zonelists because those depend on the overall topology. This patch doesn't introduce any functional change. Link: https://lkml.kernel.org/r/20220127085305.20890-5-mhocko@kernel.org Signed-off-by: Michal Hocko <mhocko@suse.com> Acked-by: Rafael Aquini <raquini@redhat.com> Acked-by: David Hildenbrand <david@redhat.com> Reviewed-by: Oscar Salvador <osalvador@suse.de> Cc: Alexey Makhalov <amakhalov@vmware.com> Cc: Christoph Lameter <cl@linux.com> Cc: Dennis Zhou <dennis@kernel.org> Cc: Eric Dumazet <eric.dumazet@gmail.com> Cc: Mike Rapoport <rppt@linux.ibm.com> Cc: Nico Pache <npache@redhat.com> Cc: Tejun Heo <tj@kernel.org> Cc: Wei Yang <richard.weiyang@gmail.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
390511e147
commit
70b5b46a75
@ -319,7 +319,7 @@ extern void set_zone_contiguous(struct zone *zone);
|
||||
extern void clear_zone_contiguous(struct zone *zone);
|
||||
|
||||
#ifdef CONFIG_MEMORY_HOTPLUG
|
||||
extern void __ref free_area_init_core_hotplug(int nid);
|
||||
extern void __ref free_area_init_core_hotplug(struct pglist_data *pgdat);
|
||||
extern int __add_memory(int nid, u64 start, u64 size, mhp_t mhp_flags);
|
||||
extern int add_memory(int nid, u64 start, u64 size, mhp_t mhp_flags);
|
||||
extern int add_memory_resource(int nid, struct resource *resource,
|
||||
|
@ -1166,39 +1166,16 @@ static pg_data_t __ref *hotadd_init_pgdat(int nid)
|
||||
{
|
||||
struct pglist_data *pgdat;
|
||||
|
||||
pgdat = NODE_DATA(nid);
|
||||
|
||||
/*
|
||||
* NODE_DATA is preallocated (free_area_init) but its internal
|
||||
* state is not allocated completely. Add missing pieces.
|
||||
* Completely offline nodes stay around and they just need
|
||||
* reintialization.
|
||||
*/
|
||||
if (pgdat->per_cpu_nodestats == &boot_nodestats) {
|
||||
pgdat->per_cpu_nodestats =
|
||||
alloc_percpu(struct per_cpu_nodestat);
|
||||
} else {
|
||||
int cpu;
|
||||
/*
|
||||
* Reset the nr_zones, order and highest_zoneidx before reuse.
|
||||
* Note that kswapd will init kswapd_highest_zoneidx properly
|
||||
* when it starts in the near future.
|
||||
*/
|
||||
pgdat->nr_zones = 0;
|
||||
pgdat->kswapd_order = 0;
|
||||
pgdat->kswapd_highest_zoneidx = 0;
|
||||
for_each_online_cpu(cpu) {
|
||||
struct per_cpu_nodestat *p;
|
||||
|
||||
p = per_cpu_ptr(pgdat->per_cpu_nodestats, cpu);
|
||||
memset(p, 0, sizeof(*p));
|
||||
}
|
||||
}
|
||||
|
||||
pgdat->node_start_pfn = 0;
|
||||
pgdat = NODE_DATA(nid);
|
||||
|
||||
/* init node's zones as empty zones, we don't have any present pages.*/
|
||||
free_area_init_core_hotplug(nid);
|
||||
free_area_init_core_hotplug(pgdat);
|
||||
|
||||
/*
|
||||
* The node we allocated has no zone fallback lists. For avoiding
|
||||
@ -1210,6 +1187,7 @@ static pg_data_t __ref *hotadd_init_pgdat(int nid)
|
||||
* When memory is hot-added, all the memory is in offline state. So
|
||||
* clear all zones' present_pages because they will be updated in
|
||||
* online_pages() and offline_pages().
|
||||
* TODO: should be in free_area_init_core_hotplug?
|
||||
*/
|
||||
reset_node_managed_pages(pgdat);
|
||||
reset_node_present_pages(pgdat);
|
||||
|
@ -7466,12 +7466,33 @@ static void __meminit zone_init_internals(struct zone *zone, enum zone_type idx,
|
||||
* NOTE: this function is only called during memory hotplug
|
||||
*/
|
||||
#ifdef CONFIG_MEMORY_HOTPLUG
|
||||
void __ref free_area_init_core_hotplug(int nid)
|
||||
void __ref free_area_init_core_hotplug(struct pglist_data *pgdat)
|
||||
{
|
||||
int nid = pgdat->node_id;
|
||||
enum zone_type z;
|
||||
pg_data_t *pgdat = NODE_DATA(nid);
|
||||
int cpu;
|
||||
|
||||
pgdat_init_internals(pgdat);
|
||||
|
||||
if (pgdat->per_cpu_nodestats == &boot_nodestats)
|
||||
pgdat->per_cpu_nodestats = alloc_percpu(struct per_cpu_nodestat);
|
||||
|
||||
/*
|
||||
* Reset the nr_zones, order and highest_zoneidx before reuse.
|
||||
* Note that kswapd will init kswapd_highest_zoneidx properly
|
||||
* when it starts in the near future.
|
||||
*/
|
||||
pgdat->nr_zones = 0;
|
||||
pgdat->kswapd_order = 0;
|
||||
pgdat->kswapd_highest_zoneidx = 0;
|
||||
pgdat->node_start_pfn = 0;
|
||||
for_each_online_cpu(cpu) {
|
||||
struct per_cpu_nodestat *p;
|
||||
|
||||
p = per_cpu_ptr(pgdat->per_cpu_nodestats, cpu);
|
||||
memset(p, 0, sizeof(*p));
|
||||
}
|
||||
|
||||
for (z = 0; z < MAX_NR_ZONES; z++)
|
||||
zone_init_internals(&pgdat->node_zones[z], z, nid, 0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user