Received: by 2002:a05:6a10:413:0:0:0:0 with SMTP id 19csp2974588pxp; Tue, 8 Mar 2022 05:38:01 -0800 (PST) X-Google-Smtp-Source: ABdhPJyc/kP2hS1B/Hj+pDaXvUsewi3ZCAUuXQmu/QQ4TpsombdLhq+7+2pomnuFxwy+2oq/H+rV X-Received: by 2002:a17:90a:8595:b0:1bf:4592:a819 with SMTP id m21-20020a17090a859500b001bf4592a819mr4654711pjn.183.1646746680792; Tue, 08 Mar 2022 05:38:00 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1646746680; cv=none; d=google.com; s=arc-20160816; b=rlA3FaNAGhXEJZ9zdkzE0EM9lt0aaqmIIshW/jbHEEXxBgYTiHr6fmlfst34JlYnL+ kjDEjWGzl/KUS2OlaoSuRtj1vf2Z7c2NXUcZj3AJjhRLfOpff/zr6umyF5AkFc8Dal7e Q1ADluTZl9wzbDwgY2/p3JjZrahDB9yS+PM4wXD+0wLZzukJ6Vq1hN5uLkLNccX+/Vz0 khRcBPRr6+/g+GVQNeNxpW3oD7mL/T5C12Glhp6ko38NElHswFDthPNfLM64uPchTrWG AWQL0wft7SVyUJf/89j2JoOpt430TxVbclsnavCcozKnH3E9Xwk87wfbrn8WQSrFL8Q/ zf1g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:dkim-signature; bh=ijc7GxRXdA+HmfzmTLANOZDH8XL9NNAM8VDg2IQJGx0=; b=tGOMXC1gVkYlXcjFvyCsCrsTcw7tJfRUTcEN7RJjqUjmouf6DeM098I/UFK3FkOPyQ Sc5H6x2me1hgP/c4yhpFMc/UNjr0/GLXRZIGsNX6gfS8n6hVdQB2kqnxE0FqU468Rhit B2Dpf7vDNIdzZ1XD5Fj1KYuG0gGu4VYmKDXL3FORqe1p168T5eyw6Ue3KSdhVqOMxmS6 8YqCKkVaztb4hzNcdsHthEOhkR4xsIv9XA0GW2/s6mwuzfEprS3KraJ5TjsKA+XTlJ2N J5MnHiKCGnrY39wIorcOnLj0vADDwIe6l0ZpysiFBp47Xwl51B5ZZaqMa5BTdPeuzFaW ioxg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=a0E3weZ9; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id u190-20020a6385c7000000b00380a9b0136bsi268258pgd.396.2022.03.08.05.37.43; Tue, 08 Mar 2022 05:38:00 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=a0E3weZ9; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238444AbiCHAiH (ORCPT + 99 others); Mon, 7 Mar 2022 19:38:07 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48034 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230263AbiCHAiG (ORCPT ); Mon, 7 Mar 2022 19:38:06 -0500 Received: from mail-oo1-xc32.google.com (mail-oo1-xc32.google.com [IPv6:2607:f8b0:4864:20::c32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E433B3B3CA for ; Mon, 7 Mar 2022 16:37:09 -0800 (PST) Received: by mail-oo1-xc32.google.com with SMTP id n5-20020a4a9545000000b0031d45a442feso20070699ooi.3 for ; Mon, 07 Mar 2022 16:37:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=ijc7GxRXdA+HmfzmTLANOZDH8XL9NNAM8VDg2IQJGx0=; b=a0E3weZ9V8rChd7Z36FqSqgw4r/K94i1aMcmm0f7yN1diV+6YgWZSKihyzekXug7Vh OQKHuPZ9RZZhldYbxYXNihh3ghZLaP9xbD/0jH1lOkRy2pbIhr0FA/bKHwRXEDHMKxev HOrt4gcnRT0u+/vlRLZE0NjfI9uZtoF6CzZXM0sGWkFMUyJhcro/BaSdt2kFpQpubWBQ mv1DDpJjG9/tTpmwZBHdzuh0mZz6BE4Ee3CYEQj6sZOryQqmlL1qMkPNAkzlY6KBa0Lo L3z5HjJTwT0IIFxG5LMnxcgwqwDUVrGFJIq6ufs8yk7dUKZpUAL+3gudRiRTUdNFEZAu aUZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=ijc7GxRXdA+HmfzmTLANOZDH8XL9NNAM8VDg2IQJGx0=; b=0ZCk6YNt2fnLocv1cF6IbOnl9OuEltehKzhCTyCQSHd4sie0MsSG+jKXOx+svz1Uw9 DhwkKZ8VIqe/V5qVeP+G8Nj2L3BkYCBtBYIX9kMTnxpBj0mf43pmoLdylVZI1G1eTLRx iPT50A+ll9s5AGZ9bTrBhm3NYGQmamfAAmbKfu09I/VSjySAp1kcVPfJoN4nGeQ4Dmkv ZBThp8b+JMuzvw+LlizIet52FKMa7mKhSSwZn3epo4maarlkz0HEtbBo8lovK0ZmkjIv 9gmJqfZNQsU8PBhHSl2XZHklabfD9JEBDLMtfcMprj31pPlyqLoECwgOrLbspIlCrrav 7iUg== X-Gm-Message-State: AOAM531li8YlRTXvv3IfVXz+yuBoTvlluzytJ4i0fiKfhljVZz88zSsH tS4cAegh71P9z1iFa5Lua30Eqi9x2Nk8u//cNUqJTw== X-Received: by 2002:a05:6870:1041:b0:d3:521b:f78a with SMTP id 1-20020a056870104100b000d3521bf78amr945118oaj.13.1646699828901; Mon, 07 Mar 2022 16:37:08 -0800 (PST) MIME-Version: 1.0 References: <20220302111334.12689-1-likexu@tencent.com> <20220302111334.12689-8-likexu@tencent.com> In-Reply-To: <20220302111334.12689-8-likexu@tencent.com> From: Jim Mattson Date: Mon, 7 Mar 2022 16:36:57 -0800 Message-ID: Subject: Re: [PATCH v2 07/12] KVM: x86/pmu: Use PERF_TYPE_RAW to merge reprogram_{gp, fixed}counter() To: Like Xu Cc: Paolo Bonzini , kvm@vger.kernel.org, Sean Christopherson , Wanpeng Li , Vitaly Kuznetsov , Joerg Roedel , linux-kernel@vger.kernel.org, Like Xu , Peter Zijlstra Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-17.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, ENV_AND_HDR_SPF_MATCH,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE,USER_IN_DEF_DKIM_WL,USER_IN_DEF_SPF_WL autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Mar 2, 2022 at 3:14 AM Like Xu wrote: > > From: Like Xu > > The code sketch for reprogram_{gp, fixed}_counter() is similar, while the > fixed counter using the PERF_TYPE_HARDWAR type and the gp being > able to use either PERF_TYPE_HARDWAR or PERF_TYPE_RAW type > depending on the pmc->eventsel value. > > After 'commit 761875634a5e ("KVM: x86/pmu: Setup pmc->eventsel > for fixed PMCs")', the pmc->eventsel of the fixed counter will also have > been setup with the same semantic value and will not be changed during > the guest runtime. But essentially, "the HARDWARE is just a convenience > wrapper over RAW IIRC", quoated from Peterz. So it could be pretty safe > to use the PERF_TYPE_RAW type only to program both gp and fixed > counters naturally in the reprogram_counter(). > > To make the gp and fixed counters more semantically symmetrical, > the selection of EVENTSEL_{USER, OS, INT} bits is temporarily translated > via fixed_ctr_ctrl before the pmc_reprogram_counter() call. > > Cc: Peter Zijlstra > Suggested-by: Jim Mattson > Signed-off-by: Like Xu > --- > arch/x86/kvm/pmu.c | 128 +++++++++++++---------------------- > arch/x86/kvm/vmx/pmu_intel.c | 2 +- > 2 files changed, 47 insertions(+), 83 deletions(-) > > diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c > index 5299488b002c..00e1660c10ca 100644 > --- a/arch/x86/kvm/pmu.c > +++ b/arch/x86/kvm/pmu.c > @@ -215,85 +215,60 @@ static bool check_pmu_event_filter(struct kvm_pmc *pmc) > return allow_event; > } > > -static void reprogram_gp_counter(struct kvm_pmc *pmc) > -{ > - u64 config; > - u32 type = PERF_TYPE_RAW; > - u64 eventsel = pmc->eventsel; > - > - if (eventsel & ARCH_PERFMON_EVENTSEL_PIN_CONTROL) > - printk_once("kvm pmu: pin control bit is ignored\n"); > - > - pmc_pause_counter(pmc); > - > - if (!(eventsel & ARCH_PERFMON_EVENTSEL_ENABLE) || !pmc_is_enabled(pmc)) > - return; > - > - if (!check_pmu_event_filter(pmc)) > - return; > - > - if (!(eventsel & (ARCH_PERFMON_EVENTSEL_EDGE | > - ARCH_PERFMON_EVENTSEL_INV | > - ARCH_PERFMON_EVENTSEL_CMASK | > - HSW_IN_TX | > - HSW_IN_TX_CHECKPOINTED))) { > - config = kvm_x86_ops.pmu_ops->pmc_perf_hw_id(pmc); > - if (config != PERF_COUNT_HW_MAX) > - type = PERF_TYPE_HARDWARE; > - } > - > - if (type == PERF_TYPE_RAW) > - config = eventsel & AMD64_RAW_EVENT_MASK; > - > - if (pmc->current_config == eventsel && pmc_resume_counter(pmc)) > - return; > - > - pmc_release_perf_event(pmc); > - > - pmc->current_config = eventsel; > - pmc_reprogram_counter(pmc, type, config, > - !(eventsel & ARCH_PERFMON_EVENTSEL_USR), > - !(eventsel & ARCH_PERFMON_EVENTSEL_OS), > - eventsel & ARCH_PERFMON_EVENTSEL_INT, > - (eventsel & HSW_IN_TX), > - (eventsel & HSW_IN_TX_CHECKPOINTED)); > -} > - > -static void reprogram_fixed_counter(struct kvm_pmc *pmc) > +static inline bool pmc_speculative_in_use(struct kvm_pmc *pmc) > { > struct kvm_pmu *pmu = pmc_to_pmu(pmc); > - int idx = pmc->idx - INTEL_PMC_IDX_FIXED; > - u8 ctrl = fixed_ctrl_field(pmu->fixed_ctr_ctrl, idx); > - unsigned en_field = ctrl & 0x3; > - bool pmi = ctrl & 0x8; > > - pmc_pause_counter(pmc); > + if (pmc_is_fixed(pmc)) > + return fixed_ctrl_field(pmu->fixed_ctr_ctrl, > + pmc->idx - INTEL_PMC_IDX_FIXED) & 0x3; > > - if (!en_field || !pmc_is_enabled(pmc)) > - return; > - > - if (!check_pmu_event_filter(pmc)) > - return; > - > - if (pmc->current_config == (u64)ctrl && pmc_resume_counter(pmc)) > - return; > - > - pmc_release_perf_event(pmc); > - > - pmc->current_config = (u64)ctrl; > - pmc_reprogram_counter(pmc, PERF_TYPE_HARDWARE, > - kvm_x86_ops.pmu_ops->pmc_perf_hw_id(pmc), > - !(en_field & 0x2), /* exclude user */ > - !(en_field & 0x1), /* exclude kernel */ > - pmi, false, false); > + return pmc->eventsel & ARCH_PERFMON_EVENTSEL_ENABLE; > } > > void reprogram_counter(struct kvm_pmc *pmc) > { > - if (pmc_is_gp(pmc)) > - reprogram_gp_counter(pmc); > - else > - reprogram_fixed_counter(pmc); > + struct kvm_pmu *pmu = pmc_to_pmu(pmc); > + u64 eventsel = pmc->eventsel; > + u64 new_config = eventsel; > + u8 fixed_ctr_ctrl; > + > + pmc_pause_counter(pmc); > + > + if (!pmc_speculative_in_use(pmc) || !pmc_is_enabled(pmc)) > + return; > + > + if (!check_pmu_event_filter(pmc)) > + return; > + > + if (eventsel & ARCH_PERFMON_EVENTSEL_PIN_CONTROL) > + printk_once("kvm pmu: pin control bit is ignored\n"); > + > + if (pmc_is_fixed(pmc)) { > + fixed_ctr_ctrl = fixed_ctrl_field(pmu->fixed_ctr_ctrl, > + pmc->idx - INTEL_PMC_IDX_FIXED); > + if (fixed_ctr_ctrl & 0x1) > + eventsel |= ARCH_PERFMON_EVENTSEL_OS; > + if (fixed_ctr_ctrl & 0x2) > + eventsel |= ARCH_PERFMON_EVENTSEL_USR; > + if (fixed_ctr_ctrl & 0x8) > + eventsel |= ARCH_PERFMON_EVENTSEL_INT; > + new_config = (u64)fixed_ctr_ctrl; > + } > + > + if (pmc->current_config == new_config && pmc_resume_counter(pmc)) > + return; > + > + pmc_release_perf_event(pmc); > + > + pmc->current_config = new_config; > + pmc_reprogram_counter(pmc, PERF_TYPE_RAW, > + (eventsel & AMD64_RAW_EVENT_MASK), > + !(eventsel & ARCH_PERFMON_EVENTSEL_USR), > + !(eventsel & ARCH_PERFMON_EVENTSEL_OS), > + eventsel & ARCH_PERFMON_EVENTSEL_INT, > + (eventsel & HSW_IN_TX), > + (eventsel & HSW_IN_TX_CHECKPOINTED)); It seems that this extremely long argument list was motivated by the differences between the two original call sites. Now that you have mocked up a full eventsel (with USR, OS, INT, IN_TX, and IN_TXCP bits) for the fixed counters, why not pass the entire eventsel as the third argument and drop all of the rest? Then, pmc_reprogram_counter() can extract/check the bits of interest. > } > EXPORT_SYMBOL_GPL(reprogram_counter); > > @@ -451,17 +426,6 @@ void kvm_pmu_init(struct kvm_vcpu *vcpu) > kvm_pmu_refresh(vcpu); > } > > -static inline bool pmc_speculative_in_use(struct kvm_pmc *pmc) > -{ > - struct kvm_pmu *pmu = pmc_to_pmu(pmc); > - > - if (pmc_is_fixed(pmc)) > - return fixed_ctrl_field(pmu->fixed_ctr_ctrl, > - pmc->idx - INTEL_PMC_IDX_FIXED) & 0x3; > - > - return pmc->eventsel & ARCH_PERFMON_EVENTSEL_ENABLE; > -} > - > /* Release perf_events for vPMCs that have been unused for a full time slice. */ > void kvm_pmu_cleanup(struct kvm_vcpu *vcpu) > { > diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c > index 19b78a9d9d47..d823fbe4e155 100644 > --- a/arch/x86/kvm/vmx/pmu_intel.c > +++ b/arch/x86/kvm/vmx/pmu_intel.c > @@ -492,7 +492,7 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu) > pmu->reserved_bits = 0xffffffff00200000ull; > > entry = kvm_find_cpuid_entry(vcpu, 0xa, 0); > - if (!entry || !vcpu->kvm->arch.enable_pmu) > + if (!entry || !vcpu->kvm->arch.enable_pmu || !boot_cpu_has(X86_FEATURE_ARCH_PERFMON)) This change seems unrelated. > return; > eax.full = entry->eax; > edx.full = entry->edx; > -- > 2.35.1 >