diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-07 02:18:07 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-07 02:18:07 +0000 |
commit | 6c080a1a353c6fc2590555ec7dd8982d1143d02d (patch) | |
tree | 5fb60c5cd3d6bb6496650d1605a3c51d09be2bf1 /mm | |
parent | Adding debian version 6.1.85-1. (diff) | |
download | linux-6c080a1a353c6fc2590555ec7dd8982d1143d02d.tar.xz linux-6c080a1a353c6fc2590555ec7dd8982d1143d02d.zip |
Merging upstream version 6.1.90.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | mm/memory-failure.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 5b846ed5d..be58ce999 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -84,11 +84,23 @@ static int __page_handle_poison(struct page *page) { int ret; - zone_pcp_disable(page_zone(page)); + /* + * zone_pcp_disable() can't be used here. It will + * hold pcp_batch_high_lock and dissolve_free_huge_page() might hold + * cpu_hotplug_lock via static_key_slow_dec() when hugetlb vmemmap + * optimization is enabled. This will break current lock dependency + * chain and leads to deadlock. + * Disabling pcp before dissolving the page was a deterministic + * approach because we made sure that those pages cannot end up in any + * PCP list. Draining PCP lists expels those pages to the buddy system, + * but nothing guarantees that those pages do not get back to a PCP + * queue if we need to refill those. + */ ret = dissolve_free_huge_page(page); - if (!ret) + if (!ret) { + drain_all_pages(page_zone(page)); ret = take_page_off_buddy(page); - zone_pcp_enable(page_zone(page)); + } return ret; } |