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 5DACD45B8E; Mon, 21 Oct 2024 06:09:18 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 4A8F7402D5; Mon, 21 Oct 2024 06:09:18 +0200 (CEST) Received: from NAM11-DM6-obe.outbound.protection.outlook.com (mail-dm6nam11on2078.outbound.protection.outlook.com [40.107.223.78]) by mails.dpdk.org (Postfix) with ESMTP id B6D634027C for ; Mon, 21 Oct 2024 06:09:16 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=pVDh5vf0igGRZJ87XIKpfy96maihMNTK6tJLoHXR/9JBgELXVGUWEidMNEMRCSOOhre74uFgvAGDcx7AaeBU3Ea++w2KmXkRpvEvnycxj4Q+DwMb0jxZd9o4NCVE8eJT88ALW9YKg0ULy1uV+6N2kvr+cvZ5eW1WG/NZAtfcOaLyLs+datdOlbY6lSxJiriV2sgTtf5Xbix5LpbjN77rOwmRXM0Jk0eFxuXMV+t0jqXzy9uh4o3CexUmk0HFplAZaqNSKUp0WHN2+Nrdd0TYt4K3K/ZqRcOrbNnZEGp6fGWhiqlT0vlp3MZJR60Vg1acuHwc0l0oevyLbfNi4R/tfg== 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=5psDFq/oZ+gD7OQ/+gwEEkcEfJA/vptCnGMunGy9Oss=; b=jrGQUyT7vDpXwmYc49/g6HHuoFjbPI2A7GeKlPM3kLUNIc871zBqf2kVWKCGE8/Mea4rqfMIhwndBnMCa113RRPIBrlCfr6KYc4Jq3zOzGakiy05p2pfOB94QHWRQwhVD+Fsl85ZHF+eG0Nkt6SOjjWhb3K096pzQ+RTrgu/BP27YToFhwFOYGPiRfS84vaG1gqkWht8El6OVsGITMGYujxhobhdaka2q8cjbRoYQISPfaQxwE1nJUOjSflMluGnCJ53wYytr10zNp7jBSnJNWZZixyLDjnjkGJPZSIP+on9+QOe434H1vtgS4W2ISpShir5CC3PC4vn84M+5xQMMQ== 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=5psDFq/oZ+gD7OQ/+gwEEkcEfJA/vptCnGMunGy9Oss=; b=mwpmqMRRpY4tZ0FQ55PCR+23LB9S39r7DP82i4qsQsQEO+aYAmFs1ZrSWn1I6iTsuL89tppJGHxyo2psYRex1EHioCOuvb/QiD6qkpPta/ExECoR6wBkyi80oAAVO1zcWjk+p9HL2LRc9xODBnFfySxyFa2qKPxGj4M39oz9z+w= Received: from BN8PR15CA0071.namprd15.prod.outlook.com (2603:10b6:408:80::48) by IA1PR12MB6330.namprd12.prod.outlook.com (2603:10b6:208:3e4::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8069.27; Mon, 21 Oct 2024 04:09:12 +0000 Received: from BL02EPF00029928.namprd02.prod.outlook.com (2603:10b6:408:80:cafe::68) by BN8PR15CA0071.outlook.office365.com (2603:10b6:408:80::48) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8069.28 via Frontend Transport; Mon, 21 Oct 2024 04:09:12 +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 BL02EPF00029928.mail.protection.outlook.com (10.167.249.53) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8093.14 via Frontend Transport; Mon, 21 Oct 2024 04:09:12 +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; Sun, 20 Oct 2024 23:08:38 -0500 From: Sivaprasad Tummala To: , , , , , , , , CC: Subject: [PATCH v7 1/5] power: refactor core power management library Date: Mon, 21 Oct 2024 04:07:19 +0000 Message-ID: <20241021040724.3325876-2-sivaprasad.tummala@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241021040724.3325876-1-sivaprasad.tummala@amd.com> References: <20241020092233.2906612-1-sivaprasad.tummala@amd.com> <20241021040724.3325876-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: 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: BL02EPF00029928:EE_|IA1PR12MB6330:EE_ X-MS-Office365-Filtering-Correlation-Id: 800b6e8f-cbc9-45e9-0b39-08dcf1861f01 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|1800799024|82310400026|36860700013|376014; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?EhntFrj6kyOU0v7af2A8RjzDaUbF455b+eoTeaN9qtDh/Z7ZPyHD4GzjSNkL?= =?us-ascii?Q?g7xWi4DwKtDzYoGJg/4ME86LoWPKx9XPYslYKEFgTC8fxffXuEX7XOCxbUs5?= =?us-ascii?Q?pCqXUwl+Ywso760xYlkacdWxXvlXHDfZdnArSi5Q6nIQvWfzBYECuNZxw02i?= =?us-ascii?Q?qgGWSD5ggBRbaIqYsd7zodBxrG2a6jRHMRHGrYcqo5fwH4YMgfNUkKzZ+YlR?= =?us-ascii?Q?807BHzkVtPI9JF/CrEWwu1HjFjtMc0Qnc1NyvUM+zGs6TiOb9dp1GN8AaDRM?= =?us-ascii?Q?sV+ocqo6DpNK39H+tNeO614ckXYzlTmQ8WSy90aApPe/W2Ecdm3MuKKQe/N1?= =?us-ascii?Q?awYVNRG4N8w1g3w2AED5460KbBz8Qw6uvS0LH6bWrRRsjbBNZwiWtjmALBn7?= =?us-ascii?Q?AY3oHHOrn3qwlkq4cCfRHaiO/Cnj8WhRD0OCzkPI5RtksZzBKeZPR+OWKQpB?= =?us-ascii?Q?QPqP/pl5i2h+VeglT/iTaXhzydTzsIpoxh5jfw7g95gqZQha954Dj143wQaz?= =?us-ascii?Q?k0WwtbhxulmnKmanotTbbQ2BtO4z4NrmrGpOm37bGrr+4DZTC1R8jHwgUuaU?= =?us-ascii?Q?x/Se8LknlT+BHV3uqY4qj0sQLBHGYpEr5dCCR95XfuLgop/GmviollxZw8To?= =?us-ascii?Q?ca3oXl/2lOA+o/kN9GVyFuMBrVMJShTuxNGGPBIPn+XFQYWW1eN4RLnJB/N0?= =?us-ascii?Q?rkDUnVIQ7hsbP3pW7eaJlJNsjtW3d51JD3UAZLp6aZglEnZdnIuutKIdHpG2?= =?us-ascii?Q?coFKOxXOAew5W5h8of4Hdbb0j6Ud1vLUjIQCbS/GrpKqhtzzhM9t6See+Rgw?= =?us-ascii?Q?DxUCER04xWjBCiehe++WS4Vxbf5g4XJASI2iezvWH9NslB6z+ZCQ3uua3qdN?= =?us-ascii?Q?gqM+ryW6I8d47V41ZpLClIqqLW6QEloX0DdKjjkQOtZXOXPdq6zi6SWCPRvV?= =?us-ascii?Q?m+s7tatbo16FdvkL45AvDEOB2EoYwbevAH4DQP2DiL/1An9D583NtvjeG8+7?= =?us-ascii?Q?qUyBOGubTrzzD2pYMUYn+fVROQ1Fg5QBNen/4geZQY3n2VwLPlttoOO6k048?= =?us-ascii?Q?dNyczPZnE+/d/J5XXHFGWYngPxabAQhd3OfyRL4LVPZH2i8Ofm4bRXc9jgMi?= =?us-ascii?Q?Uj0KhfQ6c/fAcU7/+hRL80/fdwsAmx5vEQdooKzo0rO45+Qj9Lgj6YOc8HDp?= =?us-ascii?Q?4EHqGFwxrw61ndseQ+5ZBc+QFQcEVw1tRT8yENPJ75ZTb4Qo5H1rGEL7QBeU?= =?us-ascii?Q?2cpSv1cH4WGft3Vqbd+tzh8XWCJwikvRKDzjKZEk0JRXoRwuFRk9KyP1JR4z?= =?us-ascii?Q?3TJVnaIHCNZ8cqStQKQdUzmf2t3r5ml2fXt6j/MaXd+Te57r+u2vGtCbysLH?= =?us-ascii?Q?sZWot3xz2hP73UOhBiK3mIg2dsJ6z8orZgbkyM+sx/2BgH6R1g=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)(1800799024)(82310400026)(36860700013)(376014); DIR:OUT; SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Oct 2024 04:09:12.7216 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 800b6e8f-cbc9-45e9-0b39-08dcf1861f01 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: BL02EPF00029928.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA1PR12MB6330 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. 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 | 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 | 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/rte_power.c | 355 ++++++++---------- lib/power/rte_power.h | 116 +++--- lib/power/rte_power_cpufreq_api.h | 206 ++++++++++ lib/power/version.map | 15 + 26 files changed, 665 insertions(+), 269 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 (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_cpufreq_api.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..974fbb7ba8 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_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..c685008fb5 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_cpufreq_api.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..8b93226281 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_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 96% rename from lib/power/power_amd_pstate_cpufreq.h rename to drivers/power/amd_pstate/amd_pstate_cpufreq.h index b02f9f98e4..d7188fcdac 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_cpufreq_api.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..8ca84c4b49 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_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..64a766145a 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_cpufreq_api.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..8b92054076 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_cpufreq_api.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..09a11f7c37 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_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..5fddb40280 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_cpufreq_api.h" /** * Check if pstate power management is supported. diff --git a/lib/power/meson.build b/lib/power/meson.build index 2f0f3d26e9..9a4a592caf 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_cpufreq_api.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 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/rte_power.c b/lib/power/rte_power.c index 36c3f3da98..416f0148a3 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_core_ops *global_power_core_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_core_ops) core_ops_list = + TAILQ_HEAD_INITIALIZER(core_ops_list); + +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; - } - - 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, &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,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_power_core_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_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, "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, &core_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_power_core_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_power_core_ops != NULL); + return global_power_core_ops->get_avail_freqs(lcore_id, freqs, n); +} + +uint32_t +rte_power_get_freq(unsigned int lcore_id) +{ + RTE_ASSERT(global_power_core_ops != NULL); + return global_power_core_ops->get_freq(lcore_id); +} + +uint32_t +rte_power_set_freq(unsigned int lcore_id, uint32_t index) +{ + RTE_ASSERT(global_power_core_ops != NULL); + return global_power_core_ops->set_freq(lcore_id, index); +} + +int +rte_power_freq_up(unsigned int lcore_id) +{ + RTE_ASSERT(global_power_core_ops != NULL); + return global_power_core_ops->freq_up(lcore_id); +} + +int +rte_power_freq_down(unsigned int lcore_id) +{ + RTE_ASSERT(global_power_core_ops != NULL); + return global_power_core_ops->freq_down(lcore_id); +} + +int +rte_power_freq_max(unsigned int lcore_id) +{ + RTE_ASSERT(global_power_core_ops != NULL); + return global_power_core_ops->freq_max(lcore_id); +} + +int +rte_power_freq_min(unsigned int lcore_id) +{ + RTE_ASSERT(global_power_core_ops != NULL); + return global_power_core_ops->freq_min(lcore_id); +} +int +rte_power_turbo_status(unsigned int lcore_id) +{ + RTE_ASSERT(global_power_core_ops != NULL); + return global_power_core_ops->turbo_status(lcore_id); +} + +int +rte_power_freq_enable_turbo(unsigned int lcore_id) +{ + RTE_ASSERT(global_power_core_ops != NULL); + return global_power_core_ops->enable_turbo(lcore_id); +} + +int +rte_power_freq_disable_turbo(unsigned int lcore_id) +{ + RTE_ASSERT(global_power_core_ops != NULL); + return global_power_core_ops->disable_turbo(lcore_id); +} + +int +rte_power_get_capabilities(unsigned int lcore_id, + struct rte_power_core_capabilities *caps) +{ + RTE_ASSERT(global_power_core_ops != NULL); + return global_power_core_ops->get_caps(lcore_id, caps); } diff --git a/lib/power/rte_power.h b/lib/power/rte_power.h index 4fa4afe399..e9a72b92ad 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_cpufreq_api.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/rte_power_cpufreq_api.h b/lib/power/rte_power_cpufreq_api.h new file mode 100644 index 0000000000..31fea941bf --- /dev/null +++ b/lib/power/rte_power_cpufreq_api.h @@ -0,0 +1,206 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + * Copyright(c) 2024 Advanced Micro Devices, Inc. + */ + +#ifndef _RTE_POWER_CPUFREQ_API_H +#define _RTE_POWER_CPUFREQ_API_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. + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/power/version.map b/lib/power/version.map index c9a226614e..016e599e90 100644 --- a/lib/power/version.map +++ b/lib/power/version.map @@ -51,4 +51,19 @@ EXPERIMENTAL { rte_power_set_uncore_env; rte_power_uncore_freqs; rte_power_unset_uncore_env; + # added in 24.11 + rte_power_logtype; +}; + +INTERNAL { + global: + + rte_power_register_ops; + 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