From patchwork Fri Mar 31 01:43:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Dai X-Patchwork-Id: 669365 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DDDD7C77B6D for ; Fri, 31 Mar 2023 01:44:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229685AbjCaBod (ORCPT ); Thu, 30 Mar 2023 21:44:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47576 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229609AbjCaBoc (ORCPT ); Thu, 30 Mar 2023 21:44:32 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7AEF012BD6 for ; Thu, 30 Mar 2023 18:44:23 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id m6-20020a056902118600b00aeb1e3dbd1bso20324758ybu.9 for ; Thu, 30 Mar 2023 18:44:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1680227062; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=bQHMl9pwJydZAQbrAoDkSnvavcJ/jzjaFAvojHFhORk=; b=cE6t4ZFZ1GrVpjJSvVne/IoBs3nTvhJx2/x7tbZXEgJWa1Mk0XQ0npmPY8f/9VQI/r K75GmTXHd4epQTJXabgReN4I22zYPK7rPDu8IZR6IGBgbKDvzB9+b6UtiKkohpPFxoPX b2L7y9HVxegUECa/hEkNEht7jAlxcJ1tJvwL9ceHPnOFEWz/igzM3p3WSjHHgg7mxyp8 sRMKMOEZaZQ61niu5ApADy/l4UYir9EHW+X+ghjI8PIwO+2S4AVDQ9XYGpCJ//hJsLPh NDSDv2w67CQ/pth2hxiZBg6Ks/QMp3as8Oqh8rgVpxqdYgDkYf0aXake8sqaJq31zq8n /tIg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680227062; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=bQHMl9pwJydZAQbrAoDkSnvavcJ/jzjaFAvojHFhORk=; b=OeDULu+IB6uf+nxm90Jssoo5iOW6jKd6VgK+mLD8B7ghb8LeZIS9wcAdVD+TP9XeX6 3avmyjFyu2QId20u6Mdio8rEZTL9xP70AT816FDHkUT9bZQ8W/PCXHuNzAAa4AAMBtvX KEkG1awkqMk+OhJD8VhsanDtIFHOBPGw80xPS1n2emPloajtbXS+v95Hkq76NNtrg7bX 9L5TfU/RXsjtkjDCwwJHuoGSnIczp2YmItfxzqGPII9O2q8GqlkBl0kMKohgNZfuniAi vE5TsTlG1ET7cvUB/Yfm0M/M3ouc3eema5zh/18o0DxGTvXLqQuHWoNdMbfJGC6XYZKA 1ltA== X-Gm-Message-State: AAQBX9etMcaKg/Uc181hTOsJTt4bBqX+5wmA+K0mtJDyn9Ho1/8aM/+M VB1Xkv7+77Yqv6qcxeshdceKQ4+vprYS X-Google-Smtp-Source: AKy350ZivNvxJZ18U+W1XPsWsfvpSQ+cLGN8Aj2+BZDUohIE+m0rmZgZiCfr6NdVfa3nqdRvfK2U2A2N5cMv X-Received: from davidai2.mtv.corp.google.com ([2620:15c:211:201:c162:24e8:ec5e:d520]) (user=davidai job=sendgmr) by 2002:a25:ab11:0:b0:a5f:0:bf12 with SMTP id u17-20020a25ab11000000b00a5f0000bf12mr12526269ybi.13.1680227062710; Thu, 30 Mar 2023 18:44:22 -0700 (PDT) Date: Thu, 30 Mar 2023 18:43:45 -0700 In-Reply-To: <20230331014356.1033759-1-davidai@google.com> Mime-Version: 1.0 References: <20230331014356.1033759-1-davidai@google.com> X-Mailer: git-send-email 2.40.0.348.gf938b09366-goog Message-ID: <20230331014356.1033759-2-davidai@google.com> Subject: [RFC PATCH v2 1/6] sched/fair: Add util_guest for tasks From: David Dai To: "Rafael J. Wysocki" , Viresh Kumar , Rob Herring , Krzysztof Kozlowski , Paolo Bonzini , Jonathan Corbet , Marc Zyngier , Oliver Upton , James Morse , Suzuki K Poulose , Zenghui Yu , Catalin Marinas , Will Deacon , Mark Rutland , Lorenzo Pieralisi , Sudeep Holla , Ingo Molnar , Peter Zijlstra , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Daniel Bristot de Oliveira , Valentin Schneider , David Dai Cc: Saravana Kannan , kernel-team@android.com, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org For virtualization usecases, util_est and util_avg currently tracked on the host aren't sufficient to accurately represent the workload on vCPU threads, which results in poor frequency selection and performance. For example, when a large workload migrates from a busy vCPU thread to an idle vCPU thread, it incurs additional DVFS ramp-up latencies as util accumulates. Introduce a new "util_guest" member as an additional PELT signal that's independently updated by the guest. When used, it's max aggregated to provide a boost to both task_util and task_util_est. Updating task_util and task_util_est will ensure: -Better task placement decisions for vCPU threads on the host -Correctly updating util_est.ewma during dequeue -Additive util with other threads on the same runqueue for more accurate frequency responses Co-developed-by: Saravana Kannan Signed-off-by: Saravana Kannan Signed-off-by: David Dai --- include/linux/sched.h | 11 +++++++++++ kernel/sched/core.c | 18 +++++++++++++++++- kernel/sched/fair.c | 15 +++++++++++++-- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 63d242164b1a..d8c346fcdf52 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -445,6 +445,16 @@ struct util_est { #define UTIL_AVG_UNCHANGED 0x80000000 } __attribute__((__aligned__(sizeof(u64)))); +/* + * For sched_setattr_nocheck() (kernel) only + * + * Allow vCPU threads to use UTIL_GUEST as a way to hint the scheduler with more + * accurate utilization info. This is useful when guest kernels have some way of + * tracking its own runqueue's utilization. + * + */ +#define SCHED_FLAG_UTIL_GUEST 0x20000000 + /* * The load/runnable/util_avg accumulates an infinite geometric series * (see __update_load_avg_cfs_rq() in kernel/sched/pelt.c). @@ -499,6 +509,7 @@ struct sched_avg { unsigned long load_avg; unsigned long runnable_avg; unsigned long util_avg; + unsigned long util_guest; struct util_est util_est; } ____cacheline_aligned; diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 0d18c3969f90..7700ef5610c1 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -2024,6 +2024,16 @@ static inline void uclamp_post_fork(struct task_struct *p) { } static inline void init_uclamp(void) { } #endif /* CONFIG_UCLAMP_TASK */ +static void __setscheduler_task_util(struct task_struct *p, + const struct sched_attr *attr) +{ + + if (likely(!(attr->sched_flags & SCHED_FLAG_UTIL_GUEST))) + return; + + p->se.avg.util_guest = attr->sched_util_min; +} + bool sched_task_on_rq(struct task_struct *p) { return task_on_rq_queued(p); @@ -7561,7 +7571,7 @@ static int __sched_setscheduler(struct task_struct *p, return -EINVAL; } - if (attr->sched_flags & ~(SCHED_FLAG_ALL | SCHED_FLAG_SUGOV)) + if (attr->sched_flags & ~(SCHED_FLAG_ALL | SCHED_FLAG_SUGOV | SCHED_FLAG_UTIL_GUEST)) return -EINVAL; /* @@ -7583,6 +7593,9 @@ static int __sched_setscheduler(struct task_struct *p, if (attr->sched_flags & SCHED_FLAG_SUGOV) return -EINVAL; + if (attr->sched_flags & SCHED_FLAG_UTIL_GUEST) + return -EINVAL; + retval = security_task_setscheduler(p); if (retval) return retval; @@ -7629,6 +7642,8 @@ static int __sched_setscheduler(struct task_struct *p, goto change; if (attr->sched_flags & SCHED_FLAG_UTIL_CLAMP) goto change; + if (attr->sched_flags & SCHED_FLAG_UTIL_GUEST) + goto change; p->sched_reset_on_fork = reset_on_fork; retval = 0; @@ -7718,6 +7733,7 @@ static int __sched_setscheduler(struct task_struct *p, __setscheduler_prio(p, newprio); } __setscheduler_uclamp(p, attr); + __setscheduler_task_util(p, attr); if (queued) { /* diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 6986ea31c984..998649554344 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -4276,14 +4276,16 @@ static int newidle_balance(struct rq *this_rq, struct rq_flags *rf); static inline unsigned long task_util(struct task_struct *p) { - return READ_ONCE(p->se.avg.util_avg); + return max(READ_ONCE(p->se.avg.util_avg), + READ_ONCE(p->se.avg.util_guest)); } static inline unsigned long _task_util_est(struct task_struct *p) { struct util_est ue = READ_ONCE(p->se.avg.util_est); - return max(ue.ewma, (ue.enqueued & ~UTIL_AVG_UNCHANGED)); + return max_t(unsigned long, READ_ONCE(p->se.avg.util_guest), + max(ue.ewma, (ue.enqueued & ~UTIL_AVG_UNCHANGED))); } static inline unsigned long task_util_est(struct task_struct *p) @@ -6242,6 +6244,15 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags) */ util_est_enqueue(&rq->cfs, p); + /* + * The normal code path for host thread enqueue doesn't take into + * account guest task migrations when updating cpufreq util. + * So, always update the cpufreq when a vCPU thread has a + * non-zero util_guest value. + */ + if (READ_ONCE(p->se.avg.util_guest)) + cpufreq_update_util(rq, 0); + /* * If in_iowait is set, the code below may not trigger any cpufreq * utilization updates, so do it here explicitly with the IOWAIT flag From patchwork Fri Mar 31 01:43:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Dai X-Patchwork-Id: 669584 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AA270C77B6C for ; Fri, 31 Mar 2023 01:44:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229665AbjCaBoq (ORCPT ); Thu, 30 Mar 2023 21:44:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48142 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229722AbjCaBop (ORCPT ); Thu, 30 Mar 2023 21:44:45 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2492612CCA for ; Thu, 30 Mar 2023 18:44:32 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-545e529206eso146947607b3.9 for ; Thu, 30 Mar 2023 18:44:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1680227071; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=VWrmux7hI3Vkehq4mVAPcOxXo9VZdrd7e2opoA1ab28=; b=NuRHTQ4r7Yhkm0CHKG9NT///L7D7BVftTZ4uMTv9Jr+yos7IQzRlIlQF24wZK80nq1 3PYDqCOfjo/vijWVfEQ2DKnfkFWt76dqEroDsxw75A//ZEWcOQEvWCy2e8hQhIcPLHoS aJbEi/sXA8TzotzHwRitbaNju7SYqW04vmrcr37S7KS5j4e8Z4v5V6xBirGY+k0AaC2s ugP3bO0fkKyT1Mk5yp9Er6Ew0mUI74a3p6BjdG9x9iZ6ofoCDC7Mpy4bk0FQOVIEGDiN wcW7CK+SkQx/TWr1JyZ7lwdxxWVyul+9mNOLZXleIXv7lrGhaF6gIjvemPhMIS1NB/8r 1Qxg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680227071; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=VWrmux7hI3Vkehq4mVAPcOxXo9VZdrd7e2opoA1ab28=; b=kKLY1rbVQVf01T9Mp1Ex+tpKAuQKR2d56zyGRABl1SyHnb76Mgi2e3hPutG4zFDf7B O7E0cElM6L+TnWe3XVoY7nQ8ptTWh5Q2ugK89wTIff/FQF+1ldxe/KW17ITSW4T7Nb/h M8QB36aqh2jXZirYBEYWTB6lyDBAhNMcqOf81NhKSWkZBYSu0uDOq9aD/ytS7TTsUArb 3FTFpN2pAqz0z01mjGwdszI/7MTLmE8M3wH+DB+dXsL208L4nnqPXsjnCeg11JEt/vjo Eb1rISppdA/4RjeketWFfKWXAXe1xZGAhpEokOpOxHBeovv3PnY5BRwxu9ciOAeQl8hg 6i/w== X-Gm-Message-State: AAQBX9c1ysHzVLAU1nxj72oXkwdjIl/e04pteIOxkdIByHmrWKulhaxb 0TwMk+JUOpbiWdl7+cI1rsB7WsvEp5xB X-Google-Smtp-Source: AKy350bp88zg/5gTFH328IP3goO2omhN8m6LXgFtCVO/sAA9U/n6D9I2esgS+2Dr+8WHzEn0hmnNk9z9CP52 X-Received: from davidai2.mtv.corp.google.com ([2620:15c:211:201:c162:24e8:ec5e:d520]) (user=davidai job=sendgmr) by 2002:a05:6902:a8e:b0:b7c:1144:a729 with SMTP id cd14-20020a0569020a8e00b00b7c1144a729mr8308502ybb.9.1680227071244; Thu, 30 Mar 2023 18:44:31 -0700 (PDT) Date: Thu, 30 Mar 2023 18:43:46 -0700 In-Reply-To: <20230331014356.1033759-1-davidai@google.com> Mime-Version: 1.0 References: <20230331014356.1033759-1-davidai@google.com> X-Mailer: git-send-email 2.40.0.348.gf938b09366-goog Message-ID: <20230331014356.1033759-3-davidai@google.com> Subject: [RFC PATCH v2 2/6] kvm: arm64: Add support for get_cur_cpufreq service From: David Dai To: "Rafael J. Wysocki" , Viresh Kumar , Rob Herring , Krzysztof Kozlowski , Paolo Bonzini , Jonathan Corbet , Marc Zyngier , Oliver Upton , James Morse , Suzuki K Poulose , Zenghui Yu , Catalin Marinas , Will Deacon , Mark Rutland , Lorenzo Pieralisi , Sudeep Holla , Ingo Molnar , Peter Zijlstra , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Daniel Bristot de Oliveira , Valentin Schneider , David Dai Cc: Saravana Kannan , kernel-team@android.com, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org This service allows guests to query the host for frequency of the CPU that the vCPU is currently running on. Co-developed-by: Saravana Kannan Signed-off-by: Saravana Kannan Signed-off-by: David Dai --- Documentation/virt/kvm/api.rst | 8 +++++++ .../virt/kvm/arm/get_cur_cpufreq.rst | 21 +++++++++++++++++++ Documentation/virt/kvm/arm/index.rst | 1 + arch/arm64/include/uapi/asm/kvm.h | 1 + arch/arm64/kvm/arm.c | 1 + arch/arm64/kvm/hypercalls.c | 18 ++++++++++++++++ include/linux/arm-smccc.h | 7 +++++++ include/uapi/linux/kvm.h | 1 + tools/arch/arm64/include/uapi/asm/kvm.h | 1 + 9 files changed, 59 insertions(+) create mode 100644 Documentation/virt/kvm/arm/get_cur_cpufreq.rst diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 62de0768d6aa..b0ff0ad700bf 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -8380,6 +8380,14 @@ structure. When getting the Modified Change Topology Report value, the attr->addr must point to a byte where the value will be stored or retrieved from. +8.40 KVM_CAP_GET_CUR_CPUFREQ +------------------------ + +:Architectures: arm64 + +This capability indicates that KVM supports getting the +frequency of the current CPU that the vCPU thread is running on. + 9. Known KVM API problems ========================= diff --git a/Documentation/virt/kvm/arm/get_cur_cpufreq.rst b/Documentation/virt/kvm/arm/get_cur_cpufreq.rst new file mode 100644 index 000000000000..06e0ed5b3868 --- /dev/null +++ b/Documentation/virt/kvm/arm/get_cur_cpufreq.rst @@ -0,0 +1,21 @@ +.. SPDX-License-Identifier: GPL-2.0 + +get_cur_cpufreq support for arm/arm64 +============================= + +Get_cur_cpufreq support is used to get current frequency(in KHz) of the +current CPU that the vCPU thread is running on. + +* ARM_SMCCC_VENDOR_HYP_KVM_GET_CUR_CPUFREQ_FUNC_ID: 0x86000040 + +This hypercall uses the SMC32/HVC32 calling convention: + +ARM_SMCCC_VENDOR_HYP_KVM_GET_CUR_CPUFREQ_FUNC_ID + ============== ======== ===================================== + Function ID: (uint32) 0x86000040 + Return Values: (int32) NOT_SUPPORTED(-1) on error, or + (uint32) Frequency in KHz of current CPU that the + vCPU thread is running on. + Endianness: Must be the same endianness + as the host. + ============== ======== ===================================== diff --git a/Documentation/virt/kvm/arm/index.rst b/Documentation/virt/kvm/arm/index.rst index e84848432158..47afc5c1f24a 100644 --- a/Documentation/virt/kvm/arm/index.rst +++ b/Documentation/virt/kvm/arm/index.rst @@ -11,3 +11,4 @@ ARM hypercalls pvtime ptp_kvm + get_cur_cpufreq diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h index f8129c624b07..ed8b63e91bdc 100644 --- a/arch/arm64/include/uapi/asm/kvm.h +++ b/arch/arm64/include/uapi/asm/kvm.h @@ -367,6 +367,7 @@ enum { enum { KVM_REG_ARM_VENDOR_HYP_BIT_FUNC_FEAT = 0, KVM_REG_ARM_VENDOR_HYP_BIT_PTP = 1, + KVM_REG_ARM_VENDOR_HYP_BIT_GET_CUR_CPUFREQ = 2, #ifdef __KERNEL__ KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_COUNT, #endif diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 3bd732eaf087..f960b136c611 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -220,6 +220,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_VCPU_ATTRIBUTES: case KVM_CAP_PTP_KVM: case KVM_CAP_ARM_SYSTEM_SUSPEND: + case KVM_CAP_GET_CUR_CPUFREQ: r = 1; break; case KVM_CAP_SET_GUEST_DEBUG2: diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c index 5da884e11337..b3f4b90c024b 100644 --- a/arch/arm64/kvm/hypercalls.c +++ b/arch/arm64/kvm/hypercalls.c @@ -3,6 +3,9 @@ #include #include +#include +#include +#include #include @@ -16,6 +19,15 @@ #define KVM_ARM_SMCCC_VENDOR_HYP_FEATURES \ GENMASK(KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_COUNT - 1, 0) +static void kvm_sched_get_cur_cpufreq(struct kvm_vcpu *vcpu, u64 *val) +{ + unsigned long ret_freq; + + ret_freq = cpufreq_get(task_cpu(current)); + + val[0] = ret_freq; +} + static void kvm_ptp_get_time(struct kvm_vcpu *vcpu, u64 *val) { struct system_time_snapshot systime_snapshot; @@ -116,6 +128,9 @@ static bool kvm_hvc_call_allowed(struct kvm_vcpu *vcpu, u32 func_id) case ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID: return test_bit(KVM_REG_ARM_VENDOR_HYP_BIT_PTP, &smccc_feat->vendor_hyp_bmap); + case ARM_SMCCC_VENDOR_HYP_KVM_GET_CUR_CPUFREQ_FUNC_ID: + return test_bit(KVM_REG_ARM_VENDOR_HYP_BIT_GET_CUR_CPUFREQ, + &smccc_feat->vendor_hyp_bmap); default: return kvm_hvc_call_default_allowed(func_id); } @@ -213,6 +228,9 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) case ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID: kvm_ptp_get_time(vcpu, val); break; + case ARM_SMCCC_VENDOR_HYP_KVM_GET_CUR_CPUFREQ_FUNC_ID: + kvm_sched_get_cur_cpufreq(vcpu, val); + break; case ARM_SMCCC_TRNG_VERSION: case ARM_SMCCC_TRNG_FEATURES: case ARM_SMCCC_TRNG_GET_UUID: diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h index 220c8c60e021..e15f1bdcf3f1 100644 --- a/include/linux/arm-smccc.h +++ b/include/linux/arm-smccc.h @@ -112,6 +112,7 @@ /* KVM "vendor specific" services */ #define ARM_SMCCC_KVM_FUNC_FEATURES 0 #define ARM_SMCCC_KVM_FUNC_PTP 1 +#define ARM_SMCCC_KVM_FUNC_GET_CUR_CPUFREQ 64 #define ARM_SMCCC_KVM_FUNC_FEATURES_2 127 #define ARM_SMCCC_KVM_NUM_FUNCS 128 @@ -138,6 +139,12 @@ #define KVM_PTP_VIRT_COUNTER 0 #define KVM_PTP_PHYS_COUNTER 1 +#define ARM_SMCCC_VENDOR_HYP_KVM_GET_CUR_CPUFREQ_FUNC_ID \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_32, \ + ARM_SMCCC_OWNER_VENDOR_HYP, \ + ARM_SMCCC_KVM_FUNC_GET_CUR_CPUFREQ) + /* Paravirtualised time calls (defined by ARM DEN0057A) */ #define ARM_SMCCC_HV_PV_TIME_FEATURES \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index d77aef872a0a..0a1a260243bf 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -1184,6 +1184,7 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_S390_PROTECTED_ASYNC_DISABLE 224 #define KVM_CAP_DIRTY_LOG_RING_WITH_BITMAP 225 #define KVM_CAP_PMU_EVENT_MASKED_EVENTS 226 +#define KVM_CAP_GET_CUR_CPUFREQ 512 #ifdef KVM_CAP_IRQ_ROUTING diff --git a/tools/arch/arm64/include/uapi/asm/kvm.h b/tools/arch/arm64/include/uapi/asm/kvm.h index f8129c624b07..ed8b63e91bdc 100644 --- a/tools/arch/arm64/include/uapi/asm/kvm.h +++ b/tools/arch/arm64/include/uapi/asm/kvm.h @@ -367,6 +367,7 @@ enum { enum { KVM_REG_ARM_VENDOR_HYP_BIT_FUNC_FEAT = 0, KVM_REG_ARM_VENDOR_HYP_BIT_PTP = 1, + KVM_REG_ARM_VENDOR_HYP_BIT_GET_CUR_CPUFREQ = 2, #ifdef __KERNEL__ KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_COUNT, #endif From patchwork Fri Mar 31 01:43:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Dai X-Patchwork-Id: 669364 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A8AC6C77B6C for ; Fri, 31 Mar 2023 01:45:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229741AbjCaBo7 (ORCPT ); Thu, 30 Mar 2023 21:44:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48500 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229475AbjCaBo6 (ORCPT ); Thu, 30 Mar 2023 21:44:58 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 98E5818809 for ; Thu, 30 Mar 2023 18:44:40 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-5416d3a321eso206575207b3.12 for ; Thu, 30 Mar 2023 18:44:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1680227080; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=2nOCpsUj368/jlH6/5xvHY1SZiMoDDhdnoWB6M9IhGk=; b=EoFm2EESCZFa8L2EDfRrSWrK5iTwjplzrCG15Muuw4LexoEv7cRzk3U8mMFd31uCi3 VdC3YIAw664hHqw4YqXBm6NIsYVZI/zi6aI33HgKpvZUCAq2F60LsjTAND6zuqPnJWxw dUhoC0XEDFF41sRo/izu1KWyx6xV8dMdVZVnuum5wiMrH41XrpQhbpM81Y8B9/+a6HFg 6lHwXnBerygZWkfWkozFym/kgihFZNMZdJvJ2ILOzQHd1aU1GopN0D0mcKwbW+ctaONf 42O9oES/W+GB8HkYY0aFvEtljKmYDHH0edNbuZQCFHw6OO1bklTz6k1MVWQ4/ilgFj// cuBg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680227080; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=2nOCpsUj368/jlH6/5xvHY1SZiMoDDhdnoWB6M9IhGk=; b=dm26TYf/K+Rz5tQHbkksCPh5KV9de38q9jWY+buzM6NeCWcqY28Yd46kVLviu1IgtS W131uMSAn9Pa6ocJFRTdUDNLMI6xr0WFUjt73fyTrBmtV3ED8ON4zHfBYxrzcPAPb9v4 b/YSW702Ji5Sb+m2xPQsjsoDQ/VWKj1URqF8L6/lqvUubMFGy6vF5v2CMnww0eh/78wa y7/LADBMpYqEopt6YJKOgUf4X2EtTNHIUZysrOu4MU3bgKiVzIx/cw8pGZr4M/N4oSQZ tt1E600AN2LOZ6dQuucLK6eTRw/ihdyHlxXQ7pLH0UbE1BqXQ0uGM5OeeKQTUaS3lwrt noXw== X-Gm-Message-State: AAQBX9ft/qvPVUmiou0JU7CNW9ubGs0WHbVS951zh9bHr5TgpNNAf0bn MbPcmaa68MqcEIB8h5vl4dQ9P6o2ct2V X-Google-Smtp-Source: AKy350ba7fvAQLLeLUmDHWvV6pFnNpQ3WE7NZ+hQyM9RHczPn7Ji9dv9PUy3aXAqd4B7WromdF7iWfstQpkF X-Received: from davidai2.mtv.corp.google.com ([2620:15c:211:201:c162:24e8:ec5e:d520]) (user=davidai job=sendgmr) by 2002:a05:6902:168d:b0:b26:47f3:6cb with SMTP id bx13-20020a056902168d00b00b2647f306cbmr13590397ybb.4.1680227079917; Thu, 30 Mar 2023 18:44:39 -0700 (PDT) Date: Thu, 30 Mar 2023 18:43:47 -0700 In-Reply-To: <20230331014356.1033759-1-davidai@google.com> Mime-Version: 1.0 References: <20230331014356.1033759-1-davidai@google.com> X-Mailer: git-send-email 2.40.0.348.gf938b09366-goog Message-ID: <20230331014356.1033759-4-davidai@google.com> Subject: [RFC PATCH v2 3/6] kvm: arm64: Add support for util_hint service From: David Dai To: "Rafael J. Wysocki" , Viresh Kumar , Rob Herring , Krzysztof Kozlowski , Paolo Bonzini , Jonathan Corbet , Marc Zyngier , Oliver Upton , James Morse , Suzuki K Poulose , Zenghui Yu , Catalin Marinas , Will Deacon , Mark Rutland , Lorenzo Pieralisi , Sudeep Holla , Ingo Molnar , Peter Zijlstra , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Daniel Bristot de Oliveira , Valentin Schneider , David Dai Cc: Saravana Kannan , kernel-team@android.com, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org This service allows guests to send the utilization of workoads on its vCPUs to the host. Utilization is represented as an arbitrary value of 0-1024 where 1024 represents the highest performance point normalized for frequency and architecture across all CPUs. This hint is used by the host for scheduling vCPU threads and deciding CPU frequency. Co-developed-by: Saravana Kannan Signed-off-by: Saravana Kannan Signed-off-by: David Dai --- Documentation/virt/kvm/api.rst | 12 ++++++++++++ Documentation/virt/kvm/arm/index.rst | 1 + Documentation/virt/kvm/arm/util_hint.rst | 22 ++++++++++++++++++++++ arch/arm64/include/uapi/asm/kvm.h | 1 + arch/arm64/kvm/arm.c | 1 + arch/arm64/kvm/hypercalls.c | 20 ++++++++++++++++++++ include/linux/arm-smccc.h | 7 +++++++ include/uapi/linux/kvm.h | 1 + tools/arch/arm64/include/uapi/asm/kvm.h | 1 + 9 files changed, 66 insertions(+) create mode 100644 Documentation/virt/kvm/arm/util_hint.rst diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index b0ff0ad700bf..38ce33564efc 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -8388,6 +8388,18 @@ must point to a byte where the value will be stored or retrieved from. This capability indicates that KVM supports getting the frequency of the current CPU that the vCPU thread is running on. +8.41 KVM_CAP_UTIL_HINT +---------------------- + +:Architectures: arm64 + +This capability indicates that the KVM supports taking utilization +hints from the guest. Utilization is represented as a value from 0-1024 +where 1024 represents the highest performance point across all physical CPUs +after normalizing for architecture. This is useful when guests are tracking +workload on its vCPUs. Util hints allow the host to make more accurate +frequency selections and task placement for vCPU threads. + 9. Known KVM API problems ========================= diff --git a/Documentation/virt/kvm/arm/index.rst b/Documentation/virt/kvm/arm/index.rst index 47afc5c1f24a..f83877663813 100644 --- a/Documentation/virt/kvm/arm/index.rst +++ b/Documentation/virt/kvm/arm/index.rst @@ -12,3 +12,4 @@ ARM pvtime ptp_kvm get_cur_cpufreq + util_hint diff --git a/Documentation/virt/kvm/arm/util_hint.rst b/Documentation/virt/kvm/arm/util_hint.rst new file mode 100644 index 000000000000..262d142d62d9 --- /dev/null +++ b/Documentation/virt/kvm/arm/util_hint.rst @@ -0,0 +1,22 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Util_hint support for arm64 +============================ + +Util_hint is used for sharing the utilization value from the guest +to the host. + +* ARM_SMCCC_HYP_KVM_UTIL_HINT_FUNC_ID: 0x86000041 + +This hypercall using the SMC32/HVC32 calling convention: + +ARM_SMCCC_HYP_KVM_UTIL_HINT_FUNC_ID + ============== ========= ============================ + Function ID: (uint32) 0x86000041 + Arguments: (uint32) util value(0-1024) where 1024 represents + the highest performance point normalized + across all CPUs + Return values: (int32) NOT_SUPPORTED(-1) on error. + Endianness: Must be the same endianness + as the host. + ============== ======== ============================ diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h index ed8b63e91bdc..61309ecb7241 100644 --- a/arch/arm64/include/uapi/asm/kvm.h +++ b/arch/arm64/include/uapi/asm/kvm.h @@ -368,6 +368,7 @@ enum { KVM_REG_ARM_VENDOR_HYP_BIT_FUNC_FEAT = 0, KVM_REG_ARM_VENDOR_HYP_BIT_PTP = 1, KVM_REG_ARM_VENDOR_HYP_BIT_GET_CUR_CPUFREQ = 2, + KVM_REG_ARM_VENDOR_HYP_BIT_UTIL_HINT = 3, #ifdef __KERNEL__ KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_COUNT, #endif diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index f960b136c611..bf3c4d4b9b67 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -221,6 +221,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_PTP_KVM: case KVM_CAP_ARM_SYSTEM_SUSPEND: case KVM_CAP_GET_CUR_CPUFREQ: + case KVM_CAP_UTIL_HINT: r = 1; break; case KVM_CAP_SET_GUEST_DEBUG2: diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c index b3f4b90c024b..01dba07b5183 100644 --- a/arch/arm64/kvm/hypercalls.c +++ b/arch/arm64/kvm/hypercalls.c @@ -28,6 +28,20 @@ static void kvm_sched_get_cur_cpufreq(struct kvm_vcpu *vcpu, u64 *val) val[0] = ret_freq; } +static void kvm_sched_set_util(struct kvm_vcpu *vcpu, u64 *val) +{ + struct sched_attr attr = { + .sched_flags = SCHED_FLAG_UTIL_GUEST, + }; + int ret; + + attr.sched_util_min = smccc_get_arg1(vcpu); + + ret = sched_setattr_nocheck(current, &attr); + + val[0] = (u64)ret; +} + static void kvm_ptp_get_time(struct kvm_vcpu *vcpu, u64 *val) { struct system_time_snapshot systime_snapshot; @@ -131,6 +145,9 @@ static bool kvm_hvc_call_allowed(struct kvm_vcpu *vcpu, u32 func_id) case ARM_SMCCC_VENDOR_HYP_KVM_GET_CUR_CPUFREQ_FUNC_ID: return test_bit(KVM_REG_ARM_VENDOR_HYP_BIT_GET_CUR_CPUFREQ, &smccc_feat->vendor_hyp_bmap); + case ARM_SMCCC_VENDOR_HYP_KVM_UTIL_HINT_FUNC_ID: + return test_bit(KVM_REG_ARM_VENDOR_HYP_BIT_UTIL_HINT, + &smccc_feat->vendor_hyp_bmap); default: return kvm_hvc_call_default_allowed(func_id); } @@ -231,6 +248,9 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) case ARM_SMCCC_VENDOR_HYP_KVM_GET_CUR_CPUFREQ_FUNC_ID: kvm_sched_get_cur_cpufreq(vcpu, val); break; + case ARM_SMCCC_VENDOR_HYP_KVM_UTIL_HINT_FUNC_ID: + kvm_sched_set_util(vcpu, val); + break; case ARM_SMCCC_TRNG_VERSION: case ARM_SMCCC_TRNG_FEATURES: case ARM_SMCCC_TRNG_GET_UUID: diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h index e15f1bdcf3f1..9f747e5025b6 100644 --- a/include/linux/arm-smccc.h +++ b/include/linux/arm-smccc.h @@ -113,6 +113,7 @@ #define ARM_SMCCC_KVM_FUNC_FEATURES 0 #define ARM_SMCCC_KVM_FUNC_PTP 1 #define ARM_SMCCC_KVM_FUNC_GET_CUR_CPUFREQ 64 +#define ARM_SMCCC_KVM_FUNC_UTIL_HINT 65 #define ARM_SMCCC_KVM_FUNC_FEATURES_2 127 #define ARM_SMCCC_KVM_NUM_FUNCS 128 @@ -145,6 +146,12 @@ ARM_SMCCC_OWNER_VENDOR_HYP, \ ARM_SMCCC_KVM_FUNC_GET_CUR_CPUFREQ) +#define ARM_SMCCC_VENDOR_HYP_KVM_UTIL_HINT_FUNC_ID \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_32, \ + ARM_SMCCC_OWNER_VENDOR_HYP, \ + ARM_SMCCC_KVM_FUNC_UTIL_HINT) + /* Paravirtualised time calls (defined by ARM DEN0057A) */ #define ARM_SMCCC_HV_PV_TIME_FEATURES \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 0a1a260243bf..7f667ab344ae 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -1185,6 +1185,7 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_DIRTY_LOG_RING_WITH_BITMAP 225 #define KVM_CAP_PMU_EVENT_MASKED_EVENTS 226 #define KVM_CAP_GET_CUR_CPUFREQ 512 +#define KVM_CAP_UTIL_HINT 513 #ifdef KVM_CAP_IRQ_ROUTING diff --git a/tools/arch/arm64/include/uapi/asm/kvm.h b/tools/arch/arm64/include/uapi/asm/kvm.h index ed8b63e91bdc..61309ecb7241 100644 --- a/tools/arch/arm64/include/uapi/asm/kvm.h +++ b/tools/arch/arm64/include/uapi/asm/kvm.h @@ -368,6 +368,7 @@ enum { KVM_REG_ARM_VENDOR_HYP_BIT_FUNC_FEAT = 0, KVM_REG_ARM_VENDOR_HYP_BIT_PTP = 1, KVM_REG_ARM_VENDOR_HYP_BIT_GET_CUR_CPUFREQ = 2, + KVM_REG_ARM_VENDOR_HYP_BIT_UTIL_HINT = 3, #ifdef __KERNEL__ KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_COUNT, #endif From patchwork Fri Mar 31 01:43:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Dai X-Patchwork-Id: 669583 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A51B9C6FD1D for ; Fri, 31 Mar 2023 01:45:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229574AbjCaBpN (ORCPT ); Thu, 30 Mar 2023 21:45:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48716 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229754AbjCaBpL (ORCPT ); Thu, 30 Mar 2023 21:45:11 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C1A8512BEC for ; Thu, 30 Mar 2023 18:44:48 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id k199-20020a2524d0000000b00b7f3a027e50so5737251ybk.4 for ; Thu, 30 Mar 2023 18:44:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1680227088; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=sxm82ULq9HWZFwrrpsKKW1Wi+ka2XfyIhyEC8wmryEE=; b=EwCbBy2NmGz1YSwvIaLGptaApqPEAq4wX2wnszbBXw5oQb2Uc0EFP1C20lCXszudSW ygIU6pkqOvK2AK9KQ3c60PIKQ/sfD3NboEMbtXcTSsWk925G3pjV2fMbiBFsUoRknSuK ezx+aC7quvkq5Qp6J2Hw2mSgFZr1Qr0KBroONM5YI6O4ohleQKXY+7eF7wtB6Cg88To2 7a50+zIgK7CmPHkJ1agmB5DqT4KvJ5THhi3apcHVq6stFnJbCgwc1za/ktgLOb8S3PJE L4rTFk8Jl8wIm8P/bsAnTRwlFTthcSl9W4i2XZ+2sCglww7Oyy1NNTcNDaY9V5ex4q44 ko8Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680227088; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=sxm82ULq9HWZFwrrpsKKW1Wi+ka2XfyIhyEC8wmryEE=; b=rwyP2voUiFBbU8ywa7GpDDLgTmzr4s8NQvEWhdv7w7BByi14ie1qNN6Y2IOpu6/O2t iPnkot0FjVuah5zOEFGyvNO4dtMKQHXoek7GMqE+NqJWouphkZqL7m15Gj+iX8uRN3Hv 2IrxCIPQ6mwMpxSQ/ylC6hfc308ekrPQabPEGG2euyFR3wDJcX+9bf8f9Fxaze0iBR8G WEQY+xIDpsJIB0v99K7vUXigmL2nWUmchCtDfZcZJ8/HRsqQt/zvRsLGAGZEJNQlnbYK JivAZfi0i1hrhiMYGok6D3tMQBeygrdiggxFn9eiHONNnD/sGIiW0Vb6dC8NARrpnnP+ DJlw== X-Gm-Message-State: AAQBX9ff72b8qhd77IkXBeT8JBju/utgqeAgFZLu2fNMdVfyyNI+eboH kbXx0YaG5QzjFW/XMIfzQKsaK5lbBInd X-Google-Smtp-Source: AKy350YrvUZvdqqRk49vMMwHj65sbO9FBkTq3BlYniQySKvVZ2DnixnaTt5gk7E6TsmAi1IbV2hLrS2fnA3q X-Received: from davidai2.mtv.corp.google.com ([2620:15c:211:201:c162:24e8:ec5e:d520]) (user=davidai job=sendgmr) by 2002:a05:6902:120c:b0:b74:77fa:581d with SMTP id s12-20020a056902120c00b00b7477fa581dmr13612793ybu.4.1680227088489; Thu, 30 Mar 2023 18:44:48 -0700 (PDT) Date: Thu, 30 Mar 2023 18:43:48 -0700 In-Reply-To: <20230331014356.1033759-1-davidai@google.com> Mime-Version: 1.0 References: <20230331014356.1033759-1-davidai@google.com> X-Mailer: git-send-email 2.40.0.348.gf938b09366-goog Message-ID: <20230331014356.1033759-5-davidai@google.com> Subject: [RFC PATCH v2 4/6] kvm: arm64: Add support for get_freqtbl service From: David Dai To: "Rafael J. Wysocki" , Viresh Kumar , Rob Herring , Krzysztof Kozlowski , Paolo Bonzini , Jonathan Corbet , Marc Zyngier , Oliver Upton , James Morse , Suzuki K Poulose , Zenghui Yu , Catalin Marinas , Will Deacon , Mark Rutland , Lorenzo Pieralisi , Sudeep Holla , Ingo Molnar , Peter Zijlstra , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Daniel Bristot de Oliveira , Valentin Schneider , David Dai Cc: Saravana Kannan , kernel-team@android.com, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org This service allows guests to query the host for the frequency table of the CPU that the vCPU is currently running on. Co-developed-by: Saravana Kannan Signed-off-by: Saravana Kannan Signed-off-by: David Dai --- Documentation/virt/kvm/api.rst | 8 ++++++++ Documentation/virt/kvm/arm/get_freqtbl.rst | 23 ++++++++++++++++++++++ Documentation/virt/kvm/arm/index.rst | 1 + arch/arm64/include/uapi/asm/kvm.h | 1 + arch/arm64/kvm/arm.c | 1 + arch/arm64/kvm/hypercalls.c | 22 +++++++++++++++++++++ include/linux/arm-smccc.h | 7 +++++++ include/uapi/linux/kvm.h | 1 + tools/arch/arm64/include/uapi/asm/kvm.h | 1 + 9 files changed, 65 insertions(+) create mode 100644 Documentation/virt/kvm/arm/get_freqtbl.rst diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 38ce33564efc..8f905456e2b4 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -8400,6 +8400,14 @@ after normalizing for architecture. This is useful when guests are tracking workload on its vCPUs. Util hints allow the host to make more accurate frequency selections and task placement for vCPU threads. +8.42 KVM_CAP_GET_CPUFREQ_TBL +--------------------------- + +:Architectures: arm64 + +This capability indicates that the KVM supports getting the +frequency table of the current CPU that the vCPU thread is running on. + 9. Known KVM API problems ========================= diff --git a/Documentation/virt/kvm/arm/get_freqtbl.rst b/Documentation/virt/kvm/arm/get_freqtbl.rst new file mode 100644 index 000000000000..f6832d7566e7 --- /dev/null +++ b/Documentation/virt/kvm/arm/get_freqtbl.rst @@ -0,0 +1,23 @@ +.. SPDX-License-Identifier: GPL-2.0 + +get_freqtbl support for arm/arm64 +============================= + +Allows guest to query the frequency(in KHz) table of the current CPU that +the vCPU thread is running on. + +* ARM_SMCCC_VENDOR_HYP_KVM_GET_CPUFREQ_TBL_FUNC_ID: 0x86000042 + +This hypercall uses the SMC32/HVC32 calling convention: + +ARM_SMCCC_VENDOR_HYP_KVM_GET_CPUFREQ_TBL_FUNC_ID + ============== ======== ===================================== + Function ID: (uint32) 0x86000042 + Arguments: (uint32) index of the current CPU's frequency table + Return Values: (int32) NOT_SUPPORTED(-1) on error, or + (uint32) Frequency table entry of requested index + in KHz + of current CPU(r1) + Endianness: Must be the same endianness + as the host. + ============== ======== ===================================== diff --git a/Documentation/virt/kvm/arm/index.rst b/Documentation/virt/kvm/arm/index.rst index f83877663813..e2e56bb41491 100644 --- a/Documentation/virt/kvm/arm/index.rst +++ b/Documentation/virt/kvm/arm/index.rst @@ -13,3 +13,4 @@ ARM ptp_kvm get_cur_cpufreq util_hint + get_freqtbl diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h index 61309ecb7241..ed6f593264bd 100644 --- a/arch/arm64/include/uapi/asm/kvm.h +++ b/arch/arm64/include/uapi/asm/kvm.h @@ -369,6 +369,7 @@ enum { KVM_REG_ARM_VENDOR_HYP_BIT_PTP = 1, KVM_REG_ARM_VENDOR_HYP_BIT_GET_CUR_CPUFREQ = 2, KVM_REG_ARM_VENDOR_HYP_BIT_UTIL_HINT = 3, + KVM_REG_ARM_VENDOR_HYP_BIT_GET_CPUFREQ_TBL = 4, #ifdef __KERNEL__ KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_COUNT, #endif diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index bf3c4d4b9b67..cd76128e4af4 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -222,6 +222,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_ARM_SYSTEM_SUSPEND: case KVM_CAP_GET_CUR_CPUFREQ: case KVM_CAP_UTIL_HINT: + case KVM_CAP_GET_CPUFREQ_TBL: r = 1; break; case KVM_CAP_SET_GUEST_DEBUG2: diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c index 01dba07b5183..6f96579dda80 100644 --- a/arch/arm64/kvm/hypercalls.c +++ b/arch/arm64/kvm/hypercalls.c @@ -42,6 +42,22 @@ static void kvm_sched_set_util(struct kvm_vcpu *vcpu, u64 *val) val[0] = (u64)ret; } +static void kvm_sched_get_cpufreq_table(struct kvm_vcpu *vcpu, u64 *val) +{ + struct cpufreq_policy *policy; + u32 idx = smccc_get_arg1(vcpu); + + policy = cpufreq_cpu_get(task_cpu(current)); + + if (!policy) + return; + + val[0] = SMCCC_RET_SUCCESS; + val[1] = policy->freq_table[idx].frequency; + + cpufreq_cpu_put(policy); +} + static void kvm_ptp_get_time(struct kvm_vcpu *vcpu, u64 *val) { struct system_time_snapshot systime_snapshot; @@ -148,6 +164,9 @@ static bool kvm_hvc_call_allowed(struct kvm_vcpu *vcpu, u32 func_id) case ARM_SMCCC_VENDOR_HYP_KVM_UTIL_HINT_FUNC_ID: return test_bit(KVM_REG_ARM_VENDOR_HYP_BIT_UTIL_HINT, &smccc_feat->vendor_hyp_bmap); + case ARM_SMCCC_VENDOR_HYP_KVM_GET_CPUFREQ_TBL_FUNC_ID: + return test_bit(KVM_REG_ARM_VENDOR_HYP_BIT_GET_CPUFREQ_TBL, + &smccc_feat->vendor_hyp_bmap); default: return kvm_hvc_call_default_allowed(func_id); } @@ -251,6 +270,9 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) case ARM_SMCCC_VENDOR_HYP_KVM_UTIL_HINT_FUNC_ID: kvm_sched_set_util(vcpu, val); break; + case ARM_SMCCC_VENDOR_HYP_KVM_GET_CPUFREQ_TBL_FUNC_ID: + kvm_sched_get_cpufreq_table(vcpu, val); + break; case ARM_SMCCC_TRNG_VERSION: case ARM_SMCCC_TRNG_FEATURES: case ARM_SMCCC_TRNG_GET_UUID: diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h index 9f747e5025b6..19fefb73a9bd 100644 --- a/include/linux/arm-smccc.h +++ b/include/linux/arm-smccc.h @@ -114,6 +114,7 @@ #define ARM_SMCCC_KVM_FUNC_PTP 1 #define ARM_SMCCC_KVM_FUNC_GET_CUR_CPUFREQ 64 #define ARM_SMCCC_KVM_FUNC_UTIL_HINT 65 +#define ARM_SMCCC_KVM_FUNC_GET_CPUFREQ_TBL 66 #define ARM_SMCCC_KVM_FUNC_FEATURES_2 127 #define ARM_SMCCC_KVM_NUM_FUNCS 128 @@ -152,6 +153,12 @@ ARM_SMCCC_OWNER_VENDOR_HYP, \ ARM_SMCCC_KVM_FUNC_UTIL_HINT) +#define ARM_SMCCC_VENDOR_HYP_KVM_GET_CPUFREQ_TBL_FUNC_ID \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_32, \ + ARM_SMCCC_OWNER_VENDOR_HYP, \ + ARM_SMCCC_KVM_FUNC_GET_CPUFREQ_TBL) + /* Paravirtualised time calls (defined by ARM DEN0057A) */ #define ARM_SMCCC_HV_PV_TIME_FEATURES \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 7f667ab344ae..90a7f37f046d 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -1186,6 +1186,7 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_PMU_EVENT_MASKED_EVENTS 226 #define KVM_CAP_GET_CUR_CPUFREQ 512 #define KVM_CAP_UTIL_HINT 513 +#define KVM_CAP_GET_CPUFREQ_TBL 514 #ifdef KVM_CAP_IRQ_ROUTING diff --git a/tools/arch/arm64/include/uapi/asm/kvm.h b/tools/arch/arm64/include/uapi/asm/kvm.h index 61309ecb7241..ebf9a3395c1b 100644 --- a/tools/arch/arm64/include/uapi/asm/kvm.h +++ b/tools/arch/arm64/include/uapi/asm/kvm.h @@ -369,6 +369,7 @@ enum { KVM_REG_ARM_VENDOR_HYP_BIT_PTP = 1, KVM_REG_ARM_VENDOR_HYP_BIT_GET_CUR_CPUFREQ = 2, KVM_REG_ARM_VENDOR_HYP_BIT_UTIL_HINT = 3, + KVM_REG_ARM_VENDOR_HYP_BIT_CPUFREQ_TBL = 4, #ifdef __KERNEL__ KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_COUNT, #endif From patchwork Fri Mar 31 01:43:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Dai X-Patchwork-Id: 669363 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EC289C6FD1D for ; Fri, 31 Mar 2023 01:45:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229842AbjCaBpX (ORCPT ); Thu, 30 Mar 2023 21:45:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49214 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229804AbjCaBpS (ORCPT ); Thu, 30 Mar 2023 21:45:18 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EAAE71882C for ; Thu, 30 Mar 2023 18:45:00 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-5458dde029bso207681507b3.13 for ; Thu, 30 Mar 2023 18:45:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1680227097; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=mcnJNCHDCGQ7Pzom/y/MQEMC0VEcznZRpNuHkAP16dM=; b=M/Dq0K05dn7RZdEyBco1zZW8o9aWbWD0tOGYp2aROenD9B8zG0YkXNU+ypXcmNaQHy 4te0VdM4kG75aRgDJAiNeipUhfEk+8e/2sx5TS12tTIKnwevTbmQxo+lHWm8c4GqVIme 9obizM0C3ozNmYHsi7lUhQIGaKT/Br4nuLulq8WoaCHOkuqxJMA1bY+CMXCC0ew5OUZ4 1jdQ0A+60hb3BK31NK4oiYIATEqSpKYaYoTbaF3+E58KDNOd+GbOm3KRIRxTxJKRucQs fJJk6ss0ykBavcFxwDBDlUhiJ9dG27uWdOFRP7shyzkO7Uda44T+RDaamnaXQVhGcf2m ufIg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680227097; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=mcnJNCHDCGQ7Pzom/y/MQEMC0VEcznZRpNuHkAP16dM=; b=HUNuDKrwdE/eXBvFCbdS3krETxIBswrGsFqx27LZrCJRllNXY+Iv4qnp6wP28lhmss uGT+I4oNbL3pZdxf2v/KlSv6zwH1fh2O6Mr2KhEyRvPZnFr29Fgf+yVLd+Ixe2sVqNiJ mo6oGJeZuggGYcsbaK4WqSOAOJFQ1vGxrttiJLwFxOqYQFeHASld/qbLdaJt4mrZhYhK 43sxGo0h/EmxuAqZyUpkOuvuDtcjCHQz5XEDwQnw/MoC3hMzz4OPbVPoy8g4m6CWpIIk gn8cHdoK9waABhHPbUeM0o/xgtbX5RwwTlvtWGTq/cA7wXKFmmHVSqolAIiWH89dtbOB mXoQ== X-Gm-Message-State: AAQBX9eJlTVhJA5se7IdprlOTrhjIZekRc9CI3LxCIC8kipKYYVLag4G TsC3oizrHxE2t2T1mtd92Pv+f7ilqkcc X-Google-Smtp-Source: AKy350Yd56UldAkJl7asDkNCi90KnSNtQkBy2kVHq8vFVuOOr9KiBt3/jvgItL1ugb+qYv+7kMO0tDmyjIK9 X-Received: from davidai2.mtv.corp.google.com ([2620:15c:211:201:c162:24e8:ec5e:d520]) (user=davidai job=sendgmr) by 2002:a25:344:0:b0:b27:4632:f651 with SMTP id 65-20020a250344000000b00b274632f651mr12517637ybd.3.1680227097054; Thu, 30 Mar 2023 18:44:57 -0700 (PDT) Date: Thu, 30 Mar 2023 18:43:49 -0700 In-Reply-To: <20230331014356.1033759-1-davidai@google.com> Mime-Version: 1.0 References: <20230331014356.1033759-1-davidai@google.com> X-Mailer: git-send-email 2.40.0.348.gf938b09366-goog Message-ID: <20230331014356.1033759-6-davidai@google.com> Subject: [RFC PATCH v2 5/6] dt-bindings: cpufreq: add bindings for virtual kvm cpufreq From: David Dai To: "Rafael J. Wysocki" , Viresh Kumar , Rob Herring , Krzysztof Kozlowski , Paolo Bonzini , Jonathan Corbet , Marc Zyngier , Oliver Upton , James Morse , Suzuki K Poulose , Zenghui Yu , Catalin Marinas , Will Deacon , Mark Rutland , Lorenzo Pieralisi , Sudeep Holla , Ingo Molnar , Peter Zijlstra , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Daniel Bristot de Oliveira , Valentin Schneider , David Dai Cc: Saravana Kannan , kernel-team@android.com, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Add devicetree bindings for a virtual kvm cpufreq driver. Co-developed-by: Saravana Kannan Signed-off-by: Saravana Kannan Signed-off-by: David Dai --- .../bindings/cpufreq/cpufreq-virtual-kvm.yaml | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 Documentation/devicetree/bindings/cpufreq/cpufreq-virtual-kvm.yaml diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-virtual-kvm.yaml b/Documentation/devicetree/bindings/cpufreq/cpufreq-virtual-kvm.yaml new file mode 100644 index 000000000000..31e64558a7f1 --- /dev/null +++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-virtual-kvm.yaml @@ -0,0 +1,39 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/cpufreq/cpufreq-virtual-kvm.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Virtual KVM CPUFreq + +maintainers: + - David Dai + +description: | + + KVM CPUFreq is a virtualized driver in guest kernels that sends utilization + of its vCPUs as a hint to the host. The host uses hint to schedule vCPU + threads and select CPU frequency. It enables accurate Per-Entity Load + Tracking for tasks running in the guest by querying host CPU frequency + unless a virtualized FIE exists(Like AMUs). + +properties: + compatible: + const: virtual,kvm-cpufreq + +required: + - compatible + +additionalProperties: false + +examples: + - | + { + #address-cells = <2>; + #size-cells = <2>; + + cpufreq { + compatible = "virtual,kvm-cpufreq"; + }; + + }; From patchwork Fri Mar 31 01:43:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Dai X-Patchwork-Id: 669582 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5F537C6FD1D for ; Fri, 31 Mar 2023 01:45:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229804AbjCaBph (ORCPT ); Thu, 30 Mar 2023 21:45:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49118 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229869AbjCaBpc (ORCPT ); Thu, 30 Mar 2023 21:45:32 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E6AAE1882F for ; Thu, 30 Mar 2023 18:45:09 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-5461fe3163eso75080367b3.17 for ; Thu, 30 Mar 2023 18:45:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1680227105; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=PafzZUjsN+AldhPHNYx1ZKiIIku0MB5EoRgnFO5S24A=; b=HB0lHXlx14L5D/NQiBNeXH3Bb/uJfxUFQyHKfKt354epcbSI/AILuLAo+0uZNLaPsY nnNLFCOqVFvWeuRRtL7e5TCT+7nlSV8lvh1r69fTKshrt2h1WFYXX1D3i54fGHXWusJb 9kpeKAPIku2v4ZpDGuLc99xr92yltvpON16vudiisZ/ofSc8Yc0obyNK3mu6rE3REMje tU1auuInm7EUr9ILgKZc4u1Du28tHiyrrpOM1ZkV8I+8Gd2LFRpoXH+1KGPKBrr3TOyS pXkqppPZrrAs5bQjNpMNmx9jkSAk63v+BCNKCcALN3BH7MKIHKqKBocRVg1OmLSKrm9G lYHg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680227105; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=PafzZUjsN+AldhPHNYx1ZKiIIku0MB5EoRgnFO5S24A=; b=cqAJXEPHCdNFonY0LadM37upkEDOWrP8Sb7M4/FVtu3GjVKouOZXglQOYlD3GxWdbL 20LcxGTnmuS4xJoL7HmxTacCAiwjJlzp05kdh9JGbGIF4AiChwN/88NLMcMOvJq7v6Oj mWyTfwmDaDlMoJgfn1vrwmMkZ7uGA1FGmaLm2eFBQISumKBLHi8NiHZSg+X8/amF52/o C7M+9r4vbM/rpGeRLUyFPCArX4MT4v1T0Bm9kVIkZdLCKIxb2n7RJsFgjdsMKc8SyKXl Xt7BAGcFHS2Oed2itX2bcPDqVtQ/EhYlzBoTVytaMvob1YW2zNXxmsnT972DJQa+svn6 Qm4g== X-Gm-Message-State: AAQBX9fOUxEskiDacI8wmNCzA7/fxTVS1AYlGFkG9mUxVT8AfX852MZG JmToINkSDe/zO6hBZakVIiJy1AX4Dl5t X-Google-Smtp-Source: AKy350bhSeqs1M+oOYbxOjJLrxdY2ImQyDfl5iisT3zr2AF4dLMixglhW1nhVRQR+6+PArh0sAPeweQXTc9/ X-Received: from davidai2.mtv.corp.google.com ([2620:15c:211:201:c162:24e8:ec5e:d520]) (user=davidai job=sendgmr) by 2002:a25:a323:0:b0:b35:91cc:9e29 with SMTP id d32-20020a25a323000000b00b3591cc9e29mr4229627ybi.5.1680227105606; Thu, 30 Mar 2023 18:45:05 -0700 (PDT) Date: Thu, 30 Mar 2023 18:43:50 -0700 In-Reply-To: <20230331014356.1033759-1-davidai@google.com> Mime-Version: 1.0 References: <20230331014356.1033759-1-davidai@google.com> X-Mailer: git-send-email 2.40.0.348.gf938b09366-goog Message-ID: <20230331014356.1033759-7-davidai@google.com> Subject: [RFC PATCH v2 6/6] cpufreq: add kvm-cpufreq driver From: David Dai To: "Rafael J. Wysocki" , Viresh Kumar , Rob Herring , Krzysztof Kozlowski , Paolo Bonzini , Jonathan Corbet , Marc Zyngier , Oliver Upton , James Morse , Suzuki K Poulose , Zenghui Yu , Catalin Marinas , Will Deacon , Mark Rutland , Lorenzo Pieralisi , Sudeep Holla , Ingo Molnar , Peter Zijlstra , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Daniel Bristot de Oliveira , Valentin Schneider , David Dai Cc: Saravana Kannan , kernel-team@android.com, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Introduce a virtualized cpufreq driver for guest kernels to improve performance and power of workloads within VMs. This driver does two main things: 1. Sends utilization of vCPUs as a hint to the host. The host uses the hint to schedule the vCPU threads and decide physical CPU frequency. 2. If a VM does not support a virtualized FIE(like AMUs), it uses hypercalls to update the guest's frequency scaling factor periodically by querying the host CPU frequency. This enables accurate Per-Entity Load Tracking for tasks running in the guest. Note that because the host already employs a rate_limit_us, we set the transition_delay_us of the cpufreq policy to a miniscule value(1) to avoid any additional delays between when the runqueue's util change and a frequency response on the host. Co-developed-by: Saravana Kannan Signed-off-by: Saravana Kannan Signed-off-by: David Dai --- drivers/cpufreq/Kconfig | 13 ++ drivers/cpufreq/Makefile | 1 + drivers/cpufreq/kvm-cpufreq.c | 245 ++++++++++++++++++++++++++++++++++ include/linux/sched.h | 1 + kernel/sched/core.c | 6 + 5 files changed, 266 insertions(+) create mode 100644 drivers/cpufreq/kvm-cpufreq.c diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index 2c839bd2b051..0ef9d5be7c4d 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig @@ -217,6 +217,19 @@ config CPUFREQ_DT If in doubt, say N. +config CPUFREQ_KVM + tristate "KVM cpufreq driver" + help + This adds a virtualized KVM cpufreq driver for guest kernels that + uses hypercalls to communicate with the host. It sends utilization + updates to the host and gets used to schedule vCPU threads and + select CPU frequency. If a VM does not support a virtualized FIE + such as AMUs, it updates the frequency scaling factor by polling + host CPU frequency to enable accurate Per-Entity Load Tracking + for tasks running in the guest. + + If in doubt, say N. + config CPUFREQ_DT_PLATDEV bool help diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index ef8510774913..179ea8d45135 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_CPU_FREQ_GOV_ATTR_SET) += cpufreq_governor_attr_set.o obj-$(CONFIG_CPUFREQ_DT) += cpufreq-dt.o obj-$(CONFIG_CPUFREQ_DT_PLATDEV) += cpufreq-dt-platdev.o +obj-$(CONFIG_CPUFREQ_KVM) += kvm-cpufreq.o # Traces CFLAGS_amd-pstate-trace.o := -I$(src) diff --git a/drivers/cpufreq/kvm-cpufreq.c b/drivers/cpufreq/kvm-cpufreq.c new file mode 100644 index 000000000000..1542c9ac4119 --- /dev/null +++ b/drivers/cpufreq/kvm-cpufreq.c @@ -0,0 +1,245 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2023 Google LLC + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void kvm_scale_freq_tick(void) +{ + unsigned long scale, cur_freq, max_freq; + struct arm_smccc_res hvc_res; + + arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_KVM_GET_CUR_CPUFREQ_FUNC_ID, + 0, &hvc_res); + + cur_freq = hvc_res.a0; + max_freq = cpufreq_get_hw_max_freq(task_cpu(current)); + scale = (cur_freq << SCHED_CAPACITY_SHIFT) / max_freq; + + this_cpu_write(arch_freq_scale, (unsigned long)scale); +} + +static struct scale_freq_data kvm_sfd = { + .source = SCALE_FREQ_SOURCE_ARCH, + .set_freq_scale = kvm_scale_freq_tick, +}; + +struct remote_data { + int ret; + struct cpufreq_frequency_table *table; +}; + +static void remote_get_freqtbl_num_entries(void *data) +{ + struct arm_smccc_res hvc_res; + u32 freq = 1UL; + int *idx = data; + + while (freq != CPUFREQ_TABLE_END) { + arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_KVM_GET_CPUFREQ_TBL_FUNC_ID, + *idx, &hvc_res); + if (hvc_res.a0) { + *idx = -ENODEV; + return; + } + freq = hvc_res.a1; + (*idx)++; + } +} + +static int kvm_cpufreq_get_freqtbl_num_entries(int cpu) +{ + int num_entries = 0; + + smp_call_function_single(cpu, remote_get_freqtbl_num_entries, &num_entries, true); + return num_entries; +} + +static void remote_populate_freqtbl(void *data) +{ + struct arm_smccc_res hvc_res; + struct remote_data *freq_data = data; + struct cpufreq_frequency_table *pos; + struct cpufreq_frequency_table *table = freq_data->table; + int idx; + + cpufreq_for_each_entry_idx(pos, table, idx) { + arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_KVM_GET_CPUFREQ_TBL_FUNC_ID, + idx, &hvc_res); + if (hvc_res.a0) { + freq_data->ret = -ENODEV; + return; + } + pos->frequency = hvc_res.a1; + } + freq_data->ret = 0; +} + +static int kvm_cpufreq_populate_freqtbl(struct cpufreq_frequency_table *table, int cpu) +{ + struct remote_data freq_data; + + freq_data.table = table; + smp_call_function_single(cpu, remote_populate_freqtbl, &freq_data, true); + return freq_data.ret; +} + +static unsigned int kvm_cpufreq_setutil_hyp(struct cpufreq_policy *policy) +{ + struct arm_smccc_res hvc_res; + u32 util = sched_cpu_util_freq(policy->cpu); + u32 cap = arch_scale_cpu_capacity(policy->cpu); + u32 threshold = cap - (cap >> 2); + + if (util > threshold) + util = (cap + threshold) >> 1; + + arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_KVM_UTIL_HINT_FUNC_ID, + util, &hvc_res); + + return hvc_res.a0; +} + +static unsigned int kvm_cpufreq_fast_switch(struct cpufreq_policy *policy, + unsigned int target_freq) +{ + kvm_cpufreq_setutil_hyp(policy); + return target_freq; +} + +static int kvm_cpufreq_target_index(struct cpufreq_policy *policy, + unsigned int index) +{ + return kvm_cpufreq_setutil_hyp(policy); +} + +static const struct of_device_id kvm_cpufreq_match[] = { + { .compatible = "virtual,kvm-cpufreq"}, + {} +}; +MODULE_DEVICE_TABLE(of, kvm_cpufreq_match); + +static int kvm_cpufreq_cpu_init(struct cpufreq_policy *policy) +{ + struct device *cpu_dev; + struct cpufreq_frequency_table *table; + int num_entries; + + cpu_dev = get_cpu_device(policy->cpu); + if (!cpu_dev) { + pr_err("%s: failed to get cpu%d device\n", __func__, + policy->cpu); + return -ENODEV; + } + + num_entries = kvm_cpufreq_get_freqtbl_num_entries(policy->cpu); + if (num_entries == -ENODEV) + return -ENODEV; + + table = kcalloc(num_entries, sizeof(*table), GFP_KERNEL); + if (!table) + return -ENOMEM; + + table[num_entries-1].frequency = CPUFREQ_TABLE_END; + + if (kvm_cpufreq_populate_freqtbl(table, policy->cpu)) + return -ENODEV; + + policy->freq_table = table; + policy->dvfs_possible_from_any_cpu = false; + policy->fast_switch_possible = true; + policy->transition_delay_us = 1; + + /* + * Only takes effect if another FIE source such as AMUs + * have not been registered. + */ + topology_set_scale_freq_source(&kvm_sfd, policy->cpus); + + return 0; +} + +static int kvm_cpufreq_cpu_exit(struct cpufreq_policy *policy) +{ + kfree(policy->freq_table); + return 0; +} + +static int kvm_cpufreq_online(struct cpufreq_policy *policy) +{ + /* Nothing to restore. */ + return 0; +} + +static int kvm_cpufreq_offline(struct cpufreq_policy *policy) +{ + /* Dummy offline() to avoid exit() being called and freeing resources. */ + return 0; +} + +static struct cpufreq_driver cpufreq_kvm_driver = { + .name = "kvm-cpufreq", + .init = kvm_cpufreq_cpu_init, + .exit = kvm_cpufreq_cpu_exit, + .online = kvm_cpufreq_online, + .offline = kvm_cpufreq_offline, + .verify = cpufreq_generic_frequency_table_verify, + .target_index = kvm_cpufreq_target_index, + .fast_switch = kvm_cpufreq_fast_switch, + .attr = cpufreq_generic_attr, +}; + +static int kvm_cpufreq_driver_probe(struct platform_device *pdev) +{ + int ret; + + ret = cpufreq_register_driver(&cpufreq_kvm_driver); + if (ret) { + dev_err(&pdev->dev, "KVM CPUFreq driver failed to register: %d\n", ret); + return ret; + } + + dev_dbg(&pdev->dev, "KVM CPUFreq driver initialized\n"); + return 0; +} + +static int kvm_cpufreq_driver_remove(struct platform_device *pdev) +{ + cpufreq_unregister_driver(&cpufreq_kvm_driver); + return 0; +} + +static struct platform_driver kvm_cpufreq_driver = { + .probe = kvm_cpufreq_driver_probe, + .remove = kvm_cpufreq_driver_remove, + .driver = { + .name = "kvm-cpufreq", + .of_match_table = kvm_cpufreq_match, + }, +}; + +static int __init kvm_cpufreq_init(void) +{ + return platform_driver_register(&kvm_cpufreq_driver); +} +postcore_initcall(kvm_cpufreq_init); + +static void __exit kvm_cpufreq_exit(void) +{ + platform_driver_unregister(&kvm_cpufreq_driver); +} +module_exit(kvm_cpufreq_exit); + +MODULE_DESCRIPTION("KVM cpufreq driver"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/sched.h b/include/linux/sched.h index d8c346fcdf52..bd38aa32a57c 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -2303,6 +2303,7 @@ static inline bool owner_on_cpu(struct task_struct *owner) /* Returns effective CPU energy utilization, as seen by the scheduler */ unsigned long sched_cpu_util(int cpu); +unsigned long sched_cpu_util_freq(int cpu); #endif /* CONFIG_SMP */ #ifdef CONFIG_RSEQ diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 7700ef5610c1..dd46f4cc629b 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -7421,6 +7421,12 @@ unsigned long sched_cpu_util(int cpu) { return effective_cpu_util(cpu, cpu_util_cfs(cpu), ENERGY_UTIL, NULL); } + +unsigned long sched_cpu_util_freq(int cpu) +{ + return effective_cpu_util(cpu, cpu_util_cfs(cpu), FREQUENCY_UTIL, NULL); +} + #endif /* CONFIG_SMP */ /**