[PATCH] dmabuf
Chris Wilson
chris at chris-wilson.co.uk
Mon Nov 6 17:00:29 UTC 2017
---
drivers/dma-buf/reservation.c | 57 +++++++++++++++++++++++--------------------
1 file changed, 31 insertions(+), 26 deletions(-)
diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c
index b44d9d7db347..aac4de479c60 100644
--- a/drivers/dma-buf/reservation.c
+++ b/drivers/dma-buf/reservation.c
@@ -104,6 +104,7 @@ reservation_object_add_shared_inplace(struct reservation_object *obj,
struct reservation_object_list *fobj,
struct dma_fence *fence)
{
+ struct dma_fence *replace = NULL;
u32 i;
dma_fence_get(fence);
@@ -117,14 +118,10 @@ reservation_object_add_shared_inplace(struct reservation_object *obj,
old_fence = rcu_dereference_protected(fobj->shared[i],
reservation_object_held(obj));
- if (old_fence->context == fence->context) {
- /* memory barrier is added by write_seqcount_begin */
- RCU_INIT_POINTER(fobj->shared[i], fence);
- write_seqcount_end(&obj->seq);
- preempt_enable();
-
- dma_fence_put(old_fence);
- return;
+ if (old_fence->context == fence->context ||
+ dma_fence_is_signaled(old_fence)) {
+ replace = old_fence;
+ break;
}
}
@@ -132,11 +129,14 @@ reservation_object_add_shared_inplace(struct reservation_object *obj,
* memory barrier is added by write_seqcount_begin,
* fobj->shared_count is protected by this lock too
*/
- RCU_INIT_POINTER(fobj->shared[fobj->shared_count], fence);
- fobj->shared_count++;
+ RCU_INIT_POINTER(fobj->shared[i], fence);
+ if (replace)
+ fobj->shared_count++;
write_seqcount_end(&obj->seq);
preempt_enable();
+
+ dma_fence_put(replace);
}
static void
@@ -145,8 +145,7 @@ reservation_object_add_shared_replace(struct reservation_object *obj,
struct reservation_object_list *fobj,
struct dma_fence *fence)
{
- unsigned i;
- struct dma_fence *old_fence = NULL;
+ unsigned i, j, k;
dma_fence_get(fence);
@@ -162,24 +161,23 @@ reservation_object_add_shared_replace(struct reservation_object *obj,
* references from the old struct are carried over to
* the new.
*/
- fobj->shared_count = old->shared_count;
+ j = 0;
+ k = fobj->shared_max;
+ RCU_INIT_POINTER(fobj->shared[j++], fence);
for (i = 0; i < old->shared_count; ++i) {
struct dma_fence *check;
check = rcu_dereference_protected(old->shared[i],
- reservation_object_held(obj));
+ reservation_object_held(obj));
- if (!old_fence && check->context == fence->context) {
- old_fence = check;
- RCU_INIT_POINTER(fobj->shared[i], fence);
- } else
- RCU_INIT_POINTER(fobj->shared[i], check);
- }
- if (!old_fence) {
- RCU_INIT_POINTER(fobj->shared[fobj->shared_count], fence);
- fobj->shared_count++;
+ if (check->context == fence->context ||
+ dma_fence_is_signaled(check))
+ RCU_INIT_POINTER(fobj->shared[--k], check);
+ else
+ RCU_INIT_POINTER(fobj->shared[j++], check);
}
+ fobj->shared_count = j;
done:
preempt_disable();
@@ -192,10 +190,17 @@ reservation_object_add_shared_replace(struct reservation_object *obj,
write_seqcount_end(&obj->seq);
preempt_enable();
- if (old)
- kfree_rcu(old, rcu);
+ if (!old)
+ return;
- dma_fence_put(old_fence);
+ for (; k < fobj->shared_max; ++k) {
+ struct dma_fence *old_fence;
+
+ old_fence = rcu_dereference_protected(fobj->shared[k],
+ reservation_object_held(obj));
+ dma_fence_put(old_fence);
+ }
+ kfree_rcu(old, rcu);
}
/**
--
2.15.0
More information about the Intel-gfx-trybot
mailing list