Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1571259 > unrolled thread
| Started by | Robert O'Callahan <robert@ocallahan.org> |
|---|---|
| First post | 2017-02-01 05:10 +0100 |
| Last post | 2017-02-01 05:10 +0100 |
| Articles | 2 — 1 participant |
Back to article view | Back to linux.kernel
[PATCH v2 00/01] KVM: x86: never specify a sample period for virtualized in_tx_cp counters Robert O'Callahan <robert@ocallahan.org> - 2017-02-01 05:10 +0100
[PATCH v2 01/01] KVM: x86: never specify a sample period for virtualized in_tx_cp counters Robert O'Callahan <robert@ocallahan.org> - 2017-02-01 05:10 +0100
| From | Robert O'Callahan <robert@ocallahan.org> |
|---|---|
| Date | 2017-02-01 05:10 +0100 |
| Subject | [PATCH v2 00/01] KVM: x86: never specify a sample period for virtualized in_tx_cp counters |
| Message-ID | <t5Up3-14l-1@gated-at.bofh.it> |
Changes in version 2:
- Fixed block comment formatting as requested by Ingo Molnar
- Changed commit summary to refer to a testcase that more easily shows the
problem.
For reference here's a complete testcase for an Intel TSX-enabled KVM guest:
#include <linux/perf_event.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/syscall.h>
#include <unistd.h>
int main(void) {
struct perf_event_attr attr;
int fd;
long long count;
memset(&attr, 0, sizeof(attr));
attr.type = PERF_TYPE_RAW;
attr.size = sizeof(attr);
attr.config = 0x2005101c4; // conditional branches retired IN_TXCP
attr.sample_period = 0;
attr.exclude_kernel = 1;
attr.exclude_guest = 1;
fd = syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0);
ioctl(fd, PERF_EVENT_IOC_DISABLE, 0);
ioctl(fd, PERF_EVENT_IOC_ENABLE, 0);
for (int i = 0; i < 500; ++i) {
putchar('.');
}
read(fd, &count, sizeof(count));
printf("\nConditional branches: %lld\n%s\n", count,
count < 500 ? "FAILED" : "PASSED");
return 0;
}
Robert O'Callahan (1):
KVM: x86: never specify a sample period for virtualized in_tx_cp
counters
arch/x86/kvm/pmu.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
--
2.9.3
[toc] | [next] | [standalone]
| From | Robert O'Callahan <robert@ocallahan.org> |
|---|---|
| Date | 2017-02-01 05:10 +0100 |
| Subject | [PATCH v2 01/01] KVM: x86: never specify a sample period for virtualized in_tx_cp counters |
| Message-ID | <t5Up3-14l-3@gated-at.bofh.it> |
| In reply to | #1571259 |
pmc_reprogram_counter() always sets a sample period based on the value of
pmc->counter. However, hsw_hw_config() rejects sample periods less than
2^31 - 1. So for example, if a KVM guest does
struct perf_event_attr attr;
memset(&attr, 0, sizeof(attr));
attr.type = PERF_TYPE_RAW;
attr.size = sizeof(attr);
attr.config = 0x2005101c4; // conditional branches retired IN_TXCP
attr.sample_period = 0;
int fd = syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0);
ioctl(fd, PERF_EVENT_IOC_DISABLE, 0);
ioctl(fd, PERF_EVENT_IOC_ENABLE, 0);
the guest kernel counts some conditional branch events, then updates the
virtual PMU register with a nonzero count. The host reaches
pmc_reprogram_counter() with nonzero pmc->counter, triggers EOPNOTSUPP
in hsw_hw_config(), prints "kvm_pmu: event creation failed" in
pmc_reprogram_counter(), and silently (from the guest's point of view) stops
counting events.
We fix event counting by forcing attr.sample_period to always be zero for
in_tx_cp counters. Sampling doesn't work, but it already didn't work and
can't be fixed without major changes to the approach in hsw_hw_config().
Signed-off-by: Robert O'Callahan <robert@ocallahan.org>
---
arch/x86/kvm/pmu.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index 06ce377..026db42 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -113,12 +113,19 @@ static void pmc_reprogram_counter(struct kvm_pmc *pmc, u32 type,
.config = config,
};
+ attr.sample_period = (-pmc->counter) & pmc_bitmask(pmc);
+
if (in_tx)
attr.config |= HSW_IN_TX;
- if (in_tx_cp)
+ if (in_tx_cp) {
+ /*
+ * HSW_IN_TX_CHECKPOINTED is not supported with nonzero
+ * period. Just clear the sample period so at least
+ * allocating the counter doesn't fail.
+ */
+ attr.sample_period = 0;
attr.config |= HSW_IN_TX_CHECKPOINTED;
-
- attr.sample_period = (-pmc->counter) & pmc_bitmask(pmc);
+ }
event = perf_event_create_kernel_counter(&attr, -1, current,
intr ? kvm_perf_overflow_intr :
--
2.9.3
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web