[azure][PATCH v2 2/3] Revert "UBUNTU: SAUCE: x86/hyper-v: support extended CPU ranges for TLB flush hypercalls"
Marcelo Henrique Cerri
marcelo.cerri at canonical.com
Mon Oct 2 14:45:41 UTC 2017
BugLink: http://bugs.launchpad.net/bugs/1719045
This reverts commit 0aa1395238f701fdf2c2e12e49de04b0f2d3a064.
Some golang applications are getting random failures with the linux-azure
kernel. The failures range from some unexpected SIGBUS or SIGSEGV errors to
internal memory allocation failures in the golang runtime.
Bisecting linux-azure shows the problem is caused by the changes that added
support for remote TLB flush via Hyper-V hypercalls. And removing this feature
causes the problem to not happen anymore.
Revert those changes until a proper fix is available.
Signed-off-by: Marcelo Henrique Cerri <marcelo.cerri at canonical.com>
---
arch/x86/hyperv/mmu.c | 149 +------------------------------------
arch/x86/include/uapi/asm/hyperv.h | 10 ---
2 files changed, 2 insertions(+), 157 deletions(-)
diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
index c9cecb3502e9..e3ab9b984b52 100644
--- a/arch/x86/hyperv/mmu.c
+++ b/arch/x86/hyperv/mmu.c
@@ -15,57 +15,8 @@ struct hv_flush_pcpu {
__u64 gva_list[];
};
-/* HvFlushVirtualAddressSpaceEx, HvFlushVirtualAddressListEx hypercalls */
-struct hv_flush_pcpu_ex {
- __u64 address_space;
- __u64 flags;
- struct {
- __u64 format;
- __u64 valid_bank_mask;
- __u64 bank_contents[];
- } hv_vp_set;
- __u64 gva_list[];
-};
-
static struct hv_flush_pcpu __percpu *pcpu_flush;
-static struct hv_flush_pcpu_ex __percpu *pcpu_flush_ex;
-
-static inline int cpumask_to_vp_set(struct hv_flush_pcpu_ex *flush,
- const struct cpumask *cpus)
-{
- int cur_bank, cpu, vcpu, nr_bank = 0;
- bool has_cpus;
-
- /*
- * We can't be sure that translated vcpu numbers will always be
- * in ascending order, so iterate over all possible banks and
- * check all vcpus in it instead.
- */
- for (cur_bank = 0; cur_bank < ms_hyperv.max_vp_index/64; cur_bank++) {
- has_cpus = false;
- for_each_cpu(cpu, cpus) {
- vcpu = hv_cpu_number_to_vp_number(cpu);
- if (vcpu/64 != cur_bank)
- continue;
- if (!has_cpus) {
- flush->hv_vp_set.valid_bank_mask |=
- 1 << vcpu / 64;
- flush->hv_vp_set.bank_contents[nr_bank] =
- 1 << vcpu % 64;
- has_cpus = true;
- } else {
- flush->hv_vp_set.bank_contents[nr_bank] |=
- 1 << vcpu % 64;
- }
- }
- if (has_cpus)
- nr_bank++;
- }
-
- return nr_bank;
-}
-
static void hyperv_flush_tlb_others(const struct cpumask *cpus,
struct mm_struct *mm, unsigned long start,
unsigned long end)
@@ -151,112 +102,16 @@ static void hyperv_flush_tlb_others(const struct cpumask *cpus,
native_flush_tlb_others(cpus, mm, start, end);
}
-static void hyperv_flush_tlb_others_ex(const struct cpumask *cpus,
- struct mm_struct *mm,
- unsigned long start,
- unsigned long end)
-{
- struct hv_flush_pcpu_ex *flush;
- unsigned long cur, flags;
- u64 status = -1ULL;
- int nr_bank = 0, max_gvas, gva_n;
-
- if (!pcpu_flush_ex || !hv_hypercall_pg)
- goto do_native;
-
- if (cpumask_empty(cpus))
- return;
-
- local_irq_save(flags);
-
- flush = this_cpu_ptr(pcpu_flush_ex);
-
- if (mm) {
- flush->address_space = virt_to_phys(mm->pgd);
- flush->flags = 0;
- } else {
- flush->address_space = 0;
- flush->flags = HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES;
- }
-
- flush->hv_vp_set.valid_bank_mask = 0;
-
- if (cpumask_equal(cpus, cpu_present_mask)) {
- flush->hv_vp_set.format = HV_GENERIC_SET_ALL;
- flush->flags |= HV_FLUSH_ALL_PROCESSORS;
- } else {
- flush->hv_vp_set.format = HV_GENERIC_SET_SPARCE_4K;
- nr_bank = cpumask_to_vp_set(flush, cpus);
- }
-
- /*
- * We can flush not more than max_gvas with one hypercall. Flush the
- * whole address space if we were asked to do more.
- */
- max_gvas = (PAGE_SIZE - sizeof(*flush) - nr_bank*8) / 8;
-
- if (end == TLB_FLUSH_ALL ||
- (end && ((end - start)/(PAGE_SIZE*PAGE_SIZE)) > max_gvas)) {
- if (end == TLB_FLUSH_ALL)
- flush->flags |= HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY;
-
- status = hv_do_rep_hypercall(
- HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX,
- 0, nr_bank + 2, flush, NULL);
- } else {
- cur = start;
- gva_n = nr_bank;
- do {
- flush->gva_list[gva_n] = cur & PAGE_MASK;
- /*
- * Lower 12 bits encode the number of additional
- * pages to flush (in addition to the 'cur' page).
- */
- if (end >= cur + PAGE_SIZE * PAGE_SIZE)
- flush->gva_list[gva_n] |= ~PAGE_MASK;
- else if (end > cur)
- flush->gva_list[gva_n] |=
- (end - cur - 1) >> PAGE_SHIFT;
-
- cur += PAGE_SIZE * PAGE_SIZE;
- ++gva_n;
-
- } while (cur < end);
-
- status = hv_do_rep_hypercall(
- HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX,
- gva_n, nr_bank + 2, flush, NULL);
- }
-
- local_irq_restore(flags);
-
- if (!(status & 0xffff))
- return;
-do_native:
- native_flush_tlb_others(cpus, mm, start, end);
-}
-
void hyperv_setup_mmu_ops(void)
{
- if (!(ms_hyperv.hints & HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED))
- return;
-
- if (!(ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED)) {
+ if (ms_hyperv.hints & HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED) {
pr_info("Hyper-V: Using hypercall for remote TLB flush\n");
pv_mmu_ops.flush_tlb_others = hyperv_flush_tlb_others;
- } else {
- pr_info("Hyper-V: Using ext hypercall for remote TLB flush\n");
- pv_mmu_ops.flush_tlb_others = hyperv_flush_tlb_others_ex;
}
}
void hyper_alloc_mmu(void)
{
- if (!(ms_hyperv.hints & HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED))
- return;
-
- if (!(ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED))
+ if (ms_hyperv.hints & HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED)
pcpu_flush = __alloc_percpu(PAGE_SIZE, PAGE_SIZE);
- else
- pcpu_flush_ex = __alloc_percpu(PAGE_SIZE, PAGE_SIZE);
}
diff --git a/arch/x86/include/uapi/asm/hyperv.h b/arch/x86/include/uapi/asm/hyperv.h
index a6b543cc14b6..ecb0470e520b 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -149,9 +149,6 @@
*/
#define HV_X64_DEPRECATING_AEOI_RECOMMENDED (1 << 9)
-/* Recommend using the newer ExProcessorMasks interface */
-#define HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED (1 << 11)
-
/*
* HV_VP_SET available
*/
@@ -248,8 +245,6 @@
#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE 0x0002
#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST 0x0003
#define HVCALL_NOTIFY_LONG_SPIN_WAIT 0x0008
-#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX 0x0013
-#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX 0x0014
#define HVCALL_POST_MESSAGE 0x005c
#define HVCALL_SIGNAL_EVENT 0x005d
@@ -271,11 +266,6 @@
#define HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY 0x00000004
#define HV_FLUSH_USE_EXTENDED_RANGE_FORMAT 0x00000008
-enum HV_GENERIC_SET_FORMAT {
- HV_GENERIC_SET_SPARCE_4K,
- HV_GENERIC_SET_ALL,
-};
-
/* Hypercall interface */
union hv_hypercall_input {
u64 as_uint64;
--
2.7.4
More information about the kernel-team
mailing list