From patchwork Mon May 23 20:21:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Laatz X-Patchwork-Id: 111646 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 12FA4A00C2; Mon, 23 May 2022 22:20:06 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id B6F444161A; Mon, 23 May 2022 22:20:01 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by mails.dpdk.org (Postfix) with ESMTP id 41C16410E8 for ; Mon, 23 May 2022 22:19:59 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1653337200; x=1684873200; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=5Anu1TcP7hsZPZoiOmjRUC81Hh3H7VHq8kYOQ0Tin1Y=; b=EvQW95X2e34Le/jujPtVfOKBCmTwlefYx0QyDKSCvpgxM0szxsivoWdW UmwDIOsEIxJfsgSganFfy+nHjJtAGqB1qXgH78o6dYke120zZsddIMkPJ jr07GRX8huJLthhP1V2Of36XrcgobyhJQjLFoz3qc+UYsieEyZ/vKF+tQ niokwtMQORgzyt1zG4x6HuU73O2B14m/YFo+7ga4b2MSD+kdQyrxURYOB oMYKJW1lq8WtX5U/T/3PLn87OsDxOrQE14GTOgST7CU/9K61V2bGc9RMr No5hon+FlVg4jlnTOK5c6NiHmnzK/SVwXq4BW0tBT0uIXxcvKhy84fBil A==; X-IronPort-AV: E=McAfee;i="6400,9594,10356"; a="273338323" X-IronPort-AV: E=Sophos;i="5.91,246,1647327600"; d="scan'208";a="273338323" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 May 2022 13:19:59 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.91,246,1647327600"; d="scan'208";a="744911260" Received: from silpixa00401122.ir.intel.com ([10.237.213.29]) by orsmga005.jf.intel.com with ESMTP; 23 May 2022 13:19:58 -0700 From: Kevin Laatz To: dev@dpdk.org Cc: anatoly.burakov@intel.com, Kevin Laatz , Ray Kinsella , David Hunt Subject: [PATCH v3 1/4] lib/power: add get and set API for emptypoll max Date: Mon, 23 May 2022 21:21:21 +0100 Message-Id: <20220523202124.293865-2-kevin.laatz@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220523202124.293865-1-kevin.laatz@intel.com> References: <20220419112501.1835458-1-kevin.laatz@intel.com> <20220523202124.293865-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 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 Mon May 23 20:21:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Laatz X-Patchwork-Id: 111647 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 A840BA00C2; Mon, 23 May 2022 22:20:15 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id E96C34281B; Mon, 23 May 2022 22:20:02 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by mails.dpdk.org (Postfix) with ESMTP id A4D8F410E8 for ; Mon, 23 May 2022 22:20:01 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1653337201; x=1684873201; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=4q1RF1lcJ6Q/+9hfrrDpTDZNzPpFl+l/1alZh2xyaxc=; b=GPZylauTUGNzNVeq1fuBDq6E5zm1mdNhbkLdHEN2HYbVoSv9N8OvLE84 obEXltUhxHUAaUL+l9Q5UA8njuHjnuRVsReuFIiYDXx0Fd3AacInmpqDy cBelNRh2GQbH0VYuN4oxm8C8rjrIHK6F2w+3XK+qruiaadSCoGIb/xW3p oMIBUs1QB9iVzGHH+1wDYmdf/e4vjV1mubqz94xyq4beppcocu0+Rf0aA s3iV9lqu1pHTamsh4U4FawPh7oeZvxhDK1TpF8KI+LIHAheQwX0ImDB7w 3fiyVIPs1S+NZnnGFCHhSjMvJGaUfqsjNDE3XfuXZt4qa24vcoMZzc8I5 g==; X-IronPort-AV: E=McAfee;i="6400,9594,10356"; a="273338326" X-IronPort-AV: E=Sophos;i="5.91,246,1647327600"; d="scan'208";a="273338326" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 May 2022 13:20:01 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.91,246,1647327600"; d="scan'208";a="744911279" Received: from silpixa00401122.ir.intel.com ([10.237.213.29]) by orsmga005.jf.intel.com with ESMTP; 23 May 2022 13:19:59 -0700 From: Kevin Laatz To: dev@dpdk.org Cc: anatoly.burakov@intel.com, Kevin Laatz , Ray Kinsella , David Hunt Subject: [PATCH v3 2/4] lib/power: add get and set API for pause duration Date: Mon, 23 May 2022 21:21:22 +0100 Message-Id: <20220523202124.293865-3-kevin.laatz@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220523202124.293865-1-kevin.laatz@intel.com> References: <20220419112501.1835458-1-kevin.laatz@intel.com> <20220523202124.293865-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 --- v3: changed printf to RTE_LOG --- lib/power/rte_power_pmd_mgmt.c | 25 +++++++++++++++++++++++-- lib/power/rte_power_pmd_mgmt.h | 31 +++++++++++++++++++++++++++++++ lib/power/version.map | 2 ++ 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/lib/power/rte_power_pmd_mgmt.c b/lib/power/rte_power_pmd_mgmt.c index dfb7ca9187..1374cc213d 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,24 @@ 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) { + RTE_LOG(ERR, POWER, "Pause duration must be greater than 0, value unchanged"); + return -EINVAL; + } + 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 +704,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 Mon May 23 20:21:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Laatz X-Patchwork-Id: 111648 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 82518A00C2; Mon, 23 May 2022 22:20:22 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id CBAD5427F0; Mon, 23 May 2022 22:20:05 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by mails.dpdk.org (Postfix) with ESMTP id 70F9842824 for ; Mon, 23 May 2022 22:20:03 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1653337203; x=1684873203; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=6QZ4OXq0JtlUghzkiQlzh96I35nbvdu2dfkP2V8PFS8=; b=RRbbUIllbSgFhExNc4BekI9MvHIgOw8vyjcgtwwdIb1cJjanR3807Q5Y z+VijMQnGFWC+OtB8Xibdx7rwOqhanMqn5INxImeJ3hVexlXRgnHx+c6l mEEAsGeT0zZtsmgIJ8wOAYv9WZP3REYAZVfZ133Mr0u3twS2cD7gZsl72 C9QwCj5ghWirAIgx6ooHnz8s9NnLEZzs9leAK7cyHsaoPasJ9EPSk/fB7 UMt23Z26rOs+RUYnXKu++T7SOGAODsjwySmEsmZMNDyV3psE+RV5MZ3gh /dMlPve+2ifDSEqaN2kC5DMLRsvXUQY3aHNW9R4kPBiE0voD8ICS6t4/A A==; X-IronPort-AV: E=McAfee;i="6400,9594,10356"; a="273338328" X-IronPort-AV: E=Sophos;i="5.91,246,1647327600"; d="scan'208";a="273338328" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 May 2022 13:20:03 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.91,246,1647327600"; d="scan'208";a="744911301" Received: from silpixa00401122.ir.intel.com ([10.237.213.29]) by orsmga005.jf.intel.com with ESMTP; 23 May 2022 13:20:01 -0700 From: Kevin Laatz To: dev@dpdk.org Cc: anatoly.burakov@intel.com, Kevin Laatz , Ray Kinsella , David Hunt Subject: [PATCH v3 3/4] lib/power: add get and set API for scaling freq min and max with pstate mode Date: Mon, 23 May 2022 21:21:23 +0100 Message-Id: <20220523202124.293865-4-kevin.laatz@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220523202124.293865-1-kevin.laatz@intel.com> References: <20220419112501.1835458-1-kevin.laatz@intel.com> <20220523202124.293865-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 Acked-by: Anatoly Burakov --- v3: * updated doxygen comments * added checks to ensure min/max value is valid * consider 0 as 'not set' for scaling_freq_max --- lib/power/power_pstate_cpufreq.c | 22 +++++++-- lib/power/rte_power_pmd_mgmt.c | 75 +++++++++++++++++++++++++++++ lib/power/rte_power_pmd_mgmt.h | 81 ++++++++++++++++++++++++++++++++ lib/power/version.map | 4 ++ 4 files changed, 177 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 1374cc213d..df6d3e8e15 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,75 @@ 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 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 +775,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..9ca75b91c6 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. + * + * @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. + * + * @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 + * UINT32_MAX if no value has been configured via the 'set' API. + * On success, the current configured 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; }; From patchwork Mon May 23 20:21:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Laatz X-Patchwork-Id: 111649 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 06A4FA00C2; Mon, 23 May 2022 22:20:29 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id AD2C542B6D; Mon, 23 May 2022 22:20:06 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by mails.dpdk.org (Postfix) with ESMTP id 006C340156 for ; Mon, 23 May 2022 22:20:04 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1653337205; x=1684873205; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=PQKJTsV0HYuc5YOAP+RnJfoOOgHiydU5KOQC2ZpgsK0=; b=UJWroS9vWtexy2tNg2eJVmm86WekApVxAxjV2nwEjrrobjtSZCKsp0p5 +2eAsPBw3156LlvzdSYYqzAfmczpicHS/VqydgGuqbQhJhVP5q+TIYNEP rv4cb6fQn31Tj/JfQhe5dAA62clsKmbDI8rKZUHE+HOu9uEPtNJxo3MP8 xmfPShvgZk4kw8KMrNaPzugisPvEG0FoFeHrDzqE/DQMcQ7ewXOU7o1vH TkwZ+GmPcAWzxeHib6lHOkznjyIlAtkmFUHI9667K5FJ3yOBhAo+Psegp 0POh4a1Wh1Jw15lBAjrdtSR677dyJPBrK2VCVosEIQkCYrmqO5iqMZ7C1 Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10356"; a="273338330" X-IronPort-AV: E=Sophos;i="5.91,246,1647327600"; d="scan'208";a="273338330" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 May 2022 13:20:04 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.91,246,1647327600"; d="scan'208";a="744911327" Received: from silpixa00401122.ir.intel.com ([10.237.213.29]) by orsmga005.jf.intel.com with ESMTP; 23 May 2022 13:20:03 -0700 From: Kevin Laatz To: dev@dpdk.org Cc: anatoly.burakov@intel.com, Kevin Laatz , David Hunt Subject: [PATCH v3 4/4] examples/l3fwd_power: add cli for configurable options Date: Mon, 23 May 2022 21:21:24 +0100 Message-Id: <20220523202124.293865-5-kevin.laatz@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220523202124.293865-1-kevin.laatz@intel.com> References: <20220419112501.1835458-1-kevin.laatz@intel.com> <20220523202124.293865-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 Acked-by: Anatoly Burakov --- v2: add doc update for l3fwd-power v3: move setters out of arg parsing --- .../sample_app_ug/l3_forward_power_man.rst | 8 ++ examples/l3fwd-power/main.c | 86 ++++++++++++++++++- 2 files changed, 93 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..8f6d906200 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. Applies to --pmd-mgmt mode only. + +* --pause-duration: Set the duration of the pause callback (microseconds). Applies to --pmd-mgmt mode only. + +* --scale-freq-min: Set minimum frequency for scaling. Applies to --pmd-mgmt mode only. + +* --scale-freq-max: Set maximum frequency for scaling. Applies to --pmd-mgmt mode only. + 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..887c6eae3f 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 = 512; +static uint32_t pause_duration = 1; +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 (FREQ_MIN must be in kHz, in increments of 100MHz)\n" + " --scale-freq-max FREQ_MAX: set maximum frequency for scaling mode for" + " all application lcores (FREQ_MAX must be in kHz, in increments of 100MHz)\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 @@ -1825,6 +1855,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 +2009,34 @@ 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); + } + + 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); + } + + 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); + } + + 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); + } + break; default: @@ -2801,6 +2863,28 @@ main(int argc, char **argv) } if (app_mode == APP_MODE_PMD_MGMT && !baseline_enabled) { + /* Set power_pmd_mgmt configs passed by user */ + rte_power_pmd_mgmt_set_emptypoll_max(max_empty_polls); + ret = rte_power_pmd_mgmt_set_pause_duration(pause_duration); + if (ret < 0) + rte_exit(EXIT_FAILURE, + "Error setting pause_duration: err=%d, lcore=%d\n", + ret, lcore_id); + + ret = rte_power_pmd_mgmt_set_scaling_freq_min(lcore_id, + scale_freq_min); + if (ret < 0) + rte_exit(EXIT_FAILURE, + "Error setting scaling freq min: err=%d, lcore=%d\n", + ret, lcore_id); + + ret = rte_power_pmd_mgmt_set_scaling_freq_max(lcore_id, + scale_freq_max); + if (ret < 0) + rte_exit(EXIT_FAILURE, + "Error setting scaling freq max: err=%d, lcore %d\n", + ret, lcore_id); + ret = rte_power_ethdev_pmgmt_queue_enable( lcore_id, portid, queueid, pmgmt_type);