On Thu, Mar 27, 2025 at 4:22 AM Feng, Kenneth <kenneth.f...@amd.com> wrote: > > [AMD Official Use Only - AMD Internal Distribution Only] > > -----Original Message----- > From: Alex Deucher <alexdeuc...@gmail.com> > Sent: Wednesday, March 26, 2025 11:08 PM > To: Feng, Kenneth <kenneth.f...@amd.com> > Cc: amd-gfx@lists.freedesktop.org; Wang, Yang(Kevin) > <kevinyang.w...@amd.com>; Deucher, Alexander <alexander.deuc...@amd.com>; > Wentland, Harry <harry.wentl...@amd.com> > Subject: Re: [PATCH] drm/amd/display: port the workload profile setting logic > into dm > > Caution: This message originated from an External Source. Use proper caution > when opening attachments, clicking links, or responding. > > > On Wed, Mar 26, 2025 at 1:22 AM Kenneth Feng <kenneth.f...@amd.com> wrote: > > > > Port the workload profile setting logic into dm before MALL optimization. > > > > Background: > > MALL optimization strategy has changed in the firmware.Previously, > > firmware does not care what workload type it is, once there is a > > request from DAL for MALL, firmware immediately trigger the MALL setting > > sequence on the SoC, so called D0i3.x idle power sequence. > > Now, before the D0i3.x sequence starts, firmware always check if the > > workload type is default, if it is not, then abort the D0i3.x sequence. > > > > Issue: > > Due to this strategy change, the task is moved to driver to make sure > > if gfx is really idle and if it is, reset the workload to default. > > Without this task, when DAL's work task for MALL optimization tries to > > do the optimization request to DMCUB->pmfw, the workload type is always 3D > > fullscreen or compute, then MALL will never be applied. > > > > Why: > > The idle task for setting workload type back to default interval is 1 > > second currently. The DAL's work task to optimize MALL always starts > > before the idle task for setting workload type back to default. There > > is no way to ask the idle task in the base driver to reset the > > workload type ahead of the DAL's MALL setting work task kicks off. There > > could be a workaround which sets the idle task interval to 10 millisecond. > > However, this causes some call trace issues in which the workqueues is > > flushed. > > That should already fixed by this commit: > https://web.git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=de35994ecd2dd6148ab5a6c5050a1670a04dec77 > > > > > Side effect: > > This solution is to port the logic in idle thread to DAL: check the > > fence and make sure gfx is idle, then reset the workload type. It is > > fine that when DAL's work task exits the MALL optimization, it does not set > > back the workload type to 3d fullscreen or compute since the work task in > > base driver can make sure the workload type can be set back once there are > > jobs in the ring. > > I guess this works because the workload ref count gets clamped to 0, but this > call is not balanced. It also doesn't handle the VIDEO profile that gets set > when using VCN or the COMPUTE profile when KFD queues are active. Those > would also prevent the idle optimizations. > Also what happens if the profile changes after DC optimizations are enabled? > Does that cause the optimizations to exit or will they stay intact until DC > tells it to exit? > > So I think we have two options: > 1. always disable the 3D, compute, video profiles when entering the DAL > optimization. subsequently, additional job submissions may change the > workload. will that be a problem? > 2. Add a helper to pause workload profiles while the DC optimization is > active. If the profile only has to be changed while enabling the DC > optimization, we can just call it right before and right after the dc > optimizations. Something like the attached patches should be a good starting > point. > > Alex > > Hi Alex, > In the attached patch, I guess smu->pause_workload is not needed since > workload can be switched after idle optimization is triggered. And > smu_pause_power_profile may not need the bool flag since I still think that > we don't need to take care of the imbalance of workload setting. > That is said, we just need to set the workload to default when idle > optimization is requested. When the idle optimization is cancelled from DAL, > it doesn't need to restore the previous workload setting since the ring work > will set it. > Attached is my patch. It works on my system. Let me know your thoughts.
This will race with any command submissions unless you add a lock. I think you want something like: /* switch to the bootup default profile */ amdgpu_dpm_pause_power_profile(adev, true); dc_allow_idle_optimizations(dm->dc, true); /* resume existing profiles */ amdgpu_dpm_pause_power_profile(adev, false); Alex > Thanks. > > Kenneth > > > > > Signed-off-by: Kenneth Feng <kenneth.f...@amd.com> > > --- > > .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c | 29 ++++++++++++++++++- > > 1 file changed, 28 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c > > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c > > index 36a830a7440f..2adb3b72ed05 100644 > > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c > > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c > > @@ -244,6 +244,20 @@ static void > > amdgpu_dm_crtc_vblank_control_worker(struct work_struct *work) > > struct vblank_control_work *vblank_work = > > container_of(work, struct vblank_control_work, work); > > struct amdgpu_display_manager *dm = vblank_work->dm; > > + u32 i, fences = 0; > > + int r; > > + enum PP_SMC_POWER_PROFILE profile; > > + struct amdgpu_device *adev = drm_to_adev(dm->ddev); > > + > > + if (adev->gfx.num_gfx_rings) > > + profile = PP_SMC_POWER_PROFILE_FULLSCREEN3D; > > + else > > + profile = PP_SMC_POWER_PROFILE_COMPUTE; > > + > > + for (i = 0; i < AMDGPU_MAX_GFX_RINGS; ++i) > > + fences += > > amdgpu_fence_count_emitted(&adev->gfx.gfx_ring[i]); > > + for (i = 0; i < (AMDGPU_MAX_COMPUTE_RINGS * > > AMDGPU_MAX_GC_INSTANCES); ++i) > > + fences += > > + amdgpu_fence_count_emitted(&adev->gfx.compute_ring[i]); > > > > mutex_lock(&dm->dc_lock); > > > > @@ -271,8 +285,21 @@ static void > > amdgpu_dm_crtc_vblank_control_worker(struct work_struct *work) > > vblank_work->acrtc->dm_irq_params.allow_sr_entry); > > } > > > > - if (dm->active_vblank_irq_count == 0) > > + if (dm->active_vblank_irq_count == 0) { > > + if (adev->gfx.num_gfx_rings && !fences && > > !atomic_read(&adev->gfx.total_submission_cnt)) { > > + mutex_lock(&adev->gfx.workload_profile_mutex); > > + if (adev->gfx.workload_profile_active) { > > + r = amdgpu_dpm_switch_power_profile(adev, > > profile, false); > > + if (r) > > + dev_warn(adev->dev, "(%d) failed to disable > > %s power profile mode\n", r, > > + > > profile == PP_SMC_POWER_PROFILE_FULLSCREEN3D ? > > + > > "fullscreen 3D" : "compute"); > > + adev->gfx.workload_profile_active = false; > > + } > > + mutex_unlock(&adev->gfx.workload_profile_mutex); > > + } > > dc_allow_idle_optimizations(dm->dc, true); > > + } > > > > mutex_unlock(&dm->dc_lock); > > > > -- > > 2.34.1 > >