diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/4139-dma-buf-keep-only-not-signaled-fence-in-reservation_.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.14.71/4139-dma-buf-keep-only-not-signaled-fence-in-reservation_.patch | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/4139-dma-buf-keep-only-not-signaled-fence-in-reservation_.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/4139-dma-buf-keep-only-not-signaled-fence-in-reservation_.patch new file mode 100644 index 00000000..f8c4c6ad --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/4139-dma-buf-keep-only-not-signaled-fence-in-reservation_.patch @@ -0,0 +1,217 @@ +From 4257a32da4d8822eb49b8f726d8168282536ea5f Mon Sep 17 00:00:00 2001 +From: Chaudhary Amit Kumar <chaudharyamit.kumar@amd.com> +Date: Wed, 9 Jan 2019 18:15:08 +0530 +Subject: [PATCH 4139/5725] dma-buf: keep only not signaled fence in + reservation_object_add_shared_replace v3 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +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. + +v2: temporary put the signaled fences at the end of the new container +v3: put the old fence at the end of the new container as well. + +Signed-off-by: Christian König <christian.koenig@amd.com> +Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> +Tested-by: Chris Wilson <chris@chris-wilson.co.uk> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +Link: https://patchwork.freedesktop.org/patch/msgid/20171114142436.1360-1-christian.koenig@amd.com +Signed-off-by: Kalyan Alle <kalyan.alle@amd.com> +Signed-off-by: Chaudhary Amit Kumar <chaudharyamit.kumar@amd.com> +--- + drivers/dma-buf/reservation.c | 87 ++++++++++++++++++++++++++++--------------- + 1 file changed, 58 insertions(+), 29 deletions(-) + mode change 100644 => 100755 drivers/dma-buf/reservation.c + +diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c +old mode 100644 +new mode 100755 +index 012fa3d..1bc15f6 +--- a/drivers/dma-buf/reservation.c ++++ b/drivers/dma-buf/reservation.c +@@ -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 +@@ -145,8 +157,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 +173,21 @@ 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 = fobj->shared_max; i < old->shared_count; ++i) { + struct dma_fence *check; + + check = rcu_dereference_protected(old->shared[i], + 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; ++ RCU_INIT_POINTER(fobj->shared[fobj->shared_count], fence); ++ fobj->shared_count++; + + done: + preempt_disable(); +@@ -192,10 +200,18 @@ 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); ++ /* Drop the references to the signaled fences */ ++ for (i = k; i < fobj->shared_max; ++i) { ++ struct dma_fence *f; ++ ++ f = rcu_dereference_protected(fobj->shared[i], ++ reservation_object_held(obj)); ++ dma_fence_put(f); ++ } ++ kfree_rcu(old, rcu); + } + + /** +@@ -358,8 +374,9 @@ EXPORT_SYMBOL(reservation_object_copy_fences); + * @pshared: the array of shared fence ptrs returned (array is krealloc'd to + * the required size, and must be freed by caller) + * +- * RETURNS +- * Zero or -errno ++ * Retrieve all fences from the reservation object. If the pointer for the ++ * exclusive fence is not specified the fence is put into the array of the ++ * shared fences as well. Returns either zero or -ENOMEM. + */ + int reservation_object_get_fences_rcu(struct reservation_object *obj, + struct dma_fence **pfence_excl, +@@ -373,8 +390,8 @@ int reservation_object_get_fences_rcu(struct reservation_object *obj, + + do { + struct reservation_object_list *fobj; +- unsigned seq; +- unsigned int i; ++ unsigned int i, seq; ++ size_t sz = 0; + + shared_count = i = 0; + +@@ -386,9 +403,14 @@ int reservation_object_get_fences_rcu(struct reservation_object *obj, + goto unlock; + + fobj = rcu_dereference(obj->fence); +- if (fobj) { ++ if (fobj) ++ sz += sizeof(*shared) * fobj->shared_max; ++ ++ if (!pfence_excl && fence_excl) ++ sz += sizeof(*shared); ++ ++ if (sz) { + struct dma_fence **nshared; +- size_t sz = sizeof(*shared) * fobj->shared_max; + + nshared = krealloc(shared, sz, + GFP_NOWAIT | __GFP_NOWARN); +@@ -404,13 +426,19 @@ int reservation_object_get_fences_rcu(struct reservation_object *obj, + break; + } + shared = nshared; +- shared_count = fobj->shared_count; +- ++ shared_count = fobj ? fobj->shared_count : 0; + for (i = 0; i < shared_count; ++i) { + shared[i] = rcu_dereference(fobj->shared[i]); + if (!dma_fence_get_rcu(shared[i])) + break; + } ++ ++ if (!pfence_excl && fence_excl) { ++ shared[i] = fence_excl; ++ fence_excl = NULL; ++ ++i; ++ ++shared_count; ++ } + } + + if (i != shared_count || read_seqcount_retry(&obj->seq, seq)) { +@@ -432,7 +460,8 @@ int reservation_object_get_fences_rcu(struct reservation_object *obj, + + *pshared_count = shared_count; + *pshared = shared; +- *pfence_excl = fence_excl; ++ if (pfence_excl) ++ *pfence_excl = fence_excl; + + return ret; + } +-- +2.7.4 + |