Skip to content

Commit 4cb03e3

Browse files
Peter Zijlstramerwick
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]> (cherry picked from commit 48a8b97) Orabug: 28671425 Signed-off-by: Liam Merwick <[email protected]> Reviewed-by: Darren Kenny <[email protected]> Reviewed-by: Alejandro Jimenez <[email protected]> Tested-by: Vijay Balakrishna <[email protected]>
1 parent 80343c2 commit 4cb03e3

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
@@ -172,7 +172,7 @@ config X86
172172
select HAVE_HARDLOCKUP_DETECTOR_PERF if PERF_EVENTS && HAVE_PERF_EVENTS_NMI
173173
select HAVE_PERF_REGS
174174
select HAVE_PERF_USER_STACK_DUMP
175-
select HAVE_RCU_TABLE_FREE
175+
select HAVE_RCU_TABLE_FREE if PARAVIRT
176176
select HAVE_RCU_TABLE_INVALIDATE if HAVE_RCU_TABLE_FREE
177177
select HAVE_REGS_AND_STACK_ACCESS_API
178178
select HAVE_RELIABLE_STACKTRACE if X86_64 && UNWINDER_FRAME_POINTER && 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
@@ -589,6 +589,9 @@ extern void arch_tlbbatch_flush(struct arch_tlbflush_unmap_batch *batch);
589589
#ifndef CONFIG_PARAVIRT
590590
#define flush_tlb_others(mask, info) \
591591
native_flush_tlb_others(mask, info)
592+
593+
#define paravirt_tlb_remove_table(tlb, page) \
594+
tlb_remove_page(tlb, (void *)(page))
592595
#endif
593596

594597
#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

@@ -638,8 +639,10 @@ static void __init kvm_guest_init(void)
638639

639640
if (kvm_para_has_feature(KVM_FEATURE_PV_TLB_FLUSH) &&
640641
!kvm_para_has_hint(KVM_HINTS_REALTIME) &&
641-
kvm_para_has_feature(KVM_FEATURE_STEAL_TIME))
642+
kvm_para_has_feature(KVM_FEATURE_STEAL_TIME)) {
642643
pv_mmu_ops.flush_tlb_others = kvm_flush_tlb_others;
644+
pv_mmu_ops.tlb_remove_table = tlb_remove_table;
645+
}
643646

644647
if (kvm_para_has_feature(KVM_FEATURE_PV_EOI))
645648
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
@@ -58,7 +58,7 @@ void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte)
5858
{
5959
pgtable_page_dtor(pte);
6060
paravirt_release_pte(page_to_pfn(pte));
61-
tlb_remove_table(tlb, pte);
61+
paravirt_tlb_remove_table(tlb, pte);
6262
}
6363

6464
#if CONFIG_PGTABLE_LEVELS > 2
@@ -74,21 +74,21 @@ void ___pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd)
7474
tlb->need_flush_all = 1;
7575
#endif
7676
pgtable_pmd_page_dtor(page);
77-
tlb_remove_table(tlb, page);
77+
paravirt_tlb_remove_table(tlb, page);
7878
}
7979

8080
#if CONFIG_PGTABLE_LEVELS > 3
8181
void ___pud_free_tlb(struct mmu_gather *tlb, pud_t *pud)
8282
{
8383
paravirt_release_pud(__pa(pud) >> PAGE_SHIFT);
84-
tlb_remove_table(tlb, virt_to_page(pud));
84+
paravirt_tlb_remove_table(tlb, virt_to_page(pud));
8585
}
8686

8787
#if CONFIG_PGTABLE_LEVELS > 4
8888
void ___p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d)
8989
{
9090
paravirt_release_p4d(__pa(p4d) >> PAGE_SHIFT);
91-
tlb_remove_table(tlb, virt_to_page(p4d));
91+
paravirt_tlb_remove_table(tlb, virt_to_page(p4d));
9292
}
9393
#endif /* CONFIG_PGTABLE_LEVELS > 4 */
9494
#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>
@@ -2381,6 +2382,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = {
23812382
.flush_tlb_kernel = xen_flush_tlb,
23822383
.flush_tlb_one_user = xen_flush_tlb_one_user,
23832384
.flush_tlb_others = xen_flush_tlb_others,
2385+
.tlb_remove_table = tlb_remove_table,
23842386

23852387
.pgd_alloc = xen_pgd_alloc,
23862388
.pgd_free = xen_pgd_free,

0 commit comments

Comments
 (0)