mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-11-18 15:44:02 +08:00
memory-hotplug: move pgdat_resize_lock into sparse_remove_one_section()
In __remove_section(), we locked pgdat_resize_lock when calling sparse_remove_one_section(). This lock will disable irq. But we don't need to lock the whole function. If we do some work to free pagetables in free_section_usemap(), we need to call flush_tlb_all(), which need irq enabled. Otherwise the WARN_ON_ONCE() in smp_call_function_many() will be triggered. If we lock the whole sparse_remove_one_section(), then we come to this call trace: ------------[ cut here ]------------ WARNING: at kernel/smp.c:461 smp_call_function_many+0xbd/0x260() Hardware name: PRIMEQUEST 1800E ...... Call Trace: smp_call_function_many+0xbd/0x260 smp_call_function+0x3b/0x50 on_each_cpu+0x3b/0xc0 flush_tlb_all+0x1c/0x20 remove_pagetable+0x14e/0x1d0 vmemmap_free+0x18/0x20 sparse_remove_one_section+0xf7/0x100 __remove_section+0xa2/0xb0 __remove_pages+0xa0/0xd0 arch_remove_memory+0x6b/0xc0 remove_memory+0xb8/0xf0 acpi_memory_device_remove+0x53/0x96 acpi_device_remove+0x90/0xb2 __device_release_driver+0x7c/0xf0 device_release_driver+0x2f/0x50 acpi_bus_remove+0x32/0x6d acpi_bus_trim+0x91/0x102 acpi_bus_hot_remove_device+0x88/0x16b acpi_os_execute_deferred+0x27/0x34 process_one_work+0x20e/0x5c0 worker_thread+0x12e/0x370 kthread+0xee/0x100 ret_from_fork+0x7c/0xb0 ---[ end trace 25e85300f542aa01 ]--- Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com> Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com> Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Cc: Jiang Liu <jiang.liu@huawei.com> Cc: Jianguo Wu <wujianguo@huawei.com> Cc: Wu Jianguo <wujianguo@huawei.com> Cc: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: "H. Peter Anvin" <hpa@zytor.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
46723bfa54
commit
cd099682e4
@ -444,8 +444,6 @@ static int __remove_section(struct zone *zone, struct mem_section *ms)
|
||||
#else
|
||||
static int __remove_section(struct zone *zone, struct mem_section *ms)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct pglist_data *pgdat = zone->zone_pgdat;
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (!valid_section(ms))
|
||||
@ -455,9 +453,7 @@ static int __remove_section(struct zone *zone, struct mem_section *ms)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pgdat_resize_lock(pgdat, &flags);
|
||||
sparse_remove_one_section(zone, ms);
|
||||
pgdat_resize_unlock(pgdat, &flags);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -796,8 +796,10 @@ static inline void clear_hwpoisoned_pages(struct page *memmap, int nr_pages)
|
||||
void sparse_remove_one_section(struct zone *zone, struct mem_section *ms)
|
||||
{
|
||||
struct page *memmap = NULL;
|
||||
unsigned long *usemap = NULL;
|
||||
unsigned long *usemap = NULL, flags;
|
||||
struct pglist_data *pgdat = zone->zone_pgdat;
|
||||
|
||||
pgdat_resize_lock(pgdat, &flags);
|
||||
if (ms->section_mem_map) {
|
||||
usemap = ms->pageblock_flags;
|
||||
memmap = sparse_decode_mem_map(ms->section_mem_map,
|
||||
@ -805,6 +807,7 @@ void sparse_remove_one_section(struct zone *zone, struct mem_section *ms)
|
||||
ms->section_mem_map = 0;
|
||||
ms->pageblock_flags = NULL;
|
||||
}
|
||||
pgdat_resize_unlock(pgdat, &flags);
|
||||
|
||||
clear_hwpoisoned_pages(memmap, PAGES_PER_SECTION);
|
||||
free_section_usemap(memmap, usemap);
|
||||
|
Loading…
Reference in New Issue
Block a user