Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1649546 > unrolled thread
| Started by | Vitaly Kuznetsov <vkuznets@redhat.com> |
|---|---|
| First post | 2017-05-24 14:10 +0200 |
| Last post | 2017-06-07 16:10 +0200 |
| Articles | 20 on this page of 21 — 4 participants |
Back to article view | Back to linux.kernel
[PATCH v4 00/10] Hyper-V: praravirtualized remote TLB flushing and hypercall improvements Vitaly Kuznetsov <vkuznets@redhat.com> - 2017-05-24 14:10 +0200
[PATCH v4 06/10] x86/hyper-v: implement rep hypercalls Vitaly Kuznetsov <vkuznets@redhat.com> - 2017-05-24 14:10 +0200
[PATCH v4 09/10] x86/hyper-v: support extended CPU ranges for TLB flush hypercalls Vitaly Kuznetsov <vkuznets@redhat.com> - 2017-05-24 14:10 +0200
Re: [PATCH v4 09/10] x86/hyper-v: support extended CPU ranges for TLB flush hypercalls Andy Shevchenko <andy.shevchenko@gmail.com> - 2017-05-27 20:20 +0200
[PATCH v4 01/10] x86/hyper-v: include hyperv/ only when CONFIG_HYPERV is set Vitaly Kuznetsov <vkuznets@redhat.com> - 2017-05-24 14:10 +0200
[PATCH v4 03/10] x86/hyper-v: make hv_do_hypercall() inline Vitaly Kuznetsov <vkuznets@redhat.com> - 2017-05-24 14:10 +0200
Re: [PATCH v4 03/10] x86/hyper-v: make hv_do_hypercall() inline Andy Shevchenko <andy.shevchenko@gmail.com> - 2017-05-27 19:50 +0200
[PATCH v4 04/10] x86/hyper-v: fast hypercall implementation Vitaly Kuznetsov <vkuznets@redhat.com> - 2017-05-24 14:10 +0200
Re: [PATCH v4 04/10] x86/hyper-v: fast hypercall implementation Andy Shevchenko <andy.shevchenko@gmail.com> - 2017-05-27 19:50 +0200
[PATCH v4 08/10] x86/hyper-v: use hypercall for remote TLB flush Vitaly Kuznetsov <vkuznets@redhat.com> - 2017-05-24 14:10 +0200
[PATCH v4 05/10] hyper-v: use fast hypercall for HVCALL_SIGNAL_EVENT Vitaly Kuznetsov <vkuznets@redhat.com> - 2017-05-24 14:10 +0200
Re: [PATCH v4 05/10] hyper-v: use fast hypercall for HVCALL_SIGNAL_EVENT Andy Shevchenko <andy.shevchenko@gmail.com> - 2017-05-27 20:00 +0200
[PATCH v4 02/10] x86/hyper-v: stash the max number of virtual/logical processor Vitaly Kuznetsov <vkuznets@redhat.com> - 2017-05-24 14:10 +0200
Re: [PATCH v4 02/10] x86/hyper-v: stash the max number of virtual/logical processor Andy Shevchenko <andy.shevchenko@gmail.com> - 2017-05-27 19:50 +0200
Re: [PATCH v4 02/10] x86/hyper-v: stash the max number of virtual/logical processor Steven Rostedt <rostedt@goodmis.org> - 2017-06-05 17:30 +0200
Re: [PATCH v4 02/10] x86/hyper-v: stash the max number of virtual/logical processor Stephen Hemminger <stephen@networkplumber.org> - 2017-06-05 17:40 +0200
[PATCH v4 10/10] tracing/hyper-v: trace hyperv_mmu_flush_tlb_others() Vitaly Kuznetsov <vkuznets@redhat.com> - 2017-05-24 14:10 +0200
Re: [PATCH v4 10/10] tracing/hyper-v: trace hyperv_mmu_flush_tlb_others() Steven Rostedt <rostedt@goodmis.org> - 2017-06-05 18:00 +0200
Re: [PATCH v4 10/10] tracing/hyper-v: trace hyperv_mmu_flush_tlb_others() Vitaly Kuznetsov <vkuznets@redhat.com> - 2017-06-05 18:20 +0200
Re: [PATCH v4 10/10] tracing/hyper-v: trace hyperv_mmu_flush_tlb_others() Steven Rostedt <rostedt@goodmis.org> - 2017-06-07 16:00 +0200
Re: [PATCH v4 10/10] tracing/hyper-v: trace hyperv_mmu_flush_tlb_others() Vitaly Kuznetsov <vkuznets@redhat.com> - 2017-06-07 16:10 +0200
Page 1 of 2 [1] 2 Next page →
| From | Vitaly Kuznetsov <vkuznets@redhat.com> |
|---|---|
| Date | 2017-05-24 14:10 +0200 |
| Subject | [PATCH v4 00/10] Hyper-V: praravirtualized remote TLB flushing and hypercall improvements |
| Message-ID | <tKDh0-2cD-7@gated-at.bofh.it> |
Changes since v3: - Force a stack frame in hv_do_hypercall()/hv_do_fast_hypercall8() [Andy Lutomirski] (Patches 3,4). K. Y., I'm keeping your Acked-by and Tested-by tags on these patches as I think the adjustment is minor. I smoke tested both i586 and x86_64 builds and no issues were noticed. There is a discussion if this need to go through char-misc or x86 tree. The majority of the stuff in the series is Hyper-V related so char-misc looks appropriate but Andy noticed that we're clashing with his PCID series so it may make sense to have everything in x86. Original descriptions: Hyper-V supports hypercalls for doing local and remote TLB flushing and gives its guests hints when using hypercall is preferred. While doing hypercalls for local TLB flushes is probably not practical (and is not being suggested by modern Hyper-V versions) remote TLB flush with a hypercall brings significant improvement. To test the series I wrote a special 'TLB trasher': on a 16 vCPU guest I was creating 32 threads which were doing 100000 mmap/munmaps each on some big file. Here are the results: Before: # time ./pthread_mmap ./randfile real 3m33.118s user 0m3.698s sys 3m16.624s After: # time ./pthread_mmap ./randfile real 2m19.920s user 0m2.662s sys 2m9.948s This series brings a number of small improvements along the way: fast hypercall implementation and using it for event signaling, rep hypercalls implementation, hyperv tracing subsystem (which only traces the newly added remote TLB flush for now). Vitaly Kuznetsov (10): x86/hyper-v: include hyperv/ only when CONFIG_HYPERV is set x86/hyper-v: stash the max number of virtual/logical processor x86/hyper-v: make hv_do_hypercall() inline x86/hyper-v: fast hypercall implementation hyper-v: use fast hypercall for HVCALL_SIGNAL_EVENT x86/hyper-v: implement rep hypercalls hyper-v: globalize vp_index x86/hyper-v: use hypercall for remote TLB flush x86/hyper-v: support extended CPU ranges for TLB flush hypercalls tracing/hyper-v: trace hyperv_mmu_flush_tlb_others() MAINTAINERS | 1 + arch/x86/Kbuild | 4 +- arch/x86/hyperv/Makefile | 2 +- arch/x86/hyperv/hv_init.c | 90 ++++++------ arch/x86/hyperv/mmu.c | 270 ++++++++++++++++++++++++++++++++++++ arch/x86/include/asm/mshyperv.h | 152 +++++++++++++++++++- arch/x86/include/asm/trace/hyperv.h | 34 +++++ arch/x86/include/uapi/asm/hyperv.h | 36 +++++ arch/x86/kernel/cpu/mshyperv.c | 14 +- drivers/hv/channel_mgmt.c | 22 ++- drivers/hv/connection.c | 8 +- drivers/hv/hv.c | 9 -- drivers/hv/hyperv_vmbus.h | 11 -- drivers/hv/vmbus_drv.c | 17 --- drivers/pci/host/pci-hyperv.c | 4 +- include/linux/hyperv.h | 21 ++- 16 files changed, 571 insertions(+), 124 deletions(-) create mode 100644 arch/x86/hyperv/mmu.c create mode 100644 arch/x86/include/asm/trace/hyperv.h -- 2.9.4
[toc] | [next] | [standalone]
| From | Vitaly Kuznetsov <vkuznets@redhat.com> |
|---|---|
| Date | 2017-05-24 14:10 +0200 |
| Subject | [PATCH v4 06/10] x86/hyper-v: implement rep hypercalls |
| Message-ID | <tKDh0-2cD-13@gated-at.bofh.it> |
| In reply to | #1649546 |
Rep hypercalls are normal hypercalls which perform multiple actions at
once. Hyper-V guarantees to return exectution to the caller in not more
than 50us and the caller needs to use hypercall continuation. Touch NMI
watchdog between hypercall invocations.
This is going to be used for HvFlushVirtualAddressList hypercall for
remote TLB flushing.
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Acked-by: K. Y. Srinivasan <kys@microsoft.com>
Tested-by: Simon Xiao <sixiao@microsoft.com>
Tested-by: Srikanth Myakam <v-srm@microsoft.com>
---
arch/x86/include/asm/mshyperv.h | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 52b3611..e0b4c70 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -4,6 +4,7 @@
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/clocksource.h>
+#include <linux/nmi.h>
#include <asm/hyperv.h>
/*
@@ -258,6 +259,31 @@ static inline u64 hv_do_fast_hypercall8(u16 code, u64 input1)
#endif
}
+/*
+ * Rep hypercalls. Callers of this functions are supposed to ensure that
+ * rep_count and vahead_size comply with union hv_hypercall_input definition.
+ */
+static inline u64 hv_do_rep_hypercall(u16 code, u16 rep_count, u16 varhead_size,
+ void *input, void *output)
+{
+ union hv_hypercall_input hc_input = { .code = code,
+ .varhead_size = varhead_size,
+ .rep_count = rep_count};
+ u64 status;
+
+ do {
+ status = hv_do_hypercall(hc_input.as_uint64, input, output);
+ if ((status & 0xffff) != HV_STATUS_SUCCESS)
+ return status;
+
+ hc_input.rep_start = (status >> 32) & 0xfff;
+
+ touch_nmi_watchdog();
+ } while (hc_input.rep_start < hc_input.rep_count);
+
+ return status;
+}
+
void hyperv_init(void);
void hyperv_report_panic(struct pt_regs *regs);
bool hv_is_hypercall_page_setup(void);
--
2.9.4
[toc] | [prev] | [next] | [standalone]
| From | Vitaly Kuznetsov <vkuznets@redhat.com> |
|---|---|
| Date | 2017-05-24 14:10 +0200 |
| Subject | [PATCH v4 09/10] x86/hyper-v: support extended CPU ranges for TLB flush hypercalls |
| Message-ID | <tKDh0-2cD-17@gated-at.bofh.it> |
| In reply to | #1649546 |
Hyper-V hosts may support more than 64 vCPUs, we need to use
HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX/LIST_EX hypercalls in this
case.
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Acked-by: K. Y. Srinivasan <kys@microsoft.com>
Tested-by: Simon Xiao <sixiao@microsoft.com>
Tested-by: Srikanth Myakam <v-srm@microsoft.com>
---
arch/x86/hyperv/mmu.c | 149 ++++++++++++++++++++++++++++++++++++-
arch/x86/include/uapi/asm/hyperv.h | 10 +++
2 files changed, 157 insertions(+), 2 deletions(-)
diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
index e3ab9b9..c9cecb3 100644
--- a/arch/x86/hyperv/mmu.c
+++ b/arch/x86/hyperv/mmu.c
@@ -15,8 +15,57 @@ 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)
@@ -102,16 +151,112 @@ 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) {
+ if (!(ms_hyperv.hints & HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED))
+ return;
+
+ if (!(ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_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)
+ if (!(ms_hyperv.hints & HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED))
+ return;
+
+ if (!(ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_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 3d44036..c697e20 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -152,6 +152,9 @@
*/
#define HV_X64_DEPRECATING_AEOI_RECOMMENDED (1 << 9)
+/* Recommend using the newer ExProcessorMasks interface */
+#define HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED (1 << 11)
+
/*
* Crash notification flag.
*/
@@ -242,6 +245,8 @@
#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
@@ -263,6 +268,11 @@
#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.9.4
[toc] | [prev] | [next] | [standalone]
| From | Andy Shevchenko <andy.shevchenko@gmail.com> |
|---|---|
| Date | 2017-05-27 20:20 +0200 |
| Subject | Re: [PATCH v4 09/10] x86/hyper-v: support extended CPU ranges for TLB flush hypercalls |
| Message-ID | <tLOtH-7xL-3@gated-at.bofh.it> |
| In reply to | #1649548 |
On Wed, May 24, 2017 at 3:04 PM, Vitaly Kuznetsov <vkuznets@redhat.com> wrote:
> Hyper-V hosts may support more than 64 vCPUs, we need to use
> HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX/LIST_EX hypercalls in this
> case.
> +{
> + /*
> + * 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.
vcpu -> vCPU
vcpus -> vCPUs
> + */
> + for (cur_bank = 0; cur_bank < ms_hyperv.max_vp_index/64; cur_bank++) {
> + has_cpus = false;
> + for_each_cpu(cpu, cpus) {
int vcpu_bank = vcpu / 64;
int vcpu_offset = vcpu % 64;
> + vcpu = hv_cpu_number_to_vp_number(cpu);
> + if (vcpu/64 != cur_bank)
if (vcpu_bank != cur_bank)
> + continue;
> + if (!has_cpus) {
> + flush->hv_vp_set.valid_bank_mask |=
> + 1 << vcpu / 64;
__set_bit(vcpu_bank, &mask);
> + flush->hv_vp_set.bank_contents[nr_bank] =
> + 1 << vcpu % 64;
Ditto. (vcpu_offset)
> + has_cpus = true;
> + } else {
> + flush->hv_vp_set.bank_contents[nr_bank] |=
> + 1 << vcpu % 64;
Ditto.
> + }
> + }
> + if (has_cpus)
> + nr_bank++;
> + }
> +
> + return nr_bank;
> +}
> +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;
U64_MAX
> + int nr_bank = 0, max_gvas, gva_n;
> + /*
> + * We can flush not more than max_gvas with one hypercall. Flush the
> + * whole address space if we were asked to do more.
> + */
#define XXX (PAGE_SIZE * PAGE_SIZE)
> + 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);
if (end == _FLASH_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 if (end && ((end - start) / XXX > max_gvas)) {
status = hv_do_rep_hypercall(
HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX,
0, nr_bank + 2, flush, NULL);
} else {
...
Yes, a bit more code, but IMO much more understandable.
> + } 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)
if (end >= cur + XXX)
> + 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;
+= XXX;
> + ++gva_n;
> +
> + } while (cur < end);
> +}
--
With Best Regards,
Andy Shevchenko
[toc] | [prev] | [next] | [standalone]
| From | Vitaly Kuznetsov <vkuznets@redhat.com> |
|---|---|
| Date | 2017-05-24 14:10 +0200 |
| Subject | [PATCH v4 01/10] x86/hyper-v: include hyperv/ only when CONFIG_HYPERV is set |
| Message-ID | <tKDh1-2cD-25@gated-at.bofh.it> |
| In reply to | #1649546 |
Code is arch/x86/hyperv/ is only needed when CONFIG_HYPERV is set, the
'basic' support and detection lives in arch/x86/kernel/cpu/mshyperv.c
which is included when CONFIG_HYPERVISOR_GUEST is set.
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Acked-by: K. Y. Srinivasan <kys@microsoft.com>
Tested-by: Simon Xiao <sixiao@microsoft.com>
Tested-by: Srikanth Myakam <v-srm@microsoft.com>
---
arch/x86/Kbuild | 4 +++-
arch/x86/include/asm/mshyperv.h | 10 +++++++++-
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/arch/x86/Kbuild b/arch/x86/Kbuild
index 586b786..3fa0a3c 100644
--- a/arch/x86/Kbuild
+++ b/arch/x86/Kbuild
@@ -8,7 +8,9 @@ obj-$(CONFIG_KVM) += kvm/
obj-$(CONFIG_XEN) += xen/
# Hyper-V paravirtualization support
-obj-$(CONFIG_HYPERVISOR_GUEST) += hyperv/
+ifdef CONFIG_HYPERV
+obj-y += hyperv/
+endif
# lguest paravirtualization support
obj-$(CONFIG_LGUEST_GUEST) += lguest/
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index fba1007..91acec7 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -175,7 +175,15 @@ void hyperv_init(void);
void hyperv_report_panic(struct pt_regs *regs);
bool hv_is_hypercall_page_setup(void);
void hyperv_cleanup(void);
-#endif
+#else /* CONFIG_HYPERV */
+static inline void hyperv_init(void) {}
+static inline bool hv_is_hypercall_page_setup(void)
+{
+ return false;
+}
+static inline hyperv_cleanup(void) {}
+#endif /* CONFIG_HYPERV */
+
#ifdef CONFIG_HYPERV_TSCPAGE
struct ms_hyperv_tsc_page *hv_get_tsc_page(void);
static inline u64 hv_read_tsc_page(const struct ms_hyperv_tsc_page *tsc_pg)
--
2.9.4
[toc] | [prev] | [next] | [standalone]
| From | Vitaly Kuznetsov <vkuznets@redhat.com> |
|---|---|
| Date | 2017-05-24 14:10 +0200 |
| Subject | [PATCH v4 03/10] x86/hyper-v: make hv_do_hypercall() inline |
| Message-ID | <tKDh0-2cD-19@gated-at.bofh.it> |
| In reply to | #1649546 |
We have only three call sites for hv_do_hypercall() and we're going to
change HVCALL_SIGNAL_EVENT to doing fast hypercall so we can inline this
function for optimization.
Hyper-V top level functional specification states that r9-r11 registers
and flags may be clobbered by the hypervisor during hypercall and with
inlining this is somewhat important, add the clobbers.
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Acked-by: K. Y. Srinivasan <kys@microsoft.com>
Tested-by: Simon Xiao <sixiao@microsoft.com>
Tested-by: Srikanth Myakam <v-srm@microsoft.com>
---
Change since v3:
- Force stack frame in hv_do_hypercall() [Andy Lutomirski]
---
arch/x86/hyperv/hv_init.c | 54 ++++-------------------------------------
arch/x86/include/asm/mshyperv.h | 44 +++++++++++++++++++++++++++++++++
drivers/hv/connection.c | 2 ++
include/linux/hyperv.h | 1 -
4 files changed, 51 insertions(+), 50 deletions(-)
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 5b882cc..691603e 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -75,7 +75,8 @@ static struct clocksource hyperv_cs_msr = {
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
-static void *hypercall_pg;
+void *hv_hypercall_pg;
+EXPORT_SYMBOL_GPL(hv_hypercall_pg);
struct clocksource *hyperv_cs;
EXPORT_SYMBOL_GPL(hyperv_cs);
@@ -102,15 +103,15 @@ void hyperv_init(void)
guest_id = generate_guest_id(0, LINUX_VERSION_CODE, 0);
wrmsrl(HV_X64_MSR_GUEST_OS_ID, guest_id);
- hypercall_pg = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_RX);
- if (hypercall_pg == NULL) {
+ hv_hypercall_pg = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_RX);
+ if (hv_hypercall_pg == NULL) {
wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0);
return;
}
rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
hypercall_msr.enable = 1;
- hypercall_msr.guest_physical_address = vmalloc_to_pfn(hypercall_pg);
+ hypercall_msr.guest_physical_address = vmalloc_to_pfn(hv_hypercall_pg);
wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
/*
@@ -170,51 +171,6 @@ void hyperv_cleanup(void)
}
EXPORT_SYMBOL_GPL(hyperv_cleanup);
-/*
- * hv_do_hypercall- Invoke the specified hypercall
- */
-u64 hv_do_hypercall(u64 control, void *input, void *output)
-{
- u64 input_address = (input) ? virt_to_phys(input) : 0;
- u64 output_address = (output) ? virt_to_phys(output) : 0;
-#ifdef CONFIG_X86_64
- u64 hv_status = 0;
-
- if (!hypercall_pg)
- return (u64)ULLONG_MAX;
-
- __asm__ __volatile__("mov %0, %%r8" : : "r" (output_address) : "r8");
- __asm__ __volatile__("call *%3" : "=a" (hv_status) :
- "c" (control), "d" (input_address),
- "m" (hypercall_pg));
-
- return hv_status;
-
-#else
-
- u32 control_hi = control >> 32;
- u32 control_lo = control & 0xFFFFFFFF;
- u32 hv_status_hi = 1;
- u32 hv_status_lo = 1;
- u32 input_address_hi = input_address >> 32;
- u32 input_address_lo = input_address & 0xFFFFFFFF;
- u32 output_address_hi = output_address >> 32;
- u32 output_address_lo = output_address & 0xFFFFFFFF;
-
- if (!hypercall_pg)
- return (u64)ULLONG_MAX;
-
- __asm__ __volatile__ ("call *%8" : "=d"(hv_status_hi),
- "=a"(hv_status_lo) : "d" (control_hi),
- "a" (control_lo), "b" (input_address_hi),
- "c" (input_address_lo), "D"(output_address_hi),
- "S"(output_address_lo), "m" (hypercall_pg));
-
- return hv_status_lo | ((u64)hv_status_hi << 32);
-#endif /* !x86_64 */
-}
-EXPORT_SYMBOL_GPL(hv_do_hypercall);
-
void hyperv_report_panic(struct pt_regs *regs)
{
static bool panic_reported;
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index d42b6eb..cbbf7db 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -172,6 +172,50 @@ void hv_remove_crash_handler(void);
#if IS_ENABLED(CONFIG_HYPERV)
extern struct clocksource *hyperv_cs;
+extern void *hv_hypercall_pg;
+
+static inline u64 hv_do_hypercall(u64 control, void *input, void *output)
+{
+ u64 input_address = (input) ? virt_to_phys(input) : 0;
+ u64 output_address = (output) ? virt_to_phys(output) : 0;
+ register void *__sp asm(_ASM_SP);
+#ifdef CONFIG_X86_64
+ u64 hv_status;
+
+ if (!hv_hypercall_pg)
+ return (u64)ULLONG_MAX;
+
+ __asm__ __volatile__("mov %4, %%r8\n"
+ "call *%5"
+ : "=a" (hv_status), "+r" (__sp),
+ "+c" (control), "+d" (input_address)
+ : "r" (output_address), "m" (hv_hypercall_pg)
+ : "cc", "memory", "r8", "r9", "r10", "r11");
+
+ return hv_status;
+
+#else
+ u32 control_hi = control >> 32;
+ u32 control_lo = control & 0xFFFFFFFF;
+ u32 input_address_hi = input_address >> 32;
+ u32 input_address_lo = input_address & 0xFFFFFFFF;
+ u32 output_address_hi = output_address >> 32;
+ u32 output_address_lo = output_address & 0xFFFFFFFF;
+
+ if (!hv_hypercall_pg)
+ return (u64)ULLONG_MAX;
+
+ __asm__ __volatile__("call *%7"
+ : "+a" (control_lo), "+d" (control_hi),
+ "+c" (input_address_lo), "+r" (__sp)
+ : "b" (input_address_hi),
+ "D"(output_address_hi), "S"(output_address_lo),
+ "m" (hv_hypercall_pg)
+ : "cc", "memory");
+
+ return control_lo | ((u64)control_hi << 32);
+#endif /* !x86_64 */
+}
void hyperv_init(void);
void hyperv_report_panic(struct pt_regs *regs);
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index c2d74ee..4a0a9f6 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -32,6 +32,8 @@
#include <linux/hyperv.h>
#include <linux/export.h>
#include <asm/hyperv.h>
+#include <asm/mshyperv.h>
+
#include "hyperv_vmbus.h"
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index e09fc82..d1ae02d 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1188,7 +1188,6 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
bool fb_overlap_ok);
void vmbus_free_mmio(resource_size_t start, resource_size_t size);
int vmbus_cpu_number_to_vp_number(int cpu_number);
-u64 hv_do_hypercall(u64 control, void *input, void *output);
/*
* GUID definitions of various offer types - services offered to the guest.
--
2.9.4
[toc] | [prev] | [next] | [standalone]
| From | Andy Shevchenko <andy.shevchenko@gmail.com> |
|---|---|
| Date | 2017-05-27 19:50 +0200 |
| Subject | Re: [PATCH v4 03/10] x86/hyper-v: make hv_do_hypercall() inline |
| Message-ID | <tLO0G-77h-13@gated-at.bofh.it> |
| In reply to | #1649552 |
On Wed, May 24, 2017 at 3:03 PM, Vitaly Kuznetsov <vkuznets@redhat.com> wrote: > We have only three call sites for hv_do_hypercall() and we're going to > change HVCALL_SIGNAL_EVENT to doing fast hypercall so we can inline this > function for optimization. > > Hyper-V top level functional specification states that r9-r11 registers > and flags may be clobbered by the hypervisor during hypercall and with > inlining this is somewhat important, add the clobbers. > + u32 control_hi = control >> 32; > + u32 control_lo = control & 0xFFFFFFFF; > + u32 input_address_hi = input_address >> 32; > + u32 input_address_lo = input_address & 0xFFFFFFFF; > + u32 output_address_hi = output_address >> 32; > + u32 output_address_lo = output_address & 0xFFFFFFFF; Yes, I have noticed it was in older code, but see, all conjunctions above are redundant. Besides that, you may consider to use upper_32_bits() / lower_32_bits() macros. -- With Best Regards, Andy Shevchenko
[toc] | [prev] | [next] | [standalone]
| From | Vitaly Kuznetsov <vkuznets@redhat.com> |
|---|---|
| Date | 2017-05-24 14:10 +0200 |
| Subject | [PATCH v4 04/10] x86/hyper-v: fast hypercall implementation |
| Message-ID | <tKDh0-2cD-21@gated-at.bofh.it> |
| In reply to | #1649546 |
Hyper-V supports 'fast' hypercalls when all parameters are passed through
registers. Implement an inline version of a simpliest of these calls:
hypercall with one 8-byte input and no output.
Proper hypercall input interface (struct hv_hypercall_input) definition is
added as well.
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Acked-by: K. Y. Srinivasan <kys@microsoft.com>
Tested-by: Simon Xiao <sixiao@microsoft.com>
Tested-by: Srikanth Myakam <v-srm@microsoft.com>
---
Change since v3:
- Force stack frame in hv_do_fast_hypercall8() [Andy Lutomirski]
---
arch/x86/include/asm/mshyperv.h | 41 ++++++++++++++++++++++++++++++++++++++
arch/x86/include/uapi/asm/hyperv.h | 19 ++++++++++++++++++
2 files changed, 60 insertions(+)
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index cbbf7db..52b3611 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -217,6 +217,47 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output)
#endif /* !x86_64 */
}
+/* Fast hypercall with 8 bytes of input and no output */
+static inline u64 hv_do_fast_hypercall8(u16 code, u64 input1)
+{
+ union hv_hypercall_input control = {0};
+ register void *__sp asm(_ASM_SP);
+
+ control.code = code;
+ control.fast = 1;
+#ifdef CONFIG_X86_64
+ {
+ u64 hv_status;
+
+ __asm__ __volatile__("call *%4"
+ : "=a" (hv_status), "+r" (__sp),
+ "+c" (control.as_uint64), "+d" (input1)
+ : "m" (hv_hypercall_pg)
+ : "cc", "r8", "r9", "r10", "r11");
+ return hv_status;
+ }
+#else
+ {
+ u32 hv_status_hi, hv_status_lo;
+ u32 input1_hi = (u32)(input1 >> 32);
+ u32 input1_lo = (u32)input1;
+
+ __asm__ __volatile__ ("call *%7"
+ : "=d"(hv_status_hi),
+ "=a"(hv_status_lo),
+ "+c"(input1_lo),
+ "+r"(__sp)
+ : "d" (control.as_uint32_hi),
+ "a" (control.as_uint32_lo),
+ "b" (input1_hi),
+ "m" (hv_hypercall_pg)
+ : "cc", "edi", "esi");
+
+ return hv_status_lo | ((u64)hv_status_hi << 32);
+ }
+#endif
+}
+
void hyperv_init(void);
void hyperv_report_panic(struct pt_regs *regs);
bool hv_is_hypercall_page_setup(void);
diff --git a/arch/x86/include/uapi/asm/hyperv.h b/arch/x86/include/uapi/asm/hyperv.h
index 432df4b..c87e900 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -256,6 +256,25 @@
#define HV_PROCESSOR_POWER_STATE_C2 2
#define HV_PROCESSOR_POWER_STATE_C3 3
+/* Hypercall interface */
+union hv_hypercall_input {
+ u64 as_uint64;
+ struct {
+ __u32 as_uint32_lo;
+ __u32 as_uint32_hi;
+ };
+ struct {
+ __u64 code:16;
+ __u64 fast:1;
+ __u64 varhead_size:10;
+ __u64 reserved1:5;
+ __u64 rep_count:12;
+ __u64 reserved2:4;
+ __u64 rep_start:12;
+ __u64 reserved3:4;
+ };
+};
+
/* hypercall status code */
#define HV_STATUS_SUCCESS 0
#define HV_STATUS_INVALID_HYPERCALL_CODE 2
--
2.9.4
[toc] | [prev] | [next] | [standalone]
| From | Andy Shevchenko <andy.shevchenko@gmail.com> |
|---|---|
| Date | 2017-05-27 19:50 +0200 |
| Subject | Re: [PATCH v4 04/10] x86/hyper-v: fast hypercall implementation |
| Message-ID | <tLO0F-77h-5@gated-at.bofh.it> |
| In reply to | #1649553 |
On Wed, May 24, 2017 at 3:03 PM, Vitaly Kuznetsov <vkuznets@redhat.com> wrote:
> Hyper-V supports 'fast' hypercalls when all parameters are passed through
> registers. Implement an inline version of a simpliest of these calls:
> hypercall with one 8-byte input and no output.
>
> Proper hypercall input interface (struct hv_hypercall_input) definition is
> added as well.
> + u32 hv_status_hi, hv_status_lo;
> + u32 input1_hi = (u32)(input1 >> 32);
> + u32 input1_lo = (u32)input1;
Explicit casting is redundant.
Also consider using macros.
> +/* Hypercall interface */
> +union hv_hypercall_input {
Be careful wrt union aliasing.
> + u64 as_uint64;
> + struct {
> + __u32 as_uint32_lo;
> + __u32 as_uint32_hi;
> + };
> + struct {
> + __u64 code:16;
> + __u64 fast:1;
> + __u64 varhead_size:10;
> + __u64 reserved1:5;
> + __u64 rep_count:12;
> + __u64 reserved2:4;
> + __u64 rep_start:12;
> + __u64 reserved3:4;
> + };
> +};
--
With Best Regards,
Andy Shevchenko
[toc] | [prev] | [next] | [standalone]
| From | Vitaly Kuznetsov <vkuznets@redhat.com> |
|---|---|
| Date | 2017-05-24 14:10 +0200 |
| Subject | [PATCH v4 08/10] x86/hyper-v: use hypercall for remote TLB flush |
| Message-ID | <tKDh1-2cD-31@gated-at.bofh.it> |
| In reply to | #1649546 |
Hyper-V host can suggest us to use hypercall for doing remote TLB flush,
this is supposed to work faster than IPIs.
Implementation details: to do HvFlushVirtualAddress{Space,List} hypercalls
we need to put the input somewhere in memory and we don't really want to
have memory allocation on each call so we pre-allocate per cpu memory areas
on boot. These areas are of fixes size, limit them with an arbitrary number
of 16 (16 gvas are able to specify 16 * 4096 pages).
pv_ops patching is happening very early so we need to separate
hyperv_setup_mmu_ops() and hyper_alloc_mmu().
It is possible and easy to implement local TLB flushing too and there is
even a hint for that. However, I don't see a room for optimization on the
host side as both hypercall and native tlb flush will result in vmexit. The
hint is also not set on modern Hyper-V versions.
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Acked-by: K. Y. Srinivasan <kys@microsoft.com>
Tested-by: Simon Xiao <sixiao@microsoft.com>
Tested-by: Srikanth Myakam <v-srm@microsoft.com>
---
arch/x86/hyperv/Makefile | 2 +-
arch/x86/hyperv/hv_init.c | 2 +
arch/x86/hyperv/mmu.c | 117 +++++++++++++++++++++++++++++++++++++
arch/x86/include/asm/mshyperv.h | 3 +
arch/x86/include/uapi/asm/hyperv.h | 7 +++
arch/x86/kernel/cpu/mshyperv.c | 1 +
6 files changed, 131 insertions(+), 1 deletion(-)
create mode 100644 arch/x86/hyperv/mmu.c
diff --git a/arch/x86/hyperv/Makefile b/arch/x86/hyperv/Makefile
index 171ae09..367a820 100644
--- a/arch/x86/hyperv/Makefile
+++ b/arch/x86/hyperv/Makefile
@@ -1 +1 @@
-obj-y := hv_init.o
+obj-y := hv_init.o mmu.o
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 7fd9cd3..df3252f 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -140,6 +140,8 @@ void hyperv_init(void)
hypercall_msr.guest_physical_address = vmalloc_to_pfn(hv_hypercall_pg);
wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
+ hyper_alloc_mmu();
+
/*
* Register Hyper-V specific clocksource.
*/
diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
new file mode 100644
index 0000000..e3ab9b9
--- /dev/null
+++ b/arch/x86/hyperv/mmu.c
@@ -0,0 +1,117 @@
+#include <linux/types.h>
+#include <linux/hyperv.h>
+#include <linux/slab.h>
+#include <linux/log2.h>
+#include <asm/mshyperv.h>
+#include <asm/tlbflush.h>
+#include <asm/msr.h>
+#include <asm/fpu/api.h>
+
+/* HvFlushVirtualAddressSpace, HvFlushVirtualAddressList hypercalls */
+struct hv_flush_pcpu {
+ __u64 address_space;
+ __u64 flags;
+ __u64 processor_mask;
+ __u64 gva_list[];
+};
+
+static struct hv_flush_pcpu __percpu *pcpu_flush;
+
+static void hyperv_flush_tlb_others(const struct cpumask *cpus,
+ struct mm_struct *mm, unsigned long start,
+ unsigned long end)
+{
+ struct hv_flush_pcpu *flush;
+ unsigned long cur, flags;
+ u64 status = -1ULL;
+ int cpu, vcpu, gva_n, max_gvas;
+
+ if (!pcpu_flush || !hv_hypercall_pg)
+ goto do_native;
+
+ if (cpumask_empty(cpus))
+ return;
+
+ local_irq_save(flags);
+
+ flush = this_cpu_ptr(pcpu_flush);
+
+ 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->processor_mask = 0;
+ if (cpumask_equal(cpus, cpu_present_mask)) {
+ flush->flags |= HV_FLUSH_ALL_PROCESSORS;
+ } else {
+ for_each_cpu(cpu, cpus) {
+ vcpu = hv_cpu_number_to_vp_number(cpu);
+ if (vcpu != -1 && vcpu < 64)
+ flush->processor_mask |= 1 << vcpu;
+ else
+ goto do_native;
+ }
+ }
+
+ /*
+ * 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)) / 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_hypercall(HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE,
+ flush, NULL);
+ } else {
+ cur = start;
+ gva_n = 0;
+ 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,
+ gva_n, 0, 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) {
+ pr_info("Hyper-V: Using hypercall for remote TLB flush\n");
+ pv_mmu_ops.flush_tlb_others = hyperv_flush_tlb_others;
+ }
+}
+
+void hyper_alloc_mmu(void)
+{
+ if (ms_hyperv.hints & HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED)
+ pcpu_flush = __alloc_percpu(PAGE_SIZE, PAGE_SIZE);
+}
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index cdf2391..783a8f6 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -311,6 +311,8 @@ static inline int hv_cpu_number_to_vp_number(int cpu_number)
}
void hyperv_init(void);
+void hyperv_setup_mmu_ops(void);
+void hyper_alloc_mmu(void);
void hyperv_report_panic(struct pt_regs *regs);
bool hv_is_hypercall_page_setup(void);
void hyperv_cleanup(void);
@@ -321,6 +323,7 @@ static inline bool hv_is_hypercall_page_setup(void)
return false;
}
static inline hyperv_cleanup(void) {}
+static inline void hyperv_setup_mmu_ops(void) {}
#endif /* CONFIG_HYPERV */
#ifdef CONFIG_HYPERV_TSCPAGE
diff --git a/arch/x86/include/uapi/asm/hyperv.h b/arch/x86/include/uapi/asm/hyperv.h
index c87e900..3d44036 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -239,6 +239,8 @@
(~((1ull << HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT) - 1))
/* Declare the various hypercall operations. */
+#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE 0x0002
+#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST 0x0003
#define HVCALL_NOTIFY_LONG_SPIN_WAIT 0x0008
#define HVCALL_POST_MESSAGE 0x005c
#define HVCALL_SIGNAL_EVENT 0x005d
@@ -256,6 +258,11 @@
#define HV_PROCESSOR_POWER_STATE_C2 2
#define HV_PROCESSOR_POWER_STATE_C3 3
+#define HV_FLUSH_ALL_PROCESSORS 0x00000001
+#define HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES 0x00000002
+#define HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY 0x00000004
+#define HV_FLUSH_USE_EXTENDED_RANGE_FORMAT 0x00000008
+
/* Hypercall interface */
union hv_hypercall_input {
u64 as_uint64;
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index a8b4765..16a9221 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -240,6 +240,7 @@ static void __init ms_hyperv_init_platform(void)
* Setup the hook to get control post apic initialization.
*/
x86_platform.apic_post_init = hyperv_init;
+ hyperv_setup_mmu_ops();
#endif
}
--
2.9.4
[toc] | [prev] | [next] | [standalone]
| From | Vitaly Kuznetsov <vkuznets@redhat.com> |
|---|---|
| Date | 2017-05-24 14:10 +0200 |
| Subject | [PATCH v4 05/10] hyper-v: use fast hypercall for HVCALL_SIGNAL_EVENT |
| Message-ID | <tKDh1-2cD-33@gated-at.bofh.it> |
| In reply to | #1649546 |
We need to pass only 8 bytes of input for HvSignalEvent which makes it a
perfect fit for fast hypercall. hv_input_signal_event_buffer is not needed
any more and hv_input_signal_event is converted to union for convenience.
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Acked-by: K. Y. Srinivasan <kys@microsoft.com>
Tested-by: Simon Xiao <sixiao@microsoft.com>
Tested-by: Srikanth Myakam <v-srm@microsoft.com>
---
drivers/hv/channel_mgmt.c | 15 +++++----------
drivers/hv/connection.c | 3 ++-
include/linux/hyperv.h | 19 ++++++++-----------
3 files changed, 15 insertions(+), 22 deletions(-)
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index 0fabd41..ee2a8dd 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -806,20 +806,15 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr)
/*
* Setup state for signalling the host.
*/
- newchannel->sig_event = (struct hv_input_signal_event *)
- (ALIGN((unsigned long)
- &newchannel->sig_buf,
- HV_HYPERCALL_PARAM_ALIGN));
-
- newchannel->sig_event->connectionid.asu32 = 0;
- newchannel->sig_event->connectionid.u.id = VMBUS_EVENT_CONNECTION_ID;
- newchannel->sig_event->flag_number = 0;
- newchannel->sig_event->rsvdz = 0;
+ newchannel->sig_event.connectionid.asu32 = 0;
+ newchannel->sig_event.connectionid.u.id = VMBUS_EVENT_CONNECTION_ID;
+ newchannel->sig_event.flag_number = 0;
+ newchannel->sig_event.rsvdz = 0;
if (vmbus_proto_version != VERSION_WS2008) {
newchannel->is_dedicated_interrupt =
(offer->is_dedicated_interrupt != 0);
- newchannel->sig_event->connectionid.u.id =
+ newchannel->sig_event.connectionid.u.id =
offer->connection_id;
}
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index 4a0a9f6..51f8cb2 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -408,6 +408,7 @@ void vmbus_set_event(struct vmbus_channel *channel)
if (!channel->is_dedicated_interrupt)
vmbus_send_interrupt(child_relid);
- hv_do_hypercall(HVCALL_SIGNAL_EVENT, channel->sig_event, NULL);
+ hv_do_fast_hypercall8(HVCALL_SIGNAL_EVENT,
+ channel->sig_event.as_uint64);
}
EXPORT_SYMBOL_GPL(vmbus_set_event);
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index d1ae02d..68a5772 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -678,15 +678,13 @@ union hv_connection_id {
};
/* Definition of the hv_signal_event hypercall input structure. */
-struct hv_input_signal_event {
- union hv_connection_id connectionid;
- u16 flag_number;
- u16 rsvdz;
-};
-
-struct hv_input_signal_event_buffer {
- u64 align8;
- struct hv_input_signal_event event;
+union hv_input_signal_event {
+ u64 as_uint64;
+ struct {
+ union hv_connection_id connectionid;
+ u16 flag_number;
+ u16 rsvdz;
+ };
};
enum hv_numa_policy {
@@ -771,8 +769,7 @@ struct vmbus_channel {
} callback_mode;
bool is_dedicated_interrupt;
- struct hv_input_signal_event_buffer sig_buf;
- struct hv_input_signal_event *sig_event;
+ union hv_input_signal_event sig_event;
/*
* Starting with win8, this field will be used to specify
--
2.9.4
[toc] | [prev] | [next] | [standalone]
| From | Andy Shevchenko <andy.shevchenko@gmail.com> |
|---|---|
| Date | 2017-05-27 20:00 +0200 |
| Subject | Re: [PATCH v4 05/10] hyper-v: use fast hypercall for HVCALL_SIGNAL_EVENT |
| Message-ID | <tLOam-7br-7@gated-at.bofh.it> |
| In reply to | #1649556 |
On Wed, May 24, 2017 at 3:04 PM, Vitaly Kuznetsov <vkuznets@redhat.com> wrote:
> We need to pass only 8 bytes of input for HvSignalEvent which makes it a
> perfect fit for fast hypercall. hv_input_signal_event_buffer is not needed
> any more and hv_input_signal_event is converted to union for convenience.
> +union hv_input_signal_event {
Union aliasing is UB. Avoid it for good.
> + u64 as_uint64;
> + struct {
> + union hv_connection_id connectionid;
> + u16 flag_number;
> + u16 rsvdz;
> + };
> };
--
With Best Regards,
Andy Shevchenko
[toc] | [prev] | [next] | [standalone]
| From | Vitaly Kuznetsov <vkuznets@redhat.com> |
|---|---|
| Date | 2017-05-24 14:10 +0200 |
| Subject | [PATCH v4 02/10] x86/hyper-v: stash the max number of virtual/logical processor |
| Message-ID | <tKDh1-2cD-27@gated-at.bofh.it> |
| In reply to | #1649546 |
Max virtual processor will be needed for 'extended' hypercalls supporting
more than 64 vCPUs. While on it, unify on 'Hyper-V' in mshyperv.c as we
currently have a mix, report acquired misc features as well.
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Acked-by: K. Y. Srinivasan <kys@microsoft.com>
Tested-by: Simon Xiao <sixiao@microsoft.com>
Tested-by: Srikanth Myakam <v-srm@microsoft.com>
---
arch/x86/include/asm/mshyperv.h | 2 ++
arch/x86/kernel/cpu/mshyperv.c | 13 ++++++++++---
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 91acec7..d42b6eb 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -29,6 +29,8 @@ struct ms_hyperv_info {
u32 features;
u32 misc_features;
u32 hints;
+ u32 max_vp_index;
+ u32 max_lp_index;
};
extern struct ms_hyperv_info ms_hyperv;
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 04cb8d3..a8b4765 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -175,9 +175,16 @@ static void __init ms_hyperv_init_platform(void)
ms_hyperv.misc_features = cpuid_edx(HYPERV_CPUID_FEATURES);
ms_hyperv.hints = cpuid_eax(HYPERV_CPUID_ENLIGHTMENT_INFO);
- pr_info("HyperV: features 0x%x, hints 0x%x\n",
+ pr_info("Hyper-V: features 0x%x, hints 0x%x\n",
ms_hyperv.features, ms_hyperv.hints);
+ ms_hyperv.max_vp_index = cpuid_eax(HVCPUID_IMPLEMENTATION_LIMITS);
+ ms_hyperv.max_lp_index = cpuid_ebx(HVCPUID_IMPLEMENTATION_LIMITS);
+
+ pr_info("Hyper-V: max %d virtual processors, %d logical processors\n",
+ ms_hyperv.max_vp_index, ms_hyperv.max_lp_index);
+
+
/*
* Extract host information.
*/
@@ -203,7 +210,7 @@ static void __init ms_hyperv_init_platform(void)
rdmsrl(HV_X64_MSR_APIC_FREQUENCY, hv_lapic_frequency);
hv_lapic_frequency = div_u64(hv_lapic_frequency, HZ);
lapic_timer_frequency = hv_lapic_frequency;
- pr_info("HyperV: LAPIC Timer Frequency: %#x\n",
+ pr_info("Hyper-V: LAPIC Timer Frequency: %#x\n",
lapic_timer_frequency);
}
@@ -237,7 +244,7 @@ static void __init ms_hyperv_init_platform(void)
}
const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = {
- .name = "Microsoft HyperV",
+ .name = "Microsoft Hyper-V",
.detect = ms_hyperv_platform,
.init_platform = ms_hyperv_init_platform,
};
--
2.9.4
[toc] | [prev] | [next] | [standalone]
| From | Andy Shevchenko <andy.shevchenko@gmail.com> |
|---|---|
| Date | 2017-05-27 19:50 +0200 |
| Subject | Re: [PATCH v4 02/10] x86/hyper-v: stash the max number of virtual/logical processor |
| Message-ID | <tLO0G-77h-15@gated-at.bofh.it> |
| In reply to | #1649557 |
On Wed, May 24, 2017 at 3:03 PM, Vitaly Kuznetsov <vkuznets@redhat.com> wrote:
> Max virtual processor will be needed for 'extended' hypercalls supporting
> more than 64 vCPUs. While on it, unify on 'Hyper-V' in mshyperv.c as we
> currently have a mix, report acquired misc features as well.
>
> Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
> Acked-by: K. Y. Srinivasan <kys@microsoft.com>
> Tested-by: Simon Xiao <sixiao@microsoft.com>
> Tested-by: Srikanth Myakam <v-srm@microsoft.com>
> + u32 max_vp_index;
> + u32 max_lp_index;
> + pr_info("Hyper-V: max %d virtual processors, %d logical processors\n",
> + ms_hyperv.max_vp_index, ms_hyperv.max_lp_index);
And surprisingly no-one from the above list did not get a warning?!
%u, please.
--
With Best Regards,
Andy Shevchenko
[toc] | [prev] | [next] | [standalone]
| From | Steven Rostedt <rostedt@goodmis.org> |
|---|---|
| Date | 2017-06-05 17:30 +0200 |
| Subject | Re: [PATCH v4 02/10] x86/hyper-v: stash the max number of virtual/logical processor |
| Message-ID | <tP278-4D2-15@gated-at.bofh.it> |
| In reply to | #1651947 |
On Sat, 27 May 2017 20:43:58 +0300
Andy Shevchenko <andy.shevchenko@gmail.com> wrote:
> On Wed, May 24, 2017 at 3:03 PM, Vitaly Kuznetsov <vkuznets@redhat.com> wrote:
> > Max virtual processor will be needed for 'extended' hypercalls supporting
> > more than 64 vCPUs. While on it, unify on 'Hyper-V' in mshyperv.c as we
> > currently have a mix, report acquired misc features as well.
> >
> > Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
> > Acked-by: K. Y. Srinivasan <kys@microsoft.com>
> > Tested-by: Simon Xiao <sixiao@microsoft.com>
> > Tested-by: Srikanth Myakam <v-srm@microsoft.com>
>
> > + u32 max_vp_index;
> > + u32 max_lp_index;
>
> > + pr_info("Hyper-V: max %d virtual processors, %d logical processors\n",
> > + ms_hyperv.max_vp_index, ms_hyperv.max_lp_index);
>
> And surprisingly no-one from the above list did not get a warning?!
Begs to question how many other warnings are they ignoring?
-- Steve
>
> %u, please.
>
[toc] | [prev] | [next] | [standalone]
| From | Stephen Hemminger <stephen@networkplumber.org> |
|---|---|
| Date | 2017-06-05 17:40 +0200 |
| Subject | Re: [PATCH v4 02/10] x86/hyper-v: stash the max number of virtual/logical processor |
| Message-ID | <tP2gO-4G7-5@gated-at.bofh.it> |
| In reply to | #1657668 |
On Mon, 5 Jun 2017 11:24:27 -0400
Steven Rostedt <rostedt@goodmis.org> wrote:
> On Sat, 27 May 2017 20:43:58 +0300
> Andy Shevchenko <andy.shevchenko@gmail.com> wrote:
>
> > On Wed, May 24, 2017 at 3:03 PM, Vitaly Kuznetsov <vkuznets@redhat.com> wrote:
> > > Max virtual processor will be needed for 'extended' hypercalls supporting
> > > more than 64 vCPUs. While on it, unify on 'Hyper-V' in mshyperv.c as we
> > > currently have a mix, report acquired misc features as well.
> > >
> > > Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
> > > Acked-by: K. Y. Srinivasan <kys@microsoft.com>
> > > Tested-by: Simon Xiao <sixiao@microsoft.com>
> > > Tested-by: Srikanth Myakam <v-srm@microsoft.com>
> >
> > > + u32 max_vp_index;
> > > + u32 max_lp_index;
> >
> > > + pr_info("Hyper-V: max %d virtual processors, %d logical processors\n",
> > > + ms_hyperv.max_vp_index, ms_hyperv.max_lp_index);
> >
> > And surprisingly no-one from the above list did not get a warning?!
Gcc 6.3 does not warn when %d is used on unsigned values.
> Begs to question how many other warnings are they ignoring?
None.
[toc] | [prev] | [next] | [standalone]
| From | Vitaly Kuznetsov <vkuznets@redhat.com> |
|---|---|
| Date | 2017-05-24 14:10 +0200 |
| Subject | [PATCH v4 10/10] tracing/hyper-v: trace hyperv_mmu_flush_tlb_others() |
| Message-ID | <tKDh1-2cD-35@gated-at.bofh.it> |
| In reply to | #1649546 |
Add Hyper-V tracing subsystem and trace hyperv_mmu_flush_tlb_others().
Tracing is done the same way we do xen_mmu_flush_tlb_others().
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Acked-by: K. Y. Srinivasan <kys@microsoft.com>
Tested-by: Simon Xiao <sixiao@microsoft.com>
Tested-by: Srikanth Myakam <v-srm@microsoft.com>
---
MAINTAINERS | 1 +
arch/x86/hyperv/mmu.c | 8 ++++++++
arch/x86/include/asm/trace/hyperv.h | 34 ++++++++++++++++++++++++++++++++++
3 files changed, 43 insertions(+)
create mode 100644 arch/x86/include/asm/trace/hyperv.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 9e98464..045e10a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6168,6 +6168,7 @@ M: Stephen Hemminger <sthemmin@microsoft.com>
L: devel@linuxdriverproject.org
S: Maintained
F: arch/x86/include/asm/mshyperv.h
+F: arch/x86/include/asm/trace/hyperv.h
F: arch/x86/include/uapi/asm/hyperv.h
F: arch/x86/kernel/cpu/mshyperv.c
F: arch/x86/hyperv
diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
index c9cecb3..f6b5211 100644
--- a/arch/x86/hyperv/mmu.c
+++ b/arch/x86/hyperv/mmu.c
@@ -6,6 +6,10 @@
#include <asm/tlbflush.h>
#include <asm/msr.h>
#include <asm/fpu/api.h>
+#include <asm/trace/hyperv.h>
+
+#define CREATE_TRACE_POINTS
+DEFINE_TRACE(hyperv_mmu_flush_tlb_others);
/* HvFlushVirtualAddressSpace, HvFlushVirtualAddressList hypercalls */
struct hv_flush_pcpu {
@@ -75,6 +79,8 @@ static void hyperv_flush_tlb_others(const struct cpumask *cpus,
u64 status = -1ULL;
int cpu, vcpu, gva_n, max_gvas;
+ trace_hyperv_mmu_flush_tlb_others(cpus, mm, start, end);
+
if (!pcpu_flush || !hv_hypercall_pg)
goto do_native;
@@ -161,6 +167,8 @@ static void hyperv_flush_tlb_others_ex(const struct cpumask *cpus,
u64 status = -1ULL;
int nr_bank = 0, max_gvas, gva_n;
+ trace_hyperv_mmu_flush_tlb_others(cpus, mm, start, end);
+
if (!pcpu_flush_ex || !hv_hypercall_pg)
goto do_native;
diff --git a/arch/x86/include/asm/trace/hyperv.h b/arch/x86/include/asm/trace/hyperv.h
new file mode 100644
index 0000000..e46a351
--- /dev/null
+++ b/arch/x86/include/asm/trace/hyperv.h
@@ -0,0 +1,34 @@
+#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_others,
+ TP_PROTO(const struct cpumask *cpus, struct mm_struct *mm,
+ unsigned long addr, unsigned long end),
+ TP_ARGS(cpus, mm, addr, end),
+ 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 = mm;
+ __entry->addr = addr,
+ __entry->end = end),
+ TP_printk("ncpus %d mm %p addr %lx, end %lx",
+ __entry->ncpus, __entry->mm, __entry->addr, __entry->end)
+ );
+
+#endif /* CONFIG_HYPERV */
+
+#endif /* _TRACE_HYPERV_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
--
2.9.4
[toc] | [prev] | [next] | [standalone]
| From | Steven Rostedt <rostedt@goodmis.org> |
|---|---|
| Date | 2017-06-05 18:00 +0200 |
| Subject | Re: [PATCH v4 10/10] tracing/hyper-v: trace hyperv_mmu_flush_tlb_others() |
| Message-ID | <tP2A9-4My-3@gated-at.bofh.it> |
| In reply to | #1649558 |
On Wed, 24 May 2017 14:04:05 +0200
Vitaly Kuznetsov <vkuznets@redhat.com> wrote:
> Add Hyper-V tracing subsystem and trace hyperv_mmu_flush_tlb_others().
> Tracing is done the same way we do xen_mmu_flush_tlb_others().
>
> Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
> Acked-by: K. Y. Srinivasan <kys@microsoft.com>
> Tested-by: Simon Xiao <sixiao@microsoft.com>
> Tested-by: Srikanth Myakam <v-srm@microsoft.com>
> ---
> MAINTAINERS | 1 +
> arch/x86/hyperv/mmu.c | 8 ++++++++
> arch/x86/include/asm/trace/hyperv.h | 34 ++++++++++++++++++++++++++++++++++
> 3 files changed, 43 insertions(+)
> create mode 100644 arch/x86/include/asm/trace/hyperv.h
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 9e98464..045e10a 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -6168,6 +6168,7 @@ M: Stephen Hemminger <sthemmin@microsoft.com>
> L: devel@linuxdriverproject.org
> S: Maintained
> F: arch/x86/include/asm/mshyperv.h
> +F: arch/x86/include/asm/trace/hyperv.h
> F: arch/x86/include/uapi/asm/hyperv.h
> F: arch/x86/kernel/cpu/mshyperv.c
> F: arch/x86/hyperv
> diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
> index c9cecb3..f6b5211 100644
> --- a/arch/x86/hyperv/mmu.c
> +++ b/arch/x86/hyperv/mmu.c
> @@ -6,6 +6,10 @@
> #include <asm/tlbflush.h>
> #include <asm/msr.h>
> #include <asm/fpu/api.h>
> +#include <asm/trace/hyperv.h>
> +
> +#define CREATE_TRACE_POINTS
> +DEFINE_TRACE(hyperv_mmu_flush_tlb_others);
The above looks very wrong. Why are you using "DEFINE_TRACE()" here?
The typical case is:
#define CREATE_TRACE_POINTS
#include <asm/trace/hyperv.h>
Does your patch even work?
-- Steve
>
> /* HvFlushVirtualAddressSpace, HvFlushVirtualAddressList hypercalls */
> struct hv_flush_pcpu {
> @@ -75,6 +79,8 @@ static void hyperv_flush_tlb_others(const struct cpumask *cpus,
> u64 status = -1ULL;
> int cpu, vcpu, gva_n, max_gvas;
>
> + trace_hyperv_mmu_flush_tlb_others(cpus, mm, start, end);
> +
> if (!pcpu_flush || !hv_hypercall_pg)
> goto do_native;
>
> @@ -161,6 +167,8 @@ static void hyperv_flush_tlb_others_ex(const struct cpumask *cpus,
> u64 status = -1ULL;
> int nr_bank = 0, max_gvas, gva_n;
>
> + trace_hyperv_mmu_flush_tlb_others(cpus, mm, start, end);
> +
> if (!pcpu_flush_ex || !hv_hypercall_pg)
> goto do_native;
>
> diff --git a/arch/x86/include/asm/trace/hyperv.h b/arch/x86/include/asm/trace/hyperv.h
> new file mode 100644
> index 0000000..e46a351
> --- /dev/null
> +++ b/arch/x86/include/asm/trace/hyperv.h
> @@ -0,0 +1,34 @@
> +#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_others,
> + TP_PROTO(const struct cpumask *cpus, struct mm_struct *mm,
> + unsigned long addr, unsigned long end),
> + TP_ARGS(cpus, mm, addr, end),
> + 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 = mm;
> + __entry->addr = addr,
> + __entry->end = end),
> + TP_printk("ncpus %d mm %p addr %lx, end %lx",
> + __entry->ncpus, __entry->mm, __entry->addr, __entry->end)
> + );
> +
> +#endif /* CONFIG_HYPERV */
> +
> +#endif /* _TRACE_HYPERV_H */
> +
> +/* This part must be outside protection */
> +#include <trace/define_trace.h>
[toc] | [prev] | [next] | [standalone]
| From | Vitaly Kuznetsov <vkuznets@redhat.com> |
|---|---|
| Date | 2017-06-05 18:20 +0200 |
| Subject | Re: [PATCH v4 10/10] tracing/hyper-v: trace hyperv_mmu_flush_tlb_others() |
| Message-ID | <tP2Ty-59z-59@gated-at.bofh.it> |
| In reply to | #1657683 |
Steven Rostedt <rostedt@goodmis.org> writes:
> On Wed, 24 May 2017 14:04:05 +0200
> Vitaly Kuznetsov <vkuznets@redhat.com> wrote:
>
>> Add Hyper-V tracing subsystem and trace hyperv_mmu_flush_tlb_others().
>> Tracing is done the same way we do xen_mmu_flush_tlb_others().
>>
>> Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
>> Acked-by: K. Y. Srinivasan <kys@microsoft.com>
>> Tested-by: Simon Xiao <sixiao@microsoft.com>
>> Tested-by: Srikanth Myakam <v-srm@microsoft.com>
>> ---
>> MAINTAINERS | 1 +
>> arch/x86/hyperv/mmu.c | 8 ++++++++
>> arch/x86/include/asm/trace/hyperv.h | 34 ++++++++++++++++++++++++++++++++++
>> 3 files changed, 43 insertions(+)
>> create mode 100644 arch/x86/include/asm/trace/hyperv.h
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 9e98464..045e10a 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -6168,6 +6168,7 @@ M: Stephen Hemminger <sthemmin@microsoft.com>
>> L: devel@linuxdriverproject.org
>> S: Maintained
>> F: arch/x86/include/asm/mshyperv.h
>> +F: arch/x86/include/asm/trace/hyperv.h
>> F: arch/x86/include/uapi/asm/hyperv.h
>> F: arch/x86/kernel/cpu/mshyperv.c
>> F: arch/x86/hyperv
>> diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
>> index c9cecb3..f6b5211 100644
>> --- a/arch/x86/hyperv/mmu.c
>> +++ b/arch/x86/hyperv/mmu.c
>> @@ -6,6 +6,10 @@
>> #include <asm/tlbflush.h>
>> #include <asm/msr.h>
>> #include <asm/fpu/api.h>
>> +#include <asm/trace/hyperv.h>
>> +
>> +#define CREATE_TRACE_POINTS
>> +DEFINE_TRACE(hyperv_mmu_flush_tlb_others);
>
> The above looks very wrong. Why are you using "DEFINE_TRACE()" here?
>
> The typical case is:
>
> #define CREATE_TRACE_POINTS
> #include <asm/trace/hyperv.h>
>
I probably got the idea wrong from Documentation/trace/tracepoints.txt:
"In subsys/file.c (where the tracing statement must be added) :
#include <trace/events/subsys.h>
#define CREATE_TRACE_POINTS
DEFINE_TRACE(subsys_eventname);
void somefct(void)
{
...
trace_subsys_eventname(arg, task);
...
}
"
> Does your patch even work?
>
I'm pretty sure I tested tracing this even before sending v2 of this
series, I'll retest before sending v7.
> -- Steve
>
>>
>> /* HvFlushVirtualAddressSpace, HvFlushVirtualAddressList hypercalls */
>> struct hv_flush_pcpu {
>> @@ -75,6 +79,8 @@ static void hyperv_flush_tlb_others(const struct cpumask *cpus,
>> u64 status = -1ULL;
>> int cpu, vcpu, gva_n, max_gvas;
>>
>> + trace_hyperv_mmu_flush_tlb_others(cpus, mm, start, end);
>> +
>> if (!pcpu_flush || !hv_hypercall_pg)
>> goto do_native;
>>
>> @@ -161,6 +167,8 @@ static void hyperv_flush_tlb_others_ex(const struct cpumask *cpus,
>> u64 status = -1ULL;
>> int nr_bank = 0, max_gvas, gva_n;
>>
>> + trace_hyperv_mmu_flush_tlb_others(cpus, mm, start, end);
>> +
>> if (!pcpu_flush_ex || !hv_hypercall_pg)
>> goto do_native;
>>
>> diff --git a/arch/x86/include/asm/trace/hyperv.h b/arch/x86/include/asm/trace/hyperv.h
>> new file mode 100644
>> index 0000000..e46a351
>> --- /dev/null
>> +++ b/arch/x86/include/asm/trace/hyperv.h
>> @@ -0,0 +1,34 @@
>> +#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_others,
>> + TP_PROTO(const struct cpumask *cpus, struct mm_struct *mm,
>> + unsigned long addr, unsigned long end),
>> + TP_ARGS(cpus, mm, addr, end),
>> + 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 = mm;
>> + __entry->addr = addr,
>> + __entry->end = end),
>> + TP_printk("ncpus %d mm %p addr %lx, end %lx",
>> + __entry->ncpus, __entry->mm, __entry->addr, __entry->end)
>> + );
>> +
>> +#endif /* CONFIG_HYPERV */
>> +
>> +#endif /* _TRACE_HYPERV_H */
>> +
>> +/* This part must be outside protection */
>> +#include <trace/define_trace.h>
--
Vitaly
[toc] | [prev] | [next] | [standalone]
| From | Steven Rostedt <rostedt@goodmis.org> |
|---|---|
| Date | 2017-06-07 16:00 +0200 |
| Subject | Re: [PATCH v4 10/10] tracing/hyper-v: trace hyperv_mmu_flush_tlb_others() |
| Message-ID | <tPJF7-7mI-15@gated-at.bofh.it> |
| In reply to | #1657716 |
On Mon, 05 Jun 2017 18:19:08 +0200
Vitaly Kuznetsov <vkuznets@redhat.com> wrote:
> Steven Rostedt <rostedt@goodmis.org> writes:
>
> > On Wed, 24 May 2017 14:04:05 +0200
> > Vitaly Kuznetsov <vkuznets@redhat.com> wrote:
> >
> >> Add Hyper-V tracing subsystem and trace hyperv_mmu_flush_tlb_others().
> >> Tracing is done the same way we do xen_mmu_flush_tlb_others().
> >>
> >> Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
> >> Acked-by: K. Y. Srinivasan <kys@microsoft.com>
> >> Tested-by: Simon Xiao <sixiao@microsoft.com>
> >> Tested-by: Srikanth Myakam <v-srm@microsoft.com>
> >> ---
> >> MAINTAINERS | 1 +
> >> arch/x86/hyperv/mmu.c | 8 ++++++++
> >> arch/x86/include/asm/trace/hyperv.h | 34 ++++++++++++++++++++++++++++++++++
> >> 3 files changed, 43 insertions(+)
> >> create mode 100644 arch/x86/include/asm/trace/hyperv.h
> >>
> >> diff --git a/MAINTAINERS b/MAINTAINERS
> >> index 9e98464..045e10a 100644
> >> --- a/MAINTAINERS
> >> +++ b/MAINTAINERS
> >> @@ -6168,6 +6168,7 @@ M: Stephen Hemminger <sthemmin@microsoft.com>
> >> L: devel@linuxdriverproject.org
> >> S: Maintained
> >> F: arch/x86/include/asm/mshyperv.h
> >> +F: arch/x86/include/asm/trace/hyperv.h
> >> F: arch/x86/include/uapi/asm/hyperv.h
> >> F: arch/x86/kernel/cpu/mshyperv.c
> >> F: arch/x86/hyperv
> >> diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
> >> index c9cecb3..f6b5211 100644
> >> --- a/arch/x86/hyperv/mmu.c
> >> +++ b/arch/x86/hyperv/mmu.c
> >> @@ -6,6 +6,10 @@
> >> #include <asm/tlbflush.h>
> >> #include <asm/msr.h>
> >> #include <asm/fpu/api.h>
> >> +#include <asm/trace/hyperv.h>
> >> +
> >> +#define CREATE_TRACE_POINTS
> >> +DEFINE_TRACE(hyperv_mmu_flush_tlb_others);
> >
> > The above looks very wrong. Why are you using "DEFINE_TRACE()" here?
> >
> > The typical case is:
> >
> > #define CREATE_TRACE_POINTS
> > #include <asm/trace/hyperv.h>
> >
>
> I probably got the idea wrong from Documentation/trace/tracepoints.txt:
Bah! I never was Cc'd on that file. It's totally wrong. Thanks for
pointing that out.
Ah, it was written when we had hard coded tracepoints, that use to do
that. It's very out of date, and still incorrect.
I'll send a patch to fix it.
>
> "In subsys/file.c (where the tracing statement must be added) :
>
> #include <trace/events/subsys.h>
>
> #define CREATE_TRACE_POINTS
> DEFINE_TRACE(subsys_eventname);
>
> void somefct(void)
> {
> ...
> trace_subsys_eventname(arg, task);
> ...
> }
> "
>
> > Does your patch even work?
> >
>
> I'm pretty sure I tested tracing this even before sending v2 of this
> series, I'll retest before sending v7.
Even if it does work, it's still fragile as it uses an
no-longer-supported framework.
-- Steve
> >
> >>
> >> /* HvFlushVirtualAddressSpace, HvFlushVirtualAddressList hypercalls */
> >> struct hv_flush_pcpu {
> >> @@ -75,6 +79,8 @@ static void hyperv_flush_tlb_others(const struct cpumask *cpus,
> >> u64 status = -1ULL;
> >> int cpu, vcpu, gva_n, max_gvas;
> >>
> >> + trace_hyperv_mmu_flush_tlb_others(cpus, mm, start, end);
> >> +
> >> if (!pcpu_flush || !hv_hypercall_pg)
> >> goto do_native;
> >>
> >> @@ -161,6 +167,8 @@ static void hyperv_flush_tlb_others_ex(const struct cpumask *cpus,
> >> u64 status = -1ULL;
> >> int nr_bank = 0, max_gvas, gva_n;
> >>
> >> + trace_hyperv_mmu_flush_tlb_others(cpus, mm, start, end);
> >> +
> >> if (!pcpu_flush_ex || !hv_hypercall_pg)
> >> goto do_native;
> >>
> >> diff --git a/arch/x86/include/asm/trace/hyperv.h b/arch/x86/include/asm/trace/hyperv.h
> >> new file mode 100644
> >> index 0000000..e46a351
> >> --- /dev/null
> >> +++ b/arch/x86/include/asm/trace/hyperv.h
> >> @@ -0,0 +1,34 @@
> >> +#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_others,
> >> + TP_PROTO(const struct cpumask *cpus, struct mm_struct *mm,
> >> + unsigned long addr, unsigned long end),
> >> + TP_ARGS(cpus, mm, addr, end),
> >> + 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 = mm;
> >> + __entry->addr = addr,
> >> + __entry->end = end),
> >> + TP_printk("ncpus %d mm %p addr %lx, end %lx",
> >> + __entry->ncpus, __entry->mm, __entry->addr, __entry->end)
> >> + );
> >> +
> >> +#endif /* CONFIG_HYPERV */
> >> +
> >> +#endif /* _TRACE_HYPERV_H */
> >> +
> >> +/* This part must be outside protection */
> >> +#include <trace/define_trace.h>
>
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | linux.kernel
csiph-web