Skip to content

Commit 48a8b97

Browse files
Peter Zijlstratorvalds
authored andcommitted
x86/mm: Only use tlb_remove_table() for paravirt
If we don't use paravirt; don't play unnecessary and complicated games to free page-tables. Suggested-by: Linus Torvalds <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Acked-by: Rik van Riel <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent fd1102f commit 48a8b97

File tree

9 files changed

+26
-6
lines changed

9 files changed

+26
-6
lines changed

arch/x86/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ config X86
180180
select HAVE_HARDLOCKUP_DETECTOR_PERF if PERF_EVENTS && HAVE_PERF_EVENTS_NMI
181181
select HAVE_PERF_REGS
182182
select HAVE_PERF_USER_STACK_DUMP
183-
select HAVE_RCU_TABLE_FREE
183+
select HAVE_RCU_TABLE_FREE if PARAVIRT
184184
select HAVE_RCU_TABLE_INVALIDATE if HAVE_RCU_TABLE_FREE
185185
select HAVE_REGS_AND_STACK_ACCESS_API
186186
select HAVE_RELIABLE_STACKTRACE if X86_64 && (UNWINDER_FRAME_POINTER || UNWINDER_ORC) && STACK_VALIDATION

arch/x86/hyperv/mmu.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <asm/mshyperv.h>
1010
#include <asm/msr.h>
1111
#include <asm/tlbflush.h>
12+
#include <asm/tlb.h>
1213

1314
#define CREATE_TRACE_POINTS
1415
#include <asm/trace/hyperv.h>
@@ -231,4 +232,5 @@ void hyperv_setup_mmu_ops(void)
231232

232233
pr_info("Using hypercall for remote TLB flush\n");
233234
pv_mmu_ops.flush_tlb_others = hyperv_flush_tlb_others;
235+
pv_mmu_ops.tlb_remove_table = tlb_remove_table;
234236
}

arch/x86/include/asm/paravirt.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,11 @@ static inline void flush_tlb_others(const struct cpumask *cpumask,
309309
PVOP_VCALL2(pv_mmu_ops.flush_tlb_others, cpumask, info);
310310
}
311311

312+
static inline void paravirt_tlb_remove_table(struct mmu_gather *tlb, void *table)
313+
{
314+
PVOP_VCALL2(pv_mmu_ops.tlb_remove_table, tlb, table);
315+
}
316+
312317
static inline int paravirt_pgd_alloc(struct mm_struct *mm)
313318
{
314319
return PVOP_CALL1(int, pv_mmu_ops.pgd_alloc, mm);

arch/x86/include/asm/paravirt_types.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ struct desc_struct;
5454
struct task_struct;
5555
struct cpumask;
5656
struct flush_tlb_info;
57+
struct mmu_gather;
5758

5859
/*
5960
* Wrapper type for pointers to code which uses the non-standard
@@ -222,6 +223,8 @@ struct pv_mmu_ops {
222223
void (*flush_tlb_others)(const struct cpumask *cpus,
223224
const struct flush_tlb_info *info);
224225

226+
void (*tlb_remove_table)(struct mmu_gather *tlb, void *table);
227+
225228
/* Hooks for allocating and freeing a pagetable top-level */
226229
int (*pgd_alloc)(struct mm_struct *mm);
227230
void (*pgd_free)(struct mm_struct *mm, pgd_t *pgd);

arch/x86/include/asm/tlbflush.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,9 @@ extern void arch_tlbbatch_flush(struct arch_tlbflush_unmap_batch *batch);
552552
#ifndef CONFIG_PARAVIRT
553553
#define flush_tlb_others(mask, info) \
554554
native_flush_tlb_others(mask, info)
555+
556+
#define paravirt_tlb_remove_table(tlb, page) \
557+
tlb_remove_page(tlb, (void *)(page))
555558
#endif
556559

557560
#endif /* _ASM_X86_TLBFLUSH_H */

arch/x86/kernel/kvm.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include <asm/apic.h>
4646
#include <asm/apicdef.h>
4747
#include <asm/hypervisor.h>
48+
#include <asm/tlb.h>
4849

4950
static int kvmapf = 1;
5051

@@ -636,8 +637,10 @@ static void __init kvm_guest_init(void)
636637

637638
if (kvm_para_has_feature(KVM_FEATURE_PV_TLB_FLUSH) &&
638639
!kvm_para_has_hint(KVM_HINTS_REALTIME) &&
639-
kvm_para_has_feature(KVM_FEATURE_STEAL_TIME))
640+
kvm_para_has_feature(KVM_FEATURE_STEAL_TIME)) {
640641
pv_mmu_ops.flush_tlb_others = kvm_flush_tlb_others;
642+
pv_mmu_ops.tlb_remove_table = tlb_remove_table;
643+
}
641644

642645
if (kvm_para_has_feature(KVM_FEATURE_PV_EOI))
643646
apic_set_eoi_write(kvm_guest_apic_eoi_write);

arch/x86/kernel/paravirt.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include <asm/tlbflush.h>
4242
#include <asm/timer.h>
4343
#include <asm/special_insns.h>
44+
#include <asm/tlb.h>
4445

4546
/*
4647
* nop stub, which must not clobber anything *including the stack* to
@@ -409,6 +410,7 @@ struct pv_mmu_ops pv_mmu_ops __ro_after_init = {
409410
.flush_tlb_kernel = native_flush_tlb_global,
410411
.flush_tlb_one_user = native_flush_tlb_one_user,
411412
.flush_tlb_others = native_flush_tlb_others,
413+
.tlb_remove_table = (void (*)(struct mmu_gather *, void *))tlb_remove_page,
412414

413415
.pgd_alloc = __paravirt_pgd_alloc,
414416
.pgd_free = paravirt_nop,

arch/x86/mm/pgtable.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte)
6363
{
6464
pgtable_page_dtor(pte);
6565
paravirt_release_pte(page_to_pfn(pte));
66-
tlb_remove_table(tlb, pte);
66+
paravirt_tlb_remove_table(tlb, pte);
6767
}
6868

6969
#if CONFIG_PGTABLE_LEVELS > 2
@@ -79,21 +79,21 @@ void ___pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd)
7979
tlb->need_flush_all = 1;
8080
#endif
8181
pgtable_pmd_page_dtor(page);
82-
tlb_remove_table(tlb, page);
82+
paravirt_tlb_remove_table(tlb, page);
8383
}
8484

8585
#if CONFIG_PGTABLE_LEVELS > 3
8686
void ___pud_free_tlb(struct mmu_gather *tlb, pud_t *pud)
8787
{
8888
paravirt_release_pud(__pa(pud) >> PAGE_SHIFT);
89-
tlb_remove_table(tlb, virt_to_page(pud));
89+
paravirt_tlb_remove_table(tlb, virt_to_page(pud));
9090
}
9191

9292
#if CONFIG_PGTABLE_LEVELS > 4
9393
void ___p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d)
9494
{
9595
paravirt_release_p4d(__pa(p4d) >> PAGE_SHIFT);
96-
tlb_remove_table(tlb, virt_to_page(p4d));
96+
paravirt_tlb_remove_table(tlb, virt_to_page(p4d));
9797
}
9898
#endif /* CONFIG_PGTABLE_LEVELS > 4 */
9999
#endif /* CONFIG_PGTABLE_LEVELS > 3 */

arch/x86/xen/mmu_pv.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
#include <asm/init.h>
6868
#include <asm/pat.h>
6969
#include <asm/smp.h>
70+
#include <asm/tlb.h>
7071

7172
#include <asm/xen/hypercall.h>
7273
#include <asm/xen/hypervisor.h>
@@ -2397,6 +2398,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = {
23972398
.flush_tlb_kernel = xen_flush_tlb,
23982399
.flush_tlb_one_user = xen_flush_tlb_one_user,
23992400
.flush_tlb_others = xen_flush_tlb_others,
2401+
.tlb_remove_table = tlb_remove_table,
24002402

24012403
.pgd_alloc = xen_pgd_alloc,
24022404
.pgd_free = xen_pgd_free,

0 commit comments

Comments
 (0)