diff options
author | Monk Liu | 2017-08-08 02:34:20 -0500 |
---|---|---|
committer | Alex Deucher | 2017-08-08 11:00:11 -0500 |
commit | 2a89ae5d7a7d5845226ed85146140ff4c8788d59 (patch) | |
tree | d8a7d5caec863950ba1c1a2c4a91b407fcc18ced | |
parent | 4d244155945f5531b4d9735bbe73c887aac81070 (diff) | |
download | external-libdrm-2a89ae5d7a7d5845226ed85146140ff4c8788d59.tar.gz external-libdrm-2a89ae5d7a7d5845226ed85146140ff4c8788d59.tar.xz external-libdrm-2a89ae5d7a7d5845226ed85146140ff4c8788d59.zip |
amdgpu: fix race issue between two bo functions(v2)
there is race issue between two threads on amdgpu_bo_reference and
amdgpu_bo_import, this patch tends to fix it by moving the
pthread_mutex_lock out of bo_free_internal and move to bo_reference
to cover the update_reference part.
The mutex_unlock in bo_import should also cover bo refcount
increasement.
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Monk Liu <monk.liu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | amdgpu/amdgpu_bo.c | 5 | ||||
-rw-r--r-- | amdgpu/amdgpu_internal.h | 13 |
2 files changed, 12 insertions, 6 deletions
diff --git a/amdgpu/amdgpu_bo.c b/amdgpu/amdgpu_bo.c index d2725da8..803fe54c 100644 --- a/amdgpu/amdgpu_bo.c +++ b/amdgpu/amdgpu_bo.c | |||
@@ -56,14 +56,12 @@ static void amdgpu_close_kms_handle(amdgpu_device_handle dev, | |||
56 | drm_private void amdgpu_bo_free_internal(amdgpu_bo_handle bo) | 56 | drm_private void amdgpu_bo_free_internal(amdgpu_bo_handle bo) |
57 | { | 57 | { |
58 | /* Remove the buffer from the hash tables. */ | 58 | /* Remove the buffer from the hash tables. */ |
59 | pthread_mutex_lock(&bo->dev->bo_table_mutex); | ||
60 | util_hash_table_remove(bo->dev->bo_handles, | 59 | util_hash_table_remove(bo->dev->bo_handles, |
61 | (void*)(uintptr_t)bo->handle); | 60 | (void*)(uintptr_t)bo->handle); |
62 | if (bo->flink_name) { | 61 | if (bo->flink_name) { |
63 | util_hash_table_remove(bo->dev->bo_flink_names, | 62 | util_hash_table_remove(bo->dev->bo_flink_names, |
64 | (void*)(uintptr_t)bo->flink_name); | 63 | (void*)(uintptr_t)bo->flink_name); |
65 | } | 64 | } |
66 | pthread_mutex_unlock(&bo->dev->bo_table_mutex); | ||
67 | 65 | ||
68 | /* Release CPU access. */ | 66 | /* Release CPU access. */ |
69 | if (bo->cpu_map_count > 0) { | 67 | if (bo->cpu_map_count > 0) { |
@@ -342,10 +340,9 @@ int amdgpu_bo_import(amdgpu_device_handle dev, | |||
342 | } | 340 | } |
343 | 341 | ||
344 | if (bo) { | 342 | if (bo) { |
345 | pthread_mutex_unlock(&dev->bo_table_mutex); | ||
346 | |||
347 | /* The buffer already exists, just bump the refcount. */ | 343 | /* The buffer already exists, just bump the refcount. */ |
348 | atomic_inc(&bo->refcount); | 344 | atomic_inc(&bo->refcount); |
345 | pthread_mutex_unlock(&dev->bo_table_mutex); | ||
349 | 346 | ||
350 | output->buf_handle = bo; | 347 | output->buf_handle = bo; |
351 | output->alloc_size = bo->alloc_size; | 348 | output->alloc_size = bo->alloc_size; |
diff --git a/amdgpu/amdgpu_internal.h b/amdgpu/amdgpu_internal.h index e68246bf..28d1f38f 100644 --- a/amdgpu/amdgpu_internal.h +++ b/amdgpu/amdgpu_internal.h | |||
@@ -206,8 +206,17 @@ static inline bool update_references(atomic_t *dst, atomic_t *src) | |||
206 | static inline void amdgpu_bo_reference(struct amdgpu_bo **dst, | 206 | static inline void amdgpu_bo_reference(struct amdgpu_bo **dst, |
207 | struct amdgpu_bo *src) | 207 | struct amdgpu_bo *src) |
208 | { | 208 | { |
209 | if (update_references(&(*dst)->refcount, &src->refcount)) | 209 | pthread_mutex_t *mlock; |
210 | amdgpu_bo_free_internal(*dst); | 210 | struct amdgpu_bo* bo = *dst; |
211 | |||
212 | assert(bo != NULL); | ||
213 | mlock = &bo->dev->bo_table_mutex; | ||
214 | pthread_mutex_lock(mlock); | ||
215 | |||
216 | if (update_references(&bo->refcount, src?&src->refcount:NULL)) | ||
217 | amdgpu_bo_free_internal(bo); | ||
218 | |||
219 | pthread_mutex_unlock(mlock); | ||
211 | *dst = src; | 220 | *dst = src; |
212 | } | 221 | } |
213 | 222 | ||