Skip to contentSkip to conversation

dma-buf: keep only not signaled fence in reservation_object_add_shared_replace

PATCH In review Christian König 4 participants 7 messages Oct 24, 2017 – Oct 31, 2017 2 messages not in the archive DMA buffer sharing framework

lore
Share & tools
lore
#0 lore raw

PATCH 1/2 dma-buf: keep only not signaled fence in reservation_object_add_shared_replace

From: Christian König <[email protected]>

The amdgpu issue to also need signaled fences in the reservation objects should be fixed by now.

Optimize the list by keeping only the not signaled yet fences around.

---
 drivers/dma-buf/reservation.c | 31 +++++++++++++++++++++----------
 1 file changed, 21 insertions(+), 10 deletions(-)
drivers/dma-buf/reservation.c +21 -10
index b44d9d7db347..4ede77d1bb31 100644
@@ -145,8 +145,8 @@ 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,9 +162,7 @@ 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;
-
-	for (i = 0; i < old->shared_count; ++i) {
+	for (i = 0, j = 0, k = old->shared_count; i < old->shared_count; ++i) {
 		struct dma_fence *check;
 
 		check = rcu_dereference_protected(old->shared[i],
@@ -172,10 +170,14 @@ reservation_object_add_shared_replace(struct reservation_object *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);
+			RCU_INIT_POINTER(fobj->shared[j++], fence);
+		} else if (!dma_fence_is_signaled(check)) {
+			RCU_INIT_POINTER(fobj->shared[j++], check);
+		} else {
+			RCU_INIT_POINTER(fobj->shared[--k], check);
+		}
 	}
+	fobj->shared_count = j;
 	if (!old_fence) {
 		RCU_INIT_POINTER(fobj->shared[fobj->shared_count], fence);
 		fobj->shared_count++;
@@ -192,10 +194,19 @@ reservation_object_add_shared_replace(struct reservation_object *obj,
 	write_seqcount_end(&obj->seq);
 	preempt_enable();
 
-	if (old)
-		kfree_rcu(old, rcu);
-
 	dma_fence_put(old_fence);
+
+	if (!old)
+		return;
+
+	for (i = fobj->shared_count; i < old->shared_count; ++i) {
+		struct dma_fence *f;
+
+		f = rcu_dereference_protected(fobj->shared[i],
+					      reservation_object_held(obj));
+		dma_fence_put(f);
+	}
+	kfree_rcu(old, rcu);
 }
 
 /**
Signature · 6 lines
2.11.0

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
#1 lore raw

PATCH 2/2 dma-buf: try to replace a signaled fence in reservation_object_add_shared_inplace

From: Christian König <[email protected]>

The amdgpu issue to also need signaled fences in the reservation objects should be fixed by now.

Optimize the handling by replacing a signaled fence when adding a new shared one.

---
 drivers/dma-buf/reservation.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)
drivers/dma-buf/reservation.c +15 -3
index 4ede77d1bb31..702ef03a923a 100644
@@ -104,7 +104,8 @@ reservation_object_add_shared_inplace(struct reservation_object *obj,
 				      struct reservation_object_list *fobj,
 				      struct dma_fence *fence)
 {
-	u32 i;
+	struct dma_fence *signaled = NULL;
+	u32 i, signaled_idx;
 
 	dma_fence_get(fence);
 
@@ -126,17 +127,28 @@ reservation_object_add_shared_inplace(struct reservation_object *obj,
 			dma_fence_put(old_fence);
 			return;
 		}
+
+		if (!signaled && dma_fence_is_signaled(old_fence)) {
+			signaled = old_fence;
+			signaled_idx = i;
+		}
 	}
 
 	/*
 	 * 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++;
+	if (signaled) {
+		RCU_INIT_POINTER(fobj->shared[signaled_idx], fence);
+	} else {
+		RCU_INIT_POINTER(fobj->shared[fobj->shared_count], fence);
+		fobj->shared_count++;
+	}
 
 	write_seqcount_end(&obj->seq);
 	preempt_enable();
+
+	dma_fence_put(signaled);
 }
 
 static void
Signature · 6 lines
2.11.0

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
#2 lore raw
In reply to Christian König
Quoted 44 lines · Christian König

From: Christian König <[email protected]>

The amdgpu issue to also need signaled fences in the reservation objects should be fixed by now.

Optimize the list by keeping only the not signaled yet fences around.

---
  drivers/dma-buf/reservation.c | 31 +++++++++++++++++++++----------
  1 file changed, 21 insertions(+), 10 deletions(-)
drivers/dma-buf/reservation.c +2 -7
index b44d9d7db347..4ede77d1bb31 100644
@@ -145,8 +145,8 @@ 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,9 +162,7 @@ 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;
-
-	for (i = 0; i < old->shared_count; ++i) {
+	for (i = 0, j = 0, k = old->shared_count; i < old->shared_count; ++i) {
  		struct dma_fence *check;
 
  		check = rcu_dereference_protected(old->shared[i],
@@ -172,10 +170,14 @@ reservation_object_add_shared_replace(struct reservation_object *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);

drivers/dma-buf/reservation.c reservation_object_add_shared_replace(struct reservation_object *obj, · line 182

Quoted 10 lines
drivers/dma-buf/reservation.c +7 -0
+			RCU_INIT_POINTER(fobj->shared[j++], fence);
+		} else if (!dma_fence_is_signaled(check)) {
+			RCU_INIT_POINTER(fobj->shared[j++], check);
+		} else {
+			RCU_INIT_POINTER(fobj->shared[--k], check);
+		}
  	}
+	fobj->shared_count = j;
  	if (!old_fence) {
  		RCU_INIT_POINTER(fobj->shared[fobj->shared_count], fence);

Here there is a memory leak for signaled fence slots, since you re-order the slots, the j'th slot is storing signaled fence, there is no place to put it when you assign to new one. you cam move it to end or put it here first.

Regards,
David Zhou

Quoted 14 lines
drivers/dma-buf/reservation.c +5 -3
  		fobj->shared_count++;
@@ -192,10 +194,19 @@ reservation_object_add_shared_replace(struct reservation_object *obj,
  	write_seqcount_end(&obj->seq);
  	preempt_enable();
 
-	if (old)
-		kfree_rcu(old, rcu);
-
  	dma_fence_put(old_fence);
+
+	if (!old)
+		return;
+
+	for (i = fobj->shared_count; i < old->shared_count; ++i) {

drivers/dma-buf/reservation.c reservation_object_add_shared_replace(struct reservation_object *obj, · line 212

Quoted 10 lines
drivers/dma-buf/reservation.c +7 -0
+		struct dma_fence *f;
+
+		f = rcu_dereference_protected(fobj->shared[i],
+					      reservation_object_held(obj));
+		dma_fence_put(f);
+	}
+	kfree_rcu(old, rcu);
  }
 
  /**

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel

A message that is not in the archive (sent off-list or not yet received): 5985440d-0928-31c1-4044-0e4ce3385f91-5C7GfCeVMHo@public.gmane.org

#4 lore raw

Am 25.10.2017 um 08:42 schrieb Chunming Zhou:

Quoted 50 lines · Christian König
Quoted 47 lines

From: Christian König <[email protected]>

The amdgpu issue to also need signaled fences in the reservation objects should be fixed by now.

Optimize the list by keeping only the not signaled yet fences around.

---
  drivers/dma-buf/reservation.c | 31 +++++++++++++++++++++----------

  1 file changed, 21 insertions(+), 10 deletions(-)
drivers/dma-buf/reservation.c +1 -1
index b44d9d7db347..4ede77d1bb31 100644
@@ -145,8 +145,8 @@ 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,9 +162,7 @@ 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;
-
-    for (i = 0; i < old->shared_count; ++i) {
+    for (i = 0, j = 0, k = old->shared_count; i < old->shared_count; ++i) {
          struct dma_fence *check;
            check = rcu_dereference_protected(old->shared[i],

drivers/dma-buf/reservation.c +4 -3
@@ -172,10 +170,14 @@ reservation_object_add_shared_replace(struct 
 reservation_object *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);
+            RCU_INIT_POINTER(fobj->shared[j++], fence);
+        } else if (!dma_fence_is_signaled(check)) {
+            RCU_INIT_POINTER(fobj->shared[j++], check);
+        } else {
Quoted 8 lines

drivers/dma-buf/reservation.c reservation_object_add_shared_replace(struct reservation_object *obj, · line 182

Quoted 6 lines
drivers/dma-buf/reservation.c +3 -0
+            RCU_INIT_POINTER(fobj->shared[--k], check);
+        }
       }
+    fobj->shared_count = j;
       if (!old_fence) {
 RCU_INIT_POINTER(fobj->shared[fobj->shared_count], fence);

Here there is a memory leak for signaled fence slots, since you re-order the slots, the j'th slot is storing signaled fence, there is no place to put it when you assign to new one. you cam move it to end or put it here first.

Good point, thanks. Going to respin.

Regards,
Christian.

Quoted 18 lines

Regards,
David Zhou

Quoted 15 lines
drivers/dma-buf/reservation.c +6 -2
           fobj->shared_count++;
@@ -192,10 +194,19 @@ reservation_object_add_shared_replace(struct 
 reservation_object *obj,
       write_seqcount_end(&obj->seq);
       preempt_enable();
   -    if (old)
-        kfree_rcu(old, rcu);
-
       dma_fence_put(old_fence);
+
+    if (!old)
+        return;
+
+    for (i = fobj->shared_count; i < old->shared_count; ++i) {
+        struct dma_fence *f;
Quoted 9 lines

drivers/dma-buf/reservation.c reservation_object_add_shared_replace(struct reservation_object *obj, · line 212

Quoted 8 lines
drivers/dma-buf/reservation.c +6 -0
+
+        f = rcu_dereference_protected(fobj->shared[i],
+                          reservation_object_held(obj));
+        dma_fence_put(f);
+    }
+    kfree_rcu(old, rcu);
   }
     /**

_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

#5 lore raw

Any update?

Quoted 60 lines · Christian König

Am 25.10.2017 um 08:42 schrieb Chunming Zhou:

Quoted 50 lines · Christian König
Quoted 47 lines

From: Christian König <[email protected]>

The amdgpu issue to also need signaled fences in the reservation objects should be fixed by now.

Optimize the list by keeping only the not signaled yet fences around.

---
  drivers/dma-buf/reservation.c | 31 +++++++++++++++++++++----------

  1 file changed, 21 insertions(+), 10 deletions(-)
drivers/dma-buf/reservation.c +1 -1
index b44d9d7db347..4ede77d1bb31 100644
@@ -145,8 +145,8 @@ 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,9 +162,7 @@ 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;
-
-    for (i = 0; i < old->shared_count; ++i) {
+    for (i = 0, j = 0, k = old->shared_count; i < old->shared_count; ++i) {
          struct dma_fence *check;
            check = rcu_dereference_protected(old->shared[i],

drivers/dma-buf/reservation.c +4 -3
@@ -172,10 +170,14 @@ reservation_object_add_shared_replace(struct 
 reservation_object *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);
+            RCU_INIT_POINTER(fobj->shared[j++], fence);
+        } else if (!dma_fence_is_signaled(check)) {
+            RCU_INIT_POINTER(fobj->shared[j++], check);
+        } else {
Quoted 8 lines

drivers/dma-buf/reservation.c reservation_object_add_shared_replace(struct reservation_object *obj, · line 182

Quoted 6 lines
drivers/dma-buf/reservation.c +3 -0
+            RCU_INIT_POINTER(fobj->shared[--k], check);
+        }
       }
+    fobj->shared_count = j;
       if (!old_fence) {
 RCU_INIT_POINTER(fobj->shared[fobj->shared_count], fence);

Here there is a memory leak for signaled fence slots, since you re-order the slots, the j'th slot is storing signaled fence, there is no place to put it when you assign to new one. you cam move it to end or put it here first.

Quoted 33 lines

Good point, thanks. Going to respin.

Regards,
Christian.

Quoted 27 lines

Regards,
David Zhou

Quoted 23 lines
drivers/dma-buf/reservation.c +12 -2
           fobj->shared_count++;
@@ -192,10 +194,19 @@ reservation_object_add_shared_replace(struct 
 reservation_object *obj,
       write_seqcount_end(&obj->seq);
       preempt_enable();
   -    if (old)
-        kfree_rcu(old, rcu);
-
       dma_fence_put(old_fence);
+
+    if (!old)
+        return;
+
+    for (i = fobj->shared_count; i < old->shared_count; ++i) {
+        struct dma_fence *f;
+
+        f = rcu_dereference_protected(fobj->shared[i],
+                          reservation_object_held(obj));
+        dma_fence_put(f);
+    }
+    kfree_rcu(old, rcu);
   }
     /**

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel

A message that is not in the archive (sent off-list or not yet received): ef041966-340b-1ac0-a658-c4e2693a03c2-5C7GfCeVMHo@public.gmane.org

#7 lore raw

Looks like v2 never made it to the list. I've just send the V2 patches once more.

Christian.

Am 31.10.2017 um 08:26 schrieb Chunming Zhou:

Quoted 98 lines

Any update?

Quoted 60 lines · Christian König

Am 25.10.2017 um 08:42 schrieb Chunming Zhou:

Quoted 50 lines · Christian König
Quoted 47 lines

From: Christian König <[email protected]>

The amdgpu issue to also need signaled fences in the reservation objects should be fixed by now.

Optimize the list by keeping only the not signaled yet fences around.

---
  drivers/dma-buf/reservation.c | 31 +++++++++++++++++++++----------

  1 file changed, 21 insertions(+), 10 deletions(-)
drivers/dma-buf/reservation.c +1 -1
index b44d9d7db347..4ede77d1bb31 100644
@@ -145,8 +145,8 @@ 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,9 +162,7 @@ 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;
-
-    for (i = 0; i < old->shared_count; ++i) {
+    for (i = 0, j = 0, k = old->shared_count; i < old->shared_count; ++i) {
          struct dma_fence *check;
            check = rcu_dereference_protected(old->shared[i],

drivers/dma-buf/reservation.c +4 -3
@@ -172,10 +170,14 @@ reservation_object_add_shared_replace(struct 
 reservation_object *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);
+            RCU_INIT_POINTER(fobj->shared[j++], fence);
+        } else if (!dma_fence_is_signaled(check)) {
+            RCU_INIT_POINTER(fobj->shared[j++], check);
+        } else {
Quoted 8 lines

drivers/dma-buf/reservation.c reservation_object_add_shared_replace(struct reservation_object *obj, · line 182

Quoted 6 lines
drivers/dma-buf/reservation.c +3 -0
+            RCU_INIT_POINTER(fobj->shared[--k], check);
+        }
       }
+    fobj->shared_count = j;
       if (!old_fence) {
 RCU_INIT_POINTER(fobj->shared[fobj->shared_count], fence);

Here there is a memory leak for signaled fence slots, since you re-order the slots, the j'th slot is storing signaled fence, there is no place to put it when you assign to new one. you cam move it to end or put it here first.

Quoted 33 lines

Good point, thanks. Going to respin.

Regards,
Christian.

Quoted 27 lines

Regards,
David Zhou

Quoted 23 lines
drivers/dma-buf/reservation.c +12 -2
           fobj->shared_count++;
@@ -192,10 +194,19 @@ reservation_object_add_shared_replace(struct 
 reservation_object *obj,
       write_seqcount_end(&obj->seq);
       preempt_enable();
   -    if (old)
-        kfree_rcu(old, rcu);
-
       dma_fence_put(old_fence);
+
+    if (!old)
+        return;
+
+    for (i = fobj->shared_count; i < old->shared_count; ++i) {
+        struct dma_fence *f;
+
+        f = rcu_dereference_protected(fobj->shared[i],
+                          reservation_object_held(obj));
+        dma_fence_put(f);
+    }
+    kfree_rcu(old, rcu);
   }
     /**
Quoted 4 lines

_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

#8 lore raw
Quoted 2 lines · Christian König

Looks like v2 never made it to the list. I've just send the V2 patches once more.

FWIW, I received your v2 patches yesterday, and now twice today.

Signature · 6 lines
Earthling Michel Dänzer               |               http://www.amd.com
Libre software enthusiast             |             Mesa and X developer
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel