mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-11-01 08:58:07 +00:00
4ce94eabac
To improve TLB shootdown performance, flush the remote and local TLBs concurrently. Introduce flush_tlb_multi() that does so. Introduce paravirtual versions of flush_tlb_multi() for KVM, Xen and hyper-v (Xen and hyper-v are only compile-tested). While the updated smp infrastructure is capable of running a function on a single local core, it is not optimized for this case. The multiple function calls and the indirect branch introduce some overhead, and might make local TLB flushes slower than they were before the recent changes. Before calling the SMP infrastructure, check if only a local TLB flush is needed to restore the lost performance in this common case. This requires to check mm_cpumask() one more time, but unless this mask is updated very frequently, this should impact performance negatively. Signed-off-by: Nadav Amit <namit@vmware.com> Signed-off-by: Ingo Molnar <mingo@kernel.org> Reviewed-by: Michael Kelley <mikelley@microsoft.com> # Hyper-v parts Reviewed-by: Juergen Gross <jgross@suse.com> # Xen and paravirt parts Reviewed-by: Dave Hansen <dave.hansen@linux.intel.com> Link: https://lore.kernel.org/r/20210220231712.2475218-5-namit@vmware.com
98 lines
2.4 KiB
C
98 lines
2.4 KiB
C
#undef TRACE_SYSTEM
|
|
#define TRACE_SYSTEM hyperv
|
|
|
|
#if !defined(_TRACE_HYPERV_H) || defined(TRACE_HEADER_MULTI_READ)
|
|
#define _TRACE_HYPERV_H
|
|
|
|
#include <linux/tracepoint.h>
|
|
|
|
#if IS_ENABLED(CONFIG_HYPERV)
|
|
|
|
TRACE_EVENT(hyperv_mmu_flush_tlb_multi,
|
|
TP_PROTO(const struct cpumask *cpus,
|
|
const struct flush_tlb_info *info),
|
|
TP_ARGS(cpus, info),
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, ncpus)
|
|
__field(struct mm_struct *, mm)
|
|
__field(unsigned long, addr)
|
|
__field(unsigned long, end)
|
|
),
|
|
TP_fast_assign(__entry->ncpus = cpumask_weight(cpus);
|
|
__entry->mm = info->mm;
|
|
__entry->addr = info->start;
|
|
__entry->end = info->end;
|
|
),
|
|
TP_printk("ncpus %d mm %p addr %lx, end %lx",
|
|
__entry->ncpus, __entry->mm,
|
|
__entry->addr, __entry->end)
|
|
);
|
|
|
|
TRACE_EVENT(hyperv_nested_flush_guest_mapping,
|
|
TP_PROTO(u64 as, int ret),
|
|
TP_ARGS(as, ret),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(u64, as)
|
|
__field(int, ret)
|
|
),
|
|
TP_fast_assign(__entry->as = as;
|
|
__entry->ret = ret;
|
|
),
|
|
TP_printk("address space %llx ret %d", __entry->as, __entry->ret)
|
|
);
|
|
|
|
TRACE_EVENT(hyperv_nested_flush_guest_mapping_range,
|
|
TP_PROTO(u64 as, int ret),
|
|
TP_ARGS(as, ret),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(u64, as)
|
|
__field(int, ret)
|
|
),
|
|
TP_fast_assign(__entry->as = as;
|
|
__entry->ret = ret;
|
|
),
|
|
TP_printk("address space %llx ret %d", __entry->as, __entry->ret)
|
|
);
|
|
|
|
TRACE_EVENT(hyperv_send_ipi_mask,
|
|
TP_PROTO(const struct cpumask *cpus,
|
|
int vector),
|
|
TP_ARGS(cpus, vector),
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, ncpus)
|
|
__field(int, vector)
|
|
),
|
|
TP_fast_assign(__entry->ncpus = cpumask_weight(cpus);
|
|
__entry->vector = vector;
|
|
),
|
|
TP_printk("ncpus %d vector %x",
|
|
__entry->ncpus, __entry->vector)
|
|
);
|
|
|
|
TRACE_EVENT(hyperv_send_ipi_one,
|
|
TP_PROTO(int cpu,
|
|
int vector),
|
|
TP_ARGS(cpu, vector),
|
|
TP_STRUCT__entry(
|
|
__field(int, cpu)
|
|
__field(int, vector)
|
|
),
|
|
TP_fast_assign(__entry->cpu = cpu;
|
|
__entry->vector = vector;
|
|
),
|
|
TP_printk("cpu %d vector %x",
|
|
__entry->cpu, __entry->vector)
|
|
);
|
|
|
|
#endif /* CONFIG_HYPERV */
|
|
|
|
#undef TRACE_INCLUDE_PATH
|
|
#define TRACE_INCLUDE_PATH asm/trace/
|
|
#undef TRACE_INCLUDE_FILE
|
|
#define TRACE_INCLUDE_FILE hyperv
|
|
#endif /* _TRACE_HYPERV_H */
|
|
|
|
/* This part must be outside protection */
|
|
#include <trace/define_trace.h>
|