From patchwork Tue Apr 19 11:24:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Laatz X-Patchwork-Id: 109886 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 1B902A00BE; Tue, 19 Apr 2022 13:25:23 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 9F6AD410EE; Tue, 19 Apr 2022 13:25:22 +0200 (CEST) Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by mails.dpdk.org (Postfix) with ESMTP id 883E040687 for ; Tue, 19 Apr 2022 13:25:20 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1650367520; x=1681903520; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=vLdS9fzkeMcYg8uGuegtTU+FwmeBnBUvu+TXfvnI2C8=; b=R/wiFYB0e64o1RiwPBnR8KWbaOwM7/MlZuO+KdSg5iZg3FiNE7VWgX/R 8g12lOUe8hcXLhPUd18b6nt+qBOYqGsz1NuCgyFAo4uIbFoXK/qi45SZW uC4VcPnE9OCVf3viadCelkqhUNObnMOx0v+5jFyAHk6kjnzbjfiXIYqXp Ad5gBvvNb3GLxQCtW+rD/+6Xp0KJj4G2MjwOutNs9giDaKT3gy6uI271Y l4FzMjBWAby06x+uESOjY3b1GArvvdUhcevM3Mf1+1lqeYmnryDQi12Jv MDisecOJ7XRTeSADxamVyTVY2yBvJR73Jwo6DB8B8GmR31AUzFUQpHhD3 Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10321"; a="262600085" X-IronPort-AV: E=Sophos;i="5.90,272,1643702400"; d="scan'208";a="262600085" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Apr 2022 04:25:09 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.90,272,1643702400"; d="scan'208";a="727032504" Received: from silpixa00401122.ir.intel.com ([10.55.128.10]) by orsmga005.jf.intel.com with ESMTP; 19 Apr 2022 04:25:08 -0700 From: Kevin Laatz To: dev@dpdk.org Cc: Kevin Laatz , David Hunt , Ray Kinsella Subject: [PATCH v2 1/4] lib/power: add get and set API for emptypoll max Date: Tue, 19 Apr 2022 12:24:58 +0100 Message-Id: <20220419112501.1835458-2-kevin.laatz@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220419112501.1835458-1-kevin.laatz@intel.com> References: <20220408140847.1319312-1-kevin.laatz@intel.com> <20220419112501.1835458-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 Acked-by: Ray Kinsella --- 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..812843c3f3 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_get_emptypoll_max; + rte_power_pmd_mgmt_set_emptypoll_max; }; From patchwork Tue Apr 19 11:24:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Laatz X-Patchwork-Id: 109889 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 CD6BFA00BE; Tue, 19 Apr 2022 13:25:40 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 5276C427ED; Tue, 19 Apr 2022 13:25:26 +0200 (CEST) Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by mails.dpdk.org (Postfix) with ESMTP id DA99C4068E for ; Tue, 19 Apr 2022 13:25:21 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1650367522; x=1681903522; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=YSTr/7iLNoQgmXLjsqJLKMoXOEti/dG70Gvz35qcyNE=; b=dVnFr5h01Izx8c8zgALt548+yjGwijZnsW55EVKLsSiYSY5lB3+ejxD2 mra3I5r44/7nDIWwEN1m8nK1oA2WdYmJfldfDb98MQmOICl3IHeIXe3WO a9v4DKD9LNMrVq405LWcKzxyXBXPwJNnBSDSbktEgUnPW2tcBVYUxW1wB Fai6XHXSAAXwtVruEmN5vaegxetDjJQIhMP5Pm3iL7t9BknTa/lMk9XmI xftEHhjIPe7we9A5pJBueYL5AZEi6XlLB9F0c6eDqGklPWDMcYIbgT+Pt tisKWr+vgsL2nmTwajl8jtcAjqE7ZWtL3Fy+NEGykheQ3J9MAMpzFb2eg Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10321"; a="262600087" X-IronPort-AV: E=Sophos;i="5.90,272,1643702400"; d="scan'208";a="262600087" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Apr 2022 04:25:11 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.90,272,1643702400"; d="scan'208";a="727032512" Received: from silpixa00401122.ir.intel.com ([10.55.128.10]) by orsmga005.jf.intel.com with ESMTP; 19 Apr 2022 04:25:09 -0700 From: Kevin Laatz To: dev@dpdk.org Cc: Kevin Laatz , David Hunt , Ray Kinsella Subject: [PATCH v2 2/4] lib/power: add get and set API for pause duration Date: Tue, 19 Apr 2022 12:24:59 +0100 Message-Id: <20220419112501.1835458-3-kevin.laatz@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220419112501.1835458-1-kevin.laatz@intel.com> References: <20220408140847.1319312-1-kevin.laatz@intel.com> <20220419112501.1835458-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 Acked-by: Ray Kinsella Acked-by: Anatoly Burakov --- 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 812843c3f3..4673b719f9 100644 --- a/lib/power/version.map +++ b/lib/power/version.map @@ -41,5 +41,7 @@ EXPERIMENTAL { # added in 22.07 rte_power_pmd_mgmt_get_emptypoll_max; + rte_power_pmd_mgmt_get_pause_duration; rte_power_pmd_mgmt_set_emptypoll_max; + rte_power_pmd_mgmt_set_pause_duration; }; From patchwork Tue Apr 19 11:25:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Laatz X-Patchwork-Id: 109890 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 9A31BA00BE; Tue, 19 Apr 2022 13:25:46 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 6507D427F3; Tue, 19 Apr 2022 13:25:27 +0200 (CEST) Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by mails.dpdk.org (Postfix) with ESMTP id 5649F40687 for ; Tue, 19 Apr 2022 13:25:22 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1650367522; x=1681903522; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=3AS9wCg8Xs0HBamqP21gJsMnvuUcmB671WpIkYnfxjY=; b=dOzFpNa6AD5Y7ZVwIZTAAqF+ygkvJPS+5MSchGGlMfOfxKzgg0e6r1Fe 9apLQAgUerp7+m1hXmIvYWgTJbqc3VicSXg4pKYNlIA5QL7Mk8kympb4K tZxaU5abPAk8XD716bkm71vbwOL34bUGkxSeXD98sdaCVoWAN2RJM70Ay hiqzhpGUJ2zD6+MDKxXrY63wMxqndzWjQ6L3vS9SkOFVznYWhLUSjGuqu jokN15yyQnJcscZZcQBP9ISCOP4VvU+//wJVS4xUDdJrCzAOGhTkLeh1u cnJ5AgWFAybiQqO3AL8FvZTjPOWa0CP4rGRpbrciBAcRxGrJkVb1Q2C6a Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10321"; a="262600090" X-IronPort-AV: E=Sophos;i="5.90,272,1643702400"; d="scan'208";a="262600090" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Apr 2022 04:25:13 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.90,272,1643702400"; d="scan'208";a="727032518" Received: from silpixa00401122.ir.intel.com ([10.55.128.10]) by orsmga005.jf.intel.com with ESMTP; 19 Apr 2022 04:25:11 -0700 From: Kevin Laatz To: dev@dpdk.org Cc: Kevin Laatz , David Hunt , Ray Kinsella Subject: [PATCH v2 3/4] lib/power: add get and set API for scaling freq min and max with pstate mode Date: Tue, 19 Apr 2022 12:25:00 +0100 Message-Id: <20220419112501.1835458-4-kevin.laatz@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220419112501.1835458-1-kevin.laatz@intel.com> References: <20220408140847.1319312-1-kevin.laatz@intel.com> <20220419112501.1835458-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 Acked-by: Ray Kinsella --- 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 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; }; From patchwork Tue Apr 19 11:25:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Laatz X-Patchwork-Id: 109888 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 66467A00BE; Tue, 19 Apr 2022 13:25:34 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 6C604427E9; Tue, 19 Apr 2022 13:25:25 +0200 (CEST) Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by mails.dpdk.org (Postfix) with ESMTP id B3D7740687 for ; Tue, 19 Apr 2022 13:25:21 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1650367521; x=1681903521; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=UNwZShoT+mrkV8ax9lUYYwsyQvzrtyZUX+b8nY8bFNc=; b=LrFIgtIOk/0gvwww8+yLfkRxPEG0Yg9VpIFDMBTPyv7VjZMydvxu5SIX 9xSIE6IKKauavGdeJ0th2GzFTmhxvod3fVC56B69JyPwZY/u/plzkiifv 4lhUVGHEz8ockzKv/Ej1genD+Ogcq1fmUqxn8DARTo2NdFj7/KeJ8G0OZ eqnlpQMY9LwWt+1UKLrzyEzJFj7qyU+rxw8sJuX6T6EHyQZG2IGtu98NL 7Ffs5w4Kz0Iqh0QYzPCdf0n+Hw9bhVoHiXJez+ha80ZfpTGhoRZlbyFfc mN/itLnup4kSvZp/yWVnRmqi4nFF+yP6ryAc6W0CRpvbeFGaUZjgPtgbz g==; X-IronPort-AV: E=McAfee;i="6400,9594,10321"; a="262600091" X-IronPort-AV: E=Sophos;i="5.90,272,1643702400"; d="scan'208";a="262600091" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Apr 2022 04:25:14 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.90,272,1643702400"; d="scan'208";a="727032526" Received: from silpixa00401122.ir.intel.com ([10.55.128.10]) by orsmga005.jf.intel.com with ESMTP; 19 Apr 2022 04:25:13 -0700 From: Kevin Laatz To: dev@dpdk.org Cc: Kevin Laatz , David Hunt Subject: [PATCH v2 4/4] examples/l3fwd_power: add cli for configurable options Date: Tue, 19 Apr 2022 12:25:01 +0100 Message-Id: <20220419112501.1835458-5-kevin.laatz@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220419112501.1835458-1-kevin.laatz@intel.com> References: <20220408140847.1319312-1-kevin.laatz@intel.com> <20220419112501.1835458-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 --- v2: add doc update for l3fwd-power --- .../sample_app_ug/l3_forward_power_man.rst | 8 ++ examples/l3fwd-power/main.c | 75 ++++++++++++++++++- 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/doc/guides/sample_app_ug/l3_forward_power_man.rst b/doc/guides/sample_app_ug/l3_forward_power_man.rst index 2e350c45f1..b26f11a220 100644 --- a/doc/guides/sample_app_ug/l3_forward_power_man.rst +++ b/doc/guides/sample_app_ug/l3_forward_power_man.rst @@ -109,6 +109,14 @@ where, * --pmd-mgmt: PMD power management mode. +* --max-empty-polls : Number of empty polls to wait before entering sleep state. + +* --pause-duration: Set the duration of the pause callback (microseconds). + +* --scale-freq-min: Set minimum frequency for scaling. + +* --scale-freq-max: Set maximum frequency for scaling. + See :doc:`l3_forward` for details. The L3fwd-power example reuses the L3fwd command line options. diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c index 20e5b59af9..ec2a71f02f 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-poll" +#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: