From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 27082A053C for ; Wed, 29 Jul 2020 16:03:40 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id F04FD1BFF5; Wed, 29 Jul 2020 16:03:39 +0200 (CEST) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id DC8362AB; Wed, 29 Jul 2020 16:03:36 +0200 (CEST) IronPort-SDR: w2AneVpLvOG2ZxKhE0AVSrBjkgBf65qX/kAuwo7CtwWwTF6tz67O4KAFcj4PreSJNNKqmtKkRu XeSU+M8tyzpw== X-IronPort-AV: E=McAfee;i="6000,8403,9696"; a="152650068" X-IronPort-AV: E=Sophos;i="5.75,410,1589266800"; d="scan'208";a="152650068" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Jul 2020 07:03:35 -0700 IronPort-SDR: YtHkVyhGDirzZbW4FkkOifUlL8BN6DeNG1aowJKhL0OWF4YWRiz7dUsQRMGB8zOAwQxXvW+Pv8 Qrb/8N+2BpEA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.75,410,1589266800"; d="scan'208";a="313030655" Received: from silpixa00400214.ir.intel.com (HELO silpixa00400214.ger.corp.intel.com) ([10.237.222.108]) by fmsmga004.fm.intel.com with ESMTP; 29 Jul 2020 07:03:34 -0700 From: Reshma Pattan To: dev@dpdk.org Cc: stable@dpdk.org, liang.j.ma@intel.com, Reshma Pattan Date: Wed, 29 Jul 2020 14:58:53 +0100 Message-Id: <1596031133-110878-1-git-send-email-reshma.pattan@intel.com> X-Mailer: git-send-email 1.8.3.1 Subject: [dpdk-stable] [PATCH] power: fix current frequency index X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: stable-bounces@dpdk.org Sender: "stable" 1) During power initialization the pstate cpufreq api is not setting the initial curr_idx of pstate_power_info to corresponding current frequency index. Without this the idx is always 0, which is causing the below check to pass and returns without setting the initial min/max frequency to system max frequency and this leads to incorrect frequency settings when power_pstate_cpufreq_set_freq() is called in the apps. set_freq_internal(struct pstate_power_info *pi, uint32_t idx) { ... /* Check if it is the same as current */ if (idx == pi->curr_idx) return 0; ... } scenario 1: If system has starting scaling min/max: 1000/1000, and want to set this to 2200/2200, the max frequency gets updated but not min. scenario 2: If system has starting scaling min/max: 2200/1000, and want to set to 2200/2200, the max, min frequency was not updated. Since no change in max that should be ok, but min was also ignored, which will be fixed now with the new changes. Fixes: e6c6dc0f ("power: add p-state driver compatibility") Cc: stable@dpdk.org CC: liang.j.ma@intel.com Signed-off-by: Reshma Pattan --- lib/librte_power/power_pstate_cpufreq.c | 59 +++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/lib/librte_power/power_pstate_cpufreq.c b/lib/librte_power/power_pstate_cpufreq.c index 2526441..262f024 100644 --- a/lib/librte_power/power_pstate_cpufreq.c +++ b/lib/librte_power/power_pstate_cpufreq.c @@ -52,6 +52,9 @@ } \ } while (0) +/* macros used for rounding frequency to nearest 100000 */ +#define FREQ_ROUNDING_DELTA 50000 +#define ROUND_FREQ_TO_N_100000 100000 #define POWER_CONVERT_TO_DECIMAL 10 #define BUS_FREQ 100000 @@ -532,6 +535,57 @@ struct pstate_power_info { return ret; } +static int +power_get_cur_idx(struct pstate_power_info *pi) +{ + FILE *f_cur; + int ret = -1; + char *p_cur; + char buf_cur[BUFSIZ]; + char fullpath_cur[PATH_MAX]; + char *s_cur; + uint32_t sys_cur_freq = 0; + unsigned int i; + + snprintf(fullpath_cur, sizeof(fullpath_cur), + POWER_SYSFILE_CUR_FREQ, + pi->lcore_id); + f_cur = fopen(fullpath_cur, "r"); + FOPEN_OR_ERR_RET(f_cur, ret); + + /* initialize the cur_idx to matching current frequency freq index */ + s_cur = fgets(buf_cur, sizeof(buf_cur), f_cur); + FOPS_OR_NULL_GOTO(s_cur, fail); + + p_cur = strchr(buf_cur, '\n'); + if (p_cur != NULL) + *p_cur = 0; + sys_cur_freq = strtoul(buf_cur, &p_cur, POWER_CONVERT_TO_DECIMAL); + + /* convert the frequency to nearest 100000 value + * Ex: if sys_cur_freq=1396789 then freq_conv=1400000 + * Ex: if sys_cur_freq=800030 then freq_conv=800000 + * Ex: if sys_cur_freq=800030 then freq_conv=800000 + */ + unsigned int freq_conv = 0; + freq_conv = (sys_cur_freq + FREQ_ROUNDING_DELTA) + / ROUND_FREQ_TO_N_100000; + freq_conv = freq_conv * ROUND_FREQ_TO_N_100000; + + for (i = 0; i < pi->nb_freqs; i++) { + if (freq_conv == pi->freqs[i]) { + pi->curr_idx = i; + break; + } + } + + fclose(f_cur); + return 0; +fail: + fclose(f_cur); + return ret; +} + int power_pstate_cpufreq_check_supported(void) { @@ -578,6 +632,11 @@ struct pstate_power_info { goto fail; } + if (power_get_cur_idx(pi) < 0) { + RTE_LOG(ERR, POWER, "Cannot get current frequency " + "index of lcore %u\n", lcore_id); + goto fail; + } /* Set freq to max by default */ if (power_pstate_cpufreq_freq_max(lcore_id) < 0) { -- 1.8.3.1