From patchwork Wed Feb 26 07:49:16 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mario Limonciello X-Patchwork-Id: 868851 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CCF2D26D5B4; Wed, 26 Feb 2025 07:49:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740556183; cv=none; b=W4rtcShOkTP17Jge44JlXV5Abz56aTA9IfCNJqwJHGqzI6hzcc1bFAGJCHJD6+p/DYZ6YTyzlFcPv7kz05Wm/G7A5SIkqj1lbstMXF8Vr0PlkfJ9QcCg23911Q/KdEwc8x0ARKfnGh6L6IhKYh2s6TLBKOp0bWTOPnT8XEqBj7E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740556183; c=relaxed/simple; bh=BrOubcwuEEN6CSCwegHziTWdKo7Rf4NmB0rVPPiVqIg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=W229TWXKJ7C+EqVkxwBlYmZcHtsBT4XLaI0XgsnyBdyY5jMPj67wGJe4uPR2EEfYcbCxejv3y7Opm4EdhbkaOBU5ICJNlIy21fMz1hVsoe4Op68FS4t4BrLdwGNNEY/NQSS10bDIuWdAqzlDpd5l+ZZd602KkFxXx9W4YqdCpkE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=eB80VaoQ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="eB80VaoQ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 29162C4CEE7; Wed, 26 Feb 2025 07:49:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1740556183; bh=BrOubcwuEEN6CSCwegHziTWdKo7Rf4NmB0rVPPiVqIg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eB80VaoQMVDCzHU/O0qH7o2oYKcijTkjGlrpPTZbdKSWKdn6bKpmrdTSdi4MpzN1e OjeSzAzM+DVxPTVFK5P2JGs0E7RBWqxtJQUSAU4hTblZ+F/M/vBK+F8ej/zdqk0QFL h6LlMIg+5plHR7UHct5tNVPZlhDUx0FqUxa+lhKaO10s4m+noIk3MG67KeNJydpu0j w7fUgvoUNAJ1ksOr3yBnwT7GKRn4Hy3ghD/Ih5X+JcUShrupsIr3xpe5ImSjy+F/Z1 m0gFkesnAItnfb7ddiCTzY8a11mHwsBnqOqFNN4MS4RDqk7Oh1rg2wvk8tDtm6NWTW gpDJfdD018uJw== From: Mario Limonciello To: "Gautham R . Shenoy" , Perry Yuan Cc: Dhananjay Ugwekar , linux-kernel@vger.kernel.org (open list:X86 ARCHITECTURE (32-BIT AND 64-BIT)), linux-pm@vger.kernel.org (open list:CPU FREQUENCY SCALING FRAMEWORK), Mario Limonciello , Dhananjay Ugwekar , Miroslav Pavleski Subject: [PATCH v5 01/19] cpufreq/amd-pstate: Invalidate cppc_req_cached during suspend Date: Wed, 26 Feb 2025 01:49:16 -0600 Message-ID: <20250226074934.1667721-2-superm1@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250226074934.1667721-1-superm1@kernel.org> References: <20250226074934.1667721-1-superm1@kernel.org> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Mario Limonciello During resume it's possible the firmware didn't restore the CPPC request MSR but the kernel thinks the values line up. This leads to incorrect performance after resume from suspend. To fix the issue invalidate the cached value at suspend. During resume use the saved values programmed as cached limits. Reviewed-by: Gautham R. Shenoy Reviewed-by: Dhananjay Ugwekar Reported-by: Miroslav Pavleski Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217931 Signed-off-by: Mario Limonciello --- drivers/cpufreq/amd-pstate.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index dc38ef4c8f725..a093389a8fe3e 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -1611,7 +1611,7 @@ static int amd_pstate_epp_reenable(struct cpufreq_policy *policy) max_perf, policy->boost_enabled); } - return amd_pstate_update_perf(cpudata, 0, 0, max_perf, cpudata->epp_cached, false); + return amd_pstate_epp_update_limit(policy); } static int amd_pstate_epp_cpu_online(struct cpufreq_policy *policy) @@ -1660,6 +1660,9 @@ static int amd_pstate_epp_suspend(struct cpufreq_policy *policy) if (cppc_state != AMD_PSTATE_ACTIVE) return 0; + /* invalidate to ensure it's rewritten during resume */ + cpudata->cppc_req_cached = 0; + /* set this flag to avoid setting core offline*/ cpudata->suspended = true; From patchwork Wed Feb 26 07:49:18 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mario Limonciello X-Patchwork-Id: 868850 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4C46626F455; Wed, 26 Feb 2025 07:49:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740556186; cv=none; b=qNCVwVTC1wuGKg4AISI4dfy0Kx2or3Phj3TRZQk/+00Exze8OoLfavDHM6oy42QzGKgwQF1B8AYqF2YuZ2+SlSiEBVYPviCw+j0Jt+Yxt140OxT/KFxRfSDWHrSghW4tmODAg4Xh3FqhQkOAGN5ia/JonSNVej5mA+Whmy45cvY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740556186; c=relaxed/simple; bh=+HSwYryLgJuFS/PerQiTbC2rJtMVtZPYt+ffFn0P+Ws=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fZ1x6KYXzTFUdIGiPoQxKSO4504s2HMsnWIb7yolBW8kDs94DMXdODff05ZzxlJpYQuHDaPLA/98pPy9lzGnaigQs6aNiS6oSusJgr+DTvJb2u0TifsdEhTEtIAwpkEZwMbd21V+wJPH9GjGl7coP6YZOvxLYMN/F6Zpo9SmgJ8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=SAlPnMOj; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="SAlPnMOj" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1049FC4CEE9; Wed, 26 Feb 2025 07:49:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1740556186; bh=+HSwYryLgJuFS/PerQiTbC2rJtMVtZPYt+ffFn0P+Ws=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SAlPnMOjLnWfG0EVu/mIg42KLcLavLgGt7YNOzqIrzwnFwg+YYa6ObikKPRPwrm28 QImgUa4bOauO7gLlgYIkTd7B4qGhyg8i5s6YLV/tvK4kQ/SsCz9+HObPg+liN1TKth cUU65qYoBStdF1z5fuTDpYEk10/8v63a4oZ6a9yVYKS1H++KjuKh8lDRoTnMseqN0c jybjMMT9TEjie6B0gC4eOHQjxyiVQBucRXjiImDcvbOEMuASlrAYz4dc8q5nKfuOQ4 2bH6n5msxFzevH6tz76+FbSdEe91Ww7D/rTJS+pAx6Yjjmy4GVuX55ZeH6SzMtA+1X 1yucOxbeS3g2Q== From: Mario Limonciello To: "Gautham R . Shenoy" , Perry Yuan Cc: Dhananjay Ugwekar , linux-kernel@vger.kernel.org (open list:X86 ARCHITECTURE (32-BIT AND 64-BIT)), linux-pm@vger.kernel.org (open list:CPU FREQUENCY SCALING FRAMEWORK), Mario Limonciello , Dhananjay Ugwekar Subject: [PATCH v5 03/19] cpufreq/amd-pstate: Drop min and max cached frequencies Date: Wed, 26 Feb 2025 01:49:18 -0600 Message-ID: <20250226074934.1667721-4-superm1@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250226074934.1667721-1-superm1@kernel.org> References: <20250226074934.1667721-1-superm1@kernel.org> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Mario Limonciello Use the perf_to_freq helpers to calculate this on the fly. As the members are no longer cached add an extra check into amd_pstate_epp_update_limit() to avoid unnecessary calls in amd_pstate_update_min_max_limit(). Reviewed-by: Gautham R. Shenoy Reviewed-by: Dhananjay Ugwekar Signed-off-by: Mario Limonciello --- v5: * add tag * Update commit message v4: * Avoid some unnecessary changes to amd_pstate_init_freq() * Add tag v3: * Fix calc error for min_freq v2: * Keep cached limits --- drivers/cpufreq/amd-pstate-ut.c | 14 +++++------ drivers/cpufreq/amd-pstate.c | 43 +++++++++------------------------ drivers/cpufreq/amd-pstate.h | 9 ++----- 3 files changed, 20 insertions(+), 46 deletions(-) diff --git a/drivers/cpufreq/amd-pstate-ut.c b/drivers/cpufreq/amd-pstate-ut.c index 3a0a380c3590c..445278cf40b61 100644 --- a/drivers/cpufreq/amd-pstate-ut.c +++ b/drivers/cpufreq/amd-pstate-ut.c @@ -214,14 +214,14 @@ static void amd_pstate_ut_check_freq(u32 index) break; cpudata = policy->driver_data; - if (!((cpudata->max_freq >= cpudata->nominal_freq) && + if (!((policy->cpuinfo.max_freq >= cpudata->nominal_freq) && (cpudata->nominal_freq > cpudata->lowest_nonlinear_freq) && - (cpudata->lowest_nonlinear_freq > cpudata->min_freq) && - (cpudata->min_freq > 0))) { + (cpudata->lowest_nonlinear_freq > policy->cpuinfo.min_freq) && + (policy->cpuinfo.min_freq > 0))) { amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; pr_err("%s cpu%d max=%d >= nominal=%d > lowest_nonlinear=%d > min=%d > 0, the formula is incorrect!\n", - __func__, cpu, cpudata->max_freq, cpudata->nominal_freq, - cpudata->lowest_nonlinear_freq, cpudata->min_freq); + __func__, cpu, policy->cpuinfo.max_freq, cpudata->nominal_freq, + cpudata->lowest_nonlinear_freq, policy->cpuinfo.min_freq); goto skip_test; } @@ -233,13 +233,13 @@ static void amd_pstate_ut_check_freq(u32 index) } if (cpudata->boost_supported) { - if ((policy->max == cpudata->max_freq) || + if ((policy->max == policy->cpuinfo.max_freq) || (policy->max == cpudata->nominal_freq)) amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_PASS; else { amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; pr_err("%s cpu%d policy_max=%d should be equal cpu_max=%d or cpu_nominal=%d !\n", - __func__, cpu, policy->max, cpudata->max_freq, + __func__, cpu, policy->max, policy->cpuinfo.max_freq, cpudata->nominal_freq); goto skip_test; } diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index 1b98f5d76894d..fb28b27558882 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -717,7 +717,7 @@ static int amd_pstate_cpu_boost_update(struct cpufreq_policy *policy, bool on) int ret = 0; nominal_freq = READ_ONCE(cpudata->nominal_freq); - max_freq = READ_ONCE(cpudata->max_freq); + max_freq = perf_to_freq(cpudata, READ_ONCE(cpudata->highest_perf)); if (on) policy->cpuinfo.max_freq = max_freq; @@ -923,13 +923,10 @@ static int amd_pstate_init_freq(struct amd_cpudata *cpudata) nominal_freq *= 1000; WRITE_ONCE(cpudata->nominal_freq, nominal_freq); - WRITE_ONCE(cpudata->min_freq, min_freq); max_freq = perf_to_freq(cpudata, cpudata->highest_perf); lowest_nonlinear_freq = perf_to_freq(cpudata, cpudata->lowest_nonlinear_perf); - WRITE_ONCE(cpudata->lowest_nonlinear_freq, lowest_nonlinear_freq); - WRITE_ONCE(cpudata->max_freq, max_freq); /** * Below values need to be initialized correctly, otherwise driver will fail to load @@ -954,9 +951,9 @@ static int amd_pstate_init_freq(struct amd_cpudata *cpudata) static int amd_pstate_cpu_init(struct cpufreq_policy *policy) { - int min_freq, max_freq, ret; - struct device *dev; struct amd_cpudata *cpudata; + struct device *dev; + int ret; /* * Resetting PERF_CTL_MSR will put the CPU in P0 frequency, @@ -987,17 +984,11 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy) if (ret) goto free_cpudata1; - min_freq = READ_ONCE(cpudata->min_freq); - max_freq = READ_ONCE(cpudata->max_freq); - policy->cpuinfo.transition_latency = amd_pstate_get_transition_latency(policy->cpu); policy->transition_delay_us = amd_pstate_get_transition_delay_us(policy->cpu); - policy->min = min_freq; - policy->max = max_freq; - - policy->cpuinfo.min_freq = min_freq; - policy->cpuinfo.max_freq = max_freq; + policy->cpuinfo.min_freq = policy->min = perf_to_freq(cpudata, cpudata->lowest_perf); + policy->cpuinfo.max_freq = policy->max = perf_to_freq(cpudata, cpudata->highest_perf); policy->boost_enabled = READ_ONCE(cpudata->boost_supported); @@ -1021,9 +1012,6 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy) goto free_cpudata2; } - cpudata->max_limit_freq = max_freq; - cpudata->min_limit_freq = min_freq; - policy->driver_data = cpudata; if (!current_pstate_driver->adjust_perf) @@ -1081,14 +1069,10 @@ static int amd_pstate_cpu_suspend(struct cpufreq_policy *policy) static ssize_t show_amd_pstate_max_freq(struct cpufreq_policy *policy, char *buf) { - int max_freq; struct amd_cpudata *cpudata = policy->driver_data; - max_freq = READ_ONCE(cpudata->max_freq); - if (max_freq < 0) - return max_freq; - return sysfs_emit(buf, "%u\n", max_freq); + return sysfs_emit(buf, "%u\n", perf_to_freq(cpudata, READ_ONCE(cpudata->highest_perf))); } static ssize_t show_amd_pstate_lowest_nonlinear_freq(struct cpufreq_policy *policy, @@ -1446,10 +1430,10 @@ static bool amd_pstate_acpi_pm_profile_undefined(void) static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy) { - int min_freq, max_freq, ret; struct amd_cpudata *cpudata; struct device *dev; u64 value; + int ret; /* * Resetting PERF_CTL_MSR will put the CPU in P0 frequency, @@ -1480,19 +1464,13 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy) if (ret) goto free_cpudata1; - min_freq = READ_ONCE(cpudata->min_freq); - max_freq = READ_ONCE(cpudata->max_freq); - - policy->cpuinfo.min_freq = min_freq; - policy->cpuinfo.max_freq = max_freq; + policy->cpuinfo.min_freq = policy->min = perf_to_freq(cpudata, cpudata->lowest_perf); + policy->cpuinfo.max_freq = policy->max = perf_to_freq(cpudata, cpudata->highest_perf); /* It will be updated by governor */ policy->cur = policy->cpuinfo.min_freq; policy->driver_data = cpudata; - policy->min = policy->cpuinfo.min_freq; - policy->max = policy->cpuinfo.max_freq; - policy->boost_enabled = READ_ONCE(cpudata->boost_supported); /* @@ -1550,7 +1528,8 @@ static int amd_pstate_epp_update_limit(struct cpufreq_policy *policy) struct amd_cpudata *cpudata = policy->driver_data; u8 epp; - amd_pstate_update_min_max_limit(policy); + if (policy->min != cpudata->min_limit_freq || policy->max != cpudata->max_limit_freq) + amd_pstate_update_min_max_limit(policy); if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE) epp = 0; diff --git a/drivers/cpufreq/amd-pstate.h b/drivers/cpufreq/amd-pstate.h index 19d405c6d805e..0149933692458 100644 --- a/drivers/cpufreq/amd-pstate.h +++ b/drivers/cpufreq/amd-pstate.h @@ -46,8 +46,6 @@ struct amd_aperf_mperf { * @max_limit_perf: Cached value of the performance corresponding to policy->max * @min_limit_freq: Cached value of policy->min (in khz) * @max_limit_freq: Cached value of policy->max (in khz) - * @max_freq: the frequency (in khz) that mapped to highest_perf - * @min_freq: the frequency (in khz) that mapped to lowest_perf * @nominal_freq: the frequency (in khz) that mapped to nominal_perf * @lowest_nonlinear_freq: the frequency (in khz) that mapped to lowest_nonlinear_perf * @cur: Difference of Aperf/Mperf/tsc count between last and current sample @@ -77,11 +75,8 @@ struct amd_cpudata { u8 prefcore_ranking; u8 min_limit_perf; u8 max_limit_perf; - u32 min_limit_freq; - u32 max_limit_freq; - - u32 max_freq; - u32 min_freq; + u32 min_limit_freq; + u32 max_limit_freq; u32 nominal_freq; u32 lowest_nonlinear_freq; From patchwork Wed Feb 26 07:49:20 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mario Limonciello X-Patchwork-Id: 868849 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 57877270EDD; Wed, 26 Feb 2025 07:49:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740556189; cv=none; b=KbA0+2eSigVEUcRjW//a9TgSPVuZymj8hpPzXXV4QInRbeD/z/JWeqXG3IrhsXcjswqY0Bn50s7EuxCArhUog0/6a58JczJfWhDmrpGICq9mKDBWS/REc7W+QIGcA1heV7spJC0APnAsIV/eA7JU1KTW1c0HE2/+q8PrhFsVz9w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740556189; c=relaxed/simple; bh=RhhlMY/+/0QCcNeMO/gDSOU04nQVsd/ZzzYkWaGrJqI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fmrp+udgx/4Tr35W1o4l0QM/6J0QriAs4MOEANJ+17UrouMeIwbM78UIWlKDWZTa6fWUg1zDsTy3clcA5cog8dKnUhCaNAerihflCXyRuSKB4FIfw8ueCjafYhLEB7MxwqN8fiy4kq4387TYRL1IhITZbimdcTPP8A9/Kewh34s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=QYEwJYWZ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="QYEwJYWZ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BF392C4CEE7; Wed, 26 Feb 2025 07:49:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1740556188; bh=RhhlMY/+/0QCcNeMO/gDSOU04nQVsd/ZzzYkWaGrJqI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QYEwJYWZHgp5B75oS7SQ3F5hLC6rYkWE9MFS1qvx1qxxqU+ANkW1Hd4s2nNgxY7ME 0baEBJmV+YAshlX/ecAruKnnyyDePOtM5g+2Me3Lpe+pxkmQiNmQs0SlcneHD0gUiT dtT6JbeDanB+eZ7oBpNucxjYXGr8rDF/fw1gWi2UkszkIRqC70hZrihGtdU0HjHw5P kQMIS0LJUda5Z2ApZOg+yr+uhkt7bJiM0Bz3Vz0PWrPYSXnQTq6LJoxECbMbLwERMR ESvs/hKi8rbujQoeC3ap8UKCsfr+6pz4QHnEtNQf719oD3pE1DU3scrJHJxNJTwNpJ 2p/8R6td/WCUg== From: Mario Limonciello To: "Gautham R . Shenoy" , Perry Yuan Cc: Dhananjay Ugwekar , linux-kernel@vger.kernel.org (open list:X86 ARCHITECTURE (32-BIT AND 64-BIT)), linux-pm@vger.kernel.org (open list:CPU FREQUENCY SCALING FRAMEWORK), Mario Limonciello , Dhananjay Ugwekar Subject: [PATCH v5 05/19] cpufreq/amd-pstate: Overhaul locking Date: Wed, 26 Feb 2025 01:49:20 -0600 Message-ID: <20250226074934.1667721-6-superm1@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250226074934.1667721-1-superm1@kernel.org> References: <20250226074934.1667721-1-superm1@kernel.org> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Mario Limonciello amd_pstate_cpu_boost_update() and refresh_frequency_limits() both update the policy state and have nothing to do with the amd-pstate driver itself. A global "limits" lock doesn't make sense because each CPU can have policies changed independently. Each time a CPU changes values they will atomically be written to the per-CPU perf member. Drop per CPU locking cases. The remaining "global" driver lock is used to ensure that only one entity can change driver modes at a given time. Reviewed-by: Gautham R. Shenoy Reviewed-by: Dhananjay Ugwekar Signed-off-by: Mario Limonciello --- v5: * Add tag --- drivers/cpufreq/amd-pstate.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index bd8bcda4e6eb0..95b77cf145174 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -196,7 +196,6 @@ static inline int get_mode_idx_from_str(const char *str, size_t size) return -EINVAL; } -static DEFINE_MUTEX(amd_pstate_limits_lock); static DEFINE_MUTEX(amd_pstate_driver_lock); static u8 msr_get_epp(struct amd_cpudata *cpudata) @@ -752,7 +751,6 @@ static int amd_pstate_set_boost(struct cpufreq_policy *policy, int state) pr_err("Boost mode is not supported by this processor or SBIOS\n"); return -EOPNOTSUPP; } - guard(mutex)(&amd_pstate_driver_lock); ret = amd_pstate_cpu_boost_update(policy, state); refresh_frequency_limits(policy); @@ -1176,8 +1174,6 @@ static ssize_t store_energy_performance_preference( if (ret < 0) return -EINVAL; - guard(mutex)(&amd_pstate_limits_lock); - ret = amd_pstate_set_energy_pref_index(policy, ret); return ret ? ret : count; @@ -1350,8 +1346,10 @@ int amd_pstate_update_status(const char *buf, size_t size) if (mode_idx < 0 || mode_idx >= AMD_PSTATE_MAX) return -EINVAL; - if (mode_state_machine[cppc_state][mode_idx]) + if (mode_state_machine[cppc_state][mode_idx]) { + guard(mutex)(&amd_pstate_driver_lock); return mode_state_machine[cppc_state][mode_idx](mode_idx); + } return 0; } @@ -1372,7 +1370,6 @@ static ssize_t status_store(struct device *a, struct device_attribute *b, char *p = memchr(buf, '\n', count); int ret; - guard(mutex)(&amd_pstate_driver_lock); ret = amd_pstate_update_status(buf, p ? p - buf : count); return ret < 0 ? ret : count; @@ -1644,8 +1641,6 @@ static int amd_pstate_epp_cpu_offline(struct cpufreq_policy *policy) if (cpudata->suspended) return 0; - guard(mutex)(&amd_pstate_limits_lock); - if (trace_amd_pstate_epp_perf_enabled()) { trace_amd_pstate_epp_perf(cpudata->cpu, perf.highest_perf, AMD_CPPC_EPP_BALANCE_POWERSAVE, @@ -1685,8 +1680,6 @@ static int amd_pstate_epp_resume(struct cpufreq_policy *policy) struct amd_cpudata *cpudata = policy->driver_data; if (cpudata->suspended) { - guard(mutex)(&amd_pstate_limits_lock); - /* enable amd pstate from suspend state*/ amd_pstate_epp_reenable(policy); From patchwork Wed Feb 26 07:49:22 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mario Limonciello X-Patchwork-Id: 868848 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BE5C227180F; Wed, 26 Feb 2025 07:49:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740556191; cv=none; b=B3eoLItJYeNCCvk4TkUPbVmvI9l/L8jjfmdm6+eDTuRBTxezMalFSW+rSbHuVM5gea5ww2deNDGM+RKY+jQLj3oisQMm5FIlvKrgSZryZjdCY8trLEFVNKC6w8YnKzNWS7ZcSO7FT2zUxfS111nTsE712HxgtvgcAzmv7xFp0wo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740556191; c=relaxed/simple; bh=OQYNxtGz0wJeCEblJ/slox/YGV07cQK/uO8CO726WiU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ZF0gc3ogecUxRyloBL9aB/HbvSI5T7KVwd8/p5XKDVlrurhp5EDLrP/DevFgOcr1dzbNq8r/GggoEhZy2wc/IeMgXFvk7j6sJBsHqWLEo133Q1MJIl43UxuQdkEFkaVO0r4kfLQkZElsl8ExkdW2XM3PLrrqeV+HaTDxgNUQkAI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=O/cyR0CJ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="O/cyR0CJ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8EE66C4CED6; Wed, 26 Feb 2025 07:49:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1740556191; bh=OQYNxtGz0wJeCEblJ/slox/YGV07cQK/uO8CO726WiU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=O/cyR0CJo/zwPWFWzvPgzIBhCtS7nsvhbY4l5WrilMujqXg8DWNgQTmqIvRM6mda5 dSOB+zOHgf/E8VIteRYPHk8WyrHAhOadHRNr26rGPOcei0xCKbQQb7CniCp2ZFU4rI n/KP8ax/vvD+/uy41hGH+Eob0sIGSDlizhd36guzmAKndRL6L94qZq8WNv7EBv0Fht 7/jEobIU/kbf1ZBHsodXI6GyNoV95tyxMUHTj9mCserAu7SkPg/wOhcMVnim17anNO i4bTwcV9ofWFxyDcfw2CMgG7KdnVHz/lz45IXC2XhW3rqD2G7NVJhn+PK3ajf84749 i6lGhdYe/bI3Q== From: Mario Limonciello To: "Gautham R . Shenoy" , Perry Yuan Cc: Dhananjay Ugwekar , linux-kernel@vger.kernel.org (open list:X86 ARCHITECTURE (32-BIT AND 64-BIT)), linux-pm@vger.kernel.org (open list:CPU FREQUENCY SCALING FRAMEWORK), Mario Limonciello , Dhananjay Ugwekar Subject: [PATCH v5 07/19] cpufreq/amd-pstate-ut: Use _free macro to free put policy Date: Wed, 26 Feb 2025 01:49:22 -0600 Message-ID: <20250226074934.1667721-8-superm1@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250226074934.1667721-1-superm1@kernel.org> References: <20250226074934.1667721-1-superm1@kernel.org> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Mario Limonciello Using a scoped cleanup macro simplifies cleanup code. Reviewed-by: Dhananjay Ugwekar Reviewed-by: Gautham R. Shenoy Signed-off-by: Mario Limonciello --- drivers/cpufreq/amd-pstate-ut.c | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/drivers/cpufreq/amd-pstate-ut.c b/drivers/cpufreq/amd-pstate-ut.c index 5f6a92a816e61..e02672e67380a 100644 --- a/drivers/cpufreq/amd-pstate-ut.c +++ b/drivers/cpufreq/amd-pstate-ut.c @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -127,11 +128,12 @@ static void amd_pstate_ut_check_perf(u32 index) u32 highest_perf = 0, nominal_perf = 0, lowest_nonlinear_perf = 0, lowest_perf = 0; u64 cap1 = 0; struct cppc_perf_caps cppc_perf; - struct cpufreq_policy *policy = NULL; struct amd_cpudata *cpudata = NULL; union perf_cached cur_perf; for_each_possible_cpu(cpu) { + struct cpufreq_policy *policy __free(put_cpufreq_policy) = NULL; + policy = cpufreq_cpu_get(cpu); if (!policy) break; @@ -142,7 +144,7 @@ static void amd_pstate_ut_check_perf(u32 index) if (ret) { amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; pr_err("%s cppc_get_perf_caps ret=%d error!\n", __func__, ret); - goto skip_test; + return; } highest_perf = cppc_perf.highest_perf; @@ -154,7 +156,7 @@ static void amd_pstate_ut_check_perf(u32 index) if (ret) { amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; pr_err("%s read CPPC_CAP1 ret=%d error!\n", __func__, ret); - goto skip_test; + return; } highest_perf = AMD_CPPC_HIGHEST_PERF(cap1); @@ -167,7 +169,7 @@ static void amd_pstate_ut_check_perf(u32 index) if (highest_perf != cur_perf.highest_perf && !cpudata->hw_prefcore) { pr_err("%s cpu%d highest=%d %d highest perf doesn't match\n", __func__, cpu, highest_perf, cur_perf.highest_perf); - goto skip_test; + return; } if (nominal_perf != cur_perf.nominal_perf || (lowest_nonlinear_perf != cur_perf.lowest_nonlinear_perf) || @@ -177,7 +179,7 @@ static void amd_pstate_ut_check_perf(u32 index) __func__, cpu, nominal_perf, cur_perf.nominal_perf, lowest_nonlinear_perf, cur_perf.lowest_nonlinear_perf, lowest_perf, cur_perf.lowest_perf); - goto skip_test; + return; } if (!((highest_perf >= nominal_perf) && @@ -188,15 +190,11 @@ static void amd_pstate_ut_check_perf(u32 index) pr_err("%s cpu%d highest=%d >= nominal=%d > lowest_nonlinear=%d > lowest=%d > 0, the formula is incorrect!\n", __func__, cpu, highest_perf, nominal_perf, lowest_nonlinear_perf, lowest_perf); - goto skip_test; + return; } - cpufreq_cpu_put(policy); } amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_PASS; - return; -skip_test: - cpufreq_cpu_put(policy); } /* @@ -207,10 +205,11 @@ static void amd_pstate_ut_check_perf(u32 index) static void amd_pstate_ut_check_freq(u32 index) { int cpu = 0; - struct cpufreq_policy *policy = NULL; struct amd_cpudata *cpudata = NULL; for_each_possible_cpu(cpu) { + struct cpufreq_policy *policy __free(put_cpufreq_policy) = NULL; + policy = cpufreq_cpu_get(cpu); if (!policy) break; @@ -224,14 +223,14 @@ static void amd_pstate_ut_check_freq(u32 index) pr_err("%s cpu%d max=%d >= nominal=%d > lowest_nonlinear=%d > min=%d > 0, the formula is incorrect!\n", __func__, cpu, policy->cpuinfo.max_freq, cpudata->nominal_freq, cpudata->lowest_nonlinear_freq, policy->cpuinfo.min_freq); - goto skip_test; + return; } if (cpudata->lowest_nonlinear_freq != policy->min) { amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; pr_err("%s cpu%d cpudata_lowest_nonlinear_freq=%d policy_min=%d, they should be equal!\n", __func__, cpu, cpudata->lowest_nonlinear_freq, policy->min); - goto skip_test; + return; } if (cpudata->boost_supported) { @@ -243,20 +242,16 @@ static void amd_pstate_ut_check_freq(u32 index) pr_err("%s cpu%d policy_max=%d should be equal cpu_max=%d or cpu_nominal=%d !\n", __func__, cpu, policy->max, policy->cpuinfo.max_freq, cpudata->nominal_freq); - goto skip_test; + return; } } else { amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; pr_err("%s cpu%d must support boost!\n", __func__, cpu); - goto skip_test; + return; } - cpufreq_cpu_put(policy); } amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_PASS; - return; -skip_test: - cpufreq_cpu_put(policy); } static int amd_pstate_set_mode(enum amd_pstate_mode mode) From patchwork Wed Feb 26 07:49:24 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mario Limonciello X-Patchwork-Id: 868847 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 92937272924; Wed, 26 Feb 2025 07:49:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740556194; cv=none; b=DyyJQ3HZXo0RHM5V6b1qNTkNx3nFC8kwFNTpSTT+aIrokgwFXZ668T2dw2KEW+Cz20fTwg0Jk9xsZUbMLp4mdqf+189cFDdY/q9XeqA67/aIrIBu3K1/OpkELcFQa6MdNl8uYXrZ3RzG+b2i/6r/ejFv8tQ96C9vtZx/hHQ7aNY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740556194; c=relaxed/simple; bh=Q9vnlr16LPJsaaaQcIaxKEsHF/dgnRxRXNH3cGTXpUM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uvvr48z1/+/4vw9KSUdDmhrxDjs/IKNKezAF0JKKCR6RpyuGWgcvljdoMX4yNIhRtyav7WKCAcDwJCHuapelCt5o+Twt/fSgisjvVUNLQSmXOyMlQwmlqbeCpeodkwYVF1skgTU/uUQmkETSGF4lNGZ4QUIz6YtNbgwtwUB0biI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=kaVL8ONB; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="kaVL8ONB" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 69ACAC4CED6; Wed, 26 Feb 2025 07:49:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1740556194; bh=Q9vnlr16LPJsaaaQcIaxKEsHF/dgnRxRXNH3cGTXpUM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kaVL8ONBSqDWRKKmOvqVYV3uVMrxgcbez4F2W+fPtF0v9bOa9nf/gDrRSkcJHzWgA LaYfyK3BOoIUnGL6hbsvzLeTm9C4sBF+hEol0GG87ItYk2UnSLjexwb3HtplBr5RYB fSgV1U9vAKMCQdiG5JdWlrT5pkhJT8MUKVHEtLRCTC+fbX+0SbcShLbR7xR84GXXvx KJdyVGpj3xgmMxS0s1iEXQh+8XvwWwryFkndVqpOFRvO1/y1Z2Ng/051ui73q2loBA 5Mki//Srdt9ExDppE9k8HD0NZ6aoRkSvHz+knK6tErH5OVJ/sJNqz0qbs2+bgazbUr Z9jbw4bp5NVmw== From: Mario Limonciello To: "Gautham R . Shenoy" , Perry Yuan Cc: Dhananjay Ugwekar , linux-kernel@vger.kernel.org (open list:X86 ARCHITECTURE (32-BIT AND 64-BIT)), linux-pm@vger.kernel.org (open list:CPU FREQUENCY SCALING FRAMEWORK), Mario Limonciello , Dhananjay Ugwekar Subject: [PATCH v5 09/19] cpufreq/amd-pstate-ut: Drop SUCCESS and FAIL enums Date: Wed, 26 Feb 2025 01:49:24 -0600 Message-ID: <20250226074934.1667721-10-superm1@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250226074934.1667721-1-superm1@kernel.org> References: <20250226074934.1667721-1-superm1@kernel.org> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Mario Limonciello Enums are effectively used as a boolean and don't show the return value of the failing call. Instead of using enums switch to returning the actual return code from the unit test. Reviewed-by: Gautham R. Shenoy Reviewed-by: Dhananjay Ugwekar Signed-off-by: Mario Limonciello --- v5: * Add tag --- drivers/cpufreq/amd-pstate-ut.c | 143 ++++++++++++-------------------- 1 file changed, 55 insertions(+), 88 deletions(-) diff --git a/drivers/cpufreq/amd-pstate-ut.c b/drivers/cpufreq/amd-pstate-ut.c index b3693a4c28d26..cd9a472e8dc3c 100644 --- a/drivers/cpufreq/amd-pstate-ut.c +++ b/drivers/cpufreq/amd-pstate-ut.c @@ -32,30 +32,20 @@ #include "amd-pstate.h" -/* - * Abbreviations: - * amd_pstate_ut: used as a shortform for AMD P-State unit test. - * It helps to keep variable names smaller, simpler - */ -enum amd_pstate_ut_result { - AMD_PSTATE_UT_RESULT_PASS, - AMD_PSTATE_UT_RESULT_FAIL, -}; struct amd_pstate_ut_struct { const char *name; - void (*func)(u32 index); - enum amd_pstate_ut_result result; + int (*func)(u32 index); }; /* * Kernel module for testing the AMD P-State unit test */ -static void amd_pstate_ut_acpi_cpc_valid(u32 index); -static void amd_pstate_ut_check_enabled(u32 index); -static void amd_pstate_ut_check_perf(u32 index); -static void amd_pstate_ut_check_freq(u32 index); -static void amd_pstate_ut_check_driver(u32 index); +static int amd_pstate_ut_acpi_cpc_valid(u32 index); +static int amd_pstate_ut_check_enabled(u32 index); +static int amd_pstate_ut_check_perf(u32 index); +static int amd_pstate_ut_check_freq(u32 index); +static int amd_pstate_ut_check_driver(u32 index); static struct amd_pstate_ut_struct amd_pstate_ut_cases[] = { {"amd_pstate_ut_acpi_cpc_valid", amd_pstate_ut_acpi_cpc_valid }, @@ -78,51 +68,46 @@ static bool get_shared_mem(void) /* * check the _CPC object is present in SBIOS. */ -static void amd_pstate_ut_acpi_cpc_valid(u32 index) +static int amd_pstate_ut_acpi_cpc_valid(u32 index) { - if (acpi_cpc_valid()) - amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_PASS; - else { - amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; + if (!acpi_cpc_valid()) { pr_err("%s the _CPC object is not present in SBIOS!\n", __func__); + return -EINVAL; } + + return 0; } -static void amd_pstate_ut_pstate_enable(u32 index) +/* + * check if amd pstate is enabled + */ +static int amd_pstate_ut_check_enabled(u32 index) { - int ret = 0; u64 cppc_enable = 0; + int ret; + + if (get_shared_mem()) + return 0; ret = rdmsrl_safe(MSR_AMD_CPPC_ENABLE, &cppc_enable); if (ret) { - amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; pr_err("%s rdmsrl_safe MSR_AMD_CPPC_ENABLE ret=%d error!\n", __func__, ret); - return; + return ret; } - if (cppc_enable) - amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_PASS; - else { - amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; + + if (!cppc_enable) { pr_err("%s amd pstate must be enabled!\n", __func__); + return -EINVAL; } -} -/* - * check if amd pstate is enabled - */ -static void amd_pstate_ut_check_enabled(u32 index) -{ - if (get_shared_mem()) - amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_PASS; - else - amd_pstate_ut_pstate_enable(index); + return 0; } /* * check if performance values are reasonable. * highest_perf >= nominal_perf > lowest_nonlinear_perf > lowest_perf > 0 */ -static void amd_pstate_ut_check_perf(u32 index) +static int amd_pstate_ut_check_perf(u32 index) { int cpu = 0, ret = 0; u32 highest_perf = 0, nominal_perf = 0, lowest_nonlinear_perf = 0, lowest_perf = 0; @@ -142,9 +127,8 @@ static void amd_pstate_ut_check_perf(u32 index) if (get_shared_mem()) { ret = cppc_get_perf_caps(cpu, &cppc_perf); if (ret) { - amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; pr_err("%s cppc_get_perf_caps ret=%d error!\n", __func__, ret); - return; + return ret; } highest_perf = cppc_perf.highest_perf; @@ -154,9 +138,8 @@ static void amd_pstate_ut_check_perf(u32 index) } else { ret = rdmsrl_safe_on_cpu(cpu, MSR_AMD_CPPC_CAP1, &cap1); if (ret) { - amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; pr_err("%s read CPPC_CAP1 ret=%d error!\n", __func__, ret); - return; + return ret; } highest_perf = AMD_CPPC_HIGHEST_PERF(cap1); @@ -169,32 +152,30 @@ static void amd_pstate_ut_check_perf(u32 index) if (highest_perf != cur_perf.highest_perf && !cpudata->hw_prefcore) { pr_err("%s cpu%d highest=%d %d highest perf doesn't match\n", __func__, cpu, highest_perf, cur_perf.highest_perf); - return; + return -EINVAL; } if (nominal_perf != cur_perf.nominal_perf || (lowest_nonlinear_perf != cur_perf.lowest_nonlinear_perf) || (lowest_perf != cur_perf.lowest_perf)) { - amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; pr_err("%s cpu%d nominal=%d %d lowest_nonlinear=%d %d lowest=%d %d, they should be equal!\n", __func__, cpu, nominal_perf, cur_perf.nominal_perf, lowest_nonlinear_perf, cur_perf.lowest_nonlinear_perf, lowest_perf, cur_perf.lowest_perf); - return; + return -EINVAL; } if (!((highest_perf >= nominal_perf) && (nominal_perf > lowest_nonlinear_perf) && (lowest_nonlinear_perf >= lowest_perf) && (lowest_perf > 0))) { - amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; pr_err("%s cpu%d highest=%d >= nominal=%d > lowest_nonlinear=%d > lowest=%d > 0, the formula is incorrect!\n", __func__, cpu, highest_perf, nominal_perf, lowest_nonlinear_perf, lowest_perf); - return; + return -EINVAL; } } - amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_PASS; + return 0; } /* @@ -202,7 +183,7 @@ static void amd_pstate_ut_check_perf(u32 index) * max_freq >= nominal_freq > lowest_nonlinear_freq > min_freq > 0 * check max freq when set support boost mode. */ -static void amd_pstate_ut_check_freq(u32 index) +static int amd_pstate_ut_check_freq(u32 index) { int cpu = 0; struct amd_cpudata *cpudata = NULL; @@ -219,39 +200,33 @@ static void amd_pstate_ut_check_freq(u32 index) (cpudata->nominal_freq > cpudata->lowest_nonlinear_freq) && (cpudata->lowest_nonlinear_freq >= policy->cpuinfo.min_freq) && (policy->cpuinfo.min_freq > 0))) { - amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; pr_err("%s cpu%d max=%d >= nominal=%d > lowest_nonlinear=%d > min=%d > 0, the formula is incorrect!\n", __func__, cpu, policy->cpuinfo.max_freq, cpudata->nominal_freq, cpudata->lowest_nonlinear_freq, policy->cpuinfo.min_freq); - return; + return -EINVAL; } if (cpudata->lowest_nonlinear_freq != policy->min) { - amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; pr_err("%s cpu%d cpudata_lowest_nonlinear_freq=%d policy_min=%d, they should be equal!\n", __func__, cpu, cpudata->lowest_nonlinear_freq, policy->min); - return; + return -EINVAL; } if (cpudata->boost_supported) { - if ((policy->max == policy->cpuinfo.max_freq) || - (policy->max == cpudata->nominal_freq)) - amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_PASS; - else { - amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; + if ((policy->max != policy->cpuinfo.max_freq) && + (policy->max != cpudata->nominal_freq)) { pr_err("%s cpu%d policy_max=%d should be equal cpu_max=%d or cpu_nominal=%d !\n", __func__, cpu, policy->max, policy->cpuinfo.max_freq, cpudata->nominal_freq); - return; + return -EINVAL; } } else { - amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; pr_err("%s cpu%d must support boost!\n", __func__, cpu); - return; + return -EINVAL; } } - amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_PASS; + return 0; } static int amd_pstate_set_mode(enum amd_pstate_mode mode) @@ -263,32 +238,28 @@ static int amd_pstate_set_mode(enum amd_pstate_mode mode) return amd_pstate_update_status(mode_str, strlen(mode_str)); } -static void amd_pstate_ut_check_driver(u32 index) +static int amd_pstate_ut_check_driver(u32 index) { enum amd_pstate_mode mode1, mode2 = AMD_PSTATE_DISABLE; - int ret; for (mode1 = AMD_PSTATE_DISABLE; mode1 < AMD_PSTATE_MAX; mode1++) { - ret = amd_pstate_set_mode(mode1); + int ret = amd_pstate_set_mode(mode1); if (ret) - goto out; + return ret; for (mode2 = AMD_PSTATE_DISABLE; mode2 < AMD_PSTATE_MAX; mode2++) { if (mode1 == mode2) continue; ret = amd_pstate_set_mode(mode2); - if (ret) - goto out; + if (ret) { + pr_err("%s: failed to update status for %s->%s\n", __func__, + amd_pstate_get_mode_string(mode1), + amd_pstate_get_mode_string(mode2)); + return ret; + } } } -out: - if (ret) - pr_warn("%s: failed to update status for %s->%s: %d\n", __func__, - amd_pstate_get_mode_string(mode1), - amd_pstate_get_mode_string(mode2), ret); - - amd_pstate_ut_cases[index].result = ret ? - AMD_PSTATE_UT_RESULT_FAIL : - AMD_PSTATE_UT_RESULT_PASS; + + return 0; } static int __init amd_pstate_ut_init(void) @@ -296,16 +267,12 @@ static int __init amd_pstate_ut_init(void) u32 i = 0, arr_size = ARRAY_SIZE(amd_pstate_ut_cases); for (i = 0; i < arr_size; i++) { - amd_pstate_ut_cases[i].func(i); - switch (amd_pstate_ut_cases[i].result) { - case AMD_PSTATE_UT_RESULT_PASS: + int ret = amd_pstate_ut_cases[i].func(i); + + if (ret) + pr_err("%-4d %-20s\t fail: %d!\n", i+1, amd_pstate_ut_cases[i].name, ret); + else pr_info("%-4d %-20s\t success!\n", i+1, amd_pstate_ut_cases[i].name); - break; - case AMD_PSTATE_UT_RESULT_FAIL: - default: - pr_info("%-4d %-20s\t fail!\n", i+1, amd_pstate_ut_cases[i].name); - break; - } } return 0; From patchwork Wed Feb 26 07:49:26 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mario Limonciello X-Patchwork-Id: 868846 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 636CE27426A; Wed, 26 Feb 2025 07:49:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740556197; cv=none; b=rL9CGME85apqfLsgGXXxrVS5+x0FvK3eggkGURcXZue6IPzJ4boi+DOm7DONc014QQTwxXm5JKZm8/Bv+iKsFOC7Vi0b0eRH/JdZGbrXIbscu7A8I7UmmrcSu4ubCXtijguY1TEOJEMu83R/S5FMeY54Vzny4mh811QnXdGV9Co= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740556197; c=relaxed/simple; bh=Ny+mf6wTXBWd26jscZCcfKEiG9iktam74gC2s8tYJNE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WeTYu+52ITzvtwkTnp3y6ykzrGmPb6LSp4+4WMMTktKDFc1dXeGkBAI5UFtnUoGY335/5CDENmNUfhcBF1GwCR6keTBYxGGS0Hlr+USRKhm7zUsQJcyiHcnOsfFic7XSJickTEfIdzKSs/NTlm7198Sp7cGfYVNcwaGqBsI3gmE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=oxlAEZgx; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="oxlAEZgx" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 38273C4CED6; Wed, 26 Feb 2025 07:49:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1740556197; bh=Ny+mf6wTXBWd26jscZCcfKEiG9iktam74gC2s8tYJNE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oxlAEZgxQ0J0A5gI3SDhoy/+gtYrZK85pRYTbN6XAOsD+lwRoaVNBnxSHhCTG3/CM ym9Q5zD1uaVro05T+/pqd0kliEmyNdVsvr8fp63S7ZhiW61EIlOD8+7XLZSMCkXD8/ 42FD0Sw7pGkeg4mPxJWouN+pMmAoawTtPnP4usQezZlSGMglD2zQVfS4NCpI+oBkh4 jQy7XzJu5fJEtKfQfqKltR+VP8O3OmCdVrn3ME/MNMJm22j9pladiPJ0RwC9zO0vQX 1v5BqI3tB9JxNbzzxr5jpSGtQbZXnMB0BQyLStiUsUcfm6D5mN1F26PNjhUqfNU1h+ uj67B79Frk9JQ== From: Mario Limonciello To: "Gautham R . Shenoy" , Perry Yuan Cc: Dhananjay Ugwekar , linux-kernel@vger.kernel.org (open list:X86 ARCHITECTURE (32-BIT AND 64-BIT)), linux-pm@vger.kernel.org (open list:CPU FREQUENCY SCALING FRAMEWORK), Mario Limonciello , Dhananjay Ugwekar Subject: [PATCH v5 11/19] cpufreq/amd-pstate-ut: Adjust variable scope Date: Wed, 26 Feb 2025 01:49:26 -0600 Message-ID: <20250226074934.1667721-12-superm1@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250226074934.1667721-1-superm1@kernel.org> References: <20250226074934.1667721-1-superm1@kernel.org> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Mario Limonciello In amd_pstate_ut_check_freq() and amd_pstate_ut_check_perf() the cpudata variable is only needed in the scope of the for loop. Move it there. Reviewed-by: Gautham R. Shenoy Reviewed-by: Dhananjay Ugwekar Signed-off-by: Mario Limonciello --- v5: * Apply to amd_pstate_ut_check_perf() too * Add tag --- drivers/cpufreq/amd-pstate-ut.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/amd-pstate-ut.c b/drivers/cpufreq/amd-pstate-ut.c index 2ab3017d7a0bb..edc1475989e3d 100644 --- a/drivers/cpufreq/amd-pstate-ut.c +++ b/drivers/cpufreq/amd-pstate-ut.c @@ -113,11 +113,11 @@ static int amd_pstate_ut_check_perf(u32 index) u32 highest_perf = 0, nominal_perf = 0, lowest_nonlinear_perf = 0, lowest_perf = 0; u64 cap1 = 0; struct cppc_perf_caps cppc_perf; - struct amd_cpudata *cpudata = NULL; union perf_cached cur_perf; for_each_online_cpu(cpu) { struct cpufreq_policy *policy __free(put_cpufreq_policy) = NULL; + struct amd_cpudata *cpudata; policy = cpufreq_cpu_get(cpu); if (!policy) @@ -186,10 +186,10 @@ static int amd_pstate_ut_check_perf(u32 index) static int amd_pstate_ut_check_freq(u32 index) { int cpu = 0; - struct amd_cpudata *cpudata = NULL; for_each_online_cpu(cpu) { struct cpufreq_policy *policy __free(put_cpufreq_policy) = NULL; + struct amd_cpudata *cpudata; policy = cpufreq_cpu_get(cpu); if (!policy) From patchwork Wed Feb 26 07:49:28 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mario Limonciello X-Patchwork-Id: 868845 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8CCA227426A; Wed, 26 Feb 2025 07:50:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740556200; cv=none; b=irWJEqsd7IDXFIc+FGxvATbeVDIrnNExo07gwG2yx0a4l32Bg9U2RD/dKQuYI0lz/wtDnB07qQG2YJV/5uEsJALPs/B49My7Mvnhlfzdo0k+R8Nsh3ZwvMlgsNATIyvEf4z9XutnYF4rC3bWMyezwTjrPDXa1zTsaOy7Gg45Lgg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740556200; c=relaxed/simple; bh=rU//cHwKIhLi6KZBHAg93+4ucs5Sgd4xwHdvD2vWArk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uGLb+oAnCKBTlIMxWLL88kf5vwm2G9IBFFVgACM+NJgkaedBvF6AsNmDM8NpBWxYEznMZQTzlnd2mwtBoOKa84fypKAQjf439s0erUt0X5ZsWgbM0dTQLeKd3Ur2iow6rb/k/ICCQ2IVTGX0tU0JtBdDCyhHjYOYWqiHTHsWFsk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=tS0zs3ud; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="tS0zs3ud" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 02DD0C4CEE7; Wed, 26 Feb 2025 07:49:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1740556200; bh=rU//cHwKIhLi6KZBHAg93+4ucs5Sgd4xwHdvD2vWArk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tS0zs3ud6xw7wny9/SBrsrVUyVyVHsZhMS9SLzBpGXpNzANNfpY2Te6RZHBU6XUVS 5s7X134UoMWjA5WQ1mczNMnDVZbLV1zjE26olhMfP5qEEHShEJsocXiKrYLPC+DynD GCbaPgdQTnG9bd5LH16XIY3fPv62oPNOVYqtYkz75zguazACFB98U8dxzTD58jLR+I qKr3+uCLkjvjNBCyCZYOHrp8JG+peg/q8JVMb1QZu+0cmhXlCaUCZ7AHKqFuhYMpcy uJRtw0v/nN4qKl8j83bllAnb6M66xj6030p5rUkK6OlzVFFBL6tQb4OrjOCFDX1ukU K1YUW2/rK/SQw== From: Mario Limonciello To: "Gautham R . Shenoy" , Perry Yuan Cc: Dhananjay Ugwekar , linux-kernel@vger.kernel.org (open list:X86 ARCHITECTURE (32-BIT AND 64-BIT)), linux-pm@vger.kernel.org (open list:CPU FREQUENCY SCALING FRAMEWORK), Mario Limonciello , Dhananjay Ugwekar Subject: [PATCH v5 13/19] cpufreq/amd-pstate: Cache CPPC request in shared mem case too Date: Wed, 26 Feb 2025 01:49:28 -0600 Message-ID: <20250226074934.1667721-14-superm1@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250226074934.1667721-1-superm1@kernel.org> References: <20250226074934.1667721-1-superm1@kernel.org> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Mario Limonciello In order to prevent a potential write for shmem_update_perf() cache the request into the cppc_req_cached variable normally only used for the MSR case. This adds symmetry into the code and potentially avoids extra writes. Reviewed-by: Dhananjay Ugwekar Reviewed-by: Gautham R. Shenoy Signed-off-by: Mario Limonciello --- drivers/cpufreq/amd-pstate.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index c2260bbee4eb7..0c686af5e062d 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -496,6 +496,8 @@ static int shmem_update_perf(struct amd_cpudata *cpudata, u8 min_perf, u8 des_perf, u8 max_perf, u8 epp, bool fast_switch) { struct cppc_perf_ctrls perf_ctrls; + u64 value, prev; + int ret; if (cppc_state == AMD_PSTATE_ACTIVE) { int ret = shmem_set_epp(cpudata, epp); @@ -504,11 +506,29 @@ static int shmem_update_perf(struct amd_cpudata *cpudata, u8 min_perf, return ret; } + value = prev = READ_ONCE(cpudata->cppc_req_cached); + + value &= ~(AMD_CPPC_MAX_PERF_MASK | AMD_CPPC_MIN_PERF_MASK | + AMD_CPPC_DES_PERF_MASK | AMD_CPPC_EPP_PERF_MASK); + value |= FIELD_PREP(AMD_CPPC_MAX_PERF_MASK, max_perf); + value |= FIELD_PREP(AMD_CPPC_DES_PERF_MASK, des_perf); + value |= FIELD_PREP(AMD_CPPC_MIN_PERF_MASK, min_perf); + value |= FIELD_PREP(AMD_CPPC_EPP_PERF_MASK, epp); + + if (value == prev) + return 0; + perf_ctrls.max_perf = max_perf; perf_ctrls.min_perf = min_perf; perf_ctrls.desired_perf = des_perf; - return cppc_set_perf(cpudata->cpu, &perf_ctrls); + ret = cppc_set_perf(cpudata->cpu, &perf_ctrls); + if (ret) + return ret; + + WRITE_ONCE(cpudata->cppc_req_cached, value); + + return 0; } static inline bool amd_pstate_sample(struct amd_cpudata *cpudata) From patchwork Wed Feb 26 07:49:30 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mario Limonciello X-Patchwork-Id: 868844 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 55DFB280A5F; Wed, 26 Feb 2025 07:50:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740556203; cv=none; b=uuPZCiZjBDwTihnmqlab9sYM3Asgoo6xitRneV9eQYPxDZrgIZLuD/9YZZSh1z1vawGx66fzSZ/b8LNzCavT5bMmWlGiy9tbD4ZEOouNT4gEz8I4saky3QNAr0/MHgSXS5iTITQv1lqJP9zGYTYFkrDObkB+Z9w2sHWqf5wOK5Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740556203; c=relaxed/simple; bh=lvNlhg8ZQGFHcYmuoWOZ6HwRqxeR0QKm+GESmZ3ZXpE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Ht1ZcoVwjPOKC2ZP6Rj5dRCszaOAI2zfY7FGRUnNACVurD9a6KInLgzFnyLRnp8Eavj/hfG4GbG/PQJFDBYdzjaP6Hj8iL5gQ6CLPybazQXYD7dRjoAkpWvINVScSE5WDq/EqdYu1r9WwZYHagtT0G7x0h24zbKTDtslwYsQ5ko= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gct4VRQv; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="gct4VRQv" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C0DB4C4CED6; Wed, 26 Feb 2025 07:50:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1740556202; bh=lvNlhg8ZQGFHcYmuoWOZ6HwRqxeR0QKm+GESmZ3ZXpE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gct4VRQvPVCltKkLmjYChOt093JLrbochGFkCh20Lb4YkcGUu5vgbwwZQKpRvukkF ok11NPnD8CdWu2Ae/ap4blzlRRP3Zz5UoHAiahGk7Ki6YH7e5yNtl3wMy31IZMqNc7 nzS9QbPcQInT0q+sTdF5rYw63GeCp2iFx9ay//7Ox36kYq/PyRaWgki3GJav6LxS4Y JUTATrB9pi+bqsGBi8znpd4K1vEFZ3mZ50t/E/4JaMTKkNkrS+HdzYVsx97LAnF7FD KrKpHsyFG95Duz87YT7kIYLad2oqkr8yAAWzirMinABPUmdU1JY6wkgesPj/eBKgW7 k5JGwX6Eh9PNg== From: Mario Limonciello To: "Gautham R . Shenoy" , Perry Yuan Cc: Dhananjay Ugwekar , linux-kernel@vger.kernel.org (open list:X86 ARCHITECTURE (32-BIT AND 64-BIT)), linux-pm@vger.kernel.org (open list:CPU FREQUENCY SCALING FRAMEWORK), Mario Limonciello , Dhananjay Ugwekar Subject: [PATCH v5 15/19] cpufreq/amd-pstate: Update cppc_req_cached for shared mem EPP writes Date: Wed, 26 Feb 2025 01:49:30 -0600 Message-ID: <20250226074934.1667721-16-superm1@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250226074934.1667721-1-superm1@kernel.org> References: <20250226074934.1667721-1-superm1@kernel.org> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Mario Limonciello On EPP only writes update the cached variable so that the min/max performance controls don't need to be updated again. Reviewed-by: Dhananjay Ugwekar Reviewed-by: Gautham R. Shenoy Signed-off-by: Mario Limonciello --- drivers/cpufreq/amd-pstate.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index 66b61ce124e21..55b6231e6a092 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -336,6 +336,7 @@ static int shmem_set_epp(struct cpufreq_policy *policy, u8 epp) { struct amd_cpudata *cpudata = policy->driver_data; struct cppc_perf_ctrls perf_ctrls; + u64 value; int ret; if (trace_amd_pstate_epp_perf_enabled()) { @@ -362,6 +363,11 @@ static int shmem_set_epp(struct cpufreq_policy *policy, u8 epp) } WRITE_ONCE(cpudata->epp_cached, epp); + value = READ_ONCE(cpudata->cppc_req_cached); + value &= ~AMD_CPPC_EPP_PERF_MASK; + value |= FIELD_PREP(AMD_CPPC_EPP_PERF_MASK, epp); + WRITE_ONCE(cpudata->cppc_req_cached, value); + return ret; } From patchwork Wed Feb 26 07:49:32 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mario Limonciello X-Patchwork-Id: 868843 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A61DF26E622; Wed, 26 Feb 2025 07:50:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740556205; cv=none; b=tLlwsICzKBbkm0btnp7yCFSHNcDTcuX7qW3i6KHShWFCIS04jZrwMJm44AxPdX7EbcDqqD2yZtTi/UO2PdDMzQTXOkpyMx74FwOeOpOKl7pOJsuuGpZslzHINU/b0L34az2nwbqL5k058lONoknQNnRQ6P6+PHi7JDxcnlLRVsA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740556205; c=relaxed/simple; bh=hSoP8YKlBzaIWPk988HCBosOMTnwKrYcedoh3R7B29Q=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=i5QfIkCKRqSeb4mR12Lpz5JhbbKBES+w48Q8lo9Aqazc2nYJ1VG6ytNNCBrShCi8GEJDZ+UTXkD+i9O+T2X2vgfIKrzBiv++wdfpQ7WTGSv4nx39cBBmbiw0VcHtiKle/kndHJ3MDCbx+LxlFBmeMaP0NcqMYwfFaxxj/DdD4T0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=nwISdukQ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="nwISdukQ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8CD65C4CED6; Wed, 26 Feb 2025 07:50:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1740556205; bh=hSoP8YKlBzaIWPk988HCBosOMTnwKrYcedoh3R7B29Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nwISdukQHivbvzA07w5y9agjyIxXf5opWOjNN3EFspMKeFIqLQ/dC3UbfcTXh4ne8 o5uFgA74CKkHhm4mhufOihwS5jzwwJbOuEzXhCaR69eVikugTAU9ZfwQCSLKoZr31O gICeux56GQV2C/TJp0NZWZ9R54COvlGy0SLGxG79hC+HoFAYvt663wcEGRo39POCBi R1QsrPH2Tzz5RO7cdMxO2QShrosoF9B4BVVwnS0XqfL9tPYcIA6mEd2BuA/PYyGTV2 4oSTszHlGknRvvM1KjTaXlBw/AO+C2OtUxyzOHdUU1sQ+XAIX7v8O5VbCGRFGtybXB qR9ScWagIzY8g== From: Mario Limonciello To: "Gautham R . Shenoy" , Perry Yuan Cc: Dhananjay Ugwekar , linux-kernel@vger.kernel.org (open list:X86 ARCHITECTURE (32-BIT AND 64-BIT)), linux-pm@vger.kernel.org (open list:CPU FREQUENCY SCALING FRAMEWORK), Mario Limonciello Subject: [PATCH v5 17/19] cpufreq/amd-pstate: Rework CPPC enabling Date: Wed, 26 Feb 2025 01:49:32 -0600 Message-ID: <20250226074934.1667721-18-superm1@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250226074934.1667721-1-superm1@kernel.org> References: <20250226074934.1667721-1-superm1@kernel.org> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Mario Limonciello The CPPC enable register is configured as "write once". That is any future writes don't actually do anything. Because of this, all the cleanup paths that currently exist for CPPC disable are non-effective. Rework CPPC enable to only enable after all the CAP registers have been read to avoid enabling CPPC on CPUs with invalid _CPC or unpopulated MSRs. As the register is write once, remove all cleanup paths as well. Signed-off-by: Mario Limonciello --- v5: * Drop unnecessary extra code in shmem_cppc_enable() * Remove redundant tracing in store_energy_performance_preference() * Add missing call to amd_pstate_cppc_enable() in passive case * Leave cpudata->suspended alone in amd_pstate_epp_cpu_online() * Drop spurious whitespace v4: * Remove unnecessary amd_pstate_update_perf() call during online * Remove unnecessary if (ret) ret. * Drop amd_pstate_cpu_resume() * Drop unnecessary derefs v3: * Fixup for suspend/resume issue --- drivers/cpufreq/amd-pstate.c | 179 +++++++---------------------------- 1 file changed, 35 insertions(+), 144 deletions(-) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index f0d9ee62cb30d..89e6d32223c9b 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -85,7 +85,6 @@ static struct cpufreq_driver *current_pstate_driver; static struct cpufreq_driver amd_pstate_driver; static struct cpufreq_driver amd_pstate_epp_driver; static int cppc_state = AMD_PSTATE_UNDEFINED; -static bool cppc_enabled; static bool amd_pstate_prefcore = true; static struct quirk_entry *quirks; @@ -371,89 +370,21 @@ static int shmem_set_epp(struct cpufreq_policy *policy, u8 epp) return ret; } -static int amd_pstate_set_energy_pref_index(struct cpufreq_policy *policy, - int pref_index) +static inline int msr_cppc_enable(struct cpufreq_policy *policy) { - struct amd_cpudata *cpudata = policy->driver_data; - u8 epp; - - if (!pref_index) - epp = cpudata->epp_default; - else - epp = epp_values[pref_index]; - - if (epp > 0 && cpudata->policy == CPUFREQ_POLICY_PERFORMANCE) { - pr_debug("EPP cannot be set under performance policy\n"); - return -EBUSY; - } - - return amd_pstate_set_epp(policy, epp); -} - -static inline int msr_cppc_enable(bool enable) -{ - int ret, cpu; - unsigned long logical_proc_id_mask = 0; - - /* - * MSR_AMD_CPPC_ENABLE is write-once, once set it cannot be cleared. - */ - if (!enable) - return 0; - - if (enable == cppc_enabled) - return 0; - - for_each_present_cpu(cpu) { - unsigned long logical_id = topology_logical_package_id(cpu); - - if (test_bit(logical_id, &logical_proc_id_mask)) - continue; - - set_bit(logical_id, &logical_proc_id_mask); - - ret = wrmsrl_safe_on_cpu(cpu, MSR_AMD_CPPC_ENABLE, - enable); - if (ret) - return ret; - } - - cppc_enabled = enable; - return 0; + return wrmsrl_safe_on_cpu(policy->cpu, MSR_AMD_CPPC_ENABLE, 1); } -static int shmem_cppc_enable(bool enable) +static int shmem_cppc_enable(struct cpufreq_policy *policy) { - int cpu, ret = 0; - struct cppc_perf_ctrls perf_ctrls; - - if (enable == cppc_enabled) - return 0; - - for_each_present_cpu(cpu) { - ret = cppc_set_enable(cpu, enable); - if (ret) - return ret; - - /* Enable autonomous mode for EPP */ - if (cppc_state == AMD_PSTATE_ACTIVE) { - /* Set desired perf as zero to allow EPP firmware control */ - perf_ctrls.desired_perf = 0; - ret = cppc_set_perf(cpu, &perf_ctrls); - if (ret) - return ret; - } - } - - cppc_enabled = enable; - return ret; + return cppc_set_enable(policy->cpu, 1); } DEFINE_STATIC_CALL(amd_pstate_cppc_enable, msr_cppc_enable); -static inline int amd_pstate_cppc_enable(bool enable) +static inline int amd_pstate_cppc_enable(struct cpufreq_policy *policy) { - return static_call(amd_pstate_cppc_enable)(enable); + return static_call(amd_pstate_cppc_enable)(policy); } static int msr_init_perf(struct amd_cpudata *cpudata) @@ -1069,6 +1000,10 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy) cpudata->nominal_freq, perf.highest_perf); + ret = amd_pstate_cppc_enable(policy); + if (ret) + goto free_cpudata1; + policy->boost_enabled = READ_ONCE(cpudata->boost_supported); /* It will be updated by governor */ @@ -1116,28 +1051,6 @@ static void amd_pstate_cpu_exit(struct cpufreq_policy *policy) kfree(cpudata); } -static int amd_pstate_cpu_resume(struct cpufreq_policy *policy) -{ - int ret; - - ret = amd_pstate_cppc_enable(true); - if (ret) - pr_err("failed to enable amd-pstate during resume, return %d\n", ret); - - return ret; -} - -static int amd_pstate_cpu_suspend(struct cpufreq_policy *policy) -{ - int ret; - - ret = amd_pstate_cppc_enable(false); - if (ret) - pr_err("failed to disable amd-pstate during suspend, return %d\n", ret); - - return ret; -} - /* Sysfs attributes */ /* @@ -1229,8 +1142,10 @@ static ssize_t show_energy_performance_available_preferences( static ssize_t store_energy_performance_preference( struct cpufreq_policy *policy, const char *buf, size_t count) { + struct amd_cpudata *cpudata = policy->driver_data; char str_preference[21]; ssize_t ret; + u8 epp; ret = sscanf(buf, "%20s", str_preference); if (ret != 1) @@ -1240,7 +1155,17 @@ static ssize_t store_energy_performance_preference( if (ret < 0) return -EINVAL; - ret = amd_pstate_set_energy_pref_index(policy, ret); + if (!ret) + epp = cpudata->epp_default; + else + epp = epp_values[ret]; + + if (epp > 0 && policy->policy == CPUFREQ_POLICY_PERFORMANCE) { + pr_debug("EPP cannot be set under performance policy\n"); + return -EBUSY; + } + + ret = amd_pstate_set_epp(policy, epp); return ret ? ret : count; } @@ -1273,7 +1198,6 @@ static ssize_t show_energy_performance_preference( static void amd_pstate_driver_cleanup(void) { - amd_pstate_cppc_enable(false); cppc_state = AMD_PSTATE_DISABLE; current_pstate_driver = NULL; } @@ -1307,14 +1231,6 @@ static int amd_pstate_register_driver(int mode) cppc_state = mode; - ret = amd_pstate_cppc_enable(true); - if (ret) { - pr_err("failed to enable cppc during amd-pstate driver registration, return %d\n", - ret); - amd_pstate_driver_cleanup(); - return ret; - } - /* at least one CPU supports CPB */ current_pstate_driver->boost_enabled = cpu_feature_enabled(X86_FEATURE_CPB); @@ -1554,11 +1470,15 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy) policy->cpuinfo.max_freq = policy->max = perf_to_freq(perf, cpudata->nominal_freq, perf.highest_perf); + policy->driver_data = cpudata; + + ret = amd_pstate_cppc_enable(policy); + if (ret) + goto free_cpudata1; /* It will be updated by governor */ policy->cur = policy->cpuinfo.min_freq; - policy->driver_data = cpudata; policy->boost_enabled = READ_ONCE(cpudata->boost_supported); @@ -1650,31 +1570,11 @@ static int amd_pstate_epp_set_policy(struct cpufreq_policy *policy) return 0; } -static int amd_pstate_epp_reenable(struct cpufreq_policy *policy) -{ - int ret; - - ret = amd_pstate_cppc_enable(true); - if (ret) - pr_err("failed to enable amd pstate during resume, return %d\n", ret); - - - return amd_pstate_epp_update_limit(policy); -} - static int amd_pstate_epp_cpu_online(struct cpufreq_policy *policy) { - struct amd_cpudata *cpudata = policy->driver_data; - int ret; - - pr_debug("AMD CPU Core %d going online\n", cpudata->cpu); + pr_debug("AMD CPU Core %d going online\n", policy->cpu); - ret = amd_pstate_epp_reenable(policy); - if (ret) - return ret; - cpudata->suspended = false; - - return 0; + return amd_pstate_cppc_enable(policy); } static int amd_pstate_epp_cpu_offline(struct cpufreq_policy *policy) @@ -1692,11 +1592,6 @@ static int amd_pstate_epp_cpu_offline(struct cpufreq_policy *policy) static int amd_pstate_epp_suspend(struct cpufreq_policy *policy) { struct amd_cpudata *cpudata = policy->driver_data; - int ret; - - /* avoid suspending when EPP is not enabled */ - if (cppc_state != AMD_PSTATE_ACTIVE) - return 0; /* invalidate to ensure it's rewritten during resume */ cpudata->cppc_req_cached = 0; @@ -1704,11 +1599,6 @@ static int amd_pstate_epp_suspend(struct cpufreq_policy *policy) /* set this flag to avoid setting core offline*/ cpudata->suspended = true; - /* disable CPPC in lowlevel firmware */ - ret = amd_pstate_cppc_enable(false); - if (ret) - pr_err("failed to suspend, return %d\n", ret); - return 0; } @@ -1717,8 +1607,12 @@ static int amd_pstate_epp_resume(struct cpufreq_policy *policy) struct amd_cpudata *cpudata = policy->driver_data; if (cpudata->suspended) { + int ret; + /* enable amd pstate from suspend state*/ - amd_pstate_epp_reenable(policy); + ret = amd_pstate_epp_update_limit(policy); + if (ret) + return ret; cpudata->suspended = false; } @@ -1733,8 +1627,6 @@ static struct cpufreq_driver amd_pstate_driver = { .fast_switch = amd_pstate_fast_switch, .init = amd_pstate_cpu_init, .exit = amd_pstate_cpu_exit, - .suspend = amd_pstate_cpu_suspend, - .resume = amd_pstate_cpu_resume, .set_boost = amd_pstate_set_boost, .update_limits = amd_pstate_update_limits, .name = "amd-pstate", @@ -1901,7 +1793,6 @@ static int __init amd_pstate_init(void) global_attr_free: cpufreq_unregister_driver(current_pstate_driver); - amd_pstate_cppc_enable(false); return ret; } device_initcall(amd_pstate_init); From patchwork Wed Feb 26 07:49:34 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mario Limonciello X-Patchwork-Id: 868842 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CE3E022422C; Wed, 26 Feb 2025 07:50:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740556208; cv=none; b=kDY6YOuLypIWnMfQJAwELB3Sb5hB0LggBIob9PGCHxSt9qH/BrPYpdyQbHp1YudURMCW66v6crDejdIUsi7rSVMATlJc7e6MKp7GURbfSih+ahx5gBhjZrb1VIKLx3Y5k/SeVkNh7yEHGkzgJDU5iKbfJxdnwr8I1YW1oMb24KE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740556208; c=relaxed/simple; bh=wy2qW87sv3CHOyK6U2e65npVmbKA0sNrgjJ+lZsr8Zg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ErmwBFpm08tZysovKX8dME3WQNFm6bTpYb5xqFiTZe/xzM51vDmbeKLYuvDumJJdaJ3QlTQAcUm5P9V5NmOjM5Uub0UTw8UYyqfKT1DkzPHcMPswRF/Ahnf0ZRFJUmRI52MB5JHMBtMSWQFtdozMiJp2Vg2NIXw8dfSrE9pX/80= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=TuJUCmBz; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="TuJUCmBz" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 47ABBC4CEE9; Wed, 26 Feb 2025 07:50:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1740556208; bh=wy2qW87sv3CHOyK6U2e65npVmbKA0sNrgjJ+lZsr8Zg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TuJUCmBzbN8UUQsXAEoah0Gyxhfyuao4yhEyHftpbZ+jVXyK32YpEMsE/g5z0GvRa yNzVLSUECefqJKID8TXckU5PQcjlyAlyH+0hri0wf4NJtNE5/yVKUnpC3mnHGOefbb uh0SGkhX/1s3AvgsvBTZD2rd1CtjESSkPWwHZ4n+hTnqu2KfXXelpMn6hKg1//+z8k b6RZle1ZXb7HHTa0ysOIfaejd4umXrIXsa/SMsZ/xSJPQdrq1FFJfG7KK5EGYn+ewp h42WwCCNYMrw1NvAVvplYma1o0cxd3qEA+i174RAw4McMBt1mmwDQHorKhv9LGbdPR qLaer6TO5ik3Q== From: Mario Limonciello To: "Gautham R . Shenoy" , Perry Yuan Cc: Dhananjay Ugwekar , linux-kernel@vger.kernel.org (open list:X86 ARCHITECTURE (32-BIT AND 64-BIT)), linux-pm@vger.kernel.org (open list:CPU FREQUENCY SCALING FRAMEWORK), Mario Limonciello , Dhananjay Ugwekar Subject: [PATCH v5 19/19] cpufreq/amd-pstate: Drop actions in amd_pstate_epp_cpu_offline() Date: Wed, 26 Feb 2025 01:49:34 -0600 Message-ID: <20250226074934.1667721-20-superm1@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250226074934.1667721-1-superm1@kernel.org> References: <20250226074934.1667721-1-superm1@kernel.org> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Mario Limonciello When the CPU goes offline there is no need to change the CPPC request because the CPU will go into the deepest C-state it supports already. Actually changing the CPPC request when it goes offline messes up the cached values and can lead to the wrong values being restored when it comes back. Instead drop the actions and if the CPU comes back online let amd_pstate_epp_set_policy() restore it to expected values. Reviewed-by: Dhananjay Ugwekar Signed-off-by: Mario Limonciello --- v5: * Reword commit message * Add tag --- drivers/cpufreq/amd-pstate.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index 24a1f9e129b61..4a364ae9b56a1 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -1580,14 +1580,7 @@ static int amd_pstate_epp_cpu_online(struct cpufreq_policy *policy) static int amd_pstate_epp_cpu_offline(struct cpufreq_policy *policy) { - struct amd_cpudata *cpudata = policy->driver_data; - union perf_cached perf = READ_ONCE(cpudata->perf); - - if (cpudata->suspended) - return 0; - - return amd_pstate_update_perf(policy, perf.lowest_perf, 0, perf.lowest_perf, - AMD_CPPC_EPP_BALANCE_POWERSAVE, false); + return 0; } static int amd_pstate_epp_suspend(struct cpufreq_policy *policy)