[PATCH 1/2] drm/amdgpu: LSDMA supports multiple threads
Alex Deucher <[email protected]>
| Newsgroups | org.freedesktop.lists.amd-gfx |
|---|---|
| Message-ID | <[email protected]> |
From: Philip Yang <[email protected]> Add mutex to serialize LSDMA PIO copy and fill operations for concurrent access from multiple threads. A mutex is used rather than a spinlock because the underlying lsdma_v7_1_wait_pio_status() polls with udelay(), which can busy-wait for up to usec_timeout microseconds. It is optional to call mutex_destroy for clarity and debug correctness, it is no-op for release build, leave it as lsdma block no ip callback funcs to call mutex_destroy. Signed-off-by: Philip Yang <[email protected]> Reviewed-by: Felix Kuehling <[email protected]> Signed-off-by: Alex Deucher <[email protected]> --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_lsdma.c | 20 ++++++++++++++------ drivers/gpu/drm/amd/amdgpu/amdgpu_lsdma.h | 1 + 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index b61c641b5be4f..1503bbf473c49 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -3849,6 +3849,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, spin_lock_init(&adev->mm_stats.lock); spin_lock_init(&adev->virt.rlcg_reg_lock); spin_lock_init(&adev->wb.lock); + mutex_init(&adev->lsdma.lock); INIT_LIST_HEAD(&adev->reset_list); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_lsdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_lsdma.c index 4d1d4994ea3fe..05bc281216bfc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_lsdma.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_lsdma.c @@ -48,23 +48,27 @@ int amdgpu_lsdma_copy_mem(struct amdgpu_device *adev, uint64_t dst_addr, uint64_t mem_size) { - int ret; + int ret = 0; if (mem_size == 0) return -EINVAL; + mutex_lock(&adev->lsdma.lock); + while (mem_size > 0) { uint64_t current_copy_size = min(mem_size, AMDGPU_LSDMA_MAX_SIZE); ret = adev->lsdma.funcs->copy_mem(adev, src_addr, dst_addr, current_copy_size); if (ret) - return ret; + goto out_unlock; src_addr += current_copy_size; dst_addr += current_copy_size; mem_size -= current_copy_size; } - return 0; +out_unlock: + mutex_unlock(&adev->lsdma.lock); + return ret; } int amdgpu_lsdma_fill_mem(struct amdgpu_device *adev, @@ -72,20 +76,24 @@ int amdgpu_lsdma_fill_mem(struct amdgpu_device *adev, uint32_t data, uint64_t mem_size) { - int ret; + int ret = 0; if (mem_size == 0) return -EINVAL; + mutex_lock(&adev->lsdma.lock); + while (mem_size > 0) { uint64_t current_fill_size = min(mem_size, AMDGPU_LSDMA_MAX_SIZE); ret = adev->lsdma.funcs->fill_mem(adev, dst_addr, data, current_fill_size); if (ret) - return ret; + goto out_unlock; dst_addr += current_fill_size; mem_size -= current_fill_size; } - return 0; +out_unlock: + mutex_unlock(&adev->lsdma.lock); + return ret; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_lsdma.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_lsdma.h index c61ba58c5ee0d..e9a0237efd80b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_lsdma.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_lsdma.h @@ -25,6 +25,7 @@ #define __AMDGPU_LSDMA_H__ struct amdgpu_lsdma { + struct mutex lock; const struct amdgpu_lsdma_funcs *funcs; }; -- 2.55.0