From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 02D2045BAA; Wed, 23 Oct 2024 07:12:14 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id E482640A6B; Wed, 23 Oct 2024 07:12:13 +0200 (CEST) Received: from NAM02-BN1-obe.outbound.protection.outlook.com (mail-bn1nam02on2054.outbound.protection.outlook.com [40.107.212.54]) by mails.dpdk.org (Postfix) with ESMTP id 6F1904026C for ; Wed, 23 Oct 2024 07:12:08 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=MX5E7bv960/Hu2qvtsJLZCPymirwbW1sg+IZUgaWu+LBjevdjAsDgfpBpoQ+mgGntZHa33QKYvx9r7/yo4JZFDyOUWmCYALj+CCinrVgolW3bA+NgUUwMa3Y40/mv9W5of73IDyDVO4354XN7lr7RkmnMRvpiblLK5kOVDag3cOjoObvw64FYIcwPgahOLYbykmL5RieBuvrkuHzM1SDGTrsjxq2zt0P2OIJqL+W+Ri16cBrovD8pyLW0NTAzf3Q6qElXZNAIbFIjRI79+6XgFAVv3CilW3rSWcPqYoBPnVXf0wR9CFcUx+pCms0CamPtPMTrNsWQYnOi+JzxYxHuA== 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=bEZWghAjXY7XWCYmNI9T/ncPnSsj699FdbWUTj/wovw=; b=ay4oCvoEuSewci/6WkU/YFLeL3EzCS4/9DxD8ujRz1aONgRUGvlRGbSFgRyEOT485QmHcb7BSzpMu1leP40VMXOWp+5KomFDfC/6x1uZGaARI5W8hBRmnir6FSnbs/zTyDIRuNBJ92BlZxUfN87/4otW3Q2cap8f91nB0w6CYkvJC6qrQH1OOXoT9PMSQnPqqozCSlHBvMbEnnDojlcmGbMdiBzMl6iqZDRWIXA0JXMecgnLSG+aMGoc1L3iVShKqbA0/pC1qf0po9PkuX3MEgLslRr0Y0e6qAl7w+zCItA2tGj3KqYQ3KBRuROF4g9qLV/KWpGgyNo3iEBmAQCqkg== 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=bEZWghAjXY7XWCYmNI9T/ncPnSsj699FdbWUTj/wovw=; b=0XVM2xN8uP9axu1YwvexxSRmuld+0Aq5l7XLMKAkKcRfHxQH7eLnaBvXg8jquNSx8t2KstdjYaEm0Y+lzTkXpN/hD/iRNjX+2x0varFhKmOnZ2oKj9lGmJSmpwSzmCs0OQHwF83aNI5YYUZngoJ4VOePr91A1g2xGTz6g4p/+M0= Received: from SJ0PR13CA0093.namprd13.prod.outlook.com (2603:10b6:a03:2c5::8) by CY8PR12MB7490.namprd12.prod.outlook.com (2603:10b6:930:91::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8069.29; Wed, 23 Oct 2024 05:12:03 +0000 Received: from SJ1PEPF00001CDE.namprd05.prod.outlook.com (2603:10b6:a03:2c5:cafe::88) by SJ0PR13CA0093.outlook.office365.com (2603:10b6:a03:2c5::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8093.16 via Frontend Transport; Wed, 23 Oct 2024 05:12: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 SJ1PEPF00001CDE.mail.protection.outlook.com (10.167.242.6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8093.14 via Frontend Transport; Wed, 23 Oct 2024 05:12: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; Wed, 23 Oct 2024 00:11:58 -0500 From: Sivaprasad Tummala To: , , , , , , , , CC: Subject: [PATCH v9 1/6] power: refactor core power management library Date: Wed, 23 Oct 2024 05:11:33 +0000 Message-ID: <20241023051139.1066426-2-sivaprasad.tummala@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241023051139.1066426-1-sivaprasad.tummala@amd.com> References: <20241022184133.700367-1-sivaprasad.tummala@amd.com> <20241023051139.1066426-1-sivaprasad.tummala@amd.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Originating-IP: [10.180.168.240] X-ClientProxiedBy: SATLEXMB04.amd.com (10.181.40.145) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF00001CDE:EE_|CY8PR12MB7490:EE_ X-MS-Office365-Filtering-Correlation-Id: a63a33ec-4b76-4130-e284-08dcf3213b4d X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|376014|36860700013|82310400026|1800799024; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?DSCH6aXhPp4xwqOx0x3gS+47nX3sGmdm8XxWQOrTpFwlyNEeSwbTFLhWb09m?= =?us-ascii?Q?mEHj7tCQCyesp4pOteaTXabUsUJ2nJiUh4FsC9+wr6x7wu4azqN3HpQcr92Z?= =?us-ascii?Q?ZbmlH91cJFq833u6Rjxl/Azf6offtyoWnp/0U1QtlKb8y4MUmXjpTMLc8HK2?= =?us-ascii?Q?anG58gZlzb05jokSjvASvRuAiMzeHtcH1j9Szs5oavsFiPqly8m2AqSOokrv?= =?us-ascii?Q?JTQO4SpwfYjy2Tse00vT2TSOnWJi5ch9f9LNCtTMnWAjryI9r7G49dWjhgG4?= =?us-ascii?Q?Q6TQng5q9AP9UWU02QmDfejxNAY83USaJIOgRxOEEAh4LofEwpRyi/c/Pj0h?= =?us-ascii?Q?0SZUwh1dH1XojCpJTe2YPrtBIm7hS3BAF1fjqA5neyqPeTihndt4ZjsqoTbm?= =?us-ascii?Q?TpbgNciK6y9PiAfmlkfAi1NqFGGyhIvaHS+TgrOgbeTyYkDledOghi4jEhFw?= =?us-ascii?Q?oRFDUZUNm1thw3VKiuz9A4MyX++00vhOFlkVqtXPavK++EiiJF/w2oyAqF56?= =?us-ascii?Q?zflNpG8b1f2fOjJfycPbAks6XlskBuZIgEUjpRWURA3XS4gq3eFAAhl5tcJx?= =?us-ascii?Q?H7WiZPTtPAa77wDBtDtm5xV/1CTKV6UfnY+WJKBdw/Mm9pmUUfEkSNLt8mvb?= =?us-ascii?Q?nQjjaMUnSPVLTye6U3sf0Rgv7MH0nKOxrE3Urtv9QR+JteYQOlAnmTUDCe9u?= =?us-ascii?Q?svjYvnhG/zpe5Jg++YlU3kELuWIGjGapIzak+L9qXlglNpymQdM6BG4b9x+O?= =?us-ascii?Q?BRMubXumS6c7ajVwSqMz5GLWbVCjXsTw0aoWf2jdO3U5hGx5k4ZxzAUIo8HT?= =?us-ascii?Q?CIYQEUybpPrJTDx/o2wU/5jWq5qbI1lTWqQtFOvgit4cGe3KXTpns5jwTkm+?= =?us-ascii?Q?uZn4tG4k6cEZrcEWk4GvLAFC9tMA3qhgO6kgZF7u9gpofGrPdQsNCeb4uUuM?= =?us-ascii?Q?CiBJ9GMekrg0QoBsf3kLXShUjKKir0q79b/twyi0lKF3oYUbb8ix8Rd5HFc3?= =?us-ascii?Q?aktg8FPelWTh6OGrc8kyYo9PAEda6sFZFbAPCSqkn8a/XUJ6XXC0yfIYw0sH?= =?us-ascii?Q?F4du92m2KvSNLKtLyhzAsdjOet2nZ9U+PgeZzG5xUfAkGDPAVhBOMbhjwmf9?= =?us-ascii?Q?cNMOuK1aaOVvEED7e2bFynVVh/ereseirgO3sqsP3ikEYGyU4ZeFAuqhHGgc?= =?us-ascii?Q?/pEzkAtGz7tqbLqlkHoDZm7+vC8EcB1R9T2DHP1v1TIdplBdgwGp5GqDzGsp?= =?us-ascii?Q?ornoLueE+/ZtDL2Ue4R4Qk6qNzazLl56iH176jSy4RYcPreZydSVw7bSxdnQ?= =?us-ascii?Q?/Sp8jkurTABmfSjgeOUV0iLtLN7wkx8ZVzQ1PnxabpiAZS8eyQqky2lexYha?= =?us-ascii?Q?dRy4Nyr1ywF1wllRcD0QsRIaje0nL28MMeC2fVv8JO6KKCVJ7Q=3D=3D?= 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)(376014)(36860700013)(82310400026)(1800799024); DIR:OUT; SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Oct 2024 05:12:03.2791 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: a63a33ec-4b76-4130-e284-08dcf3213b4d 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: SJ1PEPF00001CDE.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY8PR12MB7490 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. v8: - marked rte_power_logtype as internal - removed c++ guards for internal header files - renamed rte_power_cpufreq_api.h for naming convention - renamed rte_power_register_ops for naming convention v6: - fixed compilation error with symbol export in API - exported power_get_lcore_mapped_cpu_id as internal API to be used in drivers/power/* v5: - fixed code style warning v4: - fixed build error with RTE_ASSERT v3: - renamed rte_power_core_ops.h as rte_power_cpufreq_api.h - re-worked on auto detection logic v2: - added NULL check for global_core_ops in rte_power_get_core_ops 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 | 10 +- 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 | 2 +- .../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 | 14 + 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 | 18 +- lib/power/power_cpufreq.h | 191 ++++++++++ lib/power/rte_power.c | 355 ++++++++---------- lib/power/rte_power.h | 116 +++--- lib/power/version.map | 14 + 26 files changed, 650 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 (96%) 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 (99%) 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/power_cpufreq.h diff --git a/drivers/meson.build b/drivers/meson.build index 2733306698..7ef4f581a0 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 ae809fbb60..81a5e3f6ea 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 @@ -587,3 +587,23 @@ int power_acpi_get_capabilities(unsigned int lcore_id, return 0; } + +static struct rte_power_cpufreq_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_CPUFREQ_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..e18a3e6af8 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 "power_cpufreq.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 2b728eca18..95495bff7d 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 */ @@ -710,3 +710,23 @@ power_amd_pstate_get_capabilities(unsigned int lcore_id, return 0; } + +static struct rte_power_cpufreq_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_CPUFREQ_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 96% rename from lib/power/power_amd_pstate_cpufreq.h rename to drivers/power/amd_pstate/amd_pstate_cpufreq.h index b02f9f98e4..5c273df4d7 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 "power_cpufreq.h" /** * Check if amd p-state power management is supported. @@ -216,4 +216,4 @@ int power_amd_pstate_disable_turbo(unsigned int lcore_id); int power_amd_pstate_get_capabilities(unsigned int lcore_id, struct rte_power_core_capabilities *caps); -#endif /* _POWER_AMD_PSTATET_CPUFREQ_H */ +#endif /* _AMD_PSTATET_CPUFREQ_H */ 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 cc9305bdfe..3cd4165c83 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 */ @@ -695,3 +695,23 @@ power_cppc_get_capabilities(unsigned int lcore_id, return 0; } + +static struct rte_power_cpufreq_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_CPUFREQ_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..d637f53dcc 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 "power_cpufreq.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 99% rename from lib/power/guest_channel.c rename to drivers/power/kvm_vm/guest_channel.c index bc3f55b6bf..35cd4cfe6f 100644 --- a/lib/power/guest_channel.c +++ b/drivers/power/kvm_vm/guest_channel.c @@ -13,7 +13,7 @@ #include -#include +#include #include "guest_channel.h" 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..5754a441cd 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_cpufreq_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_CPUFREQ_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..4fabe4c6a5 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 "power_cpufreq.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..fe11179ab3 --- /dev/null +++ b/drivers/power/kvm_vm/meson.build @@ -0,0 +1,14 @@ +# 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 4755909466..f117ff3d17 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 */ @@ -898,3 +898,23 @@ int power_pstate_get_capabilities(unsigned int lcore_id, return 0; } + +static struct rte_power_cpufreq_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_CPUFREQ_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..b18a1ac9bc 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 "power_cpufreq.h" /** * Check if pstate power management is supported. diff --git a/lib/power/meson.build b/lib/power/meson.build index 2f0f3d26e9..dd8e4393ac 100644 --- a/lib/power/meson.build +++ b/lib/power/meson.build @@ -12,19 +12,14 @@ 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( + 'power_cpufreq.h', 'rte_power.h', 'rte_power_guest_channel.h', 'rte_power_pmd_mgmt.h', diff --git a/lib/power/power_common.c b/lib/power/power_common.c index b47c63a5f1..e482f71c64 100644 --- a/lib/power/power_common.c +++ b/lib/power/power_common.c @@ -13,7 +13,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 82fb94d0c0..c294f561bb 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,14 +24,27 @@ 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); + +__rte_internal int power_get_lcore_mapped_cpu_id(uint32_t lcore_id, uint32_t *cpu_id); #endif /* _POWER_COMMON_H_ */ diff --git a/lib/power/power_cpufreq.h b/lib/power/power_cpufreq.h new file mode 100644 index 0000000000..e33d9fe18c --- /dev/null +++ b/lib/power/power_cpufreq.h @@ -0,0 +1,191 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + * Copyright(c) 2024 Advanced Micro Devices, Inc. + */ + +#ifndef _POWER_CPUFREQ_H +#define _POWER_CPUFREQ_H + +/** + * @file + * RTE Power Management + */ + +#include +#include +#include + +#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_cpufreq_ops { + RTE_TAILQ_ENTRY(rte_power_cpufreq_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_cpufreq_ops(struct rte_power_cpufreq_ops *ops); + +/** + * Macro to statically register the ops of a cpufreq driver. + */ +#define RTE_POWER_REGISTER_CPUFREQ_OPS(ops) \ +RTE_INIT(power_hdlr_init_##ops) \ +{ \ + rte_power_register_cpufreq_ops(&ops); \ +} + +#endif diff --git a/lib/power/rte_power.c b/lib/power/rte_power.c index 36c3f3da98..3168b6d301 100644 --- a/lib/power/rte_power.c +++ b/lib/power/rte_power.c @@ -6,155 +6,88 @@ #include #include +#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_cpufreq_ops *global_cpufreq_ops; static rte_spinlock_t global_env_cfg_lock = RTE_SPINLOCK_INITIALIZER; - -/* 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) +static RTE_TAILQ_HEAD(, rte_power_cpufreq_ops) cpufreq_ops_list = + TAILQ_HEAD_INITIALIZER(cpufreq_ops_list); + +const char *power_env_str[] = { + "not set", + "acpi", + "kvm-vm", + "pstate", + "cppc", + "amd-pstate" +}; + +/* register the ops struct in rte_power_cpufreq_ops, return 0 on success. */ +int +rte_power_register_cpufreq_ops(struct rte_power_cpufreq_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 cpufreq ops"); + return -EINVAL; + } + + TAILQ_INSERT_TAIL(&cpufreq_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_cpufreq_ops *ops; + + if (env >= RTE_DIM(power_env_str)) + return 0; + + RTE_TAILQ_FOREACH(ops, &cpufreq_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_cpufreq_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; - } - - if (ret == 0) - global_default_env = env; - else { - global_default_env = PM_ENV_NOT_SET; - reset_power_function_ptrs(); + goto out; } + RTE_TAILQ_FOREACH(ops, &cpufreq_ops_list, next) + if (strncmp(ops->name, power_env_str[env], + RTE_POWER_DRIVER_NAMESZ) == 0) { + global_cpufreq_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,7 +97,7 @@ rte_power_unset_env(void) { rte_spinlock_lock(&global_env_cfg_lock); global_default_env = PM_ENV_NOT_SET; - reset_power_function_ptrs(); + global_cpufreq_ops = NULL; rte_spinlock_unlock(&global_env_cfg_lock); } @@ -176,82 +109,122 @@ rte_power_get_env(void) { 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_cpufreq_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_cpufreq_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, "Env isn't set yet!"); - 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; + /* Auto detect Environment */ + RTE_TAILQ_FOREACH(ops, &cpufreq_ops_list, next) { + POWER_LOG(INFO, + "Attempting to initialise %s cpufreq power management...", + ops->name); + for (env = 0; env < RTE_DIM(power_env_str); env++) { + if ((strncmp(ops->name, power_env_str[env], + RTE_POWER_DRIVER_NAMESZ) == 0) && + (ops->init(lcore_id) == 0)) { + rte_power_set_env(env); + return 0; + } + } } - 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; - } + 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_cpufreq_ops->exit(lcore_id); + + POWER_LOG(ERR, + "Environment has not been set, unable to exit gracefully"); - } return -1; +} + +uint32_t +rte_power_freqs(unsigned int lcore_id, uint32_t *freqs, uint32_t n) +{ + RTE_ASSERT(global_cpufreq_ops != NULL); + return global_cpufreq_ops->get_avail_freqs(lcore_id, freqs, n); +} + +uint32_t +rte_power_get_freq(unsigned int lcore_id) +{ + RTE_ASSERT(global_cpufreq_ops != NULL); + return global_cpufreq_ops->get_freq(lcore_id); +} + +uint32_t +rte_power_set_freq(unsigned int lcore_id, uint32_t index) +{ + RTE_ASSERT(global_cpufreq_ops != NULL); + return global_cpufreq_ops->set_freq(lcore_id, index); +} + +int +rte_power_freq_up(unsigned int lcore_id) +{ + RTE_ASSERT(global_cpufreq_ops != NULL); + return global_cpufreq_ops->freq_up(lcore_id); +} + +int +rte_power_freq_down(unsigned int lcore_id) +{ + RTE_ASSERT(global_cpufreq_ops != NULL); + return global_cpufreq_ops->freq_down(lcore_id); +} + +int +rte_power_freq_max(unsigned int lcore_id) +{ + RTE_ASSERT(global_cpufreq_ops != NULL); + return global_cpufreq_ops->freq_max(lcore_id); +} + +int +rte_power_freq_min(unsigned int lcore_id) +{ + RTE_ASSERT(global_cpufreq_ops != NULL); + return global_cpufreq_ops->freq_min(lcore_id); +} +int +rte_power_turbo_status(unsigned int lcore_id) +{ + RTE_ASSERT(global_cpufreq_ops != NULL); + return global_cpufreq_ops->turbo_status(lcore_id); +} + +int +rte_power_freq_enable_turbo(unsigned int lcore_id) +{ + RTE_ASSERT(global_cpufreq_ops != NULL); + return global_cpufreq_ops->enable_turbo(lcore_id); +} + +int +rte_power_freq_disable_turbo(unsigned int lcore_id) +{ + RTE_ASSERT(global_cpufreq_ops != NULL); + return global_cpufreq_ops->disable_turbo(lcore_id); +} + +int +rte_power_get_capabilities(unsigned int lcore_id, + struct rte_power_core_capabilities *caps) +{ + RTE_ASSERT(global_cpufreq_ops != NULL); + return global_cpufreq_ops->get_caps(lcore_id, caps); } diff --git a/lib/power/rte_power.h b/lib/power/rte_power.h index 4fa4afe399..7d566551bd 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 "power_cpufreq.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 @@ -108,10 +116,7 @@ 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); - -extern rte_power_freqs_t rte_power_freqs; +uint32_t rte_power_freqs(unsigned int lcore_id, uint32_t *freqs, uint32_t num); /** * Return the current index of available frequencies of a specific lcore. @@ -124,9 +129,7 @@ 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); - -extern rte_power_get_freq_t rte_power_get_freq; +uint32_t rte_power_get_freq(unsigned int lcore_id); /** * Set the new frequency for a specific lcore by indicating the index of @@ -144,13 +147,12 @@ 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; +uint32_t rte_power_set_freq(unsigned int lcore_id, uint32_t index); /** - * Function pointer definition for generic frequency change functions. Review - * each environments specific documentation for usage. + * Scale up the frequency of a specific lcore according to the available + * frequencies. + * Review each environments specific documentation for usage. * * @param lcore_id * lcore id. @@ -160,66 +162,92 @@ extern rte_power_set_freq_t rte_power_set_freq; * - 0 on success without frequency changed. * - Negative on error. */ -typedef int (*rte_power_freq_change_t)(unsigned int lcore_id); - -/** - * 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; +int rte_power_freq_up(unsigned int lcore_id); /** * Scale down the frequency of a specific lcore according to the available * frequencies. * 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. */ -extern rte_power_freq_change_t rte_power_freq_down; +int rte_power_freq_down(unsigned int 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. + * + * @param lcore_id + * lcore id. + * + * @return + * - 1 on success with frequency changed. + * - 0 on success without frequency changed. + * - Negative on error. */ -extern rte_power_freq_change_t rte_power_freq_max; +int rte_power_freq_max(unsigned int 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.. + * + * @param lcore_id + * lcore id. + * + * @return + * - 1 on success with frequency changed. + * - 0 on success without frequency changed. + * - Negative on error. */ -extern rte_power_freq_change_t rte_power_freq_min; +int rte_power_freq_min(unsigned int lcore_id); /** * Query the Turbo Boost status of a specific lcore. * Review each environments specific documentation for usage.. + * + * @param lcore_id + * lcore id. + * + * @return + * - 1 turbo boost enabled. + * - 0 turbo boost disabled. + * - Negative on error. */ -extern rte_power_freq_change_t rte_power_turbo_status; +int rte_power_turbo_status(unsigned int lcore_id); /** * Enable Turbo Boost for this lcore. * Review each environments specific documentation for usage.. + * + * @param lcore_id + * lcore id. + * + * @return + * - 0 on success. + * - Negative on error. */ -extern rte_power_freq_change_t rte_power_freq_enable_turbo; +int rte_power_freq_enable_turbo(unsigned int lcore_id); /** * Disable Turbo Boost for this lcore. * Review each environments specific documentation for usage.. + * + * @param lcore_id + * lcore id. + * + * @return + * - 0 on success. + * - Negative on error. */ -extern rte_power_freq_change_t rte_power_freq_disable_turbo; - -/** - * 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 */ - }; - }; -}; +int rte_power_freq_disable_turbo(unsigned int lcore_id); /** * Returns power capabilities for a specific lcore. @@ -235,11 +263,9 @@ struct rte_power_core_capabilities { * - 0 on success. * - Negative on error. */ -typedef int (*rte_power_get_capabilities_t)(unsigned int lcore_id, +int rte_power_get_capabilities(unsigned int lcore_id, struct rte_power_core_capabilities *caps); -extern rte_power_get_capabilities_t rte_power_get_capabilities; - #ifdef __cplusplus } #endif diff --git a/lib/power/version.map b/lib/power/version.map index c9a226614e..9c1ed4d9d6 100644 --- a/lib/power/version.map +++ b/lib/power/version.map @@ -52,3 +52,17 @@ EXPERIMENTAL { rte_power_uncore_freqs; rte_power_unset_uncore_env; }; + +INTERNAL { + global: + + rte_power_register_cpufreq_ops; + rte_power_logtype; + cpufreq_check_scaling_driver; + power_get_lcore_mapped_cpu_id; + power_set_governor; + open_core_sysfs_file; + read_core_sysfs_u32; + read_core_sysfs_s; + write_core_sysfs_s; +}; -- 2.34.1