From patchwork Fri Apr 8 14:08:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Laatz X-Patchwork-Id: 109525 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 9B7DBA050B; Fri, 8 Apr 2022 16:09:13 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 8C12A410FB; Fri, 8 Apr 2022 16:09:13 +0200 (CEST) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by mails.dpdk.org (Postfix) with ESMTP id 768314003F for ; Fri, 8 Apr 2022 16:09:11 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1649426951; x=1680962951; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=4hWLoK5YL3T4i7wAhftgzS5g669PQoRHjT/tqslvYZo=; b=Am45+Y23OoqucidbA36h5gTpYF22/sHvom2iVnewXngxNYJ0OYOkxf4D MS+/8yoSdbbP2WcS7U3tV0k1IljotM2Hf9h8QzseR6USeN3UEZC7kdXVI 4hcy6Hdri2iYYICC5954xZQcLXUv3UMXa4ZNM6L4I3VyOlrmevikZZMju +G74vjlB9CYPV9eWQqcqSz4TIVtXP82AneTNa5aFUNhhdFNqPfwbcVaHi wnqBgoZe6171FKCjqiJdc4Fx1LsSwmw6SvOZAO3RMcyiO9H/zRWwSV9YN 04+MaUzHX7My3O6Hc4V2xtxHqJNC9GkttrnCNJQ8VlRFPJTimqjIujQea A==; X-IronPort-AV: E=McAfee;i="6400,9594,10310"; a="261290210" X-IronPort-AV: E=Sophos;i="5.90,245,1643702400"; d="scan'208";a="261290210" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Apr 2022 07:09:10 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.90,245,1643702400"; d="scan'208";a="698192720" Received: from silpixa00401122.ir.intel.com ([10.55.128.10]) by fmsmga001.fm.intel.com with ESMTP; 08 Apr 2022 07:09:09 -0700 From: Kevin Laatz To: dev@dpdk.org Cc: Kevin Laatz , David Hunt , Ray Kinsella Subject: [PATCH 1/4] lib/power: add get and set API for emptypoll max Date: Fri, 8 Apr 2022 15:08:44 +0100 Message-Id: <20220408140847.1319312-2-kevin.laatz@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220408140847.1319312-1-kevin.laatz@intel.com> References: <20220408140847.1319312-1-kevin.laatz@intel.com> MIME-Version: 1.0 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 APIs to configure emptypoll max which is used to determine when a queue can go into sleep state. Signed-off-by: Kevin Laatz --- lib/power/rte_power_pmd_mgmt.c | 21 ++++++++++++++++++--- lib/power/rte_power_pmd_mgmt.h | 27 +++++++++++++++++++++++++++ lib/power/version.map | 4 ++++ 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/lib/power/rte_power_pmd_mgmt.c b/lib/power/rte_power_pmd_mgmt.c index 39a2b4cd23..dfb7ca9187 100644 --- a/lib/power/rte_power_pmd_mgmt.c +++ b/lib/power/rte_power_pmd_mgmt.c @@ -11,7 +11,7 @@ #include "rte_power_pmd_mgmt.h" -#define EMPTYPOLL_MAX 512 +unsigned int emptypoll_max; /* store some internal state */ static struct pmd_conf_data { @@ -206,7 +206,7 @@ queue_can_sleep(struct pmd_core_cfg *cfg, struct queue_list_entry *qcfg) qcfg->n_empty_polls++; /* if we haven't reached threshold for empty polls, we can't sleep */ - if (qcfg->n_empty_polls <= EMPTYPOLL_MAX) + if (qcfg->n_empty_polls <= emptypoll_max) return false; /* @@ -290,7 +290,7 @@ clb_umwait(uint16_t port_id, uint16_t qidx, struct rte_mbuf **pkts __rte_unused, /* this callback can't do more than one queue, omit multiqueue logic */ if (unlikely(nb_rx == 0)) { queue_conf->n_empty_polls++; - if (unlikely(queue_conf->n_empty_polls > EMPTYPOLL_MAX)) { + if (unlikely(queue_conf->n_empty_polls > emptypoll_max)) { struct rte_power_monitor_cond pmc; int ret; @@ -661,6 +661,18 @@ rte_power_ethdev_pmgmt_queue_disable(unsigned int lcore_id, return 0; } +void +rte_power_pmd_mgmt_set_emptypoll_max(unsigned int max) +{ + emptypoll_max = max; +} + +unsigned int +rte_power_pmd_mgmt_get_emptypoll_max(void) +{ + return emptypoll_max; +} + RTE_INIT(rte_power_ethdev_pmgmt_init) { size_t i; @@ -669,4 +681,7 @@ RTE_INIT(rte_power_ethdev_pmgmt_init) { struct pmd_core_cfg *cfg = &lcore_cfgs[i]; TAILQ_INIT(&cfg->head); } + + /* initialize config defaults */ + emptypoll_max = 512; } diff --git a/lib/power/rte_power_pmd_mgmt.h b/lib/power/rte_power_pmd_mgmt.h index 444e7b8a66..d5a94f8187 100644 --- a/lib/power/rte_power_pmd_mgmt.h +++ b/lib/power/rte_power_pmd_mgmt.h @@ -90,6 +90,33 @@ int rte_power_ethdev_pmgmt_queue_disable(unsigned int lcore_id, uint16_t port_id, uint16_t queue_id); +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice. + * + * Set a emptypoll_max to specified value. Used to specify the number of empty + * polls to wait before entering sleep state. + * + * @param max + * The value to set emptypoll_max to. + */ +__rte_experimental +void +rte_power_pmd_mgmt_set_emptypoll_max(unsigned int max); + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice. + * + * Get the current value of emptypoll_max. + * + * @return + * The current emptypoll_max value + */ +__rte_experimental +unsigned int +rte_power_pmd_mgmt_get_emptypoll_max(void); + #ifdef __cplusplus } #endif diff --git a/lib/power/version.map b/lib/power/version.map index 6ec6d5d96d..8bcd497e06 100644 --- a/lib/power/version.map +++ b/lib/power/version.map @@ -38,4 +38,8 @@ EXPERIMENTAL { # added in 21.02 rte_power_ethdev_pmgmt_queue_disable; rte_power_ethdev_pmgmt_queue_enable; + + # added in 22.07 + rte_power_pmd_mgmt_set_emptypoll_max; + rte_power_pmd_mgmt_get_emptypoll_max; }; From patchwork Fri Apr 8 14:08:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Laatz X-Patchwork-Id: 109526 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id E1B6BA050B; Fri, 8 Apr 2022 16:09:19 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id C195D427F1; Fri, 8 Apr 2022 16:09:14 +0200 (CEST) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by mails.dpdk.org (Postfix) with ESMTP id 5A49F4003F for ; Fri, 8 Apr 2022 16:09:13 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1649426953; x=1680962953; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=3YoTx5Vj1rgr31Tz0GxpXqvmHKFs1n1gBnTXFw5aM7U=; b=NaeR8UMFqXQcQZamT1arrFcvvkNgi4WYZl8ejY5Nq6crM89hhrKDLcOU TAus2idPyTUS+jxrv4tM+5TM2KPI1OgXWCeVitOMaBvMq31Naj/BHQwYk Ztcj5W/u3ocbLxjbwv0vOk/hkcch46tqQdRcjs2obCUHw4xVFqWMwjAtY 1O4TafTRKQuB5k5+vSnC0JJKztTsppYjtdNqS0t0Bu2RoAIFN+BOTMtBN zCtVAgIWUbM22nYQW6IC//HRUSqKkf/0RjwFY2LM2U3aAoIL7sKjNBg6t gP8uOAhmZbIrs/wL62TrLTA8bsSVjgRBnGHqC0Mjnz5wlDREhgc3+Eknk g==; X-IronPort-AV: E=McAfee;i="6400,9594,10310"; a="261290222" X-IronPort-AV: E=Sophos;i="5.90,245,1643702400"; d="scan'208";a="261290222" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Apr 2022 07:09:12 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.90,245,1643702400"; d="scan'208";a="698192781" Received: from silpixa00401122.ir.intel.com ([10.55.128.10]) by fmsmga001.fm.intel.com with ESMTP; 08 Apr 2022 07:09:11 -0700 From: Kevin Laatz To: dev@dpdk.org Cc: Kevin Laatz , David Hunt , Ray Kinsella Subject: [PATCH 2/4] lib/power: add get and set API for pause duration Date: Fri, 8 Apr 2022 15:08:45 +0100 Message-Id: <20220408140847.1319312-3-kevin.laatz@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220408140847.1319312-1-kevin.laatz@intel.com> References: <20220408140847.1319312-1-kevin.laatz@intel.com> MIME-Version: 1.0 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 for configuring 'pause_duration' which used to adjust the pause mode callback duration. Signed-off-by: Kevin Laatz --- lib/power/rte_power_pmd_mgmt.c | 26 ++++++++++++++++++++++++-- lib/power/rte_power_pmd_mgmt.h | 31 +++++++++++++++++++++++++++++++ lib/power/version.map | 2 ++ 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/lib/power/rte_power_pmd_mgmt.c b/lib/power/rte_power_pmd_mgmt.c index dfb7ca9187..ab92a93aa0 100644 --- a/lib/power/rte_power_pmd_mgmt.c +++ b/lib/power/rte_power_pmd_mgmt.c @@ -12,6 +12,7 @@ #include "rte_power_pmd_mgmt.h" unsigned int emptypoll_max; +unsigned int pause_duration; /* store some internal state */ static struct pmd_conf_data { @@ -315,6 +316,7 @@ clb_pause(uint16_t port_id __rte_unused, uint16_t qidx __rte_unused, struct queue_list_entry *queue_conf = arg; struct pmd_core_cfg *lcore_conf; const bool empty = nb_rx == 0; + uint32_t pause_duration = rte_power_pmd_mgmt_get_pause_duration(); lcore_conf = &lcore_cfgs[lcore]; @@ -334,11 +336,11 @@ clb_pause(uint16_t port_id __rte_unused, uint16_t qidx __rte_unused, if (global_data.intrinsics_support.power_pause) { const uint64_t cur = rte_rdtsc(); const uint64_t wait_tsc = - cur + global_data.tsc_per_us; + cur + global_data.tsc_per_us * pause_duration; rte_power_pause(wait_tsc); } else { uint64_t i; - for (i = 0; i < global_data.pause_per_us; i++) + for (i = 0; i < global_data.pause_per_us * pause_duration; i++) rte_pause(); } } @@ -673,6 +675,25 @@ rte_power_pmd_mgmt_get_emptypoll_max(void) return emptypoll_max; } +int +rte_power_pmd_mgmt_set_pause_duration(unsigned int duration) +{ + if (duration == 0) { + printf("Pause duration must be greater than 0, value unchanged\n"); + rte_errno = EINVAL; + return -1; + } + pause_duration = duration; + + return 0; +} + +unsigned int +rte_power_pmd_mgmt_get_pause_duration(void) +{ + return pause_duration; +} + RTE_INIT(rte_power_ethdev_pmgmt_init) { size_t i; @@ -684,4 +705,5 @@ RTE_INIT(rte_power_ethdev_pmgmt_init) { /* initialize config defaults */ emptypoll_max = 512; + pause_duration = 1; } diff --git a/lib/power/rte_power_pmd_mgmt.h b/lib/power/rte_power_pmd_mgmt.h index d5a94f8187..18a9c3abb5 100644 --- a/lib/power/rte_power_pmd_mgmt.h +++ b/lib/power/rte_power_pmd_mgmt.h @@ -117,6 +117,37 @@ __rte_experimental unsigned int rte_power_pmd_mgmt_get_emptypoll_max(void); +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice. + * + * Set the pause_duration. Used to adjust the pause mode callback duration. + * + * @note Duration must be greater than zero. + * + * @param duration + * The value to set pause_duration to. + * @return + * 0 on success + * <0 on error + */ +__rte_experimental +int +rte_power_pmd_mgmt_set_pause_duration(unsigned int duration); + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice. + * + * Get the current value of pause_duration. + * + * @return + * The current pause_duration value. + */ +__rte_experimental +unsigned int +rte_power_pmd_mgmt_get_pause_duration(void); + #ifdef __cplusplus } #endif diff --git a/lib/power/version.map b/lib/power/version.map index 8bcd497e06..5890e6e429 100644 --- a/lib/power/version.map +++ b/lib/power/version.map @@ -42,4 +42,6 @@ EXPERIMENTAL { # added in 22.07 rte_power_pmd_mgmt_set_emptypoll_max; rte_power_pmd_mgmt_get_emptypoll_max; + rte_power_pmd_mgmt_set_pause_duration; + rte_power_pmd_mgmt_get_pause_duration; }; From patchwork Fri Apr 8 14:08:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Laatz X-Patchwork-Id: 109527 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id C8718A050B; Fri, 8 Apr 2022 16:09:25 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id AB014427E9; Fri, 8 Apr 2022 16:09:18 +0200 (CEST) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by mails.dpdk.org (Postfix) with ESMTP id EA8D242800 for ; Fri, 8 Apr 2022 16:09:15 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1649426956; x=1680962956; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=hsBlt6WIJqKY3buLZcLnibGMG0xw/8tDHvW7OALwLEQ=; b=bIn3tj5y4XPXBI0ry6iLYwbgmCMnqT6fOOMAWR0KwBCgRiZbxMMw2Bwn vjApliKSxoTsI3HNzT8D9XfnwcqMgKLvegq9ZPa1w121el3SPb11x8Xsy dUQYLusSf1+bmqQ+4sjpXbPytqTAs/RxuxUOj7W0N4n82GBG/TXtoPzDW YDRM2EH9pUDmy0cmoj9aVUCFlrZz0ZF/8v/auBiyJqpPh19aB0fhSNMUG WbkBONSu7RI8VZTSsAsLuGwIU8Fcqnvan4r/H5zE8pEyUQGj7La9zTcOB 7WTikWFnnUQMx8ewAtxF/rPZIkq3Sna7mh+2/+hR04f96I/kv4/9LXzRy A==; X-IronPort-AV: E=McAfee;i="6400,9594,10310"; a="261290239" X-IronPort-AV: E=Sophos;i="5.90,245,1643702400"; d="scan'208";a="261290239" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Apr 2022 07:09:15 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.90,245,1643702400"; d="scan'208";a="698192835" Received: from silpixa00401122.ir.intel.com ([10.55.128.10]) by fmsmga001.fm.intel.com with ESMTP; 08 Apr 2022 07:09:14 -0700 From: Kevin Laatz To: dev@dpdk.org Cc: Kevin Laatz , David Hunt , Ray Kinsella Subject: [PATCH 3/4] lib/power: add get and set API for scaling freq min and max with pstate mode Date: Fri, 8 Apr 2022 15:08:46 +0100 Message-Id: <20220408140847.1319312-4-kevin.laatz@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220408140847.1319312-1-kevin.laatz@intel.com> References: <20220408140847.1319312-1-kevin.laatz@intel.com> MIME-Version: 1.0 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 --- lib/power/power_pstate_cpufreq.c | 22 +++++++-- lib/power/rte_power_pmd_mgmt.c | 65 ++++++++++++++++++++++++++ lib/power/rte_power_pmd_mgmt.h | 80 ++++++++++++++++++++++++++++++++ lib/power/version.map | 4 ++ 4 files changed, 166 insertions(+), 5 deletions(-) diff --git a/lib/power/power_pstate_cpufreq.c b/lib/power/power_pstate_cpufreq.c index f4c36179ec..db10deafe2 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,16 @@ 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); + sys_max_freq = RTE_MIN(sys_max_freq, (uint32_t)config_max_freq); + if (sys_max_freq < sys_min_freq) goto out; @@ -411,8 +423,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 +439,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 ab92a93aa0..5ba050dc95 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 { @@ -694,8 +697,65 @@ 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); + rte_errno = EINVAL; + return -1; + } + 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); + rte_errno = EINVAL; + return -1; + } + 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); + rte_errno = EINVAL; + return -1; + } + + 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); + rte_errno = EINVAL; + return -1; + } + + if (scale_freq_max[lcore] == UINT32_MAX) + RTE_LOG(DEBUG, POWER, "Scaling freq max config not set. Using sysfs max freq.\n"); + + 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++) { @@ -706,4 +766,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..74e3fa710b 100644 --- a/lib/power/rte_power_pmd_mgmt.h +++ b/lib/power/rte_power_pmd_mgmt.h @@ -148,6 +148,86 @@ __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. + * + * @note Supported by: Pstate mode. + * + * @param lcore + * The ID of the lcore to set the min frequency for. + * @param min + * The value, in Hertz, 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. + * + * @note Supported by: Pstate mode. + * + * @param lcore + * The ID of the lcore to set the max frequency for. + * @param max + * The value, in Hertz, to set the maximum frequency to. + * @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 Hertz, 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 + * UINT32_MAX if no value has been configured via the 'set' API. + * On success, the current configured maximum frequency, in Hertz, 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 5890e6e429..2cf08b7c5a 100644 --- a/lib/power/version.map +++ b/lib/power/version.map @@ -44,4 +44,8 @@ EXPERIMENTAL { rte_power_pmd_mgmt_get_emptypoll_max; rte_power_pmd_mgmt_set_pause_duration; rte_power_pmd_mgmt_get_pause_duration; + rte_power_pmd_mgmt_set_scaling_freq_min; + rte_power_pmd_mgmt_set_scaling_freq_max; + rte_power_pmd_mgmt_get_scaling_freq_min; + rte_power_pmd_mgmt_get_scaling_freq_max; }; From patchwork Fri Apr 8 14:08:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Laatz X-Patchwork-Id: 109528 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 20CC2A050B; Fri, 8 Apr 2022 16:09:31 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 95C5E42802; Fri, 8 Apr 2022 16:09:21 +0200 (CEST) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by mails.dpdk.org (Postfix) with ESMTP id 74C9F427F0 for ; Fri, 8 Apr 2022 16:09:19 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1649426959; x=1680962959; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=SZIegY4jMalbwMHw3L565OoxJNqT7cn1Olr793tKWO8=; b=lqf2IzqPqJGa4ZIHZL7f9vsRKdoqM1M+V/Tgz9TvQ4A9y01lz9qhOXP0 BhIjCqPIuPitL9u+zPFx8qCdpgSqEzQSv3sZEuWwNQ8SiVmvx5vfS1FUj YwwJSe/3hqGhOs68wH92JrTQLjqvjyZ+bTZ4MV5YTQ7ihNLrPoJmmrEy9 dz1/FpN3FtphpJSPEP7tceW5/fxvyeMCrSwGqi517e0zN4HN7uT7U2zgv 2eqOvskwJMv694UH5/0PAXGUjlLFNarrJo0yJcw/4BEyIJvuGY9jQxsxW ETVMjyG3gVXIjolhxFq33Pkz6wStW0w5DHQEVdCHkHankBRO91QJvc628 w==; X-IronPort-AV: E=McAfee;i="6400,9594,10310"; a="261290254" X-IronPort-AV: E=Sophos;i="5.90,245,1643702400"; d="scan'208";a="261290254" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Apr 2022 07:09:19 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.90,245,1643702400"; d="scan'208";a="698192908" Received: from silpixa00401122.ir.intel.com ([10.55.128.10]) by fmsmga001.fm.intel.com with ESMTP; 08 Apr 2022 07:09:18 -0700 From: Kevin Laatz To: dev@dpdk.org Cc: Kevin Laatz , David Hunt Subject: [PATCH 4/4] examples/l3fwd_power: add cli for configurable options Date: Fri, 8 Apr 2022 15:08:47 +0100 Message-Id: <20220408140847.1319312-5-kevin.laatz@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220408140847.1319312-1-kevin.laatz@intel.com> References: <20220408140847.1319312-1-kevin.laatz@intel.com> MIME-Version: 1.0 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 CLI options to l3fwd_power to utilize the new power APIs introduced in this patchset. These CLI options allow the user to configure the heuritstics made available through the new API via the l3fwd_power application options. Signed-off-by: Kevin Laatz --- examples/l3fwd-power/main.c | 75 ++++++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c index 20e5b59af9..f480de2420 100644 --- a/examples/l3fwd-power/main.c +++ b/examples/l3fwd-power/main.c @@ -265,6 +265,10 @@ static struct rte_eth_conf port_conf = { }; static uint32_t max_pkt_len; +static uint32_t max_empty_polls; +static uint32_t pause_duration; +static uint32_t scale_freq_min; +static uint32_t scale_freq_max; static struct rte_mempool * pktmbuf_pool[NB_SOCKETS]; @@ -1626,10 +1630,32 @@ print_usage(const char *prgname) " empty polls, full polls, and core busyness to telemetry\n" " --interrupt-only: enable interrupt-only mode\n" " --pmd-mgmt MODE: enable PMD power management mode. " - "Currently supported modes: baseline, monitor, pause, scale\n", + "Currently supported modes: baseline, monitor, pause, scale\n" + " --max-empty-polls MAX_EMPTY_POLLS: number of empty polls to" + " wait before entering sleep state\n" + " --pause-duration DURATION: set the duration, in microseconds," + " of the pause callback\n" + " --scale-freq-min FREQ_MIN: set minimum frequency for scaling" + " mode for all application lcores\n" + " --scale-freq-max FREQ_MAX: set maximum frequency for scaling" + " mode for all application lcores\n", prgname); } +static int +parse_int(const char *opt) +{ + char *end = NULL; + unsigned long val; + + /* parse integer string */ + val = strtoul(opt, &end, 10); + if ((opt[0] == '\0') || (end == NULL) || (*end != '\0')) + return -1; + + return val; +} + static int parse_max_pkt_len(const char *pktlen) { char *end = NULL; @@ -1803,6 +1829,10 @@ parse_ep_config(const char *q_arg) #define CMD_LINE_OPT_TELEMETRY "telemetry" #define CMD_LINE_OPT_PMD_MGMT "pmd-mgmt" #define CMD_LINE_OPT_MAX_PKT_LEN "max-pkt-len" +#define CMD_LINE_OPT_MAX_EMPTY_POLLS "max-empty-polls" +#define CMD_LINE_OPT_PAUSE_DURATION "pause-duration" +#define CMD_LINE_OPT_SCALE_FREQ_MIN "scale-freq-min" +#define CMD_LINE_OPT_SCALE_FREQ_MAX "scale-freq-max" /* Parse the argument given in the command line of the application */ static int @@ -1812,6 +1842,7 @@ parse_args(int argc, char **argv) char **argvopt; int option_index; uint32_t limit; + int i; char *prgname = argv[0]; static struct option lgopts[] = { {"config", 1, 0, 0}, @@ -1825,6 +1856,10 @@ parse_args(int argc, char **argv) {CMD_LINE_OPT_TELEMETRY, 0, 0, 0}, {CMD_LINE_OPT_INTERRUPT_ONLY, 0, 0, 0}, {CMD_LINE_OPT_PMD_MGMT, 1, 0, 0}, + {CMD_LINE_OPT_MAX_EMPTY_POLLS, 1, 0, 0}, + {CMD_LINE_OPT_PAUSE_DURATION, 1, 0, 0}, + {CMD_LINE_OPT_SCALE_FREQ_MIN, 1, 0, 0}, + {CMD_LINE_OPT_SCALE_FREQ_MAX, 1, 0, 0}, {NULL, 0, 0, 0} }; @@ -1975,6 +2010,44 @@ parse_args(int argc, char **argv) parse_ptype = 1; } + if (!strncmp(lgopts[option_index].name, + CMD_LINE_OPT_MAX_EMPTY_POLLS, + sizeof(CMD_LINE_OPT_MAX_EMPTY_POLLS))) { + printf("Maximum empty polls configured\n"); + max_empty_polls = parse_int(optarg); + rte_power_pmd_mgmt_set_emptypoll_max(max_empty_polls); + } + + if (!strncmp(lgopts[option_index].name, + CMD_LINE_OPT_PAUSE_DURATION, + sizeof(CMD_LINE_OPT_PAUSE_DURATION))) { + printf("Pause duration configured\n"); + pause_duration = parse_int(optarg); + rte_power_pmd_mgmt_set_pause_duration(pause_duration); + } + + if (!strncmp(lgopts[option_index].name, + CMD_LINE_OPT_SCALE_FREQ_MIN, + sizeof(CMD_LINE_OPT_SCALE_FREQ_MIN))) { + printf("Scaling frequency minimum configured\n"); + scale_freq_min = parse_int(optarg); + for (i = 0; i < RTE_MAX_LCORE; i++) + if (rte_lcore_is_enabled(i)) + rte_power_pmd_mgmt_set_scaling_freq_min(i, + scale_freq_min); + } + + if (!strncmp(lgopts[option_index].name, + CMD_LINE_OPT_SCALE_FREQ_MAX, + sizeof(CMD_LINE_OPT_SCALE_FREQ_MAX))) { + printf("Scaling frequency maximum configured\n"); + scale_freq_max = parse_int(optarg); + for (i = 0; i < RTE_MAX_LCORE; i++) + if (rte_lcore_is_enabled(i)) + rte_power_pmd_mgmt_set_scaling_freq_max(i, + scale_freq_max); + } + break; default: