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 985EAA0542; Tue, 31 May 2022 11:58:42 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id E3FA240A87; Tue, 31 May 2022 11:58:30 +0200 (CEST) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by mails.dpdk.org (Postfix) with ESMTP id 7E4E1427EC for ; Tue, 31 May 2022 11:58:28 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1653991108; x=1685527108; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=tXcagTabAGRxosu2Wwe/7c4jKSFxllDyHncvOWCrOqI=; b=dYOCSy7ZlnGkttxCrdv09VzCU1u1YPITXy98FwggQgQFQ2JU/m4o/eVZ cpYWXxPMcK5ryBIDS9COHHHOrF1U8P4YUtwEnxFsonN09f2lrADQkz/x3 yEbI8zlHVcuWWwR2Gja3xWxfAhaFXDwUQA8uR32jlfUV6EAvTn3JXgvrO y/Ni46xNAIDUk1+AgjDiCzEdS9Z8bqH6L/BKUJiKMqrNP4bNG24ZJ0pNb OrWhq1zDKuAnoQBvUhjeTuoMeVifjkE+Ne7nqpN4L3Vh9ZmuN9Rg4pSXr h6yPdDFTgCm6YNfWLiXz0Fg0BB05vV5mPPZjGU8lndGLyMhorqq83ToZa w==; X-IronPort-AV: E=McAfee;i="6400,9594,10363"; a="338248454" X-IronPort-AV: E=Sophos;i="5.91,264,1647327600"; d="scan'208";a="338248454" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 31 May 2022 02:58:28 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.91,264,1647327600"; d="scan'208";a="679507653" Received: from silpixa00401122.ir.intel.com ([10.237.213.29]) by fmsmga002.fm.intel.com with ESMTP; 31 May 2022 02:58:26 -0700 From: Kevin Laatz To: dev@dpdk.org Cc: anatoly.burakov@intel.com, Kevin Laatz , Ray Kinsella , David Hunt Subject: [PATCH v5 3/4] lib/power: add get and set API for scaling freq min and max with pstate mode Date: Tue, 31 May 2022 10:59:35 +0100 Message-Id: <20220531095936.1965727-4-kevin.laatz@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220531095936.1965727-1-kevin.laatz@intel.com> References: <20220408140847.1319312-1-kevin.laatz@intel.com> <20220531095936.1965727-1-kevin.laatz@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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 Add new get/set API to allow the user or application to set the minimum and maximum frequencies to use when scaling. Previously, the frequency range was determined by the HW capabilities of the CPU. With this new API, the user or application can constrain this if required. Signed-off-by: Kevin Laatz Acked-by: Ray Kinsella Acked-by: Anatoly Burakov Tested-by: David Hunt --- v5: * add doc entry for new API v4: * fix mismatch between comments and code * fix return value when max freq is not set v3: * updated doxygen comments * added checks to ensure min/max value is valid * consider 0 as 'not set' for scaling_freq_max --- doc/guides/prog_guide/power_man.rst | 12 +++++ lib/power/power_pstate_cpufreq.c | 24 +++++++-- lib/power/rte_power_pmd_mgmt.c | 77 +++++++++++++++++++++++++++ lib/power/rte_power_pmd_mgmt.h | 81 +++++++++++++++++++++++++++++ lib/power/version.map | 4 ++ 5 files changed, 193 insertions(+), 5 deletions(-) diff --git a/doc/guides/prog_guide/power_man.rst b/doc/guides/prog_guide/power_man.rst index f22513b324..a63a830213 100644 --- a/doc/guides/prog_guide/power_man.rst +++ b/doc/guides/prog_guide/power_man.rst @@ -264,6 +264,18 @@ API Overview for Ethernet PMD Power Management * **Set Pause Duration**: Set the duration of the pause (ms) used in the Pause mode callback. +* **Get Scaling Min Freq**: Get the configured minimum frequency to be used in + Frequency Scaling mode. + +* **Set Scaling Min Freq**: Set the minimum frequency to be used in Frequency + Scaling mode. + +* **Get Scaling Max Freq**: Get the configured maximum frequency to be used in + Frequency Scaling mode. + +* **Set Scaling Max Freq**: Set the maximum frequency to be used in Frequency + Scaling mode. + References ---------- diff --git a/lib/power/power_pstate_cpufreq.c b/lib/power/power_pstate_cpufreq.c index f4c36179ec..78c9197695 100644 --- a/lib/power/power_pstate_cpufreq.c +++ b/lib/power/power_pstate_cpufreq.c @@ -12,6 +12,7 @@ #include +#include "rte_power_pmd_mgmt.h" #include "power_pstate_cpufreq.h" #include "power_common.h" @@ -354,6 +355,7 @@ power_get_available_freqs(struct pstate_power_info *pi) FILE *f_min = NULL, *f_max = NULL; int ret = -1; uint32_t sys_min_freq = 0, sys_max_freq = 0, base_max_freq = 0; + int config_min_freq, config_max_freq; uint32_t i, num_freqs = 0; /* open all files */ @@ -388,6 +390,18 @@ power_get_available_freqs(struct pstate_power_info *pi) goto out; } + /* check for config set by user or application to limit frequency range */ + config_min_freq = rte_power_pmd_mgmt_get_scaling_freq_min(pi->lcore_id); + if (config_min_freq < 0) + goto out; + config_max_freq = rte_power_pmd_mgmt_get_scaling_freq_max(pi->lcore_id); + if (config_max_freq < 0) + goto out; + + sys_min_freq = RTE_MAX(sys_min_freq, (uint32_t)config_min_freq); + if (config_max_freq > 0) /* Only use config_max_freq if a value has been set */ + sys_max_freq = RTE_MIN(sys_max_freq, (uint32_t)config_max_freq); + if (sys_max_freq < sys_min_freq) goto out; @@ -411,8 +425,8 @@ power_get_available_freqs(struct pstate_power_info *pi) /* If turbo is available then there is one extra freq bucket * to store the sys max freq which value is base_max +1 */ - num_freqs = (base_max_freq - sys_min_freq) / BUS_FREQ + 1 + - pi->turbo_available; + num_freqs = (RTE_MIN(base_max_freq, sys_max_freq) - sys_min_freq) / BUS_FREQ + + 1 + pi->turbo_available; if (num_freqs >= RTE_MAX_LCORE_FREQS) { RTE_LOG(ERR, POWER, "Too many available frequencies: %d\n", num_freqs); @@ -427,10 +441,10 @@ power_get_available_freqs(struct pstate_power_info *pi) */ for (i = 0, pi->nb_freqs = 0; i < num_freqs; i++) { if ((i == 0) && pi->turbo_available) - pi->freqs[pi->nb_freqs++] = base_max_freq + 1; + pi->freqs[pi->nb_freqs++] = RTE_MIN(base_max_freq, sys_max_freq) + 1; else - pi->freqs[pi->nb_freqs++] = - base_max_freq - (i - pi->turbo_available) * BUS_FREQ; + pi->freqs[pi->nb_freqs++] = RTE_MIN(base_max_freq, sys_max_freq) - + (i - pi->turbo_available) * BUS_FREQ; } ret = 0; diff --git a/lib/power/rte_power_pmd_mgmt.c b/lib/power/rte_power_pmd_mgmt.c index 1374cc213d..a66e08e574 100644 --- a/lib/power/rte_power_pmd_mgmt.c +++ b/lib/power/rte_power_pmd_mgmt.c @@ -10,9 +10,12 @@ #include #include "rte_power_pmd_mgmt.h" +#include "power_common.h" unsigned int emptypoll_max; unsigned int pause_duration; +unsigned int scale_freq_min[RTE_MAX_LCORE]; +unsigned int scale_freq_max[RTE_MAX_LCORE]; /* store some internal state */ static struct pmd_conf_data { @@ -693,8 +696,77 @@ rte_power_pmd_mgmt_get_pause_duration(void) return pause_duration; } +int +rte_power_pmd_mgmt_set_scaling_freq_min(unsigned int lcore, unsigned int min) +{ + if (lcore >= RTE_MAX_LCORE) { + RTE_LOG(ERR, POWER, "Invalid lcore ID: %u\n", lcore); + return -EINVAL; + } + + if (min > scale_freq_max[lcore]) { + RTE_LOG(ERR, POWER, "Invalid min frequency: Cannot be greater than max frequency"); + return -EINVAL; + } + scale_freq_min[lcore] = min; + + return 0; +} + +int +rte_power_pmd_mgmt_set_scaling_freq_max(unsigned int lcore, unsigned int max) +{ + if (lcore >= RTE_MAX_LCORE) { + RTE_LOG(ERR, POWER, "Invalid lcore ID: %u\n", lcore); + return -EINVAL; + } + + /* Zero means 'not set'. Use UINT32_MAX to enable RTE_MIN/MAX macro use when scaling. */ + if (max == 0) + max = UINT32_MAX; + if (max < scale_freq_min[lcore]) { + RTE_LOG(ERR, POWER, "Invalid max frequency: Cannot be less than min frequency"); + return -EINVAL; + } + + scale_freq_max[lcore] = max; + + return 0; +} + +int +rte_power_pmd_mgmt_get_scaling_freq_min(unsigned int lcore) +{ + if (lcore >= RTE_MAX_LCORE) { + RTE_LOG(ERR, POWER, "Invalid lcore ID: %u\n", lcore); + return -EINVAL; + } + + if (scale_freq_max[lcore] == 0) + RTE_LOG(DEBUG, POWER, "Scaling freq min config not set. Using sysfs min freq.\n"); + + return scale_freq_min[lcore]; +} + +int +rte_power_pmd_mgmt_get_scaling_freq_max(unsigned int lcore) +{ + if (lcore >= RTE_MAX_LCORE) { + RTE_LOG(ERR, POWER, "Invalid lcore ID: %u\n", lcore); + return -EINVAL; + } + + if (scale_freq_max[lcore] == UINT32_MAX) { + RTE_LOG(DEBUG, POWER, "Scaling freq max config not set. Using sysfs max freq.\n"); + return 0; + } + + return scale_freq_max[lcore]; +} + RTE_INIT(rte_power_ethdev_pmgmt_init) { size_t i; + int j; /* initialize all tailqs */ for (i = 0; i < RTE_DIM(lcore_cfgs); i++) { @@ -705,4 +777,9 @@ RTE_INIT(rte_power_ethdev_pmgmt_init) { /* initialize config defaults */ emptypoll_max = 512; pause_duration = 1; + /* scaling defaults out of range to ensure not used unless set by user or app */ + for (j = 0; j < RTE_MAX_LCORE; j++) { + scale_freq_min[j] = 0; + scale_freq_max[j] = UINT32_MAX; + } } diff --git a/lib/power/rte_power_pmd_mgmt.h b/lib/power/rte_power_pmd_mgmt.h index 18a9c3abb5..789fbe0e4d 100644 --- a/lib/power/rte_power_pmd_mgmt.h +++ b/lib/power/rte_power_pmd_mgmt.h @@ -148,6 +148,87 @@ __rte_experimental unsigned int rte_power_pmd_mgmt_get_pause_duration(void); +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice. + * + * Set the min frequency to be used for frequency scaling or zero to use defaults. + * + * @note Supported by: Pstate mode. + * + * @param lcore + * The ID of the lcore to set the min frequency for. + * @param min + * The value, in KiloHertz, to set the minimum frequency to. + * @return + * 0 on success + * <0 on error + */ +__rte_experimental +int +rte_power_pmd_mgmt_set_scaling_freq_min(unsigned int lcore, unsigned int min); + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice. + * + * Set the max frequency to be used for frequency scaling or zero to use defaults. + * + * @note Supported by: Pstate mode. + * + * @param lcore + * The ID of the lcore to set the max frequency for. + * @param max + * The value, in KiloHertz, to set the maximum frequency to. + * If 'max' is 0, it is considered 'not set'. + * @return + * 0 on success + * <0 on error + */ +__rte_experimental +int +rte_power_pmd_mgmt_set_scaling_freq_max(unsigned int lcore, unsigned int max); + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice. + * + * Get the current configured min frequency used for frequency scaling. + * + * @note Supported by: Pstate mode. + * + * @param lcore + * The ID of the lcore to get the min frequency for. + * @return + * 0 if no value has been configured via the 'set' API. + * >0 if a minimum frequency has been configured. Value is the minimum frequency + * , in KiloHertz, used for frequency scaling. + * <0 on error + */ +__rte_experimental +int +rte_power_pmd_mgmt_get_scaling_freq_min(unsigned int lcore); + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice. + * + * Get the current configured max frequency used for frequency scaling. + * + * @note Supported by: Pstate mode. + * + * @param lcore + * The ID of the lcore to get the max frequency for. + * @return + * 0 if no value has been configured via the 'set' API. + * >0 if a maximum frequency has been configured. Value is the maximum frequency + * , in KiloHertz, used for frequency scaling. + * <0 on error + */ +__rte_experimental +int +rte_power_pmd_mgmt_get_scaling_freq_max(unsigned int lcore); + #ifdef __cplusplus } #endif diff --git a/lib/power/version.map b/lib/power/version.map index 4673b719f9..a687754f4a 100644 --- a/lib/power/version.map +++ b/lib/power/version.map @@ -42,6 +42,10 @@ EXPERIMENTAL { # added in 22.07 rte_power_pmd_mgmt_get_emptypoll_max; rte_power_pmd_mgmt_get_pause_duration; + rte_power_pmd_mgmt_get_scaling_freq_max; + rte_power_pmd_mgmt_get_scaling_freq_min; rte_power_pmd_mgmt_set_emptypoll_max; rte_power_pmd_mgmt_set_pause_duration; + rte_power_pmd_mgmt_set_scaling_freq_max; + rte_power_pmd_mgmt_set_scaling_freq_min; }; -- 2.31.1