]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/amdgpu: use atomic operation to achieve lockless serialization
authorSunil Khatri <sunil.khatri@amd.com>
Thu, 14 May 2026 07:01:00 +0000 (12:31 +0530)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 19 May 2026 16:11:34 +0000 (12:11 -0400)
In amdgpu_seq64_alloc there is a possibility that two difference cores
from two separate NODES can try to and could get the same free slot.
So this fixes that race here using atomic test_and_set clear operations.

Signed-off-by: Sunil Khatri <sunil.khatri@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 4d50a14d346141e03a7c3905e496d91e048bc30c)

drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c

index a0b479d5fff1910e9ca31e2a899061af536e60d4..f4be19223588975a8acf06a31542989afd6123b5 100644 (file)
@@ -175,11 +175,14 @@ int amdgpu_seq64_alloc(struct amdgpu_device *adev, u64 *va,
 {
        unsigned long bit_pos;
 
-       bit_pos = find_first_zero_bit(adev->seq64.used, adev->seq64.num_sem);
-       if (bit_pos >= adev->seq64.num_sem)
-               return -ENOSPC;
+       for (;;) {
+               bit_pos = find_first_zero_bit(adev->seq64.used, adev->seq64.num_sem);
+               if (bit_pos >= adev->seq64.num_sem)
+                       return -ENOSPC;
 
-       __set_bit(bit_pos, adev->seq64.used);
+               if (!test_and_set_bit(bit_pos, adev->seq64.used))
+                       break;
+       }
 
        *va = bit_pos * sizeof(u64) + amdgpu_seq64_get_va_base(adev);
 
@@ -205,7 +208,7 @@ void amdgpu_seq64_free(struct amdgpu_device *adev, u64 va)
 
        bit_pos = (va - amdgpu_seq64_get_va_base(adev)) / sizeof(u64);
        if (bit_pos < adev->seq64.num_sem)
-               __clear_bit(bit_pos, adev->seq64.used);
+               clear_bit(bit_pos, adev->seq64.used);
 }
 
 /**