[PATCH 1/2] drm/amdgpu: Handle xgmi device removal and add reset wq.
Grodzovsky, Andrey
Andrey.Grodzovsky at amd.com
Fri Nov 30 16:20:00 UTC 2018
On 11/30/2018 10:53 AM, Koenig, Christian wrote:
> Am 30.11.18 um 16:14 schrieb Grodzovsky, Andrey:
>> On 11/30/2018 04:03 AM, Christian König wrote:
>>> Am 29.11.18 um 21:36 schrieb Andrey Grodzovsky:
>>>> XGMI hive has some resources allocted on device init which
>>>> needs to be deallocated when the device is unregistered.
>>>>
>>>> Add per hive wq to allow all the nodes in hive to run resets
>>>> concurently - this should speed up the total reset time to avoid
>>>> breaching the PSP FW timeout.
>>> Do you really want a workqueue? That sounds like the exact opposite of
>>> what you describe here.
>>>
>>> E.g. a workqueue is there to serialize all work items scheduled to it.
>>>
>>> What you most likely rather want is a work item per device which are
>>> scheduled, run in parallel and are joined back together before
>>> dropping the per hive lock.
>>>
>>> Christian.
>> As you can see in second patch that exactly how I use this wq. I define
>> per adev work item all of which I enqueue during GPU reset routine.
>> I believe the wq I created will processes work items in parallel since
>> it's is served by per CPU worker thread (thread pool) while a
>> serializing wq is
>> created using the 'create_singlethread_workqueue' interface which
>> creates an ordered wq which process at most one item simultaneously.
> That is correct, but you are still limited to one work item processed
> per CPU which is not necessary what you want.
I was wrong to say it's single worker thread per CPU, it's actually work
thread pool
per CPU, so even with single CPU in the system you get concurrency of
execution.
>
>> I did have my doubts about creating a dedicated wq instead of reusing
>> existing system wide wq such as system_unbound_wq because this adds new
>> kernel threads but eventually I opted for my own queue because there is
>> a hard requirement from the PSP FW to complete all ASIC resets in
>> defined finite amount
>> of time (1s i believe) otherwise some nodes in the XGMI hive might
>> switch to single GPU mode due to timeout.
>> If I rely on system wide wq then during stress times this queue might
>> fail to process my work items within that time limit because it's
>> overloaded by work items from other queue clients.
>> Maybe I should squash the 2 changes into one to make all of this more
>> clear ?
> No, that won't help. You would rather need to document that properly.
>
> But creating a wq just for a rarely used device reset is completely
> overkill.
>
> Stuff like that should go to the system_highpri_wq work queue which
> should make already sure that it never hits the PSP timeout.
>
> Christian.
I agree in general with that, but it looks like system_highpri_wq is
'BOUND' wq meaning it's items are
limited to the thread pool of the CPU from which they were queued only,
anyway, since I mostly just wait in sleep inside PSP reset
function that should be still OK.
Will try that.
Andrey
>
>> Andrey
>>>> Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky at amd.com>
>>>> ---
>>>> drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c | 24 ++++++++++++++++++++++++
>>>> drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h | 3 +++
>>>> 2 files changed, 27 insertions(+)
>>>>
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
>>>> index fb37e69..9ac2dc5 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
>>>> @@ -61,6 +61,8 @@ struct amdgpu_hive_info
>>>> *amdgpu_get_xgmi_hive(struct amdgpu_device *adev)
>>>> INIT_LIST_HEAD(&tmp->device_list);
>>>> mutex_init(&tmp->hive_lock);
>>>> + tmp->reset_queue = alloc_workqueue("xgmi-hive", WQ_UNBOUND |
>>>> WQ_HIGHPRI, 0);
>>>> +
>>>> return tmp;
>>>> }
>>>> @@ -135,3 +137,25 @@ int amdgpu_xgmi_add_device(struct
>>>> amdgpu_device *adev)
>>>> mutex_unlock(&xgmi_mutex);
>>>> return ret;
>>>> }
>>>> +
>>>> +void amdgpu_xgmi_remove_device(struct amdgpu_device *adev)
>>>> +{
>>>> + struct amdgpu_hive_info *hive;
>>>> +
>>>> + if ((adev->asic_type < CHIP_VEGA20) || (adev->flags & AMD_IS_APU))
>>>> + return;
>>>> +
>>>> + mutex_lock(&xgmi_mutex);
>>>> +
>>>> + hive = amdgpu_get_xgmi_hive(adev);
>>>> + if (!hive)
>>>> + goto exit;
>>>> +
>>>> + if (!(hive->number_devices--)) {
>>>> + mutex_destroy(&hive->hive_lock);
>>>> + destroy_workqueue(hive->reset_queue);
>>>> + }
>>>> +
>>>> +exit:
>>>> + mutex_unlock(&xgmi_mutex);
>>>> +}
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h
>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h
>>>> index 6335bfd..285ab93 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h
>>>> @@ -30,10 +30,13 @@ struct amdgpu_hive_info {
>>>> struct psp_xgmi_topology_info topology_info;
>>>> int number_devices;
>>>> struct mutex hive_lock;
>>>> + /* hive members reset wq */
>>>> + struct workqueue_struct *reset_queue;
>>>> };
>>>> struct amdgpu_hive_info *amdgpu_get_xgmi_hive(struct
>>>> amdgpu_device *adev);
>>>> int amdgpu_xgmi_update_topology(struct amdgpu_hive_info *hive,
>>>> struct amdgpu_device *adev);
>>>> int amdgpu_xgmi_add_device(struct amdgpu_device *adev);
>>>> +void amdgpu_xgmi_remove_device(struct amdgpu_device *adev);
>>>> #endif
More information about the amd-gfx
mailing list