|
@@ -787,6 +787,30 @@ void tlb_remove_table(struct mmu_gather *tlb, void *table)
|
|
tlb_table_flush(tlb);
|
|
tlb_table_flush(tlb);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
|
|
|
+void thp_split_vma(struct vm_area_struct *vma)
|
|
|
|
+{
|
|
|
|
+ unsigned long addr;
|
|
|
|
+ struct page *page;
|
|
|
|
+
|
|
|
|
+ for (addr = vma->vm_start; addr < vma->vm_end; addr += PAGE_SIZE) {
|
|
|
|
+ page = follow_page(vma, addr, FOLL_SPLIT);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void thp_split_mm(struct mm_struct *mm)
|
|
|
|
+{
|
|
|
|
+ struct vm_area_struct *vma = mm->mmap;
|
|
|
|
+
|
|
|
|
+ while (vma != NULL) {
|
|
|
|
+ thp_split_vma(vma);
|
|
|
|
+ vma->vm_flags &= ~VM_HUGEPAGE;
|
|
|
|
+ vma->vm_flags |= VM_NOHUGEPAGE;
|
|
|
|
+ vma = vma->vm_next;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* switch on pgstes for its userspace process (for kvm)
|
|
* switch on pgstes for its userspace process (for kvm)
|
|
*/
|
|
*/
|
|
@@ -824,6 +848,12 @@ int s390_enable_sie(void)
|
|
if (!mm)
|
|
if (!mm)
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
|
|
|
+ /* split thp mappings and disable thp for future mappings */
|
|
|
|
+ thp_split_mm(mm);
|
|
|
|
+ mm->def_flags |= VM_NOHUGEPAGE;
|
|
|
|
+#endif
|
|
|
|
+
|
|
/* Now lets check again if something happened */
|
|
/* Now lets check again if something happened */
|
|
task_lock(tsk);
|
|
task_lock(tsk);
|
|
if (!tsk->mm || atomic_read(&tsk->mm->mm_users) > 1 ||
|
|
if (!tsk->mm || atomic_read(&tsk->mm->mm_users) > 1 ||
|