summaryrefslogtreecommitdiffstats
path: root/mm/khugepaged.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-08 04:15:07 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-08 04:15:07 +0000
commit7fd92ba31ac1c688b59aa93cc03b748f920df8fe (patch)
treebaa580b97c260c790730e2525483eb1953f3c39d /mm/khugepaged.c
parentAdding upstream version 4.19.269. (diff)
downloadlinux-7fd92ba31ac1c688b59aa93cc03b748f920df8fe.tar.xz
linux-7fd92ba31ac1c688b59aa93cc03b748f920df8fe.zip
Adding upstream version 4.19.282.upstream/4.19.282
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--mm/khugepaged.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index 5dd14ef2e..60f7df987 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -23,6 +23,19 @@
#include <asm/pgalloc.h>
#include "internal.h"
+/* gross hack for <=4.19 stable */
+#if defined(CONFIG_S390) || defined(CONFIG_ARM)
+static void tlb_remove_table_smp_sync(void *arg)
+{
+ /* Simply deliver the interrupt */
+}
+
+static void tlb_remove_table_sync_one(void)
+{
+ smp_call_function(tlb_remove_table_smp_sync, NULL, 1);
+}
+#endif
+
enum scan_result {
SCAN_FAIL,
SCAN_SUCCEED,
@@ -1045,6 +1058,7 @@ static void collapse_huge_page(struct mm_struct *mm,
_pmd = pmdp_collapse_flush(vma, address, pmd);
spin_unlock(pmd_ptl);
mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
+ tlb_remove_table_sync_one();
spin_lock(pte_ptl);
isolated = __collapse_huge_page_isolate(vma, address, pte);
@@ -1289,12 +1303,20 @@ static void retract_page_tables(struct address_space *mapping, pgoff_t pgoff)
*/
if (down_write_trylock(&mm->mmap_sem)) {
if (!khugepaged_test_exit(mm)) {
- spinlock_t *ptl = pmd_lock(mm, pmd);
+ spinlock_t *ptl;
+ unsigned long end = addr + HPAGE_PMD_SIZE;
+
+ mmu_notifier_invalidate_range_start(mm, addr,
+ end);
+ ptl = pmd_lock(mm, pmd);
/* assume page table is clear */
_pmd = pmdp_collapse_flush(vma, addr, pmd);
spin_unlock(ptl);
mm_dec_nr_ptes(mm);
+ tlb_remove_table_sync_one();
pte_free(mm, pmd_pgtable(_pmd));
+ mmu_notifier_invalidate_range_end(mm, addr,
+ end);
}
up_write(&mm->mmap_sem);
}