From patchwork Sat Jul 20 16:50:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sivaprasad Tummala X-Patchwork-Id: 142559 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 61B3E45665; Sat, 20 Jul 2024 18:51:10 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 228DD4060F; Sat, 20 Jul 2024 18:51:05 +0200 (CEST) Received: from NAM10-DM6-obe.outbound.protection.outlook.com (mail-dm6nam10on2076.outbound.protection.outlook.com [40.107.93.76]) by mails.dpdk.org (Postfix) with ESMTP id 70B774042E for ; Sat, 20 Jul 2024 18:51:03 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=BBaHAbhEFW9DmCD3plNklfMGCmM1Y3MC+xQn9GQi7rSvYkCwX+L2cPAMHPr6O859RH5GwGbfkAyZEDF4f4O42N8YIWwjlNOKQd/w9pmka+Yp5FZo+u8jyok2xJxoMwyW2YfW5095dfQ+L0f+8BF1Z0MnwyREnFbKhwhDHHaLDSAoq/u+cydGiSiI7WTIJt1kEr8xL8+icjbS75qfQZ4nvb41uriis7iYJDX8P0EuHTHWmxFaSl5U77RsfXnE9otZe3gGDwrbf+SAneJFvyBB9N89tDmIovliIFoc7G/N9sSLzqgYGX/CBUginkVlZDZa/3TlHko+PU9YMJzX1VrEsw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=Z1wKrp0akkaEasA7F55ssGPKhL/NljulSUg5qGnnkCU=; b=Ft2O9FnPd8f5d1qfBFg/q82HfgAzSMECp7RZJmGL/eK7yon4zg5G68O9oBmvM/dvPAmuvwkcjcGmgD+m5STwMZaOcUncBI+S4Qs/QeXgQQ2UC+acxO+zZgisa22sgJMNokMdOU55HLMVbDTmLaBry2sdeAKZGikoDhxEcTQ9KuzW51YUgkn87G0xANxYpJP/5xMiV3VRgX6njX5dTnYFD95MxzRo0W4TwqnerHhz33Qra6tE0Z55ic2f/yuJWr/2vOQQPTfAYrE2l+Pw2oEgdR70AYNudNNLkTvObkd80uG11UyRuoPFKJr0zqGELzQr+vMBQ0TY5I8N9rzpLRZ0vA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=intel.com smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Z1wKrp0akkaEasA7F55ssGPKhL/NljulSUg5qGnnkCU=; b=2ItqMZLXlbJQvYqIIzY0tcHyTgshwhT9Xvr/jIgXTYYop60vk63xHJForlu1aJ0zlrKhYOiLQvtnShXK84tC0Rfzu7rtddp/h3DwZp+Wj+D6EJOruqkw0B6ySL9XJdpAsbFuvyubtfgEB8db/1E1u+P/QTm6SjDF6fp4MArh45I= Received: from MN2PR16CA0052.namprd16.prod.outlook.com (2603:10b6:208:234::21) by SA1PR12MB7151.namprd12.prod.outlook.com (2603:10b6:806:2b1::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7784.14; Sat, 20 Jul 2024 16:50:58 +0000 Received: from BL6PEPF0001AB52.namprd02.prod.outlook.com (2603:10b6:208:234:cafe::2c) by MN2PR16CA0052.outlook.office365.com (2603:10b6:208:234::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7784.16 via Frontend Transport; Sat, 20 Jul 2024 16:50:58 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by BL6PEPF0001AB52.mail.protection.outlook.com (10.167.241.4) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.7784.11 via Frontend Transport; Sat, 20 Jul 2024 16:50:57 +0000 Received: from jfw9ny3-os.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Sat, 20 Jul 2024 11:50:54 -0500 From: Sivaprasad Tummala To: , , , , , , CC: Subject: [PATCH v1 1/4] power: refactor core power management library Date: Sat, 20 Jul 2024 16:50:26 +0000 Message-ID: <20240720165030.246294-2-sivaprasad.tummala@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240720165030.246294-1-sivaprasad.tummala@amd.com> References: <20240220153326.6236-1-sivaprasad.tummala@amd.com> <20240720165030.246294-1-sivaprasad.tummala@amd.com> MIME-Version: 1.0 X-Originating-IP: [10.180.168.240] X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BL6PEPF0001AB52:EE_|SA1PR12MB7151:EE_ X-MS-Office365-Filtering-Correlation-Id: dac3a8ba-2430-4cc5-5bd0-08dca8dc2102 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|82310400026|376014|36860700013|1800799024; X-Microsoft-Antispam-Message-Info: pLHiVBWlI6SO0OwHK6OIFWq7Uo3zGyUYw1dMQ1aFYPGONbVmzvTSRrEeL6fUYP2vqFb+Fp2q13Sh6/Ycqz9YlNDGngqzq826F8i33sdE+zlLEMqjn+aFi8lueCqA8SPA0N75VSHh/vz88CqA9XBcH7SXg+MkxmdJ92iBBwbZ8CeyEnXR1BRDaqrCH6sEN75/bkpji/lw19a5rG1Opvud8y23G6E4Ij/D3aEHKlFcoScdqEDxvszd3oB1dabLrL8O+4rBUKVcnt03OMcMR2n4DkoKnvxCFAHPWm2eamnJgZkzqKXBBrXsMQpPuq9UtU7xVLNCJZSs9+GbxvLPgl9JpRpW/fpfqmkPHDtdDjdADnTrkSYIUs58Z3CwAEtI6z8jrKzFWQR/O/2xziBMjpWuMyD5Se8HSU6pxYSMEwA5dnD8ynhAV1zT9Nazh+WLZP/7XaJ+ZNsNXmaZ0RWvgenKUAdPhDTUAGq3mPI4KnU+VKgkHJky9fb8oAOy54niRSYxmNwNLeIV3GmMmWV41zXVFZP6YdZrGawNcVBHdCGmT5nta8VLm/e7BeyzggKU67fdgoKQKPPdFtCXAElNWjOYuQn+uTQzkrLCRBf4P09Kv3Fa80qr+oETO9h+fW8ATcxRvkT7lDjSVWrEW1pfhtZ83BlLPAiwad15/a8vg6U+kSagO4z9cLla0q6t2Pid8bM07Ycl15ZSsURpA7/HXWKGZKvRvTrQAh7XeK4TCG3YmpDzbYTo2NabqKzHLtyavcax6oC45wNZ+uJ0z3qENMFZkCPc10fTW2EzAFqcN7Fnmh/etiylccWeXXAMAalnpuW5yyMPhFa6rYsjtXgv9nYUeAXA4tWBRFnj6NtVY5kL+xYQZtFUZDHboIi8HW4dwDV3nVvQfSzEuI1Pg8Qxv24Lu2rXPefIk64KumN0C4WPOU427CkSyQIAi9ap7RKtwydGITA4yAiUCQW9Y1TORMFkpMIjPuZoeFw8VY1cw8gTF3ZqdRU8aVfUuUK34NEUDjR2k+CBbQoDAz3SR9ejwgudcIvQc8m8FfgV2sy9hPmtcz10qH26lbUngaIbkgXhC1ROsocNT0tyiBFilGQX5qGuMMwIUMVD4U7uuk3eVvAdrepjyVpEGf/guUHQcm9CtUG3IWxiUKQh0p0qeiCD9QpQQV//GRIbwosEqCYJIUI9sD/Df1cbS24U99ptPNIZPtwMl5SN1uLoq7FSFYrTRASFHSeWD3/QqqGK/6akV0sGon8JLtSNyJlRdA04mSwKL9rpZFaxKU3eyeZ1Cp38yyHgerVokAWQ89k7N2BGx1Pr18WEQyWOae8ObO9dWxaz6waiQtTrPF5B+c/odHj4kROYaKKC2r5qgHPokujgZ2dYmL6pmm8zVD1CEX1EGQfAFDhLF16d0MSdIvDK2/hNqO3Inu3g+mx+xq+JrLYPp4gJ7haX8ARMwI0c8lmbx/kovBOl X-Forefront-Antispam-Report: CIP:165.204.84.17; CTRY:US; LANG:en; SCL:1; SRV:; IPV:CAL; SFV:NSPM; H:SATLEXMB04.amd.com; PTR:InfoDomainNonexistent; CAT:NONE; SFS:(13230040)(82310400026)(376014)(36860700013)(1800799024); DIR:OUT; SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 20 Jul 2024 16:50:57.9060 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: dac3a8ba-2430-4cc5-5bd0-08dca8dc2102 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d; Ip=[165.204.84.17]; Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: BL6PEPF0001AB52.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA1PR12MB7151 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org This patch introduces a comprehensive refactor to the core power management library. The primary focus is on improving modularity and organization by relocating specific driver implementations from the 'lib/power' directory to dedicated directories within 'drivers/power/core/*'. The adjustment of meson.build files enables the selective activation of individual drivers. These changes contribute to a significant enhancement in code organization, providing a clearer structure for driver implementations. The refactor aims to improve overall code clarity and boost maintainability. Additionally, it establishes a foundation for future development, allowing for more focused work on individual drivers and seamless integration of forthcoming enhancements. Signed-off-by: Sivaprasad Tummala Signed-off-by: Sivaprasad Tummala --- drivers/meson.build | 1 + .../power/acpi/acpi_cpufreq.c | 22 +- .../power/acpi/acpi_cpufreq.h | 6 +- drivers/power/acpi/meson.build | 10 + .../power/amd_pstate/amd_pstate_cpufreq.c | 24 +- .../power/amd_pstate/amd_pstate_cpufreq.h | 8 +- drivers/power/amd_pstate/meson.build | 10 + .../power/cppc/cppc_cpufreq.c | 22 +- .../power/cppc/cppc_cpufreq.h | 8 +- drivers/power/cppc/meson.build | 10 + .../power/kvm_vm}/guest_channel.c | 0 .../power/kvm_vm}/guest_channel.h | 0 .../power/kvm_vm/kvm_vm.c | 22 +- .../power/kvm_vm/kvm_vm.h | 6 +- drivers/power/kvm_vm/meson.build | 16 + drivers/power/meson.build | 12 + drivers/power/pstate/meson.build | 10 + .../power/pstate/pstate_cpufreq.c | 22 +- .../power/pstate/pstate_cpufreq.h | 6 +- lib/power/meson.build | 7 +- lib/power/power_common.c | 2 +- lib/power/power_common.h | 16 +- lib/power/rte_power.c | 287 ++++++------------ lib/power/rte_power.h | 139 ++++++--- lib/power/rte_power_core_ops.h | 208 +++++++++++++ lib/power/version.map | 14 + 26 files changed, 618 insertions(+), 270 deletions(-) rename lib/power/power_acpi_cpufreq.c => drivers/power/acpi/acpi_cpufreq.c (95%) rename lib/power/power_acpi_cpufreq.h => drivers/power/acpi/acpi_cpufreq.h (98%) create mode 100644 drivers/power/acpi/meson.build rename lib/power/power_amd_pstate_cpufreq.c => drivers/power/amd_pstate/amd_pstate_cpufreq.c (95%) rename lib/power/power_amd_pstate_cpufreq.h => drivers/power/amd_pstate/amd_pstate_cpufreq.h (97%) create mode 100644 drivers/power/amd_pstate/meson.build rename lib/power/power_cppc_cpufreq.c => drivers/power/cppc/cppc_cpufreq.c (95%) rename lib/power/power_cppc_cpufreq.h => drivers/power/cppc/cppc_cpufreq.h (97%) create mode 100644 drivers/power/cppc/meson.build rename {lib/power => drivers/power/kvm_vm}/guest_channel.c (100%) rename {lib/power => drivers/power/kvm_vm}/guest_channel.h (100%) rename lib/power/power_kvm_vm.c => drivers/power/kvm_vm/kvm_vm.c (82%) rename lib/power/power_kvm_vm.h => drivers/power/kvm_vm/kvm_vm.h (98%) create mode 100644 drivers/power/kvm_vm/meson.build create mode 100644 drivers/power/meson.build create mode 100644 drivers/power/pstate/meson.build rename lib/power/power_pstate_cpufreq.c => drivers/power/pstate/pstate_cpufreq.c (96%) rename lib/power/power_pstate_cpufreq.h => drivers/power/pstate/pstate_cpufreq.h (98%) create mode 100644 lib/power/rte_power_core_ops.h diff --git a/drivers/meson.build b/drivers/meson.build index 66931d4241..9d77e0deab 100644 --- a/drivers/meson.build +++ b/drivers/meson.build @@ -29,6 +29,7 @@ subdirs = [ 'event', # depends on common, bus, mempool and net. 'baseband', # depends on common and bus. 'gpu', # depends on common and bus. + 'power', # depends on common (in future). ] if meson.is_cross_build() diff --git a/lib/power/power_acpi_cpufreq.c b/drivers/power/acpi/acpi_cpufreq.c similarity index 95% rename from lib/power/power_acpi_cpufreq.c rename to drivers/power/acpi/acpi_cpufreq.c index 81996e1c13..8637c69703 100644 --- a/lib/power/power_acpi_cpufreq.c +++ b/drivers/power/acpi/acpi_cpufreq.c @@ -10,7 +10,7 @@ #include #include -#include "power_acpi_cpufreq.h" +#include "acpi_cpufreq.h" #include "power_common.h" #define STR_SIZE 1024 @@ -577,3 +577,23 @@ int power_acpi_get_capabilities(unsigned int lcore_id, return 0; } + +static struct rte_power_core_ops acpi_ops = { + .name = "acpi", + .init = power_acpi_cpufreq_init, + .exit = power_acpi_cpufreq_exit, + .check_env_support = power_acpi_cpufreq_check_supported, + .get_avail_freqs = power_acpi_cpufreq_freqs, + .get_freq = power_acpi_cpufreq_get_freq, + .set_freq = power_acpi_cpufreq_set_freq, + .freq_down = power_acpi_cpufreq_freq_down, + .freq_up = power_acpi_cpufreq_freq_up, + .freq_max = power_acpi_cpufreq_freq_max, + .freq_min = power_acpi_cpufreq_freq_min, + .turbo_status = power_acpi_turbo_status, + .enable_turbo = power_acpi_enable_turbo, + .disable_turbo = power_acpi_disable_turbo, + .get_caps = power_acpi_get_capabilities +}; + +RTE_POWER_REGISTER_OPS(acpi_ops); diff --git a/lib/power/power_acpi_cpufreq.h b/drivers/power/acpi/acpi_cpufreq.h similarity index 98% rename from lib/power/power_acpi_cpufreq.h rename to drivers/power/acpi/acpi_cpufreq.h index 682fd9278c..1194a7e2a5 100644 --- a/lib/power/power_acpi_cpufreq.h +++ b/drivers/power/acpi/acpi_cpufreq.h @@ -2,15 +2,15 @@ * Copyright(c) 2010-2014 Intel Corporation */ -#ifndef _POWER_ACPI_CPUFREQ_H -#define _POWER_ACPI_CPUFREQ_H +#ifndef _ACPI_CPUFREQ_H +#define _ACPI_CPUFREQ_H /** * @file * RTE Power Management via userspace ACPI cpufreq */ -#include "rte_power.h" +#include "rte_power_core_ops.h" /** * Check if ACPI power management is supported. diff --git a/drivers/power/acpi/meson.build b/drivers/power/acpi/meson.build new file mode 100644 index 0000000000..f5afc893ce --- /dev/null +++ b/drivers/power/acpi/meson.build @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2024 Advanced Micro Devices, Inc. + +if not is_linux + build = false + reason = 'only supported on Linux' +endif +sources = files('acpi_cpufreq.c') + +deps += ['power'] diff --git a/lib/power/power_amd_pstate_cpufreq.c b/drivers/power/amd_pstate/amd_pstate_cpufreq.c similarity index 95% rename from lib/power/power_amd_pstate_cpufreq.c rename to drivers/power/amd_pstate/amd_pstate_cpufreq.c index 090a0d96cb..f571f4184a 100644 --- a/lib/power/power_amd_pstate_cpufreq.c +++ b/drivers/power/amd_pstate/amd_pstate_cpufreq.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright(c) 2010-2021 Intel Corporation * Copyright(c) 2021 Arm Limited - * Copyright(c) 2023 Amd Limited + * Copyright(c) 2024 Advanced Micro Devices, Inc. */ #include @@ -9,7 +9,7 @@ #include #include -#include "power_amd_pstate_cpufreq.h" +#include "amd_pstate_cpufreq.h" #include "power_common.h" /* macros used for rounding frequency to nearest 1000 */ @@ -700,3 +700,23 @@ power_amd_pstate_get_capabilities(unsigned int lcore_id, return 0; } + +static struct rte_power_core_ops amd_pstate_ops = { + .name = "amd-pstate", + .init = power_amd_pstate_cpufreq_init, + .exit = power_amd_pstate_cpufreq_exit, + .check_env_support = power_amd_pstate_cpufreq_check_supported, + .get_avail_freqs = power_amd_pstate_cpufreq_freqs, + .get_freq = power_amd_pstate_cpufreq_get_freq, + .set_freq = power_amd_pstate_cpufreq_set_freq, + .freq_down = power_amd_pstate_cpufreq_freq_down, + .freq_up = power_amd_pstate_cpufreq_freq_up, + .freq_max = power_amd_pstate_cpufreq_freq_max, + .freq_min = power_amd_pstate_cpufreq_freq_min, + .turbo_status = power_amd_pstate_turbo_status, + .enable_turbo = power_amd_pstate_enable_turbo, + .disable_turbo = power_amd_pstate_disable_turbo, + .get_caps = power_amd_pstate_get_capabilities +}; + +RTE_POWER_REGISTER_OPS(amd_pstate_ops); diff --git a/lib/power/power_amd_pstate_cpufreq.h b/drivers/power/amd_pstate/amd_pstate_cpufreq.h similarity index 97% rename from lib/power/power_amd_pstate_cpufreq.h rename to drivers/power/amd_pstate/amd_pstate_cpufreq.h index b02f9f98e4..b04b2f28c0 100644 --- a/lib/power/power_amd_pstate_cpufreq.h +++ b/drivers/power/amd_pstate/amd_pstate_cpufreq.h @@ -1,18 +1,18 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright(c) 2010-2021 Intel Corporation * Copyright(c) 2021 Arm Limited - * Copyright(c) 2023 Amd Limited + * Copyright(c) 2024 Advanced Micro Devices, Inc. */ -#ifndef _POWER_AMD_PSTATE_CPUFREQ_H -#define _POWER_AMD_PSTATE_CPUFREQ_H +#ifndef _AMD_PSTATE_CPUFREQ_H +#define _AMD_PSTATE_CPUFREQ_H /** * @file * RTE Power Management via userspace AMD pstate cpufreq */ -#include "rte_power.h" +#include "rte_power_core_ops.h" /** * Check if amd p-state power management is supported. diff --git a/drivers/power/amd_pstate/meson.build b/drivers/power/amd_pstate/meson.build new file mode 100644 index 0000000000..acaf20b388 --- /dev/null +++ b/drivers/power/amd_pstate/meson.build @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2024 Advanced Micro Devices, Inc. + +if not is_linux + build = false + reason = 'only supported on Linux' +endif +sources = files('amd_pstate_cpufreq.c') + +deps += ['power'] diff --git a/lib/power/power_cppc_cpufreq.c b/drivers/power/cppc/cppc_cpufreq.c similarity index 95% rename from lib/power/power_cppc_cpufreq.c rename to drivers/power/cppc/cppc_cpufreq.c index 32aaacb948..775b8f4434 100644 --- a/lib/power/power_cppc_cpufreq.c +++ b/drivers/power/cppc/cppc_cpufreq.c @@ -8,7 +8,7 @@ #include #include -#include "power_cppc_cpufreq.h" +#include "cppc_cpufreq.h" #include "power_common.h" /* macros used for rounding frequency to nearest 100000 */ @@ -685,3 +685,23 @@ power_cppc_get_capabilities(unsigned int lcore_id, return 0; } + +static struct rte_power_core_ops cppc_ops = { + .name = "cppc", + .init = power_cppc_cpufreq_init, + .exit = power_cppc_cpufreq_exit, + .check_env_support = power_cppc_cpufreq_check_supported, + .get_avail_freqs = power_cppc_cpufreq_freqs, + .get_freq = power_cppc_cpufreq_get_freq, + .set_freq = power_cppc_cpufreq_set_freq, + .freq_down = power_cppc_cpufreq_freq_down, + .freq_up = power_cppc_cpufreq_freq_up, + .freq_max = power_cppc_cpufreq_freq_max, + .freq_min = power_cppc_cpufreq_freq_min, + .turbo_status = power_cppc_turbo_status, + .enable_turbo = power_cppc_enable_turbo, + .disable_turbo = power_cppc_disable_turbo, + .get_caps = power_cppc_get_capabilities +}; + +RTE_POWER_REGISTER_OPS(cppc_ops); diff --git a/lib/power/power_cppc_cpufreq.h b/drivers/power/cppc/cppc_cpufreq.h similarity index 97% rename from lib/power/power_cppc_cpufreq.h rename to drivers/power/cppc/cppc_cpufreq.h index f4121b237e..d6e32fdd47 100644 --- a/lib/power/power_cppc_cpufreq.h +++ b/drivers/power/cppc/cppc_cpufreq.h @@ -3,15 +3,15 @@ * Copyright(c) 2021 Arm Limited */ -#ifndef _POWER_CPPC_CPUFREQ_H -#define _POWER_CPPC_CPUFREQ_H +#ifndef _CPPC_CPUFREQ_H +#define _CPPC_CPUFREQ_H /** * @file * RTE Power Management via userspace CPPC cpufreq */ -#include "rte_power.h" +#include "rte_power_core_ops.h" /** * Check if CPPC power management is supported. @@ -215,4 +215,4 @@ int power_cppc_disable_turbo(unsigned int lcore_id); int power_cppc_get_capabilities(unsigned int lcore_id, struct rte_power_core_capabilities *caps); -#endif /* _POWER_CPPC_CPUFREQ_H */ +#endif /* _CPPC_CPUFREQ_H */ diff --git a/drivers/power/cppc/meson.build b/drivers/power/cppc/meson.build new file mode 100644 index 0000000000..f1948cd424 --- /dev/null +++ b/drivers/power/cppc/meson.build @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2024 Advanced Micro Devices, Inc. + +if not is_linux + build = false + reason = 'only supported on Linux' +endif +sources = files('cppc_cpufreq.c') + +deps += ['power'] diff --git a/lib/power/guest_channel.c b/drivers/power/kvm_vm/guest_channel.c similarity index 100% rename from lib/power/guest_channel.c rename to drivers/power/kvm_vm/guest_channel.c diff --git a/lib/power/guest_channel.h b/drivers/power/kvm_vm/guest_channel.h similarity index 100% rename from lib/power/guest_channel.h rename to drivers/power/kvm_vm/guest_channel.h diff --git a/lib/power/power_kvm_vm.c b/drivers/power/kvm_vm/kvm_vm.c similarity index 82% rename from lib/power/power_kvm_vm.c rename to drivers/power/kvm_vm/kvm_vm.c index f15be8fac5..a1342dcd8b 100644 --- a/lib/power/power_kvm_vm.c +++ b/drivers/power/kvm_vm/kvm_vm.c @@ -9,7 +9,7 @@ #include "rte_power_guest_channel.h" #include "guest_channel.h" #include "power_common.h" -#include "power_kvm_vm.h" +#include "kvm_vm.h" #define FD_PATH "/dev/virtio-ports/virtio.serial.port.poweragent" @@ -137,3 +137,23 @@ int power_kvm_vm_get_capabilities(__rte_unused unsigned int lcore_id, POWER_LOG(ERR, "rte_power_get_capabilities is not implemented for Virtual Machine Power Management"); return -ENOTSUP; } + +static struct rte_power_core_ops kvm_vm_ops = { + .name = "kvm-vm", + .init = power_kvm_vm_init, + .exit = power_kvm_vm_exit, + .check_env_support = power_kvm_vm_check_supported, + .get_avail_freqs = power_kvm_vm_freqs, + .get_freq = power_kvm_vm_get_freq, + .set_freq = power_kvm_vm_set_freq, + .freq_down = power_kvm_vm_freq_down, + .freq_up = power_kvm_vm_freq_up, + .freq_max = power_kvm_vm_freq_max, + .freq_min = power_kvm_vm_freq_min, + .turbo_status = power_kvm_vm_turbo_status, + .enable_turbo = power_kvm_vm_enable_turbo, + .disable_turbo = power_kvm_vm_disable_turbo, + .get_caps = power_kvm_vm_get_capabilities +}; + +RTE_POWER_REGISTER_OPS(kvm_vm_ops); diff --git a/lib/power/power_kvm_vm.h b/drivers/power/kvm_vm/kvm_vm.h similarity index 98% rename from lib/power/power_kvm_vm.h rename to drivers/power/kvm_vm/kvm_vm.h index 303fcc041b..64086a67e7 100644 --- a/lib/power/power_kvm_vm.h +++ b/drivers/power/kvm_vm/kvm_vm.h @@ -2,15 +2,15 @@ * Copyright(c) 2010-2014 Intel Corporation */ -#ifndef _POWER_KVM_VM_H -#define _POWER_KVM_VM_H +#ifndef _KVM_VM_H +#define _KVM_VM_H /** * @file * RTE Power Management KVM VM */ -#include "rte_power.h" +#include "rte_power_core_ops.h" /** * Check if KVM power management is supported. diff --git a/drivers/power/kvm_vm/meson.build b/drivers/power/kvm_vm/meson.build new file mode 100644 index 0000000000..405524ce7c --- /dev/null +++ b/drivers/power/kvm_vm/meson.build @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(C) 2024 Advanced Micro Devices, Inc. +# + +if not is_linux + build = false + reason = 'only supported on Linux' + subdir_done() +endif + +sources = files( + 'guest_channel.c', + 'kvm_vm.c', +) + +deps += ['power'] diff --git a/drivers/power/meson.build b/drivers/power/meson.build new file mode 100644 index 0000000000..8c7215c639 --- /dev/null +++ b/drivers/power/meson.build @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2024 Advanced Micro Devices, Inc. + +drivers = [ + 'acpi', + 'amd_pstate', + 'cppc', + 'kvm_vm', + 'pstate' +] + +std_deps = ['power'] diff --git a/drivers/power/pstate/meson.build b/drivers/power/pstate/meson.build new file mode 100644 index 0000000000..9cd47833fb --- /dev/null +++ b/drivers/power/pstate/meson.build @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2024 Advanced Micro Devices, Inc. + +if not is_linux + build = false + reason = 'only supported on Linux' +endif +sources = files('pstate_cpufreq.c') + +deps += ['power'] diff --git a/lib/power/power_pstate_cpufreq.c b/drivers/power/pstate/pstate_cpufreq.c similarity index 96% rename from lib/power/power_pstate_cpufreq.c rename to drivers/power/pstate/pstate_cpufreq.c index 2343121621..c32b1adabc 100644 --- a/lib/power/power_pstate_cpufreq.c +++ b/drivers/power/pstate/pstate_cpufreq.c @@ -15,7 +15,7 @@ #include #include "rte_power_pmd_mgmt.h" -#include "power_pstate_cpufreq.h" +#include "pstate_cpufreq.h" #include "power_common.h" /* macros used for rounding frequency to nearest 100000 */ @@ -888,3 +888,23 @@ int power_pstate_get_capabilities(unsigned int lcore_id, return 0; } + +static struct rte_power_core_ops pstate_ops = { + .name = "pstate", + .init = power_pstate_cpufreq_init, + .exit = power_pstate_cpufreq_exit, + .check_env_support = power_pstate_cpufreq_check_supported, + .get_avail_freqs = power_pstate_cpufreq_freqs, + .get_freq = power_pstate_cpufreq_get_freq, + .set_freq = power_pstate_cpufreq_set_freq, + .freq_down = power_pstate_cpufreq_freq_down, + .freq_up = power_pstate_cpufreq_freq_up, + .freq_max = power_pstate_cpufreq_freq_max, + .freq_min = power_pstate_cpufreq_freq_min, + .turbo_status = power_pstate_turbo_status, + .enable_turbo = power_pstate_enable_turbo, + .disable_turbo = power_pstate_disable_turbo, + .get_caps = power_pstate_get_capabilities +}; + +RTE_POWER_REGISTER_OPS(pstate_ops); diff --git a/lib/power/power_pstate_cpufreq.h b/drivers/power/pstate/pstate_cpufreq.h similarity index 98% rename from lib/power/power_pstate_cpufreq.h rename to drivers/power/pstate/pstate_cpufreq.h index 7bf64a518c..8b67b2da21 100644 --- a/lib/power/power_pstate_cpufreq.h +++ b/drivers/power/pstate/pstate_cpufreq.h @@ -2,15 +2,15 @@ * Copyright(c) 2018 Intel Corporation */ -#ifndef _POWER_PSTATE_CPUFREQ_H -#define _POWER_PSTATE_CPUFREQ_H +#ifndef _PSTATE_CPUFREQ_H +#define _PSTATE_CPUFREQ_H /** * @file * RTE Power Management via Intel Pstate driver */ -#include "rte_power.h" +#include "rte_power_core_ops.h" /** * Check if pstate power management is supported. diff --git a/lib/power/meson.build b/lib/power/meson.build index b8426589b2..f3e3451cdc 100644 --- a/lib/power/meson.build +++ b/lib/power/meson.build @@ -12,20 +12,15 @@ if not is_linux reason = 'only supported on Linux' endif sources = files( - 'guest_channel.c', - 'power_acpi_cpufreq.c', - 'power_amd_pstate_cpufreq.c', 'power_common.c', - 'power_cppc_cpufreq.c', - 'power_kvm_vm.c', 'power_intel_uncore.c', - 'power_pstate_cpufreq.c', 'rte_power.c', 'rte_power_uncore.c', 'rte_power_pmd_mgmt.c', ) headers = files( 'rte_power.h', + 'rte_power_core_ops.h', 'rte_power_guest_channel.h', 'rte_power_pmd_mgmt.h', 'rte_power_uncore.h', diff --git a/lib/power/power_common.c b/lib/power/power_common.c index 590986d5ef..6c06411e8b 100644 --- a/lib/power/power_common.c +++ b/lib/power/power_common.c @@ -12,7 +12,7 @@ #include "power_common.h" -RTE_LOG_REGISTER_DEFAULT(power_logtype, INFO); +RTE_LOG_REGISTER_DEFAULT(rte_power_logtype, INFO); #define POWER_SYSFILE_SCALING_DRIVER \ "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_driver" diff --git a/lib/power/power_common.h b/lib/power/power_common.h index 83f742f42a..767686ee12 100644 --- a/lib/power/power_common.h +++ b/lib/power/power_common.h @@ -6,12 +6,13 @@ #define _POWER_COMMON_H_ #include +#include #include #define RTE_POWER_INVALID_FREQ_INDEX (~0) -extern int power_logtype; -#define RTE_LOGTYPE_POWER power_logtype +extern int rte_power_logtype; +#define RTE_LOGTYPE_POWER rte_power_logtype #define POWER_LOG(level, ...) \ RTE_LOG_LINE(level, POWER, "" __VA_ARGS__) @@ -23,13 +24,24 @@ extern int power_logtype; #endif /* check if scaling driver matches one we want */ +__rte_internal int cpufreq_check_scaling_driver(const char *driver); + +__rte_internal int power_set_governor(unsigned int lcore_id, const char *new_governor, char *orig_governor, size_t orig_governor_len); + +__rte_internal int open_core_sysfs_file(FILE **f, const char *mode, const char *format, ...) __rte_format_printf(3, 4); + +__rte_internal int read_core_sysfs_u32(FILE *f, uint32_t *val); + +__rte_internal int read_core_sysfs_s(FILE *f, char *buf, unsigned int len); + +__rte_internal int write_core_sysfs_s(FILE *f, const char *str); #endif /* _POWER_COMMON_H_ */ diff --git a/lib/power/rte_power.c b/lib/power/rte_power.c index 36c3f3da98..8afb5949b9 100644 --- a/lib/power/rte_power.c +++ b/lib/power/rte_power.c @@ -8,153 +8,86 @@ #include #include "rte_power.h" -#include "power_acpi_cpufreq.h" -#include "power_cppc_cpufreq.h" #include "power_common.h" -#include "power_kvm_vm.h" -#include "power_pstate_cpufreq.h" -#include "power_amd_pstate_cpufreq.h" -enum power_management_env global_default_env = PM_ENV_NOT_SET; +static enum power_management_env global_default_env = PM_ENV_NOT_SET; +static struct rte_power_core_ops *global_power_core_ops; static rte_spinlock_t global_env_cfg_lock = RTE_SPINLOCK_INITIALIZER; +static RTE_TAILQ_HEAD(, rte_power_core_ops) core_ops_list = + TAILQ_HEAD_INITIALIZER(core_ops_list); -/* function pointers */ -rte_power_freqs_t rte_power_freqs = NULL; -rte_power_get_freq_t rte_power_get_freq = NULL; -rte_power_set_freq_t rte_power_set_freq = NULL; -rte_power_freq_change_t rte_power_freq_up = NULL; -rte_power_freq_change_t rte_power_freq_down = NULL; -rte_power_freq_change_t rte_power_freq_max = NULL; -rte_power_freq_change_t rte_power_freq_min = NULL; -rte_power_freq_change_t rte_power_turbo_status; -rte_power_freq_change_t rte_power_freq_enable_turbo; -rte_power_freq_change_t rte_power_freq_disable_turbo; -rte_power_get_capabilities_t rte_power_get_capabilities; -static void -reset_power_function_ptrs(void) +const char *power_env_str[] = { + "not set", + "acpi", + "kvm-vm", + "pstate", + "cppc", + "amd-pstate" +}; + +/* register the ops struct in rte_power_core_ops, return 0 on success. */ +int +rte_power_register_ops(struct rte_power_core_ops *driver_ops) { - rte_power_freqs = NULL; - rte_power_get_freq = NULL; - rte_power_set_freq = NULL; - rte_power_freq_up = NULL; - rte_power_freq_down = NULL; - rte_power_freq_max = NULL; - rte_power_freq_min = NULL; - rte_power_turbo_status = NULL; - rte_power_freq_enable_turbo = NULL; - rte_power_freq_disable_turbo = NULL; - rte_power_get_capabilities = NULL; + if (!driver_ops->init || !driver_ops->exit || + !driver_ops->check_env_support || !driver_ops->get_avail_freqs || + !driver_ops->get_freq || !driver_ops->set_freq || + !driver_ops->freq_up || !driver_ops->freq_down || + !driver_ops->freq_max || !driver_ops->freq_min || + !driver_ops->turbo_status || !driver_ops->enable_turbo || + !driver_ops->disable_turbo || !driver_ops->get_caps) { + POWER_LOG(ERR, "Missing callbacks while registering power ops"); + return -EINVAL; + } + + TAILQ_INSERT_TAIL(&core_ops_list, driver_ops, next); + + return 0; } int rte_power_check_env_supported(enum power_management_env env) { - switch (env) { - case PM_ENV_ACPI_CPUFREQ: - return power_acpi_cpufreq_check_supported(); - case PM_ENV_PSTATE_CPUFREQ: - return power_pstate_cpufreq_check_supported(); - case PM_ENV_KVM_VM: - return power_kvm_vm_check_supported(); - case PM_ENV_CPPC_CPUFREQ: - return power_cppc_cpufreq_check_supported(); - case PM_ENV_AMD_PSTATE_CPUFREQ: - return power_amd_pstate_cpufreq_check_supported(); - default: - rte_errno = EINVAL; - return -1; - } + struct rte_power_core_ops *ops; + + if (env >= RTE_DIM(power_env_str)) + return 0; + + RTE_TAILQ_FOREACH(ops, &core_ops_list, next) + if (strncmp(ops->name, power_env_str[env], + RTE_POWER_DRIVER_NAMESZ) == 0) + return ops->check_env_support(); + + return 0; } int rte_power_set_env(enum power_management_env env) { + struct rte_power_core_ops *ops; + int ret = -1; + rte_spinlock_lock(&global_env_cfg_lock); if (global_default_env != PM_ENV_NOT_SET) { POWER_LOG(ERR, "Power Management Environment already set."); - rte_spinlock_unlock(&global_env_cfg_lock); - return -1; - } - - int ret = 0; - - if (env == PM_ENV_ACPI_CPUFREQ) { - rte_power_freqs = power_acpi_cpufreq_freqs; - rte_power_get_freq = power_acpi_cpufreq_get_freq; - rte_power_set_freq = power_acpi_cpufreq_set_freq; - rte_power_freq_up = power_acpi_cpufreq_freq_up; - rte_power_freq_down = power_acpi_cpufreq_freq_down; - rte_power_freq_min = power_acpi_cpufreq_freq_min; - rte_power_freq_max = power_acpi_cpufreq_freq_max; - rte_power_turbo_status = power_acpi_turbo_status; - rte_power_freq_enable_turbo = power_acpi_enable_turbo; - rte_power_freq_disable_turbo = power_acpi_disable_turbo; - rte_power_get_capabilities = power_acpi_get_capabilities; - } else if (env == PM_ENV_KVM_VM) { - rte_power_freqs = power_kvm_vm_freqs; - rte_power_get_freq = power_kvm_vm_get_freq; - rte_power_set_freq = power_kvm_vm_set_freq; - rte_power_freq_up = power_kvm_vm_freq_up; - rte_power_freq_down = power_kvm_vm_freq_down; - rte_power_freq_min = power_kvm_vm_freq_min; - rte_power_freq_max = power_kvm_vm_freq_max; - rte_power_turbo_status = power_kvm_vm_turbo_status; - rte_power_freq_enable_turbo = power_kvm_vm_enable_turbo; - rte_power_freq_disable_turbo = power_kvm_vm_disable_turbo; - rte_power_get_capabilities = power_kvm_vm_get_capabilities; - } else if (env == PM_ENV_PSTATE_CPUFREQ) { - rte_power_freqs = power_pstate_cpufreq_freqs; - rte_power_get_freq = power_pstate_cpufreq_get_freq; - rte_power_set_freq = power_pstate_cpufreq_set_freq; - rte_power_freq_up = power_pstate_cpufreq_freq_up; - rte_power_freq_down = power_pstate_cpufreq_freq_down; - rte_power_freq_min = power_pstate_cpufreq_freq_min; - rte_power_freq_max = power_pstate_cpufreq_freq_max; - rte_power_turbo_status = power_pstate_turbo_status; - rte_power_freq_enable_turbo = power_pstate_enable_turbo; - rte_power_freq_disable_turbo = power_pstate_disable_turbo; - rte_power_get_capabilities = power_pstate_get_capabilities; - - } else if (env == PM_ENV_CPPC_CPUFREQ) { - rte_power_freqs = power_cppc_cpufreq_freqs; - rte_power_get_freq = power_cppc_cpufreq_get_freq; - rte_power_set_freq = power_cppc_cpufreq_set_freq; - rte_power_freq_up = power_cppc_cpufreq_freq_up; - rte_power_freq_down = power_cppc_cpufreq_freq_down; - rte_power_freq_min = power_cppc_cpufreq_freq_min; - rte_power_freq_max = power_cppc_cpufreq_freq_max; - rte_power_turbo_status = power_cppc_turbo_status; - rte_power_freq_enable_turbo = power_cppc_enable_turbo; - rte_power_freq_disable_turbo = power_cppc_disable_turbo; - rte_power_get_capabilities = power_cppc_get_capabilities; - } else if (env == PM_ENV_AMD_PSTATE_CPUFREQ) { - rte_power_freqs = power_amd_pstate_cpufreq_freqs; - rte_power_get_freq = power_amd_pstate_cpufreq_get_freq; - rte_power_set_freq = power_amd_pstate_cpufreq_set_freq; - rte_power_freq_up = power_amd_pstate_cpufreq_freq_up; - rte_power_freq_down = power_amd_pstate_cpufreq_freq_down; - rte_power_freq_min = power_amd_pstate_cpufreq_freq_min; - rte_power_freq_max = power_amd_pstate_cpufreq_freq_max; - rte_power_turbo_status = power_amd_pstate_turbo_status; - rte_power_freq_enable_turbo = power_amd_pstate_enable_turbo; - rte_power_freq_disable_turbo = power_amd_pstate_disable_turbo; - rte_power_get_capabilities = power_amd_pstate_get_capabilities; - } else { - POWER_LOG(ERR, "Invalid Power Management Environment(%d) set", - env); - ret = -1; + goto out; } - if (ret == 0) - global_default_env = env; - else { - global_default_env = PM_ENV_NOT_SET; - reset_power_function_ptrs(); - } + RTE_TAILQ_FOREACH(ops, &core_ops_list, next) + if (strncmp(ops->name, power_env_str[env], + RTE_POWER_DRIVER_NAMESZ) == 0) { + global_power_core_ops = ops; + global_default_env = env; + ret = 0; + goto out; + } + POWER_LOG(ERR, "Invalid Power Management Environment(%d) set", + env); +out: rte_spinlock_unlock(&global_env_cfg_lock); return ret; } @@ -164,94 +97,64 @@ rte_power_unset_env(void) { rte_spinlock_lock(&global_env_cfg_lock); global_default_env = PM_ENV_NOT_SET; - reset_power_function_ptrs(); + global_power_core_ops = NULL; rte_spinlock_unlock(&global_env_cfg_lock); } enum power_management_env -rte_power_get_env(void) { +rte_power_get_env(void) +{ return global_default_env; } +struct rte_power_core_ops * +rte_power_get_core_ops(void) +{ + return global_power_core_ops; +} + int rte_power_init(unsigned int lcore_id) { - int ret = -1; - - switch (global_default_env) { - case PM_ENV_ACPI_CPUFREQ: - return power_acpi_cpufreq_init(lcore_id); - case PM_ENV_KVM_VM: - return power_kvm_vm_init(lcore_id); - case PM_ENV_PSTATE_CPUFREQ: - return power_pstate_cpufreq_init(lcore_id); - case PM_ENV_CPPC_CPUFREQ: - return power_cppc_cpufreq_init(lcore_id); - case PM_ENV_AMD_PSTATE_CPUFREQ: - return power_amd_pstate_cpufreq_init(lcore_id); - default: - POWER_LOG(INFO, "Env isn't set yet!"); - } + struct rte_power_core_ops *ops; + uint8_t env; - /* Auto detect Environment */ - POWER_LOG(INFO, "Attempting to initialise ACPI cpufreq power management..."); - ret = power_acpi_cpufreq_init(lcore_id); - if (ret == 0) { - rte_power_set_env(PM_ENV_ACPI_CPUFREQ); - goto out; - } + if (global_default_env != PM_ENV_NOT_SET) + return global_power_core_ops->init(lcore_id); - POWER_LOG(INFO, "Attempting to initialise PSTAT power management..."); - ret = power_pstate_cpufreq_init(lcore_id); - if (ret == 0) { - rte_power_set_env(PM_ENV_PSTATE_CPUFREQ); - goto out; - } - - POWER_LOG(INFO, "Attempting to initialise AMD PSTATE power management..."); - ret = power_amd_pstate_cpufreq_init(lcore_id); - if (ret == 0) { - rte_power_set_env(PM_ENV_AMD_PSTATE_CPUFREQ); - goto out; - } + POWER_LOG(INFO, "Env isn't set yet!"); - POWER_LOG(INFO, "Attempting to initialise CPPC power management..."); - ret = power_cppc_cpufreq_init(lcore_id); - if (ret == 0) { - rte_power_set_env(PM_ENV_CPPC_CPUFREQ); - goto out; - } + /* Auto detect Environment */ + RTE_TAILQ_FOREACH(ops, &core_ops_list, next) + if (ops) { + POWER_LOG(INFO, + "Attempting to initialise %s cpufreq power management...", + ops->name); + if (ops->init(lcore_id) == 0) { + for (env = 0; env < RTE_DIM(power_env_str); env++) + if (strncmp(ops->name, power_env_str[env], + RTE_POWER_DRIVER_NAMESZ) == 0) { + rte_power_set_env(env); + return 0; + } + } + } + + POWER_LOG(ERR, + "Unable to set Power Management Environment for lcore %u", + lcore_id); - POWER_LOG(INFO, "Attempting to initialise VM power management..."); - ret = power_kvm_vm_init(lcore_id); - if (ret == 0) { - rte_power_set_env(PM_ENV_KVM_VM); - goto out; - } - POWER_LOG(ERR, "Unable to set Power Management Environment for lcore " - "%u", lcore_id); -out: - return ret; + return -1; } int rte_power_exit(unsigned int lcore_id) { - switch (global_default_env) { - case PM_ENV_ACPI_CPUFREQ: - return power_acpi_cpufreq_exit(lcore_id); - case PM_ENV_KVM_VM: - return power_kvm_vm_exit(lcore_id); - case PM_ENV_PSTATE_CPUFREQ: - return power_pstate_cpufreq_exit(lcore_id); - case PM_ENV_CPPC_CPUFREQ: - return power_cppc_cpufreq_exit(lcore_id); - case PM_ENV_AMD_PSTATE_CPUFREQ: - return power_amd_pstate_cpufreq_exit(lcore_id); - default: - POWER_LOG(ERR, "Environment has not been set, unable to exit gracefully"); + if (global_default_env != PM_ENV_NOT_SET) + return global_power_core_ops->exit(lcore_id); - } - return -1; + POWER_LOG(ERR, + "Environment has not been set, unable to exit gracefully"); + return -1; } diff --git a/lib/power/rte_power.h b/lib/power/rte_power.h index 4fa4afe399..5e4aacf08b 100644 --- a/lib/power/rte_power.h +++ b/lib/power/rte_power.h @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright(c) 2010-2014 Intel Corporation + * Copyright(c) 2024 Advanced Micro Devices, Inc. */ #ifndef _RTE_POWER_H @@ -14,14 +15,21 @@ #include #include +#include "rte_power_core_ops.h" + #ifdef __cplusplus extern "C" { #endif /* Power Management Environment State */ -enum power_management_env {PM_ENV_NOT_SET, PM_ENV_ACPI_CPUFREQ, PM_ENV_KVM_VM, - PM_ENV_PSTATE_CPUFREQ, PM_ENV_CPPC_CPUFREQ, - PM_ENV_AMD_PSTATE_CPUFREQ}; +enum power_management_env { + PM_ENV_NOT_SET = 0, + PM_ENV_ACPI_CPUFREQ, + PM_ENV_KVM_VM, + PM_ENV_PSTATE_CPUFREQ, + PM_ENV_CPPC_CPUFREQ, + PM_ENV_AMD_PSTATE_CPUFREQ +}; /** * Check if a specific power management environment type is supported on a @@ -66,6 +74,15 @@ void rte_power_unset_env(void); */ enum power_management_env rte_power_get_env(void); +/** + * @internal Get the power ops struct from its index. + * + * @return + * The pointer to the ops struct in the table if registered. + */ +struct rte_power_core_ops * +rte_power_get_core_ops(void); + /** * Initialize power management for a specific lcore. If rte_power_set_env() has * not been called then an auto-detect of the environment will start and @@ -108,10 +125,13 @@ int rte_power_exit(unsigned int lcore_id); * @return * The number of available frequencies. */ -typedef uint32_t (*rte_power_freqs_t)(unsigned int lcore_id, uint32_t *freqs, - uint32_t num); +static inline uint32_t +rte_power_freqs(unsigned int lcore_id, uint32_t *freqs, uint32_t n) +{ + struct rte_power_core_ops *ops = rte_power_get_core_ops(); -extern rte_power_freqs_t rte_power_freqs; + return ops->get_avail_freqs(lcore_id, freqs, n); +} /** * Return the current index of available frequencies of a specific lcore. @@ -124,9 +144,13 @@ extern rte_power_freqs_t rte_power_freqs; * @return * The current index of available frequencies. */ -typedef uint32_t (*rte_power_get_freq_t)(unsigned int lcore_id); +static inline uint32_t +rte_power_get_freq(unsigned int lcore_id) +{ + struct rte_power_core_ops *ops = rte_power_get_core_ops(); -extern rte_power_get_freq_t rte_power_get_freq; + return ops->get_freq(lcore_id); +} /** * Set the new frequency for a specific lcore by indicating the index of @@ -144,82 +168,101 @@ extern rte_power_get_freq_t rte_power_get_freq; * - 0 on success without frequency changed. * - Negative on error. */ -typedef int (*rte_power_set_freq_t)(unsigned int lcore_id, uint32_t index); - -extern rte_power_set_freq_t rte_power_set_freq; +static inline uint32_t +rte_power_set_freq(unsigned int lcore_id, uint32_t index) +{ + struct rte_power_core_ops *ops = rte_power_get_core_ops(); -/** - * Function pointer definition for generic frequency change functions. Review - * each environments specific documentation for usage. - * - * @param lcore_id - * lcore id. - * - * @return - * - 1 on success with frequency changed. - * - 0 on success without frequency changed. - * - Negative on error. - */ -typedef int (*rte_power_freq_change_t)(unsigned int lcore_id); + return ops->set_freq(lcore_id, index); +} /** * Scale up the frequency of a specific lcore according to the available * frequencies. * Review each environments specific documentation for usage. */ -extern rte_power_freq_change_t rte_power_freq_up; +static inline int +rte_power_freq_up(unsigned int lcore_id) +{ + struct rte_power_core_ops *ops = rte_power_get_core_ops(); + + return ops->freq_up(lcore_id); +} /** * Scale down the frequency of a specific lcore according to the available * frequencies. * Review each environments specific documentation for usage. */ -extern rte_power_freq_change_t rte_power_freq_down; +static inline int +rte_power_freq_down(unsigned int lcore_id) +{ + struct rte_power_core_ops *ops = rte_power_get_core_ops(); + + return ops->freq_down(lcore_id); +} /** * Scale up the frequency of a specific lcore to the highest according to the * available frequencies. * Review each environments specific documentation for usage. */ -extern rte_power_freq_change_t rte_power_freq_max; +static inline int +rte_power_freq_max(unsigned int lcore_id) +{ + struct rte_power_core_ops *ops = rte_power_get_core_ops(); + + return ops->freq_max(lcore_id); +} /** * Scale down the frequency of a specific lcore to the lowest according to the * available frequencies. * Review each environments specific documentation for usage.. */ -extern rte_power_freq_change_t rte_power_freq_min; +static inline int +rte_power_freq_min(unsigned int lcore_id) +{ + struct rte_power_core_ops *ops = rte_power_get_core_ops(); + + return ops->freq_min(lcore_id); +} /** * Query the Turbo Boost status of a specific lcore. * Review each environments specific documentation for usage.. */ -extern rte_power_freq_change_t rte_power_turbo_status; +static inline int +rte_power_turbo_status(unsigned int lcore_id) +{ + struct rte_power_core_ops *ops = rte_power_get_core_ops(); + + return ops->turbo_status(lcore_id); +} /** * Enable Turbo Boost for this lcore. * Review each environments specific documentation for usage.. */ -extern rte_power_freq_change_t rte_power_freq_enable_turbo; +static inline int +rte_power_freq_enable_turbo(unsigned int lcore_id) +{ + struct rte_power_core_ops *ops = rte_power_get_core_ops(); + + return ops->enable_turbo(lcore_id); +} /** * Disable Turbo Boost for this lcore. * Review each environments specific documentation for usage.. */ -extern rte_power_freq_change_t rte_power_freq_disable_turbo; +static inline int +rte_power_freq_disable_turbo(unsigned int lcore_id) +{ + struct rte_power_core_ops *ops = rte_power_get_core_ops(); -/** - * Power capabilities summary. - */ -struct rte_power_core_capabilities { - union { - uint64_t capabilities; - struct { - uint64_t turbo:1; /**< Turbo can be enabled. */ - uint64_t priority:1; /**< SST-BF high freq core */ - }; - }; -}; + return ops->disable_turbo(lcore_id); +} /** * Returns power capabilities for a specific lcore. @@ -235,10 +278,14 @@ struct rte_power_core_capabilities { * - 0 on success. * - Negative on error. */ -typedef int (*rte_power_get_capabilities_t)(unsigned int lcore_id, - struct rte_power_core_capabilities *caps); +static inline int +rte_power_get_capabilities(unsigned int lcore_id, + struct rte_power_core_capabilities *caps) +{ + struct rte_power_core_ops *ops = rte_power_get_core_ops(); -extern rte_power_get_capabilities_t rte_power_get_capabilities; + return ops->get_caps(lcore_id, caps); +} #ifdef __cplusplus } diff --git a/lib/power/rte_power_core_ops.h b/lib/power/rte_power_core_ops.h new file mode 100644 index 0000000000..356a64df79 --- /dev/null +++ b/lib/power/rte_power_core_ops.h @@ -0,0 +1,208 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + * Copyright(c) 2024 Advanced Micro Devices, Inc. + */ + +#ifndef _RTE_POWER_CORE_OPS_H +#define _RTE_POWER_CORE_OPS_H + +/** + * @file + * RTE Power Management + */ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define RTE_POWER_DRIVER_NAMESZ 24 + +/** + * Initialize power management for a specific lcore. If rte_power_set_env() has + * not been called then an auto-detect of the environment will start and + * initialise the corresponding resources. + * + * @param lcore_id + * lcore id. + * + * @return + * - 0 on success. + * - Negative on error. + */ +typedef int (*rte_power_cpufreq_init_t)(unsigned int lcore_id); + +/** + * Exit power management on a specific lcore. This will call the environment + * dependent exit function. + * + * @param lcore_id + * lcore id. + * + * @return + * - 0 on success. + * - Negative on error. + */ +typedef int (*rte_power_cpufreq_exit_t)(unsigned int lcore_id); + +/** + * Check if a specific power management environment type is supported on a + * currently running system. + * + * @return + * - 1 if supported + * - 0 if unsupported + * - -1 if error, with rte_errno indicating reason for error. + */ +typedef int (*rte_power_check_env_support_t)(void); + +/** + * Get the available frequencies of a specific lcore. + * Function pointer definition. Review each environments + * specific documentation for usage. + * + * @param lcore_id + * lcore id. + * @param freqs + * The buffer array to save the frequencies. + * @param num + * The number of frequencies to get. + * + * @return + * The number of available frequencies. + */ +typedef uint32_t (*rte_power_freqs_t)(unsigned int lcore_id, uint32_t *freqs, + uint32_t num); + +/** + * Return the current index of available frequencies of a specific lcore. + * Function pointer definition. Review each environments + * specific documentation for usage. + * + * @param lcore_id + * lcore id. + * + * @return + * The current index of available frequencies. + */ +typedef uint32_t (*rte_power_get_freq_t)(unsigned int lcore_id); + +/** + * Set the new frequency for a specific lcore by indicating the index of + * available frequencies. + * Function pointer definition. Review each environments + * specific documentation for usage. + * + * @param lcore_id + * lcore id. + * @param index + * The index of available frequencies. + * + * @return + * - 1 on success with frequency changed. + * - 0 on success without frequency changed. + * - Negative on error. + */ +typedef int (*rte_power_set_freq_t)(unsigned int lcore_id, uint32_t index); + +/** + * Function pointer definition for generic frequency change functions. Review + * each environments specific documentation for usage. + * + * @param lcore_id + * lcore id. + * + * @return + * - 1 on success with frequency changed. + * - 0 on success without frequency changed. + * - Negative on error. + */ +typedef int (*rte_power_freq_change_t)(unsigned int lcore_id); + +/** + * Function pointer definition for generic frequency change functions. Review + * each environments specific documentation for usage. + * + * @param lcore_id + * lcore id. + * + * @return + * - 1 on success with frequency changed. + * - 0 on success without frequency changed. + * - Negative on error. + */ + +/** + * Power capabilities summary. + */ +struct rte_power_core_capabilities { + union { + uint64_t capabilities; + struct { + uint64_t turbo:1; /**< Turbo can be enabled. */ + uint64_t priority:1; /**< SST-BF high freq core */ + }; + }; +}; + +typedef int (*rte_power_get_capabilities_t)(unsigned int lcore_id, + struct rte_power_core_capabilities *caps); + +/** Structure defining core power operations structure */ +struct rte_power_core_ops { + RTE_TAILQ_ENTRY(rte_power_core_ops) next; /**< Next in list. */ + char name[RTE_POWER_DRIVER_NAMESZ]; /**< power mgmt driver. */ + rte_power_cpufreq_init_t init; /**< Initialize power management. */ + rte_power_cpufreq_exit_t exit; /**< Exit power management. */ + rte_power_check_env_support_t check_env_support;/**< verify env is supported. */ + rte_power_freqs_t get_avail_freqs; /**< Get the available frequencies. */ + rte_power_get_freq_t get_freq; /**< Get frequency index. */ + rte_power_set_freq_t set_freq; /**< Set frequency index. */ + rte_power_freq_change_t freq_up; /**< Scale up frequency. */ + rte_power_freq_change_t freq_down; /**< Scale down frequency. */ + rte_power_freq_change_t freq_max; /**< Scale up frequency to highest. */ + rte_power_freq_change_t freq_min; /**< Scale up frequency to lowest. */ + rte_power_freq_change_t turbo_status; /**< Get Turbo status. */ + rte_power_freq_change_t enable_turbo; /**< Enable Turbo. */ + rte_power_freq_change_t disable_turbo; /**< Disable Turbo. */ + rte_power_get_capabilities_t get_caps; /**< power capabilities. */ +}; + +/** + * Register power cpu frequency operations. + * + * @param ops + * Pointer to an ops structure to register. + * @return + * - >=0: Success; return the index of the ops struct in the table. + * - -EINVAL - error while registering ops struct. + */ +__rte_internal +int rte_power_register_ops(struct rte_power_core_ops *ops); + +/** + * Macro to statically register the ops of a cpufreq driver. + */ +#define RTE_POWER_REGISTER_OPS(ops) \ + RTE_INIT(power_hdlr_init_##ops) \ + { \ + rte_power_register_ops(&ops); \ + } + +/** + * @internal Get the power ops struct from its index. + * + * @return + * The pointer to the ops struct in the table if registered. + */ +struct rte_power_core_ops * +rte_power_get_core_ops(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/power/version.map b/lib/power/version.map index ad92a65f91..c2098fd667 100644 --- a/lib/power/version.map +++ b/lib/power/version.map @@ -51,4 +51,18 @@ EXPERIMENTAL { rte_power_set_uncore_env; rte_power_uncore_freqs; rte_power_unset_uncore_env; + # added in 24.07 + rte_power_logtype; +}; + +INTERNAL { + global: + + rte_power_register_ops; + cpufreq_check_scaling_driver; + power_set_governor; + open_core_sysfs_file; + read_core_sysfs_u32; + read_core_sysfs_s; + write_core_sysfs_s; }; From patchwork Sat Jul 20 16:50:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sivaprasad Tummala X-Patchwork-Id: 142560 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id AF7BE45665; Sat, 20 Jul 2024 18:51:22 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 1201740678; Sat, 20 Jul 2024 18:51:07 +0200 (CEST) Received: from NAM04-BN8-obe.outbound.protection.outlook.com (mail-bn8nam04on2085.outbound.protection.outlook.com [40.107.100.85]) by mails.dpdk.org (Postfix) with ESMTP id BCBEA4042E for ; Sat, 20 Jul 2024 18:51:04 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=Z3ekogDOJqLgC7Awb7pVO6k9ST200bl/sQFlVsif1PK+mpfGhNChyNIu3FZNknTtRsHr7qFvA7nCfEUmVJXTAXVZk4rFcPr5g+I8ehvPz8yNYsx3vrJ/zN0PvfX/2QvyiCz54SurExoBBvd4TXc2SNxA/41l4X10FZXqqM6xW/iDS45vXkI7LfjCVwKLLQCMPFiQqzSSzoo7HvBjK4AergMZDbWS4jNjbg6PmqDaCtjdTOLY5Extr9KJhHGxMnZe6fxccW0VsgmffGeDcz1fta5tJQhdq+E2U/BxqenxGzb4EQ26bCcpBAFYsyKw3NOry0JQ5zHnLB3VYapjznL/WQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=+ny0+inq8uG1lIsThcDFo7C7bwvxWZM1kl17GlDTUy4=; b=U94qErpWLI0X1nMMaAQpCo8FztYnQOeSgZ0opjrfdDOgBHdQsmky+LGYBiWG4IWhI7JmBOo6O0xWaIbVB69xyMi4qkghTeQAMYcdi9neJEngRHdtdNp1GbDMJt/7gVlkaiZRJC2NnKkJSuMsb5QdiKzDqryassOWkIpYqx6oMHWOCcNWVBXDOlqw++kYkYFPAfbnvZhgSlwGN05ezw3YjgenxesOCtu4Rq4nzxoqzkXzMv87mFUJFBOhk4UUuZOfmqDyCgoTd4i0ixlfIp+2PkqfMaRL1L7lBZqAzY3Gbr78iTdxgLAK1/Aq4MP/Io3uRiXLiuyaNEIWaS6e63oZJg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=intel.com smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=+ny0+inq8uG1lIsThcDFo7C7bwvxWZM1kl17GlDTUy4=; b=QACb6TaUnEawOFVJC7YNBJsBg5xMxwKoyrghRqa/Mcfg1PPcjXiA49eriF4T0bPCHGs8N2eWGRT35GHlbHaF3un5YeUGqMCaNUHWF1n8jMuIGmpk5qRJ3ukGERyrOw0BQCbG7JXd+dCJX61I/5HarEpEPN+SVLdnhiFE3uKFDLo= Received: from MN2PR18CA0010.namprd18.prod.outlook.com (2603:10b6:208:23c::15) by SA3PR12MB9107.namprd12.prod.outlook.com (2603:10b6:806:381::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7784.16; Sat, 20 Jul 2024 16:51:01 +0000 Received: from BL6PEPF0001AB59.namprd02.prod.outlook.com (2603:10b6:208:23c:cafe::15) by MN2PR18CA0010.outlook.office365.com (2603:10b6:208:23c::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7784.16 via Frontend Transport; Sat, 20 Jul 2024 16:51:00 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by BL6PEPF0001AB59.mail.protection.outlook.com (10.167.241.11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.7784.11 via Frontend Transport; Sat, 20 Jul 2024 16:51:00 +0000 Received: from jfw9ny3-os.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Sat, 20 Jul 2024 11:50:57 -0500 From: Sivaprasad Tummala To: , , , , , , CC: Subject: [PATCH v1 2/4] power: refactor uncore power management library Date: Sat, 20 Jul 2024 16:50:27 +0000 Message-ID: <20240720165030.246294-3-sivaprasad.tummala@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240720165030.246294-1-sivaprasad.tummala@amd.com> References: <20240220153326.6236-1-sivaprasad.tummala@amd.com> <20240720165030.246294-1-sivaprasad.tummala@amd.com> MIME-Version: 1.0 X-Originating-IP: [10.180.168.240] X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BL6PEPF0001AB59:EE_|SA3PR12MB9107:EE_ X-MS-Office365-Filtering-Correlation-Id: 1850f810-06b1-4e64-2f27-08dca8dc22a5 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|36860700013|82310400026|1800799024|376014; X-Microsoft-Antispam-Message-Info: uwirpd4smu5L2g9gHfwqhxGTVSQ9dPNjTrRwW777SJUIh45yG3GVdGZrpTzO5gTAntPDXTUBrpWUlUgV40V2d1G1r1C8BxraWKsv0h/p116xwOYn0Ntma2Dx09pRcMocl3y6kSLdM8Ovv1CWVtMzitKxO8VHAr19jW6unlx/AtqCBmJmtimoNZhzPcsqE/GqjlU2Ax1eweW+rmMOSJM0yGsMWwLKSz+Ia2P5Fvf5IIXZ2Drzux0GrghEulfGprdIlRVdM23j3zQBM2K698/8R2bI8kEi12G+a3d8pItbWkoU+gLEQzsCc3dyRZtrA0SH38kTYDD1Bqk0qpZzOviAlvWLqxj/pzLbvtgBikrx70y3cxFAHe0Q4Njkylqrj30gPeyKE+nnGEMkepEoB0NFgAA7ozdKFFrDEHxn9gYWCJ1hR92FH9fcnrEJv3ncMaC4EKMIYn0kXWE/Z8cvelEofZYG4cz6SvmKwB3D4FY6CZipyZ7VTpm9aUD1dliVGV1GByg5Znv3Pygq3l3pO+EGOcMzqFPmsR5Oj9u+eosk1YyOWmoGejP3HbYigDSW53Okd/YSVuMvrTsEek20aNMGMQPnTqawxdicU5kI16M8+PlED66HX1nxOmExC+xYs2aeHvmvQ2wXekyP003ynZ+v6g2NoNoGnUFzM7V1aXJyI25a03lUFZ/2jeo84MIxcigGI5+LlF12n8+RHn7QPzuR9zGUTmk1h3Uvfu2L3WVlSECoVgWvV9qR+AGvwZt1fxfYGItm/GIVIG5qhhbdk8o8B+J74MHq9SuYmeKSKfZKucS2YCk0HMBwV4BqvDY+TpARB0I0oVsEN9A06I+30WWQV+2KejekXLXHacLCFq8vjrREQzxbEEhb6kzsPxdPqfzdJmUyxMzxXR9s/Us2QldC9yV0OXI2cdkShhkQ1c5JmAFEAQM2KsWHc70V2kyRzoXjTwyCUFrJ0WOUHdfx6/YH+ZmhOZhKGIGkyAxyC6JAiWGKD7H1SnwLUkJ/Ogzvt5cPVrypg+dzsHvuATvIqKgOuoyTQt1Nilx61lNoODlv/knzILkigDwIbv+AwU/yejyClrywPF4epR3dkj7LKGj9laJ+v0HHbqeFmgIJq2ANf+kwo9alup7MkVtsAIwboUMXH1vyaulF9cAI4eWsguTADrkDzrsjtyVaywx3o0BFB0LxRTLzWZ3v3yq2O7qQS9Dretr4Zqkvf1ZhH1R9mQ32hioE3BSQeevA3o9t6kUnFGEtvOEbKNpZD5cdmY6kmpLf++t33oU4oYufjkhMvxM9khSmWsI9q8P5oxc1tB2uQQaRotbROPA8PwkT91/NBjSdvbhDh6494oMgblKqkxUTALYDBVvluo3H0thU00r5Ln27K5pRFyB+656+ZXarLPLd/PexK2rs/pNGdXZHUUoERtj1+GYpnVl4AOIH7MxaRB3srfvOqSp+a6q7Jz17eQqw X-Forefront-Antispam-Report: CIP:165.204.84.17; CTRY:US; LANG:en; SCL:1; SRV:; IPV:CAL; SFV:NSPM; H:SATLEXMB04.amd.com; PTR:InfoDomainNonexistent; CAT:NONE; SFS:(13230040)(36860700013)(82310400026)(1800799024)(376014); DIR:OUT; SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 20 Jul 2024 16:51:00.6508 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 1850f810-06b1-4e64-2f27-08dca8dc22a5 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d; Ip=[165.204.84.17]; Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: BL6PEPF0001AB59.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA3PR12MB9107 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org This patch refactors the power management library, addressing uncore power management. The primary changes involve the creation of dedicated directories for each driver within 'drivers/power/uncore/*'. The adjustment of meson.build files enables the selective activation of individual drivers. This refactor significantly improves code organization, enhances clarity and boosts maintainability. It lays the foundation for more focused development on individual drivers and facilitates seamless integration of future enhancements, particularly the AMD uncore driver. Signed-off-by: Sivaprasad Tummala --- .../power/intel_uncore/intel_uncore.c | 18 +- .../power/intel_uncore/intel_uncore.h | 8 +- drivers/power/intel_uncore/meson.build | 7 + drivers/power/meson.build | 3 +- lib/power/meson.build | 2 +- lib/power/rte_power_uncore.c | 206 ++++++--------- lib/power/rte_power_uncore.h | 91 ++++--- lib/power/rte_power_uncore_ops.h | 239 ++++++++++++++++++ lib/power/version.map | 1 + 9 files changed, 406 insertions(+), 169 deletions(-) rename lib/power/power_intel_uncore.c => drivers/power/intel_uncore/intel_uncore.c (95%) rename lib/power/power_intel_uncore.h => drivers/power/intel_uncore/intel_uncore.h (97%) create mode 100644 drivers/power/intel_uncore/meson.build create mode 100644 lib/power/rte_power_uncore_ops.h diff --git a/lib/power/power_intel_uncore.c b/drivers/power/intel_uncore/intel_uncore.c similarity index 95% rename from lib/power/power_intel_uncore.c rename to drivers/power/intel_uncore/intel_uncore.c index 9c152e4ed2..6f3b347a8d 100644 --- a/lib/power/power_intel_uncore.c +++ b/drivers/power/intel_uncore/intel_uncore.c @@ -8,7 +8,7 @@ #include -#include "power_intel_uncore.h" +#include "intel_uncore.h" #include "power_common.h" #define MAX_UNCORE_FREQS 32 @@ -476,3 +476,19 @@ power_intel_uncore_get_num_dies(unsigned int pkg) return count; } + +static struct rte_power_uncore_ops intel_uncore_ops = { + .name = "intel-uncore", + .init = power_intel_uncore_init, + .exit = power_intel_uncore_exit, + .get_avail_freqs = power_intel_uncore_freqs, + .get_num_pkgs = power_intel_uncore_get_num_pkgs, + .get_num_dies = power_intel_uncore_get_num_dies, + .get_num_freqs = power_intel_uncore_get_num_freqs, + .get_freq = power_get_intel_uncore_freq, + .set_freq = power_set_intel_uncore_freq, + .freq_max = power_intel_uncore_freq_max, + .freq_min = power_intel_uncore_freq_min, +}; + +RTE_POWER_REGISTER_UNCORE_OPS(intel_uncore_ops); diff --git a/lib/power/power_intel_uncore.h b/drivers/power/intel_uncore/intel_uncore.h similarity index 97% rename from lib/power/power_intel_uncore.h rename to drivers/power/intel_uncore/intel_uncore.h index 20a3ba8ebe..f2ce2f0c66 100644 --- a/lib/power/power_intel_uncore.h +++ b/drivers/power/intel_uncore/intel_uncore.h @@ -2,8 +2,8 @@ * Copyright(c) 2022 Intel Corporation */ -#ifndef POWER_INTEL_UNCORE_H -#define POWER_INTEL_UNCORE_H +#ifndef INTEL_UNCORE_H +#define INTEL_UNCORE_H /** * @file @@ -11,7 +11,7 @@ */ #include "rte_power.h" -#include "rte_power_uncore.h" +#include "rte_power_uncore_ops.h" #ifdef __cplusplus extern "C" { @@ -223,4 +223,4 @@ power_intel_uncore_get_num_dies(unsigned int pkg); } #endif -#endif /* POWER_INTEL_UNCORE_H */ +#endif /* INTEL_UNCORE_H */ diff --git a/drivers/power/intel_uncore/meson.build b/drivers/power/intel_uncore/meson.build new file mode 100644 index 0000000000..c46202fd6a --- /dev/null +++ b/drivers/power/intel_uncore/meson.build @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2017 Intel Corporation +# Copyright(c) 2024 Advanced Micro Devices, Inc. + +sources = files('intel_uncore.c') + +deps += ['power'] diff --git a/drivers/power/meson.build b/drivers/power/meson.build index 8c7215c639..c83047af94 100644 --- a/drivers/power/meson.build +++ b/drivers/power/meson.build @@ -6,7 +6,8 @@ drivers = [ 'amd_pstate', 'cppc', 'kvm_vm', - 'pstate' + 'pstate', + 'intel_uncore' ] std_deps = ['power'] diff --git a/lib/power/meson.build b/lib/power/meson.build index f3e3451cdc..9b13d98810 100644 --- a/lib/power/meson.build +++ b/lib/power/meson.build @@ -13,7 +13,6 @@ if not is_linux endif sources = files( 'power_common.c', - 'power_intel_uncore.c', 'rte_power.c', 'rte_power_uncore.c', 'rte_power_pmd_mgmt.c', @@ -24,6 +23,7 @@ headers = files( 'rte_power_guest_channel.h', 'rte_power_pmd_mgmt.h', 'rte_power_uncore.h', + 'rte_power_uncore_ops.h', ) if cc.has_argument('-Wno-cast-qual') cflags += '-Wno-cast-qual' diff --git a/lib/power/rte_power_uncore.c b/lib/power/rte_power_uncore.c index 48c75a5da0..127f6ed212 100644 --- a/lib/power/rte_power_uncore.c +++ b/lib/power/rte_power_uncore.c @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright(c) 2010-2014 Intel Corporation - * Copyright(c) 2023 AMD Corporation + * Copyright(c) 2024 Advanced Micro Devices, Inc. */ #include @@ -10,100 +10,52 @@ #include "power_common.h" #include "rte_power_uncore.h" -#include "power_intel_uncore.h" -enum rte_uncore_power_mgmt_env default_uncore_env = RTE_UNCORE_PM_ENV_NOT_SET; +static enum rte_uncore_power_mgmt_env global_uncore_env = RTE_UNCORE_PM_ENV_NOT_SET; +static struct rte_power_uncore_ops *global_uncore_ops; static rte_spinlock_t global_env_cfg_lock = RTE_SPINLOCK_INITIALIZER; +static RTE_TAILQ_HEAD(, rte_power_uncore_ops) uncore_ops_list = + TAILQ_HEAD_INITIALIZER(uncore_ops_list); -static uint32_t -power_get_dummy_uncore_freq(unsigned int pkg __rte_unused, - unsigned int die __rte_unused) -{ - return 0; -} - -static int -power_set_dummy_uncore_freq(unsigned int pkg __rte_unused, - unsigned int die __rte_unused, uint32_t index __rte_unused) -{ - return 0; -} +const char *uncore_env_str[] = { + "not set", + "auto-detect", + "intel-uncore", + "amd-hsmp" +}; -static int -power_dummy_uncore_freq_max(unsigned int pkg __rte_unused, - unsigned int die __rte_unused) -{ - return 0; -} - -static int -power_dummy_uncore_freq_min(unsigned int pkg __rte_unused, - unsigned int die __rte_unused) -{ - return 0; -} - -static int -power_dummy_uncore_freqs(unsigned int pkg __rte_unused, unsigned int die __rte_unused, - uint32_t *freqs __rte_unused, uint32_t num __rte_unused) -{ - return 0; -} - -static int -power_dummy_uncore_get_num_freqs(unsigned int pkg __rte_unused, - unsigned int die __rte_unused) +/* register the ops struct in rte_power_uncore_ops, return 0 on success. */ +int +rte_power_register_uncore_ops(struct rte_power_uncore_ops *driver_ops) { - return 0; -} + if (!driver_ops->init || !driver_ops->exit || !driver_ops->get_num_pkgs || + !driver_ops->get_num_dies || !driver_ops->get_num_freqs || + !driver_ops->get_avail_freqs || !driver_ops->get_freq || + !driver_ops->set_freq || !driver_ops->freq_max || + !driver_ops->freq_min) { + POWER_LOG(ERR, "Missing callbacks while registering power ops"); + return -1; + } + if (driver_ops->cb) + driver_ops->cb(); -static unsigned int -power_dummy_uncore_get_num_pkgs(void) -{ - return 0; -} + TAILQ_INSERT_TAIL(&uncore_ops_list, driver_ops, next); -static unsigned int -power_dummy_uncore_get_num_dies(unsigned int pkg __rte_unused) -{ return 0; } -/* function pointers */ -rte_power_get_uncore_freq_t rte_power_get_uncore_freq = power_get_dummy_uncore_freq; -rte_power_set_uncore_freq_t rte_power_set_uncore_freq = power_set_dummy_uncore_freq; -rte_power_uncore_freq_change_t rte_power_uncore_freq_max = power_dummy_uncore_freq_max; -rte_power_uncore_freq_change_t rte_power_uncore_freq_min = power_dummy_uncore_freq_min; -rte_power_uncore_freqs_t rte_power_uncore_freqs = power_dummy_uncore_freqs; -rte_power_uncore_get_num_freqs_t rte_power_uncore_get_num_freqs = power_dummy_uncore_get_num_freqs; -rte_power_uncore_get_num_pkgs_t rte_power_uncore_get_num_pkgs = power_dummy_uncore_get_num_pkgs; -rte_power_uncore_get_num_dies_t rte_power_uncore_get_num_dies = power_dummy_uncore_get_num_dies; - -static void -reset_power_uncore_function_ptrs(void) -{ - rte_power_get_uncore_freq = power_get_dummy_uncore_freq; - rte_power_set_uncore_freq = power_set_dummy_uncore_freq; - rte_power_uncore_freq_max = power_dummy_uncore_freq_max; - rte_power_uncore_freq_min = power_dummy_uncore_freq_min; - rte_power_uncore_freqs = power_dummy_uncore_freqs; - rte_power_uncore_get_num_freqs = power_dummy_uncore_get_num_freqs; - rte_power_uncore_get_num_pkgs = power_dummy_uncore_get_num_pkgs; - rte_power_uncore_get_num_dies = power_dummy_uncore_get_num_dies; -} - int rte_power_set_uncore_env(enum rte_uncore_power_mgmt_env env) { - int ret; + int ret = -1; + struct rte_power_uncore_ops *ops; rte_spinlock_lock(&global_env_cfg_lock); - if (default_uncore_env != RTE_UNCORE_PM_ENV_NOT_SET) { + if (global_uncore_env != RTE_UNCORE_PM_ENV_NOT_SET) { POWER_LOG(ERR, "Uncore Power Management Env already set."); - rte_spinlock_unlock(&global_env_cfg_lock); - return -1; + goto out; } if (env == RTE_UNCORE_PM_ENV_AUTO_DETECT) @@ -113,25 +65,23 @@ rte_power_set_uncore_env(enum rte_uncore_power_mgmt_env env) */ env = RTE_UNCORE_PM_ENV_INTEL_UNCORE; - ret = 0; - if (env == RTE_UNCORE_PM_ENV_INTEL_UNCORE) { - rte_power_get_uncore_freq = power_get_intel_uncore_freq; - rte_power_set_uncore_freq = power_set_intel_uncore_freq; - rte_power_uncore_freq_min = power_intel_uncore_freq_min; - rte_power_uncore_freq_max = power_intel_uncore_freq_max; - rte_power_uncore_freqs = power_intel_uncore_freqs; - rte_power_uncore_get_num_freqs = power_intel_uncore_get_num_freqs; - rte_power_uncore_get_num_pkgs = power_intel_uncore_get_num_pkgs; - rte_power_uncore_get_num_dies = power_intel_uncore_get_num_dies; - } else { - POWER_LOG(ERR, "Invalid Power Management Environment(%d) set", env); - ret = -1; - goto out; - } + if (env <= RTE_DIM(uncore_env_str)) { + RTE_TAILQ_FOREACH(ops, &uncore_ops_list, next) + if (strncmp(ops->name, uncore_env_str[env], + RTE_POWER_UNCORE_DRIVER_NAMESZ) == 0) { + global_uncore_env = env; + global_uncore_ops = ops; + ret = 0; + goto out; + } + POWER_LOG(ERR, "Power Management (%s) not supported", + uncore_env_str[env]); + } else + POWER_LOG(ERR, "Invalid Power Management Environment"); - default_uncore_env = env; out: rte_spinlock_unlock(&global_env_cfg_lock); + return ret; } @@ -139,42 +89,50 @@ void rte_power_unset_uncore_env(void) { rte_spinlock_lock(&global_env_cfg_lock); - default_uncore_env = RTE_UNCORE_PM_ENV_NOT_SET; - reset_power_uncore_function_ptrs(); + global_uncore_env = RTE_UNCORE_PM_ENV_NOT_SET; rte_spinlock_unlock(&global_env_cfg_lock); } enum rte_uncore_power_mgmt_env rte_power_get_uncore_env(void) { - return default_uncore_env; + return global_uncore_env; +} + +struct rte_power_uncore_ops * +rte_power_get_uncore_ops(void) +{ + RTE_ASSERT(global_uncore_ops != NULL); + + return global_uncore_ops; } int rte_power_uncore_init(unsigned int pkg, unsigned int die) { int ret = -1; - - switch (default_uncore_env) { - case RTE_UNCORE_PM_ENV_INTEL_UNCORE: - return power_intel_uncore_init(pkg, die); - default: - POWER_LOG(INFO, "Uncore Env isn't set yet!"); - break; - } - - /* Auto detect Environment */ - POWER_LOG(INFO, "Attempting to initialise Intel Uncore power mgmt..."); - ret = power_intel_uncore_init(pkg, die); - if (ret == 0) { - rte_power_set_uncore_env(RTE_UNCORE_PM_ENV_INTEL_UNCORE); - goto out; - } - - if (default_uncore_env == RTE_UNCORE_PM_ENV_NOT_SET) { - POWER_LOG(ERR, "Unable to set Power Management Environment " - "for package %u Die %u", pkg, die); - ret = 0; + struct rte_power_uncore_ops *ops; + uint8_t env; + + if ((global_uncore_env != RTE_UNCORE_PM_ENV_NOT_SET) && + (global_uncore_env != RTE_UNCORE_PM_ENV_AUTO_DETECT)) + return global_uncore_ops->init(pkg, die); + + /* Auto Detect Environment */ + RTE_TAILQ_FOREACH(ops, &uncore_ops_list, next) + if (ops) { + POWER_LOG(INFO, + "Attempting to initialise %s power management...", + ops->name); + ret = ops->init(pkg, die); + if (ret == 0) { + for (env = 0; env < RTE_DIM(uncore_env_str); env++) + if (strncmp(ops->name, uncore_env_str[env], + RTE_POWER_UNCORE_DRIVER_NAMESZ) == 0) { + rte_power_set_uncore_env(env); + goto out; + } + } } out: return ret; @@ -183,12 +141,12 @@ rte_power_uncore_init(unsigned int pkg, unsigned int die) int rte_power_uncore_exit(unsigned int pkg, unsigned int die) { - switch (default_uncore_env) { - case RTE_UNCORE_PM_ENV_INTEL_UNCORE: - return power_intel_uncore_exit(pkg, die); - default: - POWER_LOG(ERR, "Uncore Env has not been set, unable to exit gracefully"); - break; - } + if ((global_uncore_env != RTE_UNCORE_PM_ENV_NOT_SET) && + global_uncore_ops) + return global_uncore_ops->exit(pkg, die); + + POWER_LOG(ERR, + "Uncore Env has not been set, unable to exit gracefully"); + return -1; } diff --git a/lib/power/rte_power_uncore.h b/lib/power/rte_power_uncore.h index 99859042dd..5415032ff4 100644 --- a/lib/power/rte_power_uncore.h +++ b/lib/power/rte_power_uncore.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright(c) 2022 Intel Corporation - * Copyright(c) 2023 AMD Corporation + * Copyright(c) 2024 Advanced Micro Devices, Inc. */ #ifndef RTE_POWER_UNCORE_H @@ -10,9 +10,7 @@ * @file * RTE Uncore Frequency Management */ - -#include -#include "rte_power.h" +#include "rte_power_uncore_ops.h" #ifdef __cplusplus extern "C" { @@ -116,9 +114,13 @@ rte_power_uncore_exit(unsigned int pkg, unsigned int die); * The current index of available frequencies. * If error, it will return 'RTE_POWER_INVALID_FREQ_INDEX = (~0)'. */ -typedef uint32_t (*rte_power_get_uncore_freq_t)(unsigned int pkg, unsigned int die); +static inline uint32_t +rte_power_get_uncore_freq(unsigned int pkg, unsigned int die) +{ + struct rte_power_uncore_ops *ops = rte_power_get_uncore_ops(); -extern rte_power_get_uncore_freq_t rte_power_get_uncore_freq; + return ops->get_freq(pkg, die); +} /** * Set minimum and maximum uncore frequency for specified die on a package @@ -141,26 +143,13 @@ extern rte_power_get_uncore_freq_t rte_power_get_uncore_freq; * - 0 on success without frequency changed. * - Negative on error. */ -typedef int (*rte_power_set_uncore_freq_t)(unsigned int pkg, unsigned int die, uint32_t index); +static inline uint32_t +rte_power_set_uncore_freq(unsigned int pkg, unsigned int die, uint32_t index) +{ + struct rte_power_uncore_ops *ops = rte_power_get_uncore_ops(); -extern rte_power_set_uncore_freq_t rte_power_set_uncore_freq; - -/** - * Function pointer definition for generic frequency change functions. - * - * @param pkg - * Package number. - * Each physical CPU in a system is referred to as a package. - * @param die - * Die number. - * Each package can have several dies connected together via the uncore mesh. - * - * @return - * - 1 on success with frequency changed. - * - 0 on success without frequency changed. - * - Negative on error. - */ -typedef int (*rte_power_uncore_freq_change_t)(unsigned int pkg, unsigned int die); + return ops->set_freq(pkg, die, index); +} /** * Set minimum and maximum uncore frequency for specified die on a package @@ -169,7 +158,13 @@ typedef int (*rte_power_uncore_freq_change_t)(unsigned int pkg, unsigned int die * * This function should NOT be called in the fast path. */ -extern rte_power_uncore_freq_change_t rte_power_uncore_freq_max; +static inline uint32_t +rte_power_uncore_freq_max(unsigned int pkg, unsigned int die) +{ + struct rte_power_uncore_ops *ops = rte_power_get_uncore_ops(); + + return ops->freq_max(pkg, die); +} /** * Set minimum and maximum uncore frequency for specified die on a package @@ -178,7 +173,13 @@ extern rte_power_uncore_freq_change_t rte_power_uncore_freq_max; * * This function should NOT be called in the fast path. */ -extern rte_power_uncore_freq_change_t rte_power_uncore_freq_min; +static inline uint32_t +rte_power_uncore_freq_min(unsigned int pkg, unsigned int die) +{ + struct rte_power_uncore_ops *ops = rte_power_get_uncore_ops(); + + return ops->freq_min(pkg, die); +} /** * Return the list of available frequencies in the index array. @@ -200,10 +201,14 @@ extern rte_power_uncore_freq_change_t rte_power_uncore_freq_min; * - The number of available index's in frequency array. * - Negative on error. */ -typedef int (*rte_power_uncore_freqs_t)(unsigned int pkg, unsigned int die, - uint32_t *freqs, uint32_t num); +static inline uint32_t +rte_power_uncore_freqs(unsigned int pkg, unsigned int die, + uint32_t *freqs, uint32_t num) +{ + struct rte_power_uncore_ops *ops = rte_power_get_uncore_ops(); -extern rte_power_uncore_freqs_t rte_power_uncore_freqs; + return ops->get_avail_freqs(pkg, die, freqs, num); +} /** * Return the list length of available frequencies in the index array. @@ -221,10 +226,13 @@ extern rte_power_uncore_freqs_t rte_power_uncore_freqs; * - The number of available index's in frequency array. * - Negative on error. */ -typedef int (*rte_power_uncore_get_num_freqs_t)(unsigned int pkg, unsigned int die); - -extern rte_power_uncore_get_num_freqs_t rte_power_uncore_get_num_freqs; +static inline int +rte_power_uncore_get_num_freqs(unsigned int pkg, unsigned int die) +{ + struct rte_power_uncore_ops *ops = rte_power_get_uncore_ops(); + return ops->get_num_freqs(pkg, die); +} /** * Return the number of packages (CPUs) on a system * by parsing the uncore sysfs directory. @@ -235,10 +243,13 @@ extern rte_power_uncore_get_num_freqs_t rte_power_uncore_get_num_freqs; * - Zero on error. * - Number of package on system on success. */ -typedef unsigned int (*rte_power_uncore_get_num_pkgs_t)(void); - -extern rte_power_uncore_get_num_pkgs_t rte_power_uncore_get_num_pkgs; +static inline unsigned int +rte_power_uncore_get_num_pkgs(void) +{ + struct rte_power_uncore_ops *ops = rte_power_get_uncore_ops(); + return ops->get_num_pkgs(); +} /** * Return the number of dies for pakckages (CPUs) specified * from parsing the uncore sysfs directory. @@ -253,9 +264,13 @@ extern rte_power_uncore_get_num_pkgs_t rte_power_uncore_get_num_pkgs; * - Zero on error. * - Number of dies for package on sucecss. */ -typedef unsigned int (*rte_power_uncore_get_num_dies_t)(unsigned int pkg); +static inline unsigned int +rte_power_uncore_get_num_dies(unsigned int pkg) +{ + struct rte_power_uncore_ops *ops = rte_power_get_uncore_ops(); -extern rte_power_uncore_get_num_dies_t rte_power_uncore_get_num_dies; + return ops->get_num_dies(pkg); +} #ifdef __cplusplus } diff --git a/lib/power/rte_power_uncore_ops.h b/lib/power/rte_power_uncore_ops.h new file mode 100644 index 0000000000..91cb9ec518 --- /dev/null +++ b/lib/power/rte_power_uncore_ops.h @@ -0,0 +1,239 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2022 Intel Corporation + * Copyright(c) 2024 Advanced Micro Devices, Inc. + */ + +#ifndef RTE_POWER_UNCORE_OPS_H +#define RTE_POWER_UNCORE_OPS_H + +/** + * @file + * RTE Uncore Frequency Management + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define RTE_POWER_UNCORE_DRIVER_NAMESZ 24 + +/** + * Initialize uncore frequency management for specific die on a package. + * It will get the available frequencies and prepare to set new die frequencies. + * + * This function should NOT be called in the fast path. + * + * @param pkg + * Package number. + * Each physical CPU in a system is referred to as a package. + * @param die + * Die number. + * Each package can have several dies connected together via the uncore mesh. + * + * @return + * - 0 on success. + * - Negative on error. + */ +typedef int (*rte_power_uncore_init_t)(unsigned int pkg, unsigned int die); + +/** + * Exit uncore frequency management on a specific die on a package. + * It will restore uncore min and* max values to previous values + * before initialization of API. + * + * This function should NOT be called in the fast path. + * + * @param pkg + * Package number. + * Each physical CPU in a system is referred to as a package. + * @param die + * Die number. + * Each package can have several dies connected together via the uncore mesh. + * + * @return + * - 0 on success. + * - Negative on error. + */ +typedef int (*rte_power_uncore_exit_t)(unsigned int pkg, unsigned int die); + +/** + * Return the current index of available frequencies of a specific die on a package. + * It should be protected outside of this function for threadsafe. + * + * This function should NOT be called in the fast path. + * + * @param pkg + * Package number. + * Each physical CPU in a system is referred to as a package. + * @param die + * Die number. + * Each package can have several dies connected together via the uncore mesh. + * + * @return + * The current index of available frequencies. + * If error, it will return 'RTE_POWER_INVALID_FREQ_INDEX = (~0)'. + */ +typedef uint32_t (*rte_power_get_uncore_freq_t)(unsigned int pkg, unsigned int die); + +/** + * Set minimum and maximum uncore frequency for specified die on a package + * to specified index value. + * It should be protected outside of this function for threadsafe. + * + * This function should NOT be called in the fast path. + * + * @param pkg + * Package number. + * Each physical CPU in a system is referred to as a package. + * @param die + * Die number. + * Each package can have several dies connected together via the uncore mesh. + * @param index + * The index of available frequencies. + * + * @return + * - 1 on success with frequency changed. + * - 0 on success without frequency changed. + * - Negative on error. + */ +typedef int (*rte_power_set_uncore_freq_t)(unsigned int pkg, unsigned int die, uint32_t index); + +/** + * Return the list length of available frequencies in the index array. + * + * This function should NOT be called in the fast path. + * + * @param pkg + * Package number. + * Each physical CPU in a system is referred to as a package. + * @param die + * Die number. + * Each package can have several dies connected together via the uncore mesh. + * + * @return + * - The number of available index's in frequency array. + * - Negative on error. + */ +typedef int (*rte_power_uncore_get_num_freqs_t)(unsigned int pkg, unsigned int die); + +/** + * Return the list of available frequencies in the index array. + * + * This function should NOT be called in the fast path. + * + * @param pkg + * Package number. + * Each physical CPU in a system is referred to as a package. + * @param die + * Die number. + * Each package can have several dies connected together via the uncore mesh. + * @param freqs + * The buffer array to save the frequencies. + * @param num + * The number of frequencies to get. + * + * @return + * - The number of available index's in frequency array. + * - Negative on error. + */ +typedef int (*rte_power_uncore_freqs_t)(unsigned int pkg, unsigned int die, + uint32_t *freqs, uint32_t num); +/** + * Function pointers for generic frequency change functions. + * + * @param pkg + * Package number. + * Each physical CPU in a system is referred to as a package. + * @param die + * Die number. + * Each package can have several dies connected together via the uncore mesh. + * + * @return + * - 1 on success with frequency changed. + * - 0 on success without frequency changed. + * - Negative on error. + */ +typedef int (*rte_power_uncore_freq_change_t)(unsigned int pkg, unsigned int die); + +/** + * Return the number of packages (CPUs) on a system + * by parsing the uncore sysfs directory. + * + * This function should NOT be called in the fast path. + * + * @return + * - Zero on error. + * - Number of package on system on success. + */ +typedef unsigned int (*rte_power_uncore_get_num_pkgs_t)(void); + +/** + * Return the number of dies for pakckages (CPUs) specified + * from parsing the uncore sysfs directory. + * + * This function should NOT be called in the fast path. + * + * @param pkg + * Package number. + * Each physical CPU in a system is referred to as a package. + * + * @return + * - Zero on error. + * - Number of dies for package on sucecss. + */ +typedef unsigned int (*rte_power_uncore_get_num_dies_t)(unsigned int pkg); +typedef void (*rte_power_uncore_driver_cb_t)(void); + +/** Structure defining uncore power operations structure */ +struct rte_power_uncore_ops { + RTE_TAILQ_ENTRY(rte_power_uncore_ops) next; /**< Next in list. */ + char name[RTE_POWER_UNCORE_DRIVER_NAMESZ]; /**< power mgmt driver. */ + rte_power_uncore_driver_cb_t cb; /**< Driver specific callbacks. */ + rte_power_uncore_init_t init; /**< Initialize power management. */ + rte_power_uncore_exit_t exit; /**< Exit power management. */ + rte_power_uncore_get_num_pkgs_t get_num_pkgs; + rte_power_uncore_get_num_dies_t get_num_dies; + rte_power_uncore_get_num_freqs_t get_num_freqs; /**< Number of available frequencies. */ + rte_power_uncore_freqs_t get_avail_freqs; /**< Get the available frequencies. */ + rte_power_get_uncore_freq_t get_freq; /**< Get frequency index. */ + rte_power_set_uncore_freq_t set_freq; /**< Set frequency index. */ + rte_power_uncore_freq_change_t freq_max; /**< Scale up frequency to highest. */ + rte_power_uncore_freq_change_t freq_min; /**< Scale up frequency to lowest. */ +}; + +/** + * Register power uncore frequency operations. + * @param ops + * Pointer to an ops structure to register. + * @return + * - >=0: Success; return the index of the ops struct in the table. + * - -EINVAL - error while registering ops struct. + */ +__rte_internal +int rte_power_register_uncore_ops(struct rte_power_uncore_ops *ops); + +/** + * Macro to statically register the ops of an uncore driver. + */ +#define RTE_POWER_REGISTER_UNCORE_OPS(ops) \ + RTE_INIT(power_hdlr_init_uncore_##ops) \ + { \ + rte_power_register_uncore_ops(&ops); \ + } + +/** + * @internal Get the power uncore ops struct from its index. + * + * @return + * The pointer to the ops struct in the table if registered. + */ +struct rte_power_uncore_ops * +rte_power_get_uncore_ops(void); + +#ifdef __cplusplus +} +#endif + +#endif /* RTE_POWER_UNCORE_H */ diff --git a/lib/power/version.map b/lib/power/version.map index c2098fd667..112790df73 100644 --- a/lib/power/version.map +++ b/lib/power/version.map @@ -59,6 +59,7 @@ INTERNAL { global: rte_power_register_ops; + rte_power_register_uncore_ops; cpufreq_check_scaling_driver; power_set_governor; open_core_sysfs_file; From patchwork Sat Jul 20 16:50:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sivaprasad Tummala X-Patchwork-Id: 142562 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 5C0CC45665; Sat, 20 Jul 2024 18:51:40 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 9C75E4068E; Sat, 20 Jul 2024 18:51:12 +0200 (CEST) Received: from NAM10-MW2-obe.outbound.protection.outlook.com (mail-mw2nam10on2057.outbound.protection.outlook.com [40.107.94.57]) by mails.dpdk.org (Postfix) with ESMTP id 4EBD040A7A for ; Sat, 20 Jul 2024 18:51:09 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=ATlIGhddxlDt2PkRqyW7jPZCkU811wbwCmdNK6v6zwgu9NbDwKBA8PNwJkbvhFSvaY3/0dYmCZRgHZbYjoCuj39xgZ1b7kHbw2VqvpkcXeUYSQghNJYAD7a+vIEhykuD+rA85i3m/hRedIQFpmHEK0rUtc5BpBEAtlPp2297/OxKK1LVaj0dzQPrhgAOGn/aWJifd7DVVpmNSq0MfzI5eU7Tql4EtLVw1khmuJPXvmjyHwy+23p8BR6Miip+fz82XqkS5Jt3YXdAAgooxD3isqiPU22MRBHl06xktWq73Lc3Xq4zaOVBsaw1gt71p9vdIcoI1sMDHuZHGycQlcf3jw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=KMdti4oCWIaejQ5mitD0EbyTSmeiPTSYYMMIhC2j45s=; b=knBDa7pYblZt/OKsLQP2ri6t9Ls3+MRzO1whp0AIjNQFhWBR69C9anoMNzkN1dysWcAsyL1DNV0b7Ht0QC6x1ADlD5BwCkj42pWNSkcDEjzekOhSc77F0KKNtWShqiM6Tye0MDMv9aPOkOiVPQjif7fBIkO7WIU6jQsPeLHNkuVOtYSaPYJV1RPNOdE7hta5K6PZOsWY2YbyDJnfrDCywrXNl39xkFHD+lGCgWnQeRHdwUTeBLDsAEgG6+j+WXvWWMLGRhEOjYcwgABh3kZDM+AHtzemOdbTATvSB1DzijgOJPQD4+x1Jupx5fuYB5l3gy3hlR7uQAV8Jz0UqUoyFA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=intel.com smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=KMdti4oCWIaejQ5mitD0EbyTSmeiPTSYYMMIhC2j45s=; b=eyLL/TWUFbTMNYTfD6zvQv2Ue5zzF6y/bn3hzW01gVmxIe8indjLO9FRhGelX485EODOta5aKW71Nq86EsztiPtHTyv8rWTijiP9Urqojwh6EJ1T3qVaAJA7T7NMMSP2XJweBlM4+aTXgb2HKnxCHnNnDF2WLHRW0WvY6wj0YYg= Received: from MN2PR18CA0016.namprd18.prod.outlook.com (2603:10b6:208:23c::21) by SJ0PR12MB6807.namprd12.prod.outlook.com (2603:10b6:a03:479::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7762.29; Sat, 20 Jul 2024 16:51:04 +0000 Received: from BL6PEPF0001AB59.namprd02.prod.outlook.com (2603:10b6:208:23c:cafe::70) by MN2PR18CA0016.outlook.office365.com (2603:10b6:208:23c::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7784.20 via Frontend Transport; Sat, 20 Jul 2024 16:51:03 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by BL6PEPF0001AB59.mail.protection.outlook.com (10.167.241.11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.7784.11 via Frontend Transport; Sat, 20 Jul 2024 16:51:03 +0000 Received: from jfw9ny3-os.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Sat, 20 Jul 2024 11:51:00 -0500 From: Sivaprasad Tummala To: , , , , , , CC: Subject: [PATCH v1 3/4] test/power: removed function pointer validations Date: Sat, 20 Jul 2024 16:50:28 +0000 Message-ID: <20240720165030.246294-4-sivaprasad.tummala@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240720165030.246294-1-sivaprasad.tummala@amd.com> References: <20240220153326.6236-1-sivaprasad.tummala@amd.com> <20240720165030.246294-1-sivaprasad.tummala@amd.com> MIME-Version: 1.0 X-Originating-IP: [10.180.168.240] X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BL6PEPF0001AB59:EE_|SJ0PR12MB6807:EE_ X-MS-Office365-Filtering-Correlation-Id: 38f59ae8-8e19-40a2-bbb9-08dca8dc2435 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|1800799024|36860700013|82310400026|376014; X-Microsoft-Antispam-Message-Info: ZXTH0SHah8PLUD7fek3BsdUvSMgdOTURLD9z2HbvWp+usYb+bouAHS2xzEIjDZr9mTeuhdQG6h7oEsndA+tas5Kz0ORrRfH/T5llIp2iY7K41SXpqKAQDh9MTmAMRR1zh/oSwYL6pBiMrQmD3Jye9kfWcT/XybHUbS8Qy6W7J+6s4YE18uwYboQedDLlTQdKbqq4/EaljEAiJ0WURjyuavhARSGk8J5qR/khT7KViv7N+Vet6mVi5ZvY23tE4FvTE8H89HmVBw8TxTThWWroa2EBotrglOkY9YOiNQGCYkEnc/V5qa84X1IE3vTxHT4H3WoMRqIJZPQlkNH6btOiSBDOtjbaVPU20rpX8tTgua3bbGe6elPaTAqKOmGjnRvow1+0h496XS4CX/TDa3b6sXFeP/JSnrDQyx1yZaGWcl6PPuhKRAVJOQ1KZq2wS1Hg4sUDJnTifj9gaXOcqUUYdKLjIKbfasUB9cIG/KoCo1b7KsDpc32sd+q0pOkIg19H2ycL2vYoNykM8O5M+FGgmxfQjONh13RlaMLx9TVSVXJDP6OCQgsY4oEiNa7J46XsE2/v4CbtGU7xSrJOzSWwexWOoTnO8MQiD8lB8u33+dkpvwE789U+8v8ZVJNcR/5Rt2BUSfNS4sctN8q7ghLe9I0tRMpui8ViJ28ZqAKKlleUxH14EMEwCy7MGRwsn1vJn8vsWqo+dFIpRNm+cBmiKFV01deBJQdqzfNf20+iQohRA3rMxg+xZkqjOF2nFv65K8JEfb9Y1hgTuPS+1BZBCm0/E9lzsTiT1fjcKQijqCgC6UgeUIA5djUPwatB5cdRhpwayeNtvdDlgEwgnSevuj5WoQDl3UNOlk+foNekU5KGXbtYJLxGTUaM82YTfqFQN3HM7hqRMHQUrSuP7dKmarsblozWQDuZucBQ4Tu2HmB0BAJJ68Fu7DFSgKs3BjqCUKVT8KcwjhUFyfFg3Q0Thde4HA/Xc3e+r5DwIS4eVZoFsTskwmRBJWcRVB6a9xzOUgjyJ8u3LZOKO6aHHDqrslJ2gJPlW49Dz/IYxykdRlTI9AWpSZply4Wrhcw056QsvdLt6Jw1tRRJZY1uUwa4dJBy4GffQArWLZntlwTpL79QjX1bYr4RINHXCClZx5t8KdL3vFZRSh7YoxTB8H6LcutRkQcaeDJr6Dzv5nXA83YvwAOEz2OH4fKwSAFbQlozn9D8LtCif6Nq/qYh9br5el7Ig03KvPx1pBsoQhE/CvGpCEdCBS0E88vNdt62AJrmld+lvEMt0X6KV1vSaNJFqyXOEWdFei5fCr3E9/a9kPZlv9mh4QytO3xcR0jq9i/pLnJHrTjZSJ6DKPNmbKKxyaK74MYjBlmi8a9n243HYwCjqtxu2Kf9JTdCPoY3NSConY/S9RKU1dOStk1i5jZEVikN6zc0mvfoZFaouIdg3RERRttDY6wxiUtmPvVJFZ1I X-Forefront-Antispam-Report: CIP:165.204.84.17; CTRY:US; LANG:en; SCL:1; SRV:; IPV:CAL; SFV:NSPM; H:SATLEXMB04.amd.com; PTR:InfoDomainNonexistent; CAT:NONE; SFS:(13230040)(1800799024)(36860700013)(82310400026)(376014); DIR:OUT; SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 20 Jul 2024 16:51:03.2915 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 38f59ae8-8e19-40a2-bbb9-08dca8dc2435 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d; Ip=[165.204.84.17]; Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: BL6PEPF0001AB59.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SJ0PR12MB6807 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org After refactoring the power library, power management operations are now consistently supported regardless of the operating environment, making function pointer checks unnecessary and thus removed from applications. Signed-off-by: Sivaprasad Tummala Signed-off-by: Sivaprasad Tummala --- app/test/test_power.c | 95 ----------------------------------- app/test/test_power_cpufreq.c | 52 ------------------- app/test/test_power_kvm_vm.c | 36 ------------- 3 files changed, 183 deletions(-) diff --git a/app/test/test_power.c b/app/test/test_power.c index 403adc22d6..5df5848c70 100644 --- a/app/test/test_power.c +++ b/app/test/test_power.c @@ -24,86 +24,6 @@ test_power(void) #include -static int -check_function_ptrs(void) -{ - enum power_management_env env = rte_power_get_env(); - - const bool not_null_expected = !(env == PM_ENV_NOT_SET); - - const char *inject_not_string1 = not_null_expected ? " not" : ""; - const char *inject_not_string2 = not_null_expected ? "" : " not"; - - if ((rte_power_freqs == NULL) == not_null_expected) { - printf("rte_power_freqs should%s be NULL, environment has%s been " - "initialised\n", inject_not_string1, - inject_not_string2); - return -1; - } - if ((rte_power_get_freq == NULL) == not_null_expected) { - printf("rte_power_get_freq should%s be NULL, environment has%s been " - "initialised\n", inject_not_string1, - inject_not_string2); - return -1; - } - if ((rte_power_set_freq == NULL) == not_null_expected) { - printf("rte_power_set_freq should%s be NULL, environment has%s been " - "initialised\n", inject_not_string1, - inject_not_string2); - return -1; - } - if ((rte_power_freq_up == NULL) == not_null_expected) { - printf("rte_power_freq_up should%s be NULL, environment has%s been " - "initialised\n", inject_not_string1, - inject_not_string2); - return -1; - } - if ((rte_power_freq_down == NULL) == not_null_expected) { - printf("rte_power_freq_down should%s be NULL, environment has%s been " - "initialised\n", inject_not_string1, - inject_not_string2); - return -1; - } - if ((rte_power_freq_max == NULL) == not_null_expected) { - printf("rte_power_freq_max should%s be NULL, environment has%s been " - "initialised\n", inject_not_string1, - inject_not_string2); - return -1; - } - if ((rte_power_freq_min == NULL) == not_null_expected) { - printf("rte_power_freq_min should%s be NULL, environment has%s been " - "initialised\n", inject_not_string1, - inject_not_string2); - return -1; - } - if ((rte_power_turbo_status == NULL) == not_null_expected) { - printf("rte_power_turbo_status should%s be NULL, environment has%s been " - "initialised\n", inject_not_string1, - inject_not_string2); - return -1; - } - if ((rte_power_freq_enable_turbo == NULL) == not_null_expected) { - printf("rte_power_freq_enable_turbo should%s be NULL, environment has%s been " - "initialised\n", inject_not_string1, - inject_not_string2); - return -1; - } - if ((rte_power_freq_disable_turbo == NULL) == not_null_expected) { - printf("rte_power_freq_disable_turbo should%s be NULL, environment has%s been " - "initialised\n", inject_not_string1, - inject_not_string2); - return -1; - } - if ((rte_power_get_capabilities == NULL) == not_null_expected) { - printf("rte_power_get_capabilities should%s be NULL, environment has%s been " - "initialised\n", inject_not_string1, - inject_not_string2); - return -1; - } - - return 0; -} - static int test_power(void) { @@ -124,10 +44,6 @@ test_power(void) return -1; } - /* Verify that function pointers are NULL */ - if (check_function_ptrs() < 0) - goto fail_all; - rte_power_unset_env(); /* Perform tests for valid environments.*/ @@ -154,22 +70,11 @@ test_power(void) return -1; } - /* Verify that function pointers are NOT NULL */ - if (check_function_ptrs() < 0) - goto fail_all; - rte_power_unset_env(); - /* Verify that function pointers are NULL */ - if (check_function_ptrs() < 0) - goto fail_all; - } return 0; -fail_all: - rte_power_unset_env(); - return -1; } #endif diff --git a/app/test/test_power_cpufreq.c b/app/test/test_power_cpufreq.c index 619b2811c6..8cb67e662c 100644 --- a/app/test/test_power_cpufreq.c +++ b/app/test/test_power_cpufreq.c @@ -519,58 +519,6 @@ test_power_cpufreq(void) goto fail_all; } - /* verify that function pointers are not NULL */ - if (rte_power_freqs == NULL) { - printf("rte_power_freqs should not be NULL, environment has not been " - "initialised\n"); - goto fail_all; - } - if (rte_power_get_freq == NULL) { - printf("rte_power_get_freq should not be NULL, environment has not " - "been initialised\n"); - goto fail_all; - } - if (rte_power_set_freq == NULL) { - printf("rte_power_set_freq should not be NULL, environment has not " - "been initialised\n"); - goto fail_all; - } - if (rte_power_freq_up == NULL) { - printf("rte_power_freq_up should not be NULL, environment has not " - "been initialised\n"); - goto fail_all; - } - if (rte_power_freq_down == NULL) { - printf("rte_power_freq_down should not be NULL, environment has not " - "been initialised\n"); - goto fail_all; - } - if (rte_power_freq_max == NULL) { - printf("rte_power_freq_max should not be NULL, environment has not " - "been initialised\n"); - goto fail_all; - } - if (rte_power_freq_min == NULL) { - printf("rte_power_freq_min should not be NULL, environment has not " - "been initialised\n"); - goto fail_all; - } - if (rte_power_turbo_status == NULL) { - printf("rte_power_turbo_status should not be NULL, environment has not " - "been initialised\n"); - goto fail_all; - } - if (rte_power_freq_enable_turbo == NULL) { - printf("rte_power_freq_enable_turbo should not be NULL, environment has not " - "been initialised\n"); - goto fail_all; - } - if (rte_power_freq_disable_turbo == NULL) { - printf("rte_power_freq_disable_turbo should not be NULL, environment has not " - "been initialised\n"); - goto fail_all; - } - ret = rte_power_exit(TEST_POWER_LCORE_ID); if (ret < 0) { printf("Cannot exit power management for lcore %u\n", diff --git a/app/test/test_power_kvm_vm.c b/app/test/test_power_kvm_vm.c index 464e06002e..a7d104e973 100644 --- a/app/test/test_power_kvm_vm.c +++ b/app/test/test_power_kvm_vm.c @@ -47,42 +47,6 @@ test_power_kvm_vm(void) return -1; } - /* verify that function pointers are not NULL */ - if (rte_power_freqs == NULL) { - printf("rte_power_freqs should not be NULL, environment has not been " - "initialised\n"); - return -1; - } - if (rte_power_get_freq == NULL) { - printf("rte_power_get_freq should not be NULL, environment has not " - "been initialised\n"); - return -1; - } - if (rte_power_set_freq == NULL) { - printf("rte_power_set_freq should not be NULL, environment has not " - "been initialised\n"); - return -1; - } - if (rte_power_freq_up == NULL) { - printf("rte_power_freq_up should not be NULL, environment has not " - "been initialised\n"); - return -1; - } - if (rte_power_freq_down == NULL) { - printf("rte_power_freq_down should not be NULL, environment has not " - "been initialised\n"); - return -1; - } - if (rte_power_freq_max == NULL) { - printf("rte_power_freq_max should not be NULL, environment has not " - "been initialised\n"); - return -1; - } - if (rte_power_freq_min == NULL) { - printf("rte_power_freq_min should not be NULL, environment has not " - "been initialised\n"); - return -1; - } /* Test initialisation of an out of bounds lcore */ ret = rte_power_init(TEST_POWER_VM_LCORE_OUT_OF_BOUNDS); if (ret != -1) { From patchwork Sat Jul 20 16:50:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sivaprasad Tummala X-Patchwork-Id: 142561 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 9964445665; Sat, 20 Jul 2024 18:51:33 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 55CD140656; Sat, 20 Jul 2024 18:51:10 +0200 (CEST) Received: from NAM12-BN8-obe.outbound.protection.outlook.com (mail-bn8nam12on2052.outbound.protection.outlook.com [40.107.237.52]) by mails.dpdk.org (Postfix) with ESMTP id CBF2340A7A for ; Sat, 20 Jul 2024 18:51:08 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=o1IXzc7Nm7MDxSCDfmKv2tmIG7QoWwyQnY9Ec4EEi8XMJx4/zIkgI0JycPHn1CNjTuwW5V4vJOE9BBwjHXWnl5HbprIFn+cc0Vx+Aw8H5uRz2K9QFBpcnSdPRk+MhWLjchaMeHrPYHg+bzTbUXpgGHTjDjRJEbrxTpxo0qPI8KhkmFxnUaHN4xUIg4F/PTKMCOzM79k5yd3xiiMbMBLt4jiNi3OvCnmWo34LISf9Ng3xJJX0fnR0emut8KAiiQbh1AUzYpd74s9UUT49hWbIXA/hB/o5zYfQAuGL9IEHgMTZkfC76XRa1kRCCjPmBCAcP7ijnuN6jEMxaNNgdP5YSQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=dQ+ntb2krZ2WjQOnmg5A8H8ymMd9iZihCBBwVvrcxbo=; b=KIkykm2Ie3iVLdXie9ryKPPyRaJqOsbdmIRkDXeA8taw7T/AfvmXlrAcwXFYB4Y+ihE3QsGdjL0KiXvPZpedjyje/qrDGVZL/IqGBE7NW4oFynh3sBZ+KOMqXByeQdr3yMPXodbWuykvZcs1AMaRm0r/tJ+hHzIopRf0ZDUS7YYw4/IZBTZH60pBwTD3TUm10r0OdjN5+fKVh+AlAt2T8VAjEKRMTCdeAwj1bvzNXjlz9rj7vzKKbEmbQc/ZfpCLz/+q4caqKZWDKZrzheJ2XsGPhXpllYFKRWagDjNRa87eU0/QZ1Grs97FPXd2YDfXnWmNUafTgEWpbP2SkD9whw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=intel.com smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=dQ+ntb2krZ2WjQOnmg5A8H8ymMd9iZihCBBwVvrcxbo=; b=Lw8G9R+j3qOJ8G36spui5NTmQF5CuoBpA3DzKHe6RDOXYsgtPx9cdE9PMGyX+wl2tjvw6rkuw+qWeC+OiNfoU+lNFKXPck5OxiNq27+yXWNqUWgwj6sHi5bqGVQYoXkyJOANVdI6F1dBwDSu7vWHUGRMkU5JSevysFhti5r9kno= Received: from BL1P221CA0025.NAMP221.PROD.OUTLOOK.COM (2603:10b6:208:2c5::13) by CH2PR12MB4232.namprd12.prod.outlook.com (2603:10b6:610:a4::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7784.19; Sat, 20 Jul 2024 16:51:06 +0000 Received: from BL6PEPF0001AB58.namprd02.prod.outlook.com (2603:10b6:208:2c5:cafe::fa) by BL1P221CA0025.outlook.office365.com (2603:10b6:208:2c5::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7784.15 via Frontend Transport; Sat, 20 Jul 2024 16:51:06 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by BL6PEPF0001AB58.mail.protection.outlook.com (10.167.241.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.7784.11 via Frontend Transport; Sat, 20 Jul 2024 16:51:05 +0000 Received: from jfw9ny3-os.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Sat, 20 Jul 2024 11:51:03 -0500 From: Sivaprasad Tummala To: , , , , , , CC: Subject: [PATCH v1 4/4] power/amd_uncore: uncore power management support for AMD EPYC processors Date: Sat, 20 Jul 2024 16:50:29 +0000 Message-ID: <20240720165030.246294-5-sivaprasad.tummala@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240720165030.246294-1-sivaprasad.tummala@amd.com> References: <20240220153326.6236-1-sivaprasad.tummala@amd.com> <20240720165030.246294-1-sivaprasad.tummala@amd.com> MIME-Version: 1.0 X-Originating-IP: [10.180.168.240] X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BL6PEPF0001AB58:EE_|CH2PR12MB4232:EE_ X-MS-Office365-Filtering-Correlation-Id: 2c7780da-ca55-44a3-4686-08dca8dc25cb X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|1800799024|376014|82310400026|36860700013; X-Microsoft-Antispam-Message-Info: Q1cfUcFRVJwVReedaZfzsr6TVSt5ln1HmbETsE9JtQmlg95SHRHn827qqYIjFCsK7dgDkHeLAuG8Oh4QRGEw+LU7+Ckqq7fuoBL/d2pYqfk9AuZDS2KKZJgOy2JbFXC+BspVvuG9spOOr4vT17J61P1QYomOR/nKyJw6qgo1J85JCLoUl0uQtzb8aUFCwamluS2usrr/KksyN1f4rTwYeJNi5oW2Vsb6tKWI9Xfil56Tbb03dCE222QPIjQB4qZxfHjx5vAziTTGmu8cB/RfPeLW9ECJndrrw5lqgyXPlpL0selkX895hNVchq1JQtSo4EWTJqPJP+ANTcmg6f3R65VxwIYz8arrRY81Ias+gybPDZNppDbwZ8NlsU76G4IylJDFMCue9kSkDRYXPPd2Sctf2PXaWlsgNYQRgeqaN6U4dyqJuxusXUX1FhJ8RwcMxqGDGhcVM6M3KMp1MPym5/jWePonK4of0TqtPfyIzF1v1lQqAH6l0okG/V5nfoWQg7X4kp4eK2R6Yo8BJs2jRcEtqtHRl6PxeEBnT4Q+x613JzQvSzM4uHd8wUARBSyHFzWPXljwianQ1u9pdZy3ElCcKXe7zs2bOaCKxn+6m7aEnSBycKqxjOVTBorTgzEkHQQalELvRs0MnrvNpI2SZPD+kDXQIJoLPhGwfv5V8IrK2mBXkby/LhhDTF4xaW/owQJPy+W2YC7t8ffW2playU9BXchns87WV/3jrZSBy18kbEtnqMDTviN5LVTPl8eLWFHGfVH7BbtSK9gaPYHKuR4XKGfX+Ncw4THyZA5FOfUi/AjCZzPgiZ76/UhJeaec7eVYiXpvP3NvPXGrpNiruaruuDwnWbYYA/Tzk8B2EjH3R/F8ea6kRMGVIjYnuhAFBNjzyIjpmeYoECZOzNf8mjgpD6nGP9znyFYacC2NUJi1/X/w9rV2NwIvqEexvbqr66ximUz/ef3LoTJ/4LJaqnlBJns/U2ANwjeyaoaVu2ugleC9+JJV1BanLx3XMlgPa0UFRGaoCsZsXPk/kEyY4lEoRKLFNYJ5SrTFRMp5km23OGoQUwZb3WtY6cYtPOgmhHA4b07QWnmr9udciRT8NBmYyvKYQFFLWvYB70ggECM3uw4385jTI9WzXFDbTrVT+YrvnedtjnUAIhVkVOlsXcz495b3gvUwwfR8Uv58ZK/KWyDzITGBC4E6ly+pVV+6BV9KiwvmiVoTM7/oQQMm71EqOBvPGqW5UIszfIiHqy9HpM9HKpORARqJwqBcnUlVwdgx80x1WmD0RdpFkGSC5jrlQ0EqgYWyKvF4WHg0fbmhqkGU2OkTWWAlSiBSxQtafoDe7+u88bZiIqKFF+wMDRfMUtXuxhUqvZ+LScNhOmMSQRfEo9Vq+Rj1sTs706d1DsWKO/krgLELpKVF1YmnkGAgb3WaXJxn//bRg2KtPbxUo7GBurgJn6Q7RQht8DIn X-Forefront-Antispam-Report: CIP:165.204.84.17; CTRY:US; LANG:en; SCL:1; SRV:; IPV:CAL; SFV:NSPM; H:SATLEXMB04.amd.com; PTR:InfoDomainNonexistent; CAT:NONE; SFS:(13230040)(1800799024)(376014)(82310400026)(36860700013); DIR:OUT; SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 20 Jul 2024 16:51:05.9493 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 2c7780da-ca55-44a3-4686-08dca8dc25cb X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d; Ip=[165.204.84.17]; Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: BL6PEPF0001AB58.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH2PR12MB4232 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org This patch introduces driver support for power management of uncore components in AMD EPYC processors. Signed-off-by: Sivaprasad Tummala --- drivers/power/amd_uncore/amd_uncore.c | 321 ++++++++++++++++++++++++++ drivers/power/amd_uncore/amd_uncore.h | 226 ++++++++++++++++++ drivers/power/amd_uncore/meson.build | 20 ++ drivers/power/meson.build | 1 + 4 files changed, 568 insertions(+) create mode 100644 drivers/power/amd_uncore/amd_uncore.c create mode 100644 drivers/power/amd_uncore/amd_uncore.h create mode 100644 drivers/power/amd_uncore/meson.build diff --git a/drivers/power/amd_uncore/amd_uncore.c b/drivers/power/amd_uncore/amd_uncore.c new file mode 100644 index 0000000000..f15eaaa307 --- /dev/null +++ b/drivers/power/amd_uncore/amd_uncore.c @@ -0,0 +1,321 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2024 Advanced Micro Devices, Inc. + */ + +#include +#include +#include + +#include + +#include "amd_uncore.h" +#include "power_common.h" +#include "e_smi/e_smi.h" + +#define MAX_UNCORE_FREQS 8 +#define MAX_NUMA_DIE 8 + +#define BUS_FREQ 1000 + +struct __rte_cache_aligned uncore_power_info { + unsigned int die; /* Core die id */ + unsigned int pkg; /* Package id */ + uint32_t freqs[MAX_UNCORE_FREQS]; /* Frequency array */ + uint32_t nb_freqs; /* Number of available freqs */ + uint32_t curr_idx; /* Freq index in freqs array */ + uint32_t max_freq; /* System max uncore freq */ + uint32_t min_freq; /* System min uncore freq */ +}; + +static struct uncore_power_info uncore_info[RTE_MAX_NUMA_NODES][MAX_NUMA_DIE]; +static int esmi_initialized; + +static int +set_uncore_freq_internal(struct uncore_power_info *ui, uint32_t idx) +{ + int ret; + + if (idx >= MAX_UNCORE_FREQS || idx >= ui->nb_freqs) { + POWER_LOG(DEBUG, "Invalid uncore frequency index %u, which " + "should be less than %u", idx, ui->nb_freqs); + return -1; + } + + ret = esmi_apb_disable(ui->pkg, idx); + if (ret != ESMI_SUCCESS) { + POWER_LOG(ERR, "DF P-state '%u' set failed for pkg %02u", + idx, ui->pkg); + return -1; + } + + POWER_DEBUG_LOG("DF P-state '%u' to be set for pkg %02u die %02u", + idx, ui->pkg, ui->die); + + /* write the minimum value first if the target freq is less than current max */ + ui->curr_idx = idx; + + return 0; +} + +/* + * Fopen the sys file for the future setting of the uncore die frequency. + */ +static int +power_init_for_setting_uncore_freq(struct uncore_power_info *ui) +{ + /* open and read all uncore sys files */ + /* Base max */ + ui->max_freq = 1800000; + ui->min_freq = 1200000; + + return 0; +} + +/* + * Get the available uncore frequencies of the specific die by reading the + * sys file. + */ +static int +power_get_available_uncore_freqs(struct uncore_power_info *ui) +{ + int ret = -1; + uint32_t i, num_uncore_freqs = 3; + uint32_t fabric_freqs[] = { + /* to be extended for probing support in future */ + 1800, + 1444, + 1200 + }; + + if (num_uncore_freqs >= MAX_UNCORE_FREQS) { + POWER_LOG(ERR, "Too many available uncore frequencies: %d", + num_uncore_freqs); + goto out; + } + + /* Generate the uncore freq bucket array. */ + for (i = 0; i < num_uncore_freqs; i++) + ui->freqs[i] = fabric_freqs[i] * BUS_FREQ; + + ui->nb_freqs = num_uncore_freqs; + + ret = 0; + + POWER_DEBUG_LOG("%d frequency(s) of pkg %02u die %02u are available", + num_uncore_freqs, ui->pkg, ui->die); + +out: + return ret; +} + +static int +check_pkg_die_values(unsigned int pkg, unsigned int die) +{ + unsigned int max_pkgs, max_dies; + max_pkgs = power_amd_uncore_get_num_pkgs(); + if (max_pkgs == 0) + return -1; + if (pkg >= max_pkgs) { + POWER_LOG(DEBUG, "Package number %02u can not exceed %u", + pkg, max_pkgs); + return -1; + } + + max_dies = power_amd_uncore_get_num_dies(pkg); + if (max_dies == 0) + return -1; + if (die >= max_dies) { + POWER_LOG(DEBUG, "Die number %02u can not exceed %u", + die, max_dies); + return -1; + } + + return 0; +} + +static void +power_amd_uncore_esmi_init(void) +{ + if (esmi_init() == ESMI_SUCCESS) + esmi_initialized = 1; +} + +int +power_amd_uncore_init(unsigned int pkg, unsigned int die) +{ + struct uncore_power_info *ui; + int ret; + + if (!esmi_initialized) { + ret = esmi_init(); + if (ret != ESMI_SUCCESS) { + POWER_LOG(DEBUG, "ESMI Not initialized, drivers not found"); + return -1; + } + } + + ret = check_pkg_die_values(pkg, die); + if (ret < 0) + return -1; + + ui = &uncore_info[pkg][die]; + ui->die = die; + ui->pkg = pkg; + + /* Init for setting uncore die frequency */ + if (power_init_for_setting_uncore_freq(ui) < 0) { + POWER_LOG(DEBUG, "Cannot init for setting uncore frequency for " + "pkg %02u die %02u", pkg, die); + return -1; + } + + /* Get the available frequencies */ + if (power_get_available_uncore_freqs(ui) < 0) { + POWER_LOG(DEBUG, "Cannot get available uncore frequencies of " + "pkg %02u die %02u", pkg, die); + return -1; + } + + return 0; +} + +int +power_amd_uncore_exit(unsigned int pkg, unsigned int die) +{ + struct uncore_power_info *ui; + + int ret = check_pkg_die_values(pkg, die); + if (ret < 0) + return -1; + + ui = &uncore_info[pkg][die]; + ui->nb_freqs = 0; + + if (esmi_initialized) { + esmi_exit(); + esmi_initialized = 0; + } + + return 0; +} + +uint32_t +power_get_amd_uncore_freq(unsigned int pkg, unsigned int die) +{ + int ret = check_pkg_die_values(pkg, die); + if (ret < 0) + return -1; + + return uncore_info[pkg][die].curr_idx; +} + +int +power_set_amd_uncore_freq(unsigned int pkg, unsigned int die, uint32_t index) +{ + int ret = check_pkg_die_values(pkg, die); + if (ret < 0) + return -1; + + return set_uncore_freq_internal(&(uncore_info[pkg][die]), index); +} + +int +power_amd_uncore_freq_max(unsigned int pkg, unsigned int die) +{ + int ret = check_pkg_die_values(pkg, die); + if (ret < 0) + return -1; + + return set_uncore_freq_internal(&(uncore_info[pkg][die]), 0); +} + + +int +power_amd_uncore_freq_min(unsigned int pkg, unsigned int die) +{ + int ret = check_pkg_die_values(pkg, die); + if (ret < 0) + return -1; + + struct uncore_power_info *ui = &uncore_info[pkg][die]; + + return set_uncore_freq_internal(&(uncore_info[pkg][die]), ui->nb_freqs - 1); +} + +int +power_amd_uncore_freqs(unsigned int pkg, unsigned int die, uint32_t *freqs, uint32_t num) +{ + struct uncore_power_info *ui; + + int ret = check_pkg_die_values(pkg, die); + if (ret < 0) + return -1; + + if (freqs == NULL) { + POWER_LOG(ERR, "NULL buffer supplied"); + return 0; + } + + ui = &uncore_info[pkg][die]; + if (num < ui->nb_freqs) { + POWER_LOG(ERR, "Buffer size is not enough"); + return 0; + } + rte_memcpy(freqs, ui->freqs, ui->nb_freqs * sizeof(uint32_t)); + + return ui->nb_freqs; +} + +int +power_amd_uncore_get_num_freqs(unsigned int pkg, unsigned int die) +{ + int ret = check_pkg_die_values(pkg, die); + if (ret < 0) + return -1; + + return uncore_info[pkg][die].nb_freqs; +} + +unsigned int +power_amd_uncore_get_num_pkgs(void) +{ + uint32_t num_pkgs = 0; + int ret; + + if (esmi_initialized) { + ret = esmi_number_of_sockets_get(&num_pkgs); + if (ret != ESMI_SUCCESS) { + POWER_LOG(ERR, "Failed to get number of sockets"); + num_pkgs = 0; + } + } + return num_pkgs; +} + +unsigned int +power_amd_uncore_get_num_dies(unsigned int pkg) +{ + if (pkg >= power_amd_uncore_get_num_pkgs()) { + POWER_LOG(ERR, "Invalid package ID"); + return 0; + } + + return 1; +} + +static struct rte_power_uncore_ops amd_uncore_ops = { + .name = "amd-hsmp", + .cb = power_amd_uncore_esmi_init, + .init = power_amd_uncore_init, + .exit = power_amd_uncore_exit, + .get_avail_freqs = power_amd_uncore_freqs, + .get_num_pkgs = power_amd_uncore_get_num_pkgs, + .get_num_dies = power_amd_uncore_get_num_dies, + .get_num_freqs = power_amd_uncore_get_num_freqs, + .get_freq = power_get_amd_uncore_freq, + .set_freq = power_set_amd_uncore_freq, + .freq_max = power_amd_uncore_freq_max, + .freq_min = power_amd_uncore_freq_min, +}; + +RTE_POWER_REGISTER_UNCORE_OPS(amd_uncore_ops); diff --git a/drivers/power/amd_uncore/amd_uncore.h b/drivers/power/amd_uncore/amd_uncore.h new file mode 100644 index 0000000000..60e0e64d27 --- /dev/null +++ b/drivers/power/amd_uncore/amd_uncore.h @@ -0,0 +1,226 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2024 Advanced Micro Devices, Inc. + */ + +#ifndef POWER_AMD_UNCORE_H +#define POWER_AMD_UNCORE_H + +/** + * @file + * RTE AMD Uncore Frequency Management + */ + +#include "rte_power.h" +#include "rte_power_uncore.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Initialize uncore frequency management for specific die on a package. + * It will get the available frequencies and prepare to set new die frequencies. + * + * This function should NOT be called in the fast path. + * + * @param pkg + * Package number. + * Each physical CPU in a system is referred to as a package. + * @param die + * Die number. + * Each package can have several dies connected together via the uncore mesh. + * + * @return + * - 0 on success. + * - Negative on error. + */ +int +power_amd_uncore_init(unsigned int pkg, unsigned int die); + +/** + * Exit uncore frequency management on a specific die on a package. + * It will restore uncore min and* max values to previous values + * before initialization of API. + * + * This function should NOT be called in the fast path. + * + * @param pkg + * Package number. + * Each physical CPU in a system is referred to as a package. + * @param die + * Die number. + * Each package can have several dies connected together via the uncore mesh. + * + * @return + * - 0 on success. + * - Negative on error. + */ +int +power_amd_uncore_exit(unsigned int pkg, unsigned int die); + +/** + * Return the current index of available frequencies of a specific die on a package. + * It should be protected outside of this function for threadsafe. + * + * This function should NOT be called in the fast path. + * + * @param pkg + * Package number. + * Each physical CPU in a system is referred to as a package. + * @param die + * Die number. + * Each package can have several dies connected together via the uncore mesh. + * + * @return + * The current index of available frequencies. + * If error, it will return 'RTE_POWER_INVALID_FREQ_INDEX = (~0)'. + */ +uint32_t +power_get_amd_uncore_freq(unsigned int pkg, unsigned int die); + +/** + * Set minimum and maximum uncore frequency for specified die on a package + * to specified index value. + * It should be protected outside of this function for threadsafe. + * + * This function should NOT be called in the fast path. + * + * @param pkg + * Package number. + * Each physical CPU in a system is referred to as a package. + * @param die + * Die number. + * Each package can have several dies connected together via the uncore mesh. + * @param index + * The index of available frequencies. + * + * @return + * - 1 on success with frequency changed. + * - 0 on success without frequency changed. + * - Negative on error. + */ +int +power_set_amd_uncore_freq(unsigned int pkg, unsigned int die, uint32_t index); + +/** + * Set minimum and maximum uncore frequency for specified die on a package + * to maximum value according to the available frequencies. + * It should be protected outside of this function for threadsafe. + * + * This function should NOT be called in the fast path. + * + * @param pkg + * Package number. + * Each physical CPU in a system is referred to as a package. + * @param die + * Die number. + * Each package can have several dies connected together via the uncore mesh. + * + * @return + * - 1 on success with frequency changed. + * - 0 on success without frequency changed. + * - Negative on error. + */ +int +power_amd_uncore_freq_max(unsigned int pkg, unsigned int die); + +/** + * Set minimum and maximum uncore frequency for specified die on a package + * to minimum value according to the available frequencies. + * It should be protected outside of this function for threadsafe. + * + * This function should NOT be called in the fast path. + * + * @param pkg + * Package number. + * Each physical CPU in a system is referred to as a package. + * @param die + * Die number. + * Each package can have several dies connected together via the uncore mesh. + * + * @return + * - 1 on success with frequency changed. + * - 0 on success without frequency changed. + * - Negative on error. + */ +int +power_amd_uncore_freq_min(unsigned int pkg, unsigned int die); + +/** + * Return the list of available frequencies in the index array. + * + * This function should NOT be called in the fast path. + * + * @param pkg + * Package number. + * Each physical CPU in a system is referred to as a package. + * @param die + * Die number. + * Each package can have several dies connected together via the uncore mesh. + * @param freqs + * The buffer array to save the frequencies. + * @param num + * The number of frequencies to get. + * + * @return + * - The number of available index's in frequency array. + * - Negative on error. + */ +int +power_amd_uncore_freqs(unsigned int pkg, unsigned int die, + unsigned int *freqs, unsigned int num); + +/** + * Return the list length of available frequencies in the index array. + * + * This function should NOT be called in the fast path. + * + * @param pkg + * Package number. + * Each physical CPU in a system is referred to as a package. + * @param die + * Die number. + * Each package can have several dies connected together via the uncore mesh. + * + * @return + * - The number of available index's in frequency array. + * - Negative on error. + */ +int +power_amd_uncore_get_num_freqs(unsigned int pkg, unsigned int die); + +/** + * Return the number of packages (CPUs) on a system + * by parsing the uncore sysfs directory. + * + * This function should NOT be called in the fast path. + * + * @return + * - Zero on error. + * - Number of package on system on success. + */ +unsigned int +power_amd_uncore_get_num_pkgs(void); + +/** + * Return the number of dies for pakckages (CPUs) specified + * from parsing the uncore sysfs directory. + * + * This function should NOT be called in the fast path. + * + * @param pkg + * Package number. + * Each physical CPU in a system is referred to as a package. + * + * @return + * - Zero on error. + * - Number of dies for package on sucecss. + */ +unsigned int +power_amd_uncore_get_num_dies(unsigned int pkg); + +#ifdef __cplusplus +} +#endif + +#endif /* POWER_INTEL_UNCORE_H */ diff --git a/drivers/power/amd_uncore/meson.build b/drivers/power/amd_uncore/meson.build new file mode 100644 index 0000000000..ec1b741c3a --- /dev/null +++ b/drivers/power/amd_uncore/meson.build @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2024 Advanced Micro Devices, Inc. + +if not is_linux + build = false + reason = 'only supported on Linux' + subdir_done() +endif + +IMB_header = '#include' +lib = cc.find_library('e_smi64', required: false) +if not lib.found() + build = false + reason = 'missing dependency, "libe_smi"' +else + ext_deps += lib +endif + +sources = files('amd_uncore.c') +deps += ['power'] diff --git a/drivers/power/meson.build b/drivers/power/meson.build index c83047af94..4ba5954e13 100644 --- a/drivers/power/meson.build +++ b/drivers/power/meson.build @@ -7,6 +7,7 @@ drivers = [ 'cppc', 'kvm_vm', 'pstate', + 'amd_uncore', 'intel_uncore' ]