[PATCH v3 2/5] drm/amdgpu: add new functions to set GPU power profile

Lazar, Lijo lijo.lazar at amd.com
Tue Sep 27 14:34:38 UTC 2022



On 9/27/2022 7:50 PM, Sharma, Shashank wrote:
> 
> 
> On 9/27/2022 4:00 PM, Lazar, Lijo wrote:
>>
>>
>> On 9/27/2022 7:17 PM, Sharma, Shashank wrote:
>>>
>>>
>>> On 9/27/2022 3:29 PM, Lazar, Lijo wrote:
>>>>
>>>>
>>>> On 9/27/2022 6:23 PM, Sharma, Shashank wrote:
>>>>>
>>>>>
>>>>> On 9/27/2022 2:39 PM, Lazar, Lijo wrote:
>>>>>>
>>>>>>
>>>>>> On 9/27/2022 5:53 PM, Sharma, Shashank wrote:
>>>>>>>
>>>>>>>
>>>>>>> On 9/27/2022 2:10 PM, Lazar, Lijo wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>> On 9/27/2022 5:11 PM, Sharma, Shashank wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On 9/27/2022 11:58 AM, Lazar, Lijo wrote:
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On 9/27/2022 3:10 AM, Shashank Sharma wrote:
>>>>>>>>>>> This patch adds new functions which will allow a user to
>>>>>>>>>>> change the GPU power profile based a GPU workload hint
>>>>>>>>>>> flag.
>>>>>>>>>>>
>>>>>>>>>>> Cc: Alex Deucher <alexander.deucher at amd.com>
>>>>>>>>>>> Signed-off-by: Shashank Sharma <shashank.sharma at amd.com>
>>>>>>>>>>> ---
>>>>>>>>>>>   drivers/gpu/drm/amd/amdgpu/Makefile           |  2 +-
>>>>>>>>>>>   .../gpu/drm/amd/amdgpu/amdgpu_ctx_workload.c  | 97 
>>>>>>>>>>> +++++++++++++++++++
>>>>>>>>>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_device.c    |  1 +
>>>>>>>>>>>   .../gpu/drm/amd/include/amdgpu_ctx_workload.h | 54 +++++++++++
>>>>>>>>>>>   drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h       |  5 +
>>>>>>>>>>>   5 files changed, 158 insertions(+), 1 deletion(-)
>>>>>>>>>>>   create mode 100644 
>>>>>>>>>>> drivers/gpu/drm/amd/amdgpu/amdgpu_ctx_workload.c
>>>>>>>>>>>   create mode 100644 
>>>>>>>>>>> drivers/gpu/drm/amd/include/amdgpu_ctx_workload.h
>>>>>>>>>>>
>>>>>>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile 
>>>>>>>>>>> b/drivers/gpu/drm/amd/amdgpu/Makefile
>>>>>>>>>>> index 5a283d12f8e1..34679c657ecc 100644
>>>>>>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/Makefile
>>>>>>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/Makefile
>>>>>>>>>>> @@ -50,7 +50,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \
>>>>>>>>>>>       atombios_dp.o amdgpu_afmt.o amdgpu_trace_points.o \
>>>>>>>>>>>       atombios_encoders.o amdgpu_sa.o atombios_i2c.o \
>>>>>>>>>>>       amdgpu_dma_buf.o amdgpu_vm.o amdgpu_vm_pt.o amdgpu_ib.o 
>>>>>>>>>>> amdgpu_pll.o \
>>>>>>>>>>> -    amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o 
>>>>>>>>>>> amdgpu_sync.o \
>>>>>>>>>>> +    amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o 
>>>>>>>>>>> amdgpu_ctx_workload.o amdgpu_sync.o \
>>>>>>>>>>>       amdgpu_gtt_mgr.o amdgpu_preempt_mgr.o amdgpu_vram_mgr.o 
>>>>>>>>>>> amdgpu_virt.o \
>>>>>>>>>>>       amdgpu_atomfirmware.o amdgpu_vf_error.o amdgpu_sched.o \
>>>>>>>>>>>       amdgpu_debugfs.o amdgpu_ids.o amdgpu_gmc.o \
>>>>>>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx_workload.c 
>>>>>>>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx_workload.c
>>>>>>>>>>> new file mode 100644
>>>>>>>>>>> index 000000000000..a11cf29bc388
>>>>>>>>>>> --- /dev/null
>>>>>>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx_workload.c
>>>>>>>>>>> @@ -0,0 +1,97 @@
>>>>>>>>>>> +/*
>>>>>>>>>>> + * Copyright 2022 Advanced Micro Devices, Inc.
>>>>>>>>>>> + *
>>>>>>>>>>> + * Permission is hereby granted, free of charge, to any 
>>>>>>>>>>> person obtaining a
>>>>>>>>>>> + * copy of this software and associated documentation files 
>>>>>>>>>>> (the "Software"),
>>>>>>>>>>> + * to deal in the Software without restriction, including 
>>>>>>>>>>> without limitation
>>>>>>>>>>> + * the rights to use, copy, modify, merge, publish, 
>>>>>>>>>>> distribute, sublicense,
>>>>>>>>>>> + * and/or sell copies of the Software, and to permit persons 
>>>>>>>>>>> to whom the
>>>>>>>>>>> + * Software is furnished to do so, subject to the following 
>>>>>>>>>>> conditions:
>>>>>>>>>>> + *
>>>>>>>>>>> + * The above copyright notice and this permission notice 
>>>>>>>>>>> shall be included in
>>>>>>>>>>> + * all copies or substantial portions of the Software.
>>>>>>>>>>> + *
>>>>>>>>>>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY 
>>>>>>>>>>> KIND, EXPRESS OR
>>>>>>>>>>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
>>>>>>>>>>> MERCHANTABILITY,
>>>>>>>>>>> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN 
>>>>>>>>>>> NO EVENT SHALL
>>>>>>>>>>> + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY 
>>>>>>>>>>> CLAIM, DAMAGES OR
>>>>>>>>>>> + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT 
>>>>>>>>>>> OR OTHERWISE,
>>>>>>>>>>> + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
>>>>>>>>>>> OR THE USE OR
>>>>>>>>>>> + * OTHER DEALINGS IN THE SOFTWARE.
>>>>>>>>>>> + *
>>>>>>>>>>> + */
>>>>>>>>>>> +#include <drm/drm.h>
>>>>>>>>>>> +#include "kgd_pp_interface.h"
>>>>>>>>>>> +#include "amdgpu_ctx_workload.h"
>>>>>>>>>>> +
>>>>>>>>>>> +static enum PP_SMC_POWER_PROFILE
>>>>>>>>>>> +amdgpu_workload_to_power_profile(uint32_t hint)
>>>>>>>>>>> +{
>>>>>>>>>>> +    switch (hint) {
>>>>>>>>>>> +    case AMDGPU_CTX_WORKLOAD_HINT_NONE:
>>>>>>>>>>> +    default:
>>>>>>>>>>> +        return PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
>>>>>>>>>>> +
>>>>>>>>>>> +    case AMDGPU_CTX_WORKLOAD_HINT_3D:
>>>>>>>>>>> +        return PP_SMC_POWER_PROFILE_FULLSCREEN3D;
>>>>>>>>>>> +    case AMDGPU_CTX_WORKLOAD_HINT_VIDEO:
>>>>>>>>>>> +        return PP_SMC_POWER_PROFILE_VIDEO;
>>>>>>>>>>> +    case AMDGPU_CTX_WORKLOAD_HINT_VR:
>>>>>>>>>>> +        return PP_SMC_POWER_PROFILE_VR;
>>>>>>>>>>> +    case AMDGPU_CTX_WORKLOAD_HINT_COMPUTE:
>>>>>>>>>>> +        return PP_SMC_POWER_PROFILE_COMPUTE;
>>>>>>>>>>> +    }
>>>>>>>>>>> +}
>>>>>>>>>>> +
>>>>>>>>>>> +int amdgpu_set_workload_profile(struct amdgpu_device *adev,
>>>>>>>>>>> +                uint32_t hint)
>>>>>>>>>>> +{
>>>>>>>>>>> +    int ret = 0;
>>>>>>>>>>> +    enum PP_SMC_POWER_PROFILE profile =
>>>>>>>>>>> +            amdgpu_workload_to_power_profile(hint);
>>>>>>>>>>> +
>>>>>>>>>>> +    if (adev->pm.workload_mode == hint)
>>>>>>>>>>> +        return 0;
>>>>>>>>>>> +
>>>>>>>>>>> +    mutex_lock(&adev->pm.smu_workload_lock);
>>>>>>>>>>
>>>>>>>>>> If it's all about pm subsystem variable accesses, this API 
>>>>>>>>>> should rather be inside amd/pm subsystem. No need to expose 
>>>>>>>>>> the variable outside pm subsytem. Also currently all 
>>>>>>>>>> amdgpu_dpm* calls are protected under one mutex. Then this 
>>>>>>>>>> extra lock won't be needed.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> This is tricky, this is not all about PM subsystem. Note that 
>>>>>>>>> the job management and scheduling is handled into amdgpu_ctx, 
>>>>>>>>> so the workload hint is set in context_management API. The API 
>>>>>>>>> is consumed when the job is actually run from amdgpu_run() 
>>>>>>>>> layer. So its a joint interface between context and PM.
>>>>>>>>>
>>>>>>>>
>>>>>>>> If you take out amdgpu_workload_to_power_profile() line, 
>>>>>>>> everything else looks to touch only pm variables/functions. 
>>>>>>>
>>>>>>> That's not a line, that function converts a AMGPU_CTX hint to PPM 
>>>>>>> profile. And going by that logic, this whole code was kept in the 
>>>>>>> amdgpu_ctx.c file as well, coz this code is consuming the PM API. 
>>>>>>> So to avoid these conflicts and having a new file is a better idea.
>>>>>>>
>>>>>>> You could still keep a
>>>>>>>> wrapper though. Also dpm_* functions are protected, so the extra 
>>>>>>>> mutex can be avoided as well.
>>>>>>>>
>>>>>>> The lock also protects pm.workload_mode writes.
>>>>>>>
>>>>>>>>>>> +
>>>>>>>>>>> +    if (adev->pm.workload_mode == hint)
>>>>>>>>>>> +        goto unlock;
>>>>>>>>>>> +
>>>>>>>>>>> +    ret = amdgpu_dpm_switch_power_profile(adev, profile, 1);
>>>>>>>>>>> +    if (!ret)
>>>>>>>>>>> +        adev->pm.workload_mode = hint;
>>>>>>>>>>> +    atomic_inc(&adev->pm.workload_switch_ref);
>>>>>>>>>>
>>>>>>>>>> Why is this reference kept? The swtiching happens inside a 
>>>>>>>>>> lock and there is already a check not to switch if the hint 
>>>>>>>>>> matches with current workload.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> This reference is kept so that we would not reset the PM mode 
>>>>>>>>> to DEFAULT when some other context has switched the PP mode. If 
>>>>>>>>> you see the 4th patch, the PM mode will be changed when the job 
>>>>>>>>> in that context is run, and a pm_reset function will be 
>>>>>>>>> scheduled when the job is done. But in between if another job 
>>>>>>>>> from another context has changed the PM mode, the refrence 
>>>>>>>>> count will prevent us from resetting the PM mode.
>>>>>>>>>
>>>>>>>>
>>>>>>>> This helps only if multiple jobs request the same mode. If they 
>>>>>>>> request different modes, then this is not helping much.
>>>>>>>
>>>>>>> No that's certainly not the case. It's a counter, whose aim is to 
>>>>>>> allow a PP reset only when the counter is 0. Do note that the 
>>>>>>> reset() happens only in the job_free_cb(), which gets schedule 
>>>>>>> later. If this counter is not zero, which means another work has 
>>>>>>> changed the profile in between, and we should not reset it.
>>>>>>>
>>>>>>>>
>>>>>>>> It could be useful to profile some apps assuming it has 
>>>>>>>> exclusive access.
>>>>>>>>
>>>>>>>> However, in general, the API is not reliable from a user point 
>>>>>>>> as the mode requested can be overridden by some other job. Then 
>>>>>>>> a better thing to do is to document that and avoid the extra 
>>>>>>>> stuff around it.
>>>>>>>>
>>>>>>> As I mentioned before, like any PM feature, the benefits can be 
>>>>>>> seen only while running consistant workloads for long time. I an 
>>>>>>> still add a doc note in the UAPI page.
>>>>>>>
>>>>>>
>>>>>>
>>>>>> a) What is the goal of the API? Is it guaranteeing the job to run 
>>>>>> under a workprofile mode or something else?
>>>>>
>>>>> No, it does not guarentee anything. If you see the cover letter, it 
>>>>> just provides an interface to an app to submit workload under a 
>>>>> power profile which can be more suitable for its workload type. As 
>>>>> I mentioned, it could be very useful for many scenarios like 
>>>>> fullscreen 3D / fullscreen MM scenarios. It could also allow a 
>>>>> system-gfx-manager to shift load balance towards one type of 
>>>>> workload. There are many applications, once the UAPI is in place.
>>>>>
>>>>>>
>>>>>> b) If it's to guarantee work profile mode, does it really 
>>>>>> guarantee that - the answer is NO when some other job is running. 
>>>>>> It may or may not work is the answer.
>>>>>>
>>>>>> c) What is the difference between one job resetting the profile 
>>>>>> mode to NONE vs another job change the mode to say VIDEO when the 
>>>>>> original request is for COMPUTE? While that is the case, what is 
>>>>>> the use of any sort of 'pseudo-protection' other than running some 
>>>>>> code to do extra lock/unlock stuff.
>>>>>>
>>>>>
>>>>> Your understanding of protection is wrong here. There is 
>>>>> intentionally no protection for a job changing another job's set 
>>>>> workload profile, coz in that was we will end up 
>>>>> seriazling/bottlenecking workload submission until PM profile is 
>>>>> ready to be changed, which takes away benefit of having multiple 
>>>>> queues of parallel submission.
>>>>>
>>>>> The protection provided by the ref counter is to avoid the clearing 
>>>>> of the profile (to NONE), while another workload is in execution. 
>>>>> The difference between NONE and VIDEO is still that NONE is the 
>>>>> default profile without any fine tuning, and VIDEO is still fine 
>>>>> tuned for VIDEO type of workloads.
>>>>>
>>>>
>>>> Protection 1 is - mutex_lock(&adev->pm.smu_workload_lock);
>>>>
>>>> The line that follows is amdgpu_dpm_switch_power_profile() - this 
>>>> one will allow only single client use- two jobs won't be able to 
>>>> switch at the same time. All *dpm* APIs are protected like that.
>>>>
>>>
>>> this also protects the pm.workload_mode variable which is being set 
>>> after the amdgpu_dpm_switch_power_profile call is successful here:
>>> adev->pm.workload_mode = hint;
>>>
>>>> Protection 2 is - ref counter.
>>>>
>>>> It helps only in this kind of scenario when two jobs requested the 
>>>> same mode successively -
>>>>      Job 1 requested compute
>>>>      Job 2 requested compute
>>>>      Job 1 ends (doesnt't reset)
>>>>
>>>> Scenario - 2
>>>>      Job 1 requested compute
>>>>      Job 2 requested compute
>>>>      Job 3 requested 3D
>>>>      Job 1 ends (doesnt't reset, it continues in 3D)
>>>>
>>>> In this mixed scenario case, I would say NONE is much more optimized 
>>>> as it's under FW control. Actually, it does much more fine tuning 
>>>> because of its background data collection.
>>>>
>>>
>>>
>>> It helps in mixed scenarios as well, consider this scenario:
>>> Job 1 requests: 3D
>>> Job 2 requests: Media
>>
>> Ok, let's take this as the example.
>>
>> Protection case :
>>
>> Job 1 requests: 3D => adev->pm.workload_mode = 3D; and protected by 
>> mutex_lock(&adev->pm.smu_workload_lock)
>>
>> Jobe 2 requests  => adev->pm.workload_mode = Media;
>>
>> What is the use of this variable then? Two jobs can come at different 
>> times and change it independently? Any use in keeping this?
> 
>> Some other job came in and changed to some other value. So, what is 
>> the use of this lock finally?
>>
> ?? The locks are not to save the variable from being changed, but to 
> save the variable being changed out of context. If two threads try to 
> change it at the same time, one of them will have to wait until the 
> other critical section is done execution.
> 
> Do note that this variable is changed only when 
> amdgpu_dpm_switch_power_profile() call is successful. Going by the same 
> logic, what is the use of having these pm locks inside the function 
> dpm_switch_power_profile(), as Job 1 changed the power profile to 3D, 
> and Job 2 changed it to media :) ?

That lock is protecting the swsmu internal states from concurrent access 
and not profile mode. Here I don't see the use of this variable.

  Using those locks does not prevent
> chaning the PM profile, it makes sure that it happens in a serialized way.
> 
>> Use case:
>>
>> Job 1 requests: 3D
>> Job 2 requests: Media
>>
>> Job 1 now runs under Media. What is achieved considering the intent of 
>> the API and extra CPU cycles run to protect nothing?
>>
> 
> This is how it is intended to work, I have explained this multiple times 
> before that we do not want to block the change in PP from two different 
> jobs. The lock is to protect concurrancy sequence, not change in mode:
> 
> without that lock in the worst case scenario:
> 
> Thread: 1
> Job 1 requests: 3D
> PM mode changed to: 3D
> just before writing (adev->pm.workload_mode = 3d) this thread schedules out
> 
> Thread:2
> Job 2 requests: Media
> PM mode changed to: Media
> adev->pm.workload_mode = media
> 
> Thread 1 schedules in:
> adev->pm.workload_mode = 3d but PM mode media.
> 
> State machine broken here. So the lock is to provide sequential 
> execution of the code.
> 
> 
> If your suggestion is we should not let the mode get changed until one 
> job is done execution, that's a different discussion and certainly not 
> being reflected from what you wrote above.

My suggestion is not to waste extra CPU cycles/memory when the API 
doesn't give any guarantee about its intended purpose (which is to keep 
the profile mode as requested by a job). Let it be stateless and 
document the usage.

Thanks,
Lijo

> 
> - Shashank
> 
>> Thanks,
>> Lijo
>>
>>> Job 1 finishes, but job 2 is ongoing
>>> Job 1 calls reset(), but checks the counter is non-zero and doesn't 
>>> reset
>>>
>>> So the media workload continues in Media mode, not None.
>>>
>>> - Shashank
>>>
>>>>> In the end, *again* the actual benefit comes when consistant 
>>>>> workload is submitted for a long time, like fullscreen 3D game 
>>>>> playback, fullscreen Video movie playback, and so on.
>>>>>
>>>>
>>>> "only under consistent", doesn't justify any software protection 
>>>> logic. Again, if the workload is consistent most likely PMFW could 
>>>> be managing it better.
>>>>
>>>> Thanks,
>>>> Lijo
>>>>
>>>>> - Shashank
>>>>>
>>>>>> Thanks,
>>>>>> Lijo
>>>>>>
>>>>>>> - Shashank
>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Lijo
>>>>>>>>
>>>>>>>>> - Shashank
>>>>>>>>>
>>>>>>>>>> Thanks,
>>>>>>>>>> Lijo
>>>>>>>>>>
>>>>>>>>>>> +
>>>>>>>>>>> +unlock:
>>>>>>>>>>> +    mutex_unlock(&adev->pm.smu_workload_lock);
>>>>>>>>>>> +    return ret;
>>>>>>>>>>> +}
>>>>>>>>>>> +
>>>>>>>>>>> +int amdgpu_clear_workload_profile(struct amdgpu_device *adev,
>>>>>>>>>>> +                  uint32_t hint)
>>>>>>>>>>> +{
>>>>>>>>>>> +    int ret = 0;
>>>>>>>>>>> +    enum PP_SMC_POWER_PROFILE profile =
>>>>>>>>>>> +            amdgpu_workload_to_power_profile(hint);
>>>>>>>>>>> +
>>>>>>>>>>> +    if (hint == AMDGPU_CTX_WORKLOAD_HINT_NONE)
>>>>>>>>>>> +        return 0;
>>>>>>>>>>> +
>>>>>>>>>>> +    /* Do not reset GPU power profile if another reset is 
>>>>>>>>>>> coming */
>>>>>>>>>>> +    if (atomic_dec_return(&adev->pm.workload_switch_ref) > 0)
>>>>>>>>>>> +        return 0;
>>>>>>>>>>> +
>>>>>>>>>>> +    mutex_lock(&adev->pm.smu_workload_lock);
>>>>>>>>>>> +
>>>>>>>>>>> +    if (adev->pm.workload_mode != hint)
>>>>>>>>>>> +        goto unlock;
>>>>>>>>>>> +
>>>>>>>>>>> +    ret = amdgpu_dpm_switch_power_profile(adev, profile, 0);
>>>>>>>>>>> +    if (!ret)
>>>>>>>>>>> +        adev->pm.workload_mode = AMDGPU_CTX_WORKLOAD_HINT_NONE;
>>>>>>>>>>> +
>>>>>>>>>>> +unlock:
>>>>>>>>>>> +    mutex_unlock(&adev->pm.smu_workload_lock);
>>>>>>>>>>> +    return ret;
>>>>>>>>>>> +}
>>>>>>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
>>>>>>>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>>>>>>>>>>> index be7aff2d4a57..1f0f64662c04 100644
>>>>>>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>>>>>>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>>>>>>>>>>> @@ -3554,6 +3554,7 @@ int amdgpu_device_init(struct 
>>>>>>>>>>> amdgpu_device *adev,
>>>>>>>>>>>       mutex_init(&adev->psp.mutex);
>>>>>>>>>>>       mutex_init(&adev->notifier_lock);
>>>>>>>>>>>       mutex_init(&adev->pm.stable_pstate_ctx_lock);
>>>>>>>>>>> +    mutex_init(&adev->pm.smu_workload_lock);
>>>>>>>>>>>       mutex_init(&adev->benchmark_mutex);
>>>>>>>>>>>       amdgpu_device_init_apu_flags(adev);
>>>>>>>>>>> diff --git 
>>>>>>>>>>> a/drivers/gpu/drm/amd/include/amdgpu_ctx_workload.h 
>>>>>>>>>>> b/drivers/gpu/drm/amd/include/amdgpu_ctx_workload.h
>>>>>>>>>>> new file mode 100644
>>>>>>>>>>> index 000000000000..6060fc53c3b0
>>>>>>>>>>> --- /dev/null
>>>>>>>>>>> +++ b/drivers/gpu/drm/amd/include/amdgpu_ctx_workload.h
>>>>>>>>>>> @@ -0,0 +1,54 @@
>>>>>>>>>>> +/*
>>>>>>>>>>> + * Copyright 2022 Advanced Micro Devices, Inc.
>>>>>>>>>>> + *
>>>>>>>>>>> + * Permission is hereby granted, free of charge, to any 
>>>>>>>>>>> person obtaining a
>>>>>>>>>>> + * copy of this software and associated documentation files 
>>>>>>>>>>> (the "Software"),
>>>>>>>>>>> + * to deal in the Software without restriction, including 
>>>>>>>>>>> without limitation
>>>>>>>>>>> + * the rights to use, copy, modify, merge, publish, 
>>>>>>>>>>> distribute, sublicense,
>>>>>>>>>>> + * and/or sell copies of the Software, and to permit persons 
>>>>>>>>>>> to whom the
>>>>>>>>>>> + * Software is furnished to do so, subject to the following 
>>>>>>>>>>> conditions:
>>>>>>>>>>> + *
>>>>>>>>>>> + * The above copyright notice and this permission notice 
>>>>>>>>>>> shall be included in
>>>>>>>>>>> + * all copies or substantial portions of the Software.
>>>>>>>>>>> + *
>>>>>>>>>>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY 
>>>>>>>>>>> KIND, EXPRESS OR
>>>>>>>>>>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
>>>>>>>>>>> MERCHANTABILITY,
>>>>>>>>>>> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN 
>>>>>>>>>>> NO EVENT SHALL
>>>>>>>>>>> + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY 
>>>>>>>>>>> CLAIM, DAMAGES OR
>>>>>>>>>>> + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT 
>>>>>>>>>>> OR OTHERWISE,
>>>>>>>>>>> + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
>>>>>>>>>>> OR THE USE OR
>>>>>>>>>>> + * OTHER DEALINGS IN THE SOFTWARE.
>>>>>>>>>>> + *
>>>>>>>>>>> + */
>>>>>>>>>>> +#ifndef _AMDGPU_CTX_WL_H_
>>>>>>>>>>> +#define _AMDGPU_CTX_WL_H_
>>>>>>>>>>> +#include <drm/amdgpu_drm.h>
>>>>>>>>>>> +#include "amdgpu.h"
>>>>>>>>>>> +
>>>>>>>>>>> +/* Workload mode names */
>>>>>>>>>>> +static const char * const amdgpu_workload_mode_name[] = {
>>>>>>>>>>> +    "None",
>>>>>>>>>>> +    "3D",
>>>>>>>>>>> +    "Video",
>>>>>>>>>>> +    "VR",
>>>>>>>>>>> +    "Compute",
>>>>>>>>>>> +    "Unknown",
>>>>>>>>>>> +};
>>>>>>>>>>> +
>>>>>>>>>>> +static inline const
>>>>>>>>>>> +char *amdgpu_workload_profile_name(uint32_t profile)
>>>>>>>>>>> +{
>>>>>>>>>>> +    if (profile >= AMDGPU_CTX_WORKLOAD_HINT_NONE &&
>>>>>>>>>>> +        profile < AMDGPU_CTX_WORKLOAD_HINT_MAX)
>>>>>>>>>>> +        return 
>>>>>>>>>>> amdgpu_workload_mode_name[AMDGPU_CTX_WORKLOAD_INDEX(profile)];
>>>>>>>>>>> +
>>>>>>>>>>> +    return 
>>>>>>>>>>> amdgpu_workload_mode_name[AMDGPU_CTX_WORKLOAD_HINT_MAX];
>>>>>>>>>>> +}
>>>>>>>>>>> +
>>>>>>>>>>> +int amdgpu_clear_workload_profile(struct amdgpu_device *adev,
>>>>>>>>>>> +                uint32_t hint);
>>>>>>>>>>> +
>>>>>>>>>>> +int amdgpu_set_workload_profile(struct amdgpu_device *adev,
>>>>>>>>>>> +                uint32_t hint);
>>>>>>>>>>> +
>>>>>>>>>>> +#endif
>>>>>>>>>>> diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h 
>>>>>>>>>>> b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
>>>>>>>>>>> index 65624d091ed2..565131f789d0 100644
>>>>>>>>>>> --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
>>>>>>>>>>> +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
>>>>>>>>>>> @@ -361,6 +361,11 @@ struct amdgpu_pm {
>>>>>>>>>>>       struct mutex            stable_pstate_ctx_lock;
>>>>>>>>>>>       struct amdgpu_ctx       *stable_pstate_ctx;
>>>>>>>>>>> +    /* SMU workload mode */
>>>>>>>>>>> +    struct mutex smu_workload_lock;
>>>>>>>>>>> +    uint32_t workload_mode;
>>>>>>>>>>> +    atomic_t workload_switch_ref;
>>>>>>>>>>> +
>>>>>>>>>>>       struct config_table_setting config_table;
>>>>>>>>>>>       /* runtime mode */
>>>>>>>>>>>       enum amdgpu_runpm_mode rpm_mode;
>>>>>>>>>>>


More information about the amd-gfx mailing list