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 <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
index a0b479d5fff1..f4be19223588 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
@@ -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);
 }
 
 /**
-- 
2.34.1

Reply via email to