mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +03:00
gpu: nvgpu: remove unnecessary devfreq limit checks
gk20a_scale_target is called through the target member of a devfreq_profile. It is only called from devfreqs update_devfreq function or through governor_passive. governor_passive is not used for nvgpu. Since update_devfreq already enforce the devfreq limits, gka20_scale_target can be simplified by only checking pm_qos limits and also only if GK20A_PM_QOS is enabled. This also resolves a race between creating devfreq sysfs files and setting 'l->devfreq' in gk20a_scale_init that can lead to accessing a NULL pointer by writing to the sysfs files. Example: Unable to handle kernel NULL pointer dereference at virtual address 00000430 <snip> Call trace: [<000000006aa50d89>] gk20a_scale_target+0x5c/0x120 [nvgpu] [<00000000e5a63f7c>] update_devfreq+0xec/0x22c [<0000000014a13c8a>] max_freq_store+0xa8/0xfc [<0000000072139393>] dev_attr_store+0x48/0x60 [<000000008ec280df>] sysfs_kf_write+0x60/0x70 [<0000000038427ed5>] kernfs_fop_write+0xc4/0x1e0 [<00000000c0b74aa9>] __vfs_write+0x60/0x14c [<0000000078fcebb4>] vfs_write+0xb0/0x1b4 [<000000007720da30>] SyS_write+0x74/0xf0 [<0000000067443e2c>] __sys_trace_return+0x0/0x4 Bug 3910155 Change-Id: I7193cc5ea85454acf0890b3ca8d1c3526ca8517e Signed-off-by: Ken Chang <kenc@nvidia.com> Signed-off-by: Sagar Kamble <skamble@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2828219 Reviewed-by: Rajesh Devaraj <rdevaraj@nvidia.com> Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
b432b5f41a
commit
49a6676ef6
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* gk20a clock scaling profile
|
* gk20a clock scaling profile
|
||||||
*
|
*
|
||||||
* Copyright (c) 2013-2020, NVIDIA Corporation. All rights reserved.
|
* Copyright (c) 2013-2023, NVIDIA Corporation. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -148,32 +148,24 @@ static int gk20a_scale_target(struct device *dev, unsigned long *freq,
|
|||||||
{
|
{
|
||||||
struct gk20a_platform *platform = dev_get_drvdata(dev);
|
struct gk20a_platform *platform = dev_get_drvdata(dev);
|
||||||
struct gk20a *g = platform->g;
|
struct gk20a *g = platform->g;
|
||||||
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
|
|
||||||
struct gk20a_scale_profile *profile = g->scale_profile;
|
struct gk20a_scale_profile *profile = g->scale_profile;
|
||||||
struct devfreq *devfreq = l->devfreq;
|
|
||||||
unsigned long local_freq = *freq;
|
unsigned long local_freq = *freq;
|
||||||
unsigned long rounded_rate;
|
unsigned long rounded_rate;
|
||||||
|
#ifdef CONFIG_GK20A_PM_QOS
|
||||||
unsigned long min_freq = 0, max_freq = 0;
|
unsigned long min_freq = 0, max_freq = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (nvgpu_clk_arb_has_active_req(g))
|
if (nvgpu_clk_arb_has_active_req(g))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
#ifdef CONFIG_GK20A_PM_QOS
|
||||||
/*
|
/*
|
||||||
* Calculate floor and cap frequency values
|
* devfreq takes care of min/max freq clipping in update_devfreq() then
|
||||||
*
|
* invoked devfreq->profile->target(), thus we only need to do freq
|
||||||
* Policy :
|
* clipping based on pm_qos constraint
|
||||||
* We have two APIs to clip the frequency
|
|
||||||
* 1. devfreq
|
|
||||||
* 2. pm_qos
|
|
||||||
*
|
|
||||||
* To calculate floor (min) freq, we select MAX of floor frequencies
|
|
||||||
* requested from both APIs
|
|
||||||
* To get cap (max) freq, we select MIN of max frequencies
|
|
||||||
*
|
|
||||||
* In case we have conflict (min_freq > max_freq) after above
|
|
||||||
* steps, we ensure that max_freq wins over min_freq
|
|
||||||
*/
|
*/
|
||||||
min_freq = max_t(u32, devfreq->min_freq, profile->qos_min_freq);
|
min_freq = profile->qos_min_freq;
|
||||||
max_freq = min_t(u32, devfreq->max_freq, profile->qos_max_freq);
|
max_freq = profile->qos_max_freq;
|
||||||
|
|
||||||
if (min_freq > max_freq)
|
if (min_freq > max_freq)
|
||||||
min_freq = max_freq;
|
min_freq = max_freq;
|
||||||
@@ -184,6 +176,7 @@ static int gk20a_scale_target(struct device *dev, unsigned long *freq,
|
|||||||
|
|
||||||
if (local_freq > max_freq)
|
if (local_freq > max_freq)
|
||||||
local_freq = max_freq;
|
local_freq = max_freq;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* set the final frequency */
|
/* set the final frequency */
|
||||||
rounded_rate = platform->clk_round_rate(dev, local_freq);
|
rounded_rate = platform->clk_round_rate(dev, local_freq);
|
||||||
|
|||||||
Reference in New Issue
Block a user