You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
drm/radeon/kms: fix bo's fence association
Previous code did associate fence to bo before the fence was emited and it also didn't lock protected access to ttm sync_obj member. Both of this flaw leads to possible race between different code path. This patch fix this by associating fence only once the fence is emitted and properly lock protect access to sync_obj member of ttm. Fix: https://bugs.freedesktop.org/show_bug.cgi?id=26438 and likely similar others bugs Signed-off-by: Jerome Glisse <jglisse@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
committed by
Dave Airlie
parent
e821767beb
commit
6cb8e1f71c
@@ -306,11 +306,10 @@ void radeon_bo_list_unreserve(struct list_head *head)
|
||||
}
|
||||
}
|
||||
|
||||
int radeon_bo_list_validate(struct list_head *head, void *fence)
|
||||
int radeon_bo_list_validate(struct list_head *head)
|
||||
{
|
||||
struct radeon_bo_list *lobj;
|
||||
struct radeon_bo *bo;
|
||||
struct radeon_fence *old_fence = NULL;
|
||||
int r;
|
||||
|
||||
r = radeon_bo_list_reserve(head);
|
||||
@@ -334,32 +333,27 @@ int radeon_bo_list_validate(struct list_head *head, void *fence)
|
||||
}
|
||||
lobj->gpu_offset = radeon_bo_gpu_offset(bo);
|
||||
lobj->tiling_flags = bo->tiling_flags;
|
||||
if (fence) {
|
||||
old_fence = (struct radeon_fence *)bo->tbo.sync_obj;
|
||||
bo->tbo.sync_obj = radeon_fence_ref(fence);
|
||||
bo->tbo.sync_obj_arg = NULL;
|
||||
}
|
||||
if (old_fence) {
|
||||
radeon_fence_unref(&old_fence);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void radeon_bo_list_unvalidate(struct list_head *head, void *fence)
|
||||
void radeon_bo_list_fence(struct list_head *head, void *fence)
|
||||
{
|
||||
struct radeon_bo_list *lobj;
|
||||
struct radeon_fence *old_fence;
|
||||
struct radeon_bo *bo;
|
||||
struct radeon_fence *old_fence = NULL;
|
||||
|
||||
if (fence)
|
||||
list_for_each_entry(lobj, head, list) {
|
||||
old_fence = to_radeon_fence(lobj->bo->tbo.sync_obj);
|
||||
if (old_fence == fence) {
|
||||
lobj->bo->tbo.sync_obj = NULL;
|
||||
radeon_fence_unref(&old_fence);
|
||||
}
|
||||
list_for_each_entry(lobj, head, list) {
|
||||
bo = lobj->bo;
|
||||
spin_lock(&bo->tbo.lock);
|
||||
old_fence = (struct radeon_fence *)bo->tbo.sync_obj;
|
||||
bo->tbo.sync_obj = radeon_fence_ref(fence);
|
||||
bo->tbo.sync_obj_arg = NULL;
|
||||
spin_unlock(&bo->tbo.lock);
|
||||
if (old_fence) {
|
||||
radeon_fence_unref(&old_fence);
|
||||
}
|
||||
radeon_bo_list_unreserve(head);
|
||||
}
|
||||
}
|
||||
|
||||
int radeon_bo_fbdev_mmap(struct radeon_bo *bo,
|
||||
|
||||
Reference in New Issue
Block a user