Commit 497d7cee authored by Alex Deucher's avatar Alex Deucher

drm/amdgpu: add a spinlock to wb allocation

As we use wb slots more dynamically, we need to lock
access to avoid racing on allocation or free.
Reviewed-by: default avatarShaoyun.liu <shaoyunl@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 754c366e
...@@ -502,6 +502,7 @@ struct amdgpu_wb { ...@@ -502,6 +502,7 @@ struct amdgpu_wb {
uint64_t gpu_addr; uint64_t gpu_addr;
u32 num_wb; /* Number of wb slots actually reserved for amdgpu. */ u32 num_wb; /* Number of wb slots actually reserved for amdgpu. */
unsigned long used[DIV_ROUND_UP(AMDGPU_MAX_WB, BITS_PER_LONG)]; unsigned long used[DIV_ROUND_UP(AMDGPU_MAX_WB, BITS_PER_LONG)];
spinlock_t lock;
}; };
int amdgpu_device_wb_get(struct amdgpu_device *adev, u32 *wb); int amdgpu_device_wb_get(struct amdgpu_device *adev, u32 *wb);
......
...@@ -1482,13 +1482,17 @@ static int amdgpu_device_wb_init(struct amdgpu_device *adev) ...@@ -1482,13 +1482,17 @@ static int amdgpu_device_wb_init(struct amdgpu_device *adev)
*/ */
int amdgpu_device_wb_get(struct amdgpu_device *adev, u32 *wb) int amdgpu_device_wb_get(struct amdgpu_device *adev, u32 *wb)
{ {
unsigned long offset = find_first_zero_bit(adev->wb.used, adev->wb.num_wb); unsigned long flags, offset;
spin_lock_irqsave(&adev->wb.lock, flags);
offset = find_first_zero_bit(adev->wb.used, adev->wb.num_wb);
if (offset < adev->wb.num_wb) { if (offset < adev->wb.num_wb) {
__set_bit(offset, adev->wb.used); __set_bit(offset, adev->wb.used);
spin_unlock_irqrestore(&adev->wb.lock, flags);
*wb = offset << 3; /* convert to dw offset */ *wb = offset << 3; /* convert to dw offset */
return 0; return 0;
} else { } else {
spin_unlock_irqrestore(&adev->wb.lock, flags);
return -EINVAL; return -EINVAL;
} }
} }
...@@ -1503,9 +1507,13 @@ int amdgpu_device_wb_get(struct amdgpu_device *adev, u32 *wb) ...@@ -1503,9 +1507,13 @@ int amdgpu_device_wb_get(struct amdgpu_device *adev, u32 *wb)
*/ */
void amdgpu_device_wb_free(struct amdgpu_device *adev, u32 wb) void amdgpu_device_wb_free(struct amdgpu_device *adev, u32 wb)
{ {
unsigned long flags;
wb >>= 3; wb >>= 3;
spin_lock_irqsave(&adev->wb.lock, flags);
if (wb < adev->wb.num_wb) if (wb < adev->wb.num_wb)
__clear_bit(wb, adev->wb.used); __clear_bit(wb, adev->wb.used);
spin_unlock_irqrestore(&adev->wb.lock, flags);
} }
/** /**
...@@ -4061,6 +4069,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, ...@@ -4061,6 +4069,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
spin_lock_init(&adev->se_cac_idx_lock); spin_lock_init(&adev->se_cac_idx_lock);
spin_lock_init(&adev->audio_endpt_idx_lock); spin_lock_init(&adev->audio_endpt_idx_lock);
spin_lock_init(&adev->mm_stats.lock); spin_lock_init(&adev->mm_stats.lock);
spin_lock_init(&adev->wb.lock);
INIT_LIST_HEAD(&adev->shadow_list); INIT_LIST_HEAD(&adev->shadow_list);
mutex_init(&adev->shadow_list_lock); mutex_init(&adev->shadow_list_lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment