From: Sean Christopherson <seanjc@google.com>
To: Reinette Chatre <reinette.chatre@intel.com>
Cc: isaku.yamahata@intel.com, pbonzini@redhat.com,
erdemaktas@google.com, vkuznets@redhat.com,
vannapurve@google.com, jmattson@google.com, mlevitsk@redhat.com,
xiaoyao.li@intel.com, chao.gao@intel.com,
rick.p.edgecombe@intel.com, yuan.yao@intel.com,
kvm@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH V9 2/2] KVM: selftests: Add test for configure of x86 APIC bus frequency
Date: Fri, 28 Jun 2024 15:50:51 -0700 [thread overview]
Message-ID: <Zn8-S-QFSzm8du90@google.com> (raw)
In-Reply-To: <2fccf35715b5ba8aec5e5708d86ad7015b8d74e6.1718214999.git.reinette.chatre@intel.com>
On Wed, Jun 12, 2024, Reinette Chatre wrote:
> +/*
> + * Pick 25MHz for APIC bus frequency. Different enough from the default 1GHz.
> + * User can override via command line.
> + */
> +static uint64_t apic_hz = 25 * 1000 * 1000;
> +
> +/*
> + * Delay in msec that guest uses to determine APIC bus frequency.
> + * User can override via command line.
> + */
> +static unsigned long delay_ms = 100;
There's no need for these to be global, it's easy enough to pass them as params
to apic_guest_code(). Making is_x2apic is wortwhile as it cuts down on the noise,
but for these, I think it's better to keep them local.
> +
> +/*
> + * Possible TDCR values with matching divide count. Used to modify APIC
> + * timer frequency.
> + */
> +static struct {
> + uint32_t tdcr;
> + uint32_t divide_count;
These can/should all be const.
> +} tdcrs[] = {
> + {0x0, 2},
> + {0x1, 4},
> + {0x2, 8},
> + {0x3, 16},
> + {0x8, 32},
> + {0x9, 64},
> + {0xa, 128},
> + {0xb, 1},
> +};
> +
> +/* true if x2APIC test is running, false if xAPIC test is running. */
> +static bool is_x2apic;
> +
> +static void apic_enable(void)
> +{
> + if (is_x2apic)
> + x2apic_enable();
> + else
> + xapic_enable();
> +}
> +
> +static uint32_t apic_read_reg(unsigned int reg)
> +{
> + return is_x2apic ? x2apic_read_reg(reg) : xapic_read_reg(reg);
> +}
> +
> +static void apic_write_reg(unsigned int reg, uint32_t val)
> +{
> + if (is_x2apic)
> + x2apic_write_reg(reg, val);
> + else
> + xapic_write_reg(reg, val);
> +}
> +
> +static void apic_guest_code(void)
> +{
> + uint64_t tsc_hz = (uint64_t)tsc_khz * 1000;
> + const uint32_t tmict = ~0u;
> + uint64_t tsc0, tsc1, freq;
> + uint32_t tmcct;
> + int i;
> +
> + apic_enable();
> +
> + /*
> + * Setup one-shot timer. The vector does not matter because the
> + * interrupt should not fire.
> + */
> + apic_write_reg(APIC_LVTT, APIC_LVT_TIMER_ONESHOT | APIC_LVT_MASKED);
> +
> + for (i = 0; i < ARRAY_SIZE(tdcrs); i++) {
> +
> + apic_write_reg(APIC_TDCR, tdcrs[i].tdcr);
> + apic_write_reg(APIC_TMICT, tmict);
> +
> + tsc0 = rdtsc();
> + udelay(delay_ms * 1000);
> + tmcct = apic_read_reg(APIC_TMCCT);
> + tsc1 = rdtsc();
> +
> + /*
> + * Stop the timer _after_ reading the current, final count, as
> + * writing the initial counter also modifies the current count.
> + */
> + apic_write_reg(APIC_TMICT, 0);
> +
> + freq = (tmict - tmcct) * tdcrs[i].divide_count * tsc_hz / (tsc1 - tsc0);
> + /* Check if measured frequency is within 1% of configured frequency. */
1% is likely too aggressive, i.e. we'll get false failures due to host activity.
On our systems, even a single pr_warn() in the timer path causes failure. For
now, I think 5% is good enough, e.g. it'll catch cases where KVM is waaay off.
If we want to do better (or that's still too tight), then we can add a '-t <tolerance'
param or something.
> + GUEST_ASSERT(freq < apic_hz * 101 / 100);
> + GUEST_ASSERT(freq > apic_hz * 99 / 100);
Combine these into a single assert, and print the params, i.e. don't rely on the
line number to figure out what's up.
__GUEST_ASSERT(freq < apic_hz * 105 / 100 && freq > apic_hz * 95 / 100,
"Frequency = %lu (wanted %lu - %lu), bus = %lu, div = %u, tsc = %lu",
freq, apic_hz * 95 / 100, apic_hz * 105 / 100,
apic_hz, tdcrs[i].divide_count, tsc_hz);
> +int main(int argc, char *argv[])
> +{
> + int opt;
> +
> + TEST_REQUIRE(kvm_has_cap(KVM_CAP_X86_APIC_BUS_CYCLES_NS));
> +
> + while ((opt = getopt(argc, argv, "d:f:h")) != -1) {
> + switch (opt) {
> + case 'f':
> + apic_hz = atol(optarg);
> + break;
> + case 'd':
> + delay_ms = atol(optarg);
> + break;
> + case 'h':
> + help(argv[0]);
> + exit(0);
> + default:
> + help(argv[0]);
> + exit(1);
Heh, selftests are anything but consistent, but this should be exit(KSFT_SKIP)
for both.
> + }
> + }
> +
> + run_apic_bus_clock_test(false);
> + run_apic_bus_clock_test(true);
> +}
> --
> 2.34.1
>
next prev parent reply other threads:[~2024-06-28 22:50 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-12 18:16 [PATCH V9 0/2] KVM: x86: Make bus clock frequency for vAPIC timer configurable Reinette Chatre
2024-06-12 18:16 ` [PATCH V9 1/2] KVM: selftests: Add x86_64 guest udelay() utility Reinette Chatre
2024-06-28 22:46 ` Sean Christopherson
2024-06-12 18:16 ` [PATCH V9 2/2] KVM: selftests: Add test for configure of x86 APIC bus frequency Reinette Chatre
2024-06-28 22:50 ` Sean Christopherson [this message]
2024-06-29 0:39 ` VMX Preemption Timer appears to be buggy on SKX, CLX, and ICX Sean Christopherson
2024-07-03 20:14 ` Reinette Chatre
2024-07-03 21:37 ` Reinette Chatre
2024-07-08 5:55 ` Yuan Yao
2026-05-13 1:31 ` Chao Gao
2026-05-14 21:09 ` Sean Christopherson
2026-05-15 6:34 ` Chao Gao
2024-06-28 22:55 ` [PATCH V9 0/2] KVM: x86: Make bus clock frequency for vAPIC timer configurable Sean Christopherson
2024-06-29 0:10 ` Reinette Chatre
2024-07-10 15:42 ` Sean Christopherson
2024-07-10 17:14 ` Reinette Chatre
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Zn8-S-QFSzm8du90@google.com \
--to=seanjc@google.com \
--cc=chao.gao@intel.com \
--cc=erdemaktas@google.com \
--cc=isaku.yamahata@intel.com \
--cc=jmattson@google.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mlevitsk@redhat.com \
--cc=pbonzini@redhat.com \
--cc=reinette.chatre@intel.com \
--cc=rick.p.edgecombe@intel.com \
--cc=vannapurve@google.com \
--cc=vkuznets@redhat.com \
--cc=xiaoyao.li@intel.com \
--cc=yuan.yao@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.