* [PATCH] drm/amdgpu/userq: fix userq_signal_ioctl stuck in drm_exec_until_all_locked()
@ 2026-09-07 8:47 Yogesh Mohan Marimuthu
2026-09-07 8:53 ` Christian König
0 siblings, 1 reply; 5+ messages in thread
From: Yogesh Mohan Marimuthu @ 2026-09-07 8:47 UTC (permalink / raw)
To: amd-gfx
Cc: alexander.deucher, christian.koenig, sukhatri,
Yogesh Mohan Marimuthu
If in userq_signal_ioctl only bo_write_handles is passed and
num_bo_read_handles is zero then if there is contention the code is stuck
in drm_exec_until_all_locked()
This happens because read bo's are handled first and then write bo's in
drm_exec_until_all_locked loop. When there is contention in one of the
write bo, exec->contended bo is set and the loop is retried, but
read bo is zero, still drm_exec_retry_on_contention() macro for read bo
is executed without drm_exec_lock_contended() getting executed.
drm_exec_retry_on_contention will keep going to beginning of the loop
causing infinite loop.
Fix this by only locking and reserving fence for bo only if there are
bo passed userq_signal_ioctl.
Observed this issue when testing with MR
https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40808
Signed-off-by: Yogesh Mohan Marimuthu <yogesh.mohanmarimuthu@amd.com>
---
.../gpu/drm/amd/amdgpu/amdgpu_userq_fence.c | 24 +++++++++++--------
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
index c270635c9..135e77837 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
@@ -572,17 +572,21 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data,
(num_read_bo_handles + num_write_bo_handles));
drm_exec_until_all_locked(&exec) {
- r = drm_exec_prepare_array(&exec, gobj_read,
- num_read_bo_handles, 1);
- drm_exec_retry_on_contention(&exec);
- if (r)
- goto exec_fini;
+ if (num_read_bo_handles) {
+ r = drm_exec_prepare_array(&exec, gobj_read,
+ num_read_bo_handles, 1);
+ drm_exec_retry_on_contention(&exec);
+ if (r)
+ goto exec_fini;
+ }
- r = drm_exec_prepare_array(&exec, gobj_write,
- num_write_bo_handles, 1);
- drm_exec_retry_on_contention(&exec);
- if (r)
- goto exec_fini;
+ if (num_write_bo_handles) {
+ r = drm_exec_prepare_array(&exec, gobj_write,
+ num_write_bo_handles, 1);
+ drm_exec_retry_on_contention(&exec);
+ if (r)
+ goto exec_fini;
+ }
}
/* And publish the new fence in the BOs and syncobj */
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] drm/amdgpu/userq: fix userq_signal_ioctl stuck in drm_exec_until_all_locked()
2026-09-07 8:47 [PATCH] drm/amdgpu/userq: fix userq_signal_ioctl stuck in drm_exec_until_all_locked() Yogesh Mohan Marimuthu
@ 2026-09-07 8:53 ` Christian König
2026-09-07 14:42 ` Khatri, Sunil
0 siblings, 1 reply; 5+ messages in thread
From: Christian König @ 2026-09-07 8:53 UTC (permalink / raw)
To: Yogesh Mohan Marimuthu, amd-gfx; +Cc: alexander.deucher, sukhatri
On 9/7/26 10:47, Yogesh Mohan Marimuthu wrote:
> If in userq_signal_ioctl only bo_write_handles is passed and
> num_bo_read_handles is zero then if there is contention the code is stuck
> in drm_exec_until_all_locked()
>
> This happens because read bo's are handled first and then write bo's in
> drm_exec_until_all_locked loop. When there is contention in one of the
> write bo, exec->contended bo is set and the loop is retried, but
> read bo is zero, still drm_exec_retry_on_contention() macro for read bo
> is executed without drm_exec_lock_contended() getting executed.
> drm_exec_retry_on_contention will keep going to beginning of the loop
> causing infinite loop.
Well that is a really good find but clear NAK to the solution.
This if this causes an infinite loop there is a bug somewhere in the drm_exec object.
My educated guess is that drm_exec_prepare_array() needs to call drm_exec_lock_contended() even when num_objects is zero.
Regards,
Christian.
>
> Fix this by only locking and reserving fence for bo only if there are
> bo passed userq_signal_ioctl.
>
> Observed this issue when testing with MR
> https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40808
>
> Signed-off-by: Yogesh Mohan Marimuthu <yogesh.mohanmarimuthu@amd.com>
> ---
> .../gpu/drm/amd/amdgpu/amdgpu_userq_fence.c | 24 +++++++++++--------
> 1 file changed, 14 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
> index c270635c9..135e77837 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
> @@ -572,17 +572,21 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data,
> (num_read_bo_handles + num_write_bo_handles));
>
> drm_exec_until_all_locked(&exec) {
> - r = drm_exec_prepare_array(&exec, gobj_read,
> - num_read_bo_handles, 1);
> - drm_exec_retry_on_contention(&exec);
> - if (r)
> - goto exec_fini;
> + if (num_read_bo_handles) {
> + r = drm_exec_prepare_array(&exec, gobj_read,
> + num_read_bo_handles, 1);
> + drm_exec_retry_on_contention(&exec);
> + if (r)
> + goto exec_fini;
> + }
>
> - r = drm_exec_prepare_array(&exec, gobj_write,
> - num_write_bo_handles, 1);
> - drm_exec_retry_on_contention(&exec);
> - if (r)
> - goto exec_fini;
> + if (num_write_bo_handles) {
> + r = drm_exec_prepare_array(&exec, gobj_write,
> + num_write_bo_handles, 1);
> + drm_exec_retry_on_contention(&exec);
> + if (r)
> + goto exec_fini;
> + }
> }
>
> /* And publish the new fence in the BOs and syncobj */
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] drm/amdgpu/userq: fix userq_signal_ioctl stuck in drm_exec_until_all_locked()
2026-09-07 8:53 ` Christian König
@ 2026-09-07 14:42 ` Khatri, Sunil
2026-09-07 15:11 ` Christian König
0 siblings, 1 reply; 5+ messages in thread
From: Khatri, Sunil @ 2026-09-07 14:42 UTC (permalink / raw)
To: Christian König, Yogesh Mohan Marimuthu, amd-gfx; +Cc: alexander.deucher
[-- Attachment #1: Type: text/plain, Size: 3220 bytes --]
On 07-09-2026 02:23 pm, Christian König wrote:
> On 9/7/26 10:47, Yogesh Mohan Marimuthu wrote:
>> If in userq_signal_ioctl only bo_write_handles is passed and
>> num_bo_read_handles is zero then if there is contention the code is stuck
>> in drm_exec_until_all_locked()
>>
>> This happens because read bo's are handled first and then write bo's in
>> drm_exec_until_all_locked loop. When there is contention in one of the
>> write bo, exec->contended bo is set and the loop is retried, but
>> read bo is zero, still drm_exec_retry_on_contention() macro for read bo
>> is executed without drm_exec_lock_contended() getting executed.
>> drm_exec_retry_on_contention will keep going to beginning of the loop
>> causing infinite loop.
> Well that is a really good find but clear NAK to the solution.
>
> This if this causes an infinite loop there is a bug somewhere in the drm_exec object.
>
> My educated guess is that drm_exec_prepare_array() needs to call drm_exec_lock_contended() even when num_objects is zero.
drm_exec_prepare_array() returns immediately if no of objects is 0. If
its not 0 in that case order of calls from prepare_array is
drm_exec_prepare_obj -> drm_exec_lock_obj -> drm_exec_lock_contended
So contention is never cleaned.
I can patch this up in drm_exec_prepare_array in case no of objects is 0
call the drm_exec_lock_contended like below.
if(!num_objects)
returndrm_exec_lock_contended(exec);
Regards
Sunil Khatri
>
> Regards,
> Christian.
>
>> Fix this by only locking and reserving fence for bo only if there are
>> bo passed userq_signal_ioctl.
>>
>> Observed this issue when testing with MR
>> https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40808
>>
>> Signed-off-by: Yogesh Mohan Marimuthu<yogesh.mohanmarimuthu@amd.com>
>> ---
>> .../gpu/drm/amd/amdgpu/amdgpu_userq_fence.c | 24 +++++++++++--------
>> 1 file changed, 14 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
>> index c270635c9..135e77837 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
>> @@ -572,17 +572,21 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data,
>> (num_read_bo_handles + num_write_bo_handles));
>>
>> drm_exec_until_all_locked(&exec) {
>> - r = drm_exec_prepare_array(&exec, gobj_read,
>> - num_read_bo_handles, 1);
>> - drm_exec_retry_on_contention(&exec);
>> - if (r)
>> - goto exec_fini;
>> + if (num_read_bo_handles) {
>> + r = drm_exec_prepare_array(&exec, gobj_read,
>> + num_read_bo_handles, 1);
>> + drm_exec_retry_on_contention(&exec);
>> + if (r)
>> + goto exec_fini;
>> + }
>>
>> - r = drm_exec_prepare_array(&exec, gobj_write,
>> - num_write_bo_handles, 1);
>> - drm_exec_retry_on_contention(&exec);
>> - if (r)
>> - goto exec_fini;
>> + if (num_write_bo_handles) {
>> + r = drm_exec_prepare_array(&exec, gobj_write,
>> + num_write_bo_handles, 1);
>> + drm_exec_retry_on_contention(&exec);
>> + if (r)
>> + goto exec_fini;
>> + }
>> }
>>
>> /* And publish the new fence in the BOs and syncobj */
[-- Attachment #2: Type: text/html, Size: 4907 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] drm/amdgpu/userq: fix userq_signal_ioctl stuck in drm_exec_until_all_locked()
2026-09-07 14:42 ` Khatri, Sunil
@ 2026-09-07 15:11 ` Christian König
2026-09-07 15:40 ` Khatri, Sunil
0 siblings, 1 reply; 5+ messages in thread
From: Christian König @ 2026-09-07 15:11 UTC (permalink / raw)
To: Khatri, Sunil, Yogesh Mohan Marimuthu, amd-gfx; +Cc: alexander.deucher
On 9/7/26 16:42, Khatri, Sunil wrote:
>
> On 07-09-2026 02:23 pm, Christian König wrote:
>> On 9/7/26 10:47, Yogesh Mohan Marimuthu wrote:
>>> If in userq_signal_ioctl only bo_write_handles is passed and
>>> num_bo_read_handles is zero then if there is contention the code is stuck
>>> in drm_exec_until_all_locked()
>>>
>>> This happens because read bo's are handled first and then write bo's in
>>> drm_exec_until_all_locked loop. When there is contention in one of the
>>> write bo, exec->contended bo is set and the loop is retried, but
>>> read bo is zero, still drm_exec_retry_on_contention() macro for read bo
>>> is executed without drm_exec_lock_contended() getting executed.
>>> drm_exec_retry_on_contention will keep going to beginning of the loop
>>> causing infinite loop.
>> Well that is a really good find but clear NAK to the solution.
>>
>> This if this causes an infinite loop there is a bug somewhere in the drm_exec object.
>>
>> My educated guess is that drm_exec_prepare_array() needs to call drm_exec_lock_contended() even when num_objects is zero.
> drm_exec_prepare_array() returns immediately if no of objects is 0. If its not 0 in that case order of calls from prepare_array is drm_exec_prepare_obj -> drm_exec_lock_obj -> drm_exec_lock_contended
> So contention is never cleaned.
>
> I can patch this up in drm_exec_prepare_array in case no of objects is 0 call the drm_exec_lock_contended like below.
> if(!num_objects)
> returndrm_exec_lock_contended(exec);
That sounds reasonable, yes.
Thanks,
Christian.
>
> Regards
> Sunil Khatri
>> Regards,
>> Christian.
>>
>>> Fix this by only locking and reserving fence for bo only if there are
>>> bo passed userq_signal_ioctl.
>>>
>>> Observed this issue when testing with MR
>>> https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40808
>>>
>>> Signed-off-by: Yogesh Mohan Marimuthu <yogesh.mohanmarimuthu@amd.com>
>>> ---
>>> .../gpu/drm/amd/amdgpu/amdgpu_userq_fence.c | 24 +++++++++++--------
>>> 1 file changed, 14 insertions(+), 10 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
>>> index c270635c9..135e77837 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
>>> @@ -572,17 +572,21 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data,
>>> (num_read_bo_handles + num_write_bo_handles));
>>>
>>> drm_exec_until_all_locked(&exec) {
>>> - r = drm_exec_prepare_array(&exec, gobj_read,
>>> - num_read_bo_handles, 1);
>>> - drm_exec_retry_on_contention(&exec);
>>> - if (r)
>>> - goto exec_fini;
>>> + if (num_read_bo_handles) {
>>> + r = drm_exec_prepare_array(&exec, gobj_read,
>>> + num_read_bo_handles, 1);
>>> + drm_exec_retry_on_contention(&exec);
>>> + if (r)
>>> + goto exec_fini;
>>> + }
>>>
>>> - r = drm_exec_prepare_array(&exec, gobj_write,
>>> - num_write_bo_handles, 1);
>>> - drm_exec_retry_on_contention(&exec);
>>> - if (r)
>>> - goto exec_fini;
>>> + if (num_write_bo_handles) {
>>> + r = drm_exec_prepare_array(&exec, gobj_write,
>>> + num_write_bo_handles, 1);
>>> + drm_exec_retry_on_contention(&exec);
>>> + if (r)
>>> + goto exec_fini;
>>> + }
>>> }
>>>
>>> /* And publish the new fence in the BOs and syncobj */
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] drm/amdgpu/userq: fix userq_signal_ioctl stuck in drm_exec_until_all_locked()
2026-09-07 15:11 ` Christian König
@ 2026-09-07 15:40 ` Khatri, Sunil
0 siblings, 0 replies; 5+ messages in thread
From: Khatri, Sunil @ 2026-09-07 15:40 UTC (permalink / raw)
To: Christian König, Yogesh Mohan Marimuthu, amd-gfx; +Cc: alexander.deucher
On 07-09-2026 08:41 pm, Christian König wrote:
> On 9/7/26 16:42, Khatri, Sunil wrote:
>> On 07-09-2026 02:23 pm, Christian König wrote:
>>> On 9/7/26 10:47, Yogesh Mohan Marimuthu wrote:
>>>> If in userq_signal_ioctl only bo_write_handles is passed and
>>>> num_bo_read_handles is zero then if there is contention the code is stuck
>>>> in drm_exec_until_all_locked()
>>>>
>>>> This happens because read bo's are handled first and then write bo's in
>>>> drm_exec_until_all_locked loop. When there is contention in one of the
>>>> write bo, exec->contended bo is set and the loop is retried, but
>>>> read bo is zero, still drm_exec_retry_on_contention() macro for read bo
>>>> is executed without drm_exec_lock_contended() getting executed.
>>>> drm_exec_retry_on_contention will keep going to beginning of the loop
>>>> causing infinite loop.
>>> Well that is a really good find but clear NAK to the solution.
>>>
>>> This if this causes an infinite loop there is a bug somewhere in the drm_exec object.
>>>
>>> My educated guess is that drm_exec_prepare_array() needs to call drm_exec_lock_contended() even when num_objects is zero.
>> drm_exec_prepare_array() returns immediately if no of objects is 0. If its not 0 in that case order of calls from prepare_array is drm_exec_prepare_obj -> drm_exec_lock_obj -> drm_exec_lock_contended
>> So contention is never cleaned.
>>
>> I can patch this up in drm_exec_prepare_array in case no of objects is 0 call the drm_exec_lock_contended like below.
>> if(!num_objects)
>> returndrm_exec_lock_contended(exec);
> That sounds reasonable, yes.
Thanks Christian,
sent the patch for review on dri-devel@lists.freedesktop.org
[PATCH] drm/drm_exec: remove contention for num_objects is 0
have a look please.
Regards
Sunil khatri
>
> Thanks,
> Christian.
>
>> Regards
>> Sunil Khatri
>>> Regards,
>>> Christian.
>>>
>>>> Fix this by only locking and reserving fence for bo only if there are
>>>> bo passed userq_signal_ioctl.
>>>>
>>>> Observed this issue when testing with MR
>>>> https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40808
>>>>
>>>> Signed-off-by: Yogesh Mohan Marimuthu <yogesh.mohanmarimuthu@amd.com>
>>>> ---
>>>> .../gpu/drm/amd/amdgpu/amdgpu_userq_fence.c | 24 +++++++++++--------
>>>> 1 file changed, 14 insertions(+), 10 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
>>>> index c270635c9..135e77837 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
>>>> @@ -572,17 +572,21 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data,
>>>> (num_read_bo_handles + num_write_bo_handles));
>>>>
>>>> drm_exec_until_all_locked(&exec) {
>>>> - r = drm_exec_prepare_array(&exec, gobj_read,
>>>> - num_read_bo_handles, 1);
>>>> - drm_exec_retry_on_contention(&exec);
>>>> - if (r)
>>>> - goto exec_fini;
>>>> + if (num_read_bo_handles) {
>>>> + r = drm_exec_prepare_array(&exec, gobj_read,
>>>> + num_read_bo_handles, 1);
>>>> + drm_exec_retry_on_contention(&exec);
>>>> + if (r)
>>>> + goto exec_fini;
>>>> + }
>>>>
>>>> - r = drm_exec_prepare_array(&exec, gobj_write,
>>>> - num_write_bo_handles, 1);
>>>> - drm_exec_retry_on_contention(&exec);
>>>> - if (r)
>>>> - goto exec_fini;
>>>> + if (num_write_bo_handles) {
>>>> + r = drm_exec_prepare_array(&exec, gobj_write,
>>>> + num_write_bo_handles, 1);
>>>> + drm_exec_retry_on_contention(&exec);
>>>> + if (r)
>>>> + goto exec_fini;
>>>> + }
>>>> }
>>>>
>>>> /* And publish the new fence in the BOs and syncobj */
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-09-07 15:40 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-07 8:47 [PATCH] drm/amdgpu/userq: fix userq_signal_ioctl stuck in drm_exec_until_all_locked() Yogesh Mohan Marimuthu
2026-09-07 8:53 ` Christian König
2026-09-07 14:42 ` Khatri, Sunil
2026-09-07 15:11 ` Christian König
2026-09-07 15:40 ` Khatri, Sunil
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.