This patch adds new IOCTL flags in amdgpu_context_IOCTL to set GPU workload profile. These calls will allow a user to switch to a GPU power profile which might be better suitable to its workload type. The currently supported workload types are: "None": Default workload profile "3D": Workload profile for 3D rendering work "Video": Workload profile for Media/Encode/Decode work "VR": Workload profile for VR rendering work "Compute": Workload profile for Compute work The workload hint flag is saved in GPU context, and then its applied when we actually run the job. V3: Create only set_workload interface, there is no need for get_workload (Christian) Cc: Alex Deucher <alexander.deucher@xxxxxxx> Signed-off-by: Shashank Sharma <shashank.sharma@xxxxxxx> --- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 42 +++++++++++++++++++++++-- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h | 1 + 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index 8ee4e8491f39..937c294f8d84 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -27,6 +27,7 @@ #include "amdgpu.h" #include "amdgpu_sched.h" #include "amdgpu_ras.h" +#include "amdgpu_ctx_workload.h" #include <linux/nospec.h> #define to_amdgpu_ctx_entity(e) \ @@ -328,7 +329,7 @@ static int amdgpu_ctx_init(struct amdgpu_ctx_mgr *mgr, int32_t priority, return r; ctx->stable_pstate = current_stable_pstate; - + ctx->workload_mode = AMDGPU_CTX_WORKLOAD_HINT_NONE; return 0; } @@ -633,11 +634,34 @@ static int amdgpu_ctx_stable_pstate(struct amdgpu_device *adev, return r; } +static int amdgpu_ctx_set_workload_profile(struct amdgpu_device *adev, + struct amdgpu_fpriv *fpriv, uint32_t id, + u32 workload_hint) +{ + struct amdgpu_ctx *ctx; + struct amdgpu_ctx_mgr *mgr; + + if (!fpriv) + return -EINVAL; + + mgr = &fpriv->ctx_mgr; + mutex_lock(&mgr->lock); + ctx = idr_find(&mgr->ctx_handles, id); + if (!ctx) { + mutex_unlock(&mgr->lock); + return -EINVAL; + } + + ctx->workload_mode = workload_hint; + mutex_unlock(&mgr->lock); + return 0; +} + int amdgpu_ctx_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { int r; - uint32_t id, stable_pstate; + uint32_t id, stable_pstate, wl_hint; int32_t priority; union drm_amdgpu_ctx *args = data; @@ -681,6 +705,20 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data, return -EINVAL; r = amdgpu_ctx_stable_pstate(adev, fpriv, id, true, &stable_pstate); break; + case AMDGPU_CTX_OP_SET_WORKLOAD_PROFILE: + if (args->in.flags & ~AMDGPU_CTX_WORKLOAD_HINT_MASK) + return -EINVAL; + wl_hint = args->in.flags & AMDGPU_CTX_WORKLOAD_HINT_MASK; + if (wl_hint > AMDGPU_CTX_WORKLOAD_HINT_MAX) + return -EINVAL; + r = amdgpu_ctx_set_workload_profile(adev, fpriv, id, wl_hint); + if (r) + DRM_ERROR("Failed to set workload profile to %s\n", + amdgpu_workload_profile_name(wl_hint)); + else + DRM_DEBUG_DRIVER("Workload profile set to %s\n", + amdgpu_workload_profile_name(wl_hint)); + break; default: return -EINVAL; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h index cc7c8afff414..6c8032c3291a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h @@ -58,6 +58,7 @@ struct amdgpu_ctx { unsigned long ras_counter_ce; unsigned long ras_counter_ue; uint32_t stable_pstate; + uint32_t workload_mode; }; struct amdgpu_ctx_mgr { -- 2.34.1