[PATCH v2 2/4] drm/amdgpu: Put enable gfx off feature to a delay thread
Felix Kuehling
felix.kuehling at amd.com
Mon Jul 30 19:33:47 UTC 2018
NACK.
See inline ...
On 2018-07-30 05:23 AM, Rex Zhu wrote:
> delay to enable gfx off feature to avoid gfx on/off frequently
> suggested by Alex and Evan.
>
> Signed-off-by: Rex Zhu <Rex.Zhu at amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 ++
> drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 15 +++++++++++++++
> drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 8 ++++++--
> 3 files changed, 23 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 188bc53..ff16689 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -992,6 +992,8 @@ struct amdgpu_gfx {
> bool gfx_off_state; /* true: enabled, false: disabled */
> struct mutex gfx_off_mutex;
> uint32_t gfx_off_req_count; /* default 1, enable gfx off: dec 1, disable gfx off: add 1 */
> + struct delayed_work gfx_off_delay_work;
> +
> /* pipe reservation */
> struct mutex pipe_reserve_mutex;
> DECLARE_BITMAP (pipe_reserve_bitmap, AMDGPU_MAX_COMPUTE_QUEUES);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index 122653f..f6a6fb5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -1925,6 +1925,19 @@ static void amdgpu_device_ip_late_init_func_handler(struct work_struct *work)
> DRM_ERROR("ib ring test failed (%d).\n", r);
> }
>
> +static void amdgpu_device_delay_enable_gfx_off(struct work_struct *work)
> +{
> + struct amdgpu_device *adev =
> + container_of(work, struct amdgpu_device, gfx.gfx_off_delay_work.work);
> +
> + mutex_lock(&adev->gfx.gfx_off_mutex);
> + if (!adev->gfx.gfx_off_state && !adev->gfx.gfx_off_req_count) {
> + if (!amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, true))
> + adev->gfx.gfx_off_state = true;
> + }
> + mutex_unlock(&adev->gfx.gfx_off_mutex);
> +}
> +
> /**
> * amdgpu_device_ip_suspend_phase1 - run suspend for hardware IPs (phase 1)
> *
> @@ -2394,6 +2407,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,
>
> INIT_DELAYED_WORK(&adev->late_init_work,
> amdgpu_device_ip_late_init_func_handler);
> + INIT_DELAYED_WORK(&adev->gfx.gfx_off_delay_work,
> + amdgpu_device_delay_enable_gfx_off);
>
> adev->gfx.gfx_off_req_count = 1;
> adev->pm.ac_power = power_supply_is_system_supplied() > 0 ? true : false;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
> index 1cdb264..11d4d9f 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
> @@ -26,6 +26,9 @@
> #include "amdgpu.h"
> #include "amdgpu_gfx.h"
>
> +/* 0.5 second timeout */
> +#define GFX_OFF_DELAY_ENABLE msecs_to_jiffies(500)
> +
> /*
> * GPU scratch registers helpers function.
> */
> @@ -360,6 +363,7 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
> if (!adev->powerplay.pp_funcs->set_powergating_by_smu)
> return;
>
> +
> mutex_lock(&adev->gfx.gfx_off_mutex);
>
> if (!enable)
> @@ -368,11 +372,11 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
> adev->gfx.gfx_off_req_count--;
>
> if (enable && !adev->gfx.gfx_off_state && !adev->gfx.gfx_off_req_count) {
> - if (!amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, true))
> - adev->gfx.gfx_off_state = true;
> + schedule_delayed_work(&adev->gfx.gfx_off_delay_work, GFX_OFF_DELAY_ENABLE);
> } else if (!enable && adev->gfx.gfx_off_state) {
There may still be delayed work pending to enable GFXOFF. You need to
use cancel_delayed_work_sync to cancel it and make sure GFXOFF doesn't
get enabled again while your caller still needs it disabled.
That may also wait for a worker function that has already started.
Therefore you need to cancel before taking the gfx_off_mutex, otherwise
you can deadlock with the worker function trying to take the lock as well.
Regards,
Felix
> if (!amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, false))
> adev->gfx.gfx_off_state = false;
> }
> +
> mutex_unlock(&adev->gfx.gfx_off_mutex);
> }
More information about the amd-gfx
mailing list