aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2017-08-10 13:01:48 -0400
committerAlex Deucher <alexander.deucher@amd.com>2017-08-14 13:00:49 -0400
commit7faf952a3030d304334fe527be339b63e9e2745f (patch)
treeb683adcf0d77b936849899e06e7b6f0054a26faa
parenteac99d4a2013d9e68d12d8a5695b221593d3aa8d (diff)
dma-buf: add reservation_object_copy_fences (v2)
Allows us to copy all the fences in a reservation object to another one. v2: handle NULL src_list Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/1502384509-10465-2-git-send-email-alexander.deucher@amd.com
-rw-r--r--drivers/dma-buf/reservation.c60
-rw-r--r--include/linux/reservation.h3
2 files changed, 63 insertions, 0 deletions
diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c
index 87f8f5747500..d4881f91c43b 100644
--- a/drivers/dma-buf/reservation.c
+++ b/drivers/dma-buf/reservation.c
@@ -262,6 +262,66 @@ void reservation_object_add_excl_fence(struct reservation_object *obj,
262EXPORT_SYMBOL(reservation_object_add_excl_fence); 262EXPORT_SYMBOL(reservation_object_add_excl_fence);
263 263
264/** 264/**
265* reservation_object_copy_fences - Copy all fences from src to dst.
266* @dst: the destination reservation object
267* @src: the source reservation object
268*
269* Copy all fences from src to dst. Both src->lock as well as dst-lock must be
270* held.
271*/
272int reservation_object_copy_fences(struct reservation_object *dst,
273 struct reservation_object *src)
274{
275 struct reservation_object_list *src_list, *dst_list;
276 struct dma_fence *old, *new;
277 size_t size;
278 unsigned i;
279
280 src_list = reservation_object_get_list(src);
281
282 if (src_list) {
283 size = offsetof(typeof(*src_list),
284 shared[src_list->shared_count]);
285 dst_list = kmalloc(size, GFP_KERNEL);
286 if (!dst_list)
287 return -ENOMEM;
288
289 dst_list->shared_count = src_list->shared_count;
290 dst_list->shared_max = src_list->shared_count;
291 for (i = 0; i < src_list->shared_count; ++i)
292 dst_list->shared[i] =
293 dma_fence_get(src_list->shared[i]);
294 } else {
295 dst_list = NULL;
296 }
297
298 kfree(dst->staged);
299 dst->staged = NULL;
300
301 src_list = reservation_object_get_list(dst);
302
303 old = reservation_object_get_excl(dst);
304 new = reservation_object_get_excl(src);
305
306 dma_fence_get(new);
307
308 preempt_disable();
309 write_seqcount_begin(&dst->seq);
310 /* write_seqcount_begin provides the necessary memory barrier */
311 RCU_INIT_POINTER(dst->fence_excl, new);
312 RCU_INIT_POINTER(dst->fence, dst_list);
313 write_seqcount_end(&dst->seq);
314 preempt_enable();
315
316 if (src_list)
317 kfree_rcu(src_list, rcu);
318 dma_fence_put(old);
319
320 return 0;
321}
322EXPORT_SYMBOL(reservation_object_copy_fences);
323
324/**
265 * reservation_object_get_fences_rcu - Get an object's shared and exclusive 325 * reservation_object_get_fences_rcu - Get an object's shared and exclusive
266 * fences without update side lock held 326 * fences without update side lock held
267 * @obj: the reservation object 327 * @obj: the reservation object
diff --git a/include/linux/reservation.h b/include/linux/reservation.h
index 156cfd330b66..21fc84d82d41 100644
--- a/include/linux/reservation.h
+++ b/include/linux/reservation.h
@@ -254,6 +254,9 @@ int reservation_object_get_fences_rcu(struct reservation_object *obj,
254 unsigned *pshared_count, 254 unsigned *pshared_count,
255 struct dma_fence ***pshared); 255 struct dma_fence ***pshared);
256 256
257int reservation_object_copy_fences(struct reservation_object *dst,
258 struct reservation_object *src);
259
257long reservation_object_wait_timeout_rcu(struct reservation_object *obj, 260long reservation_object_wait_timeout_rcu(struct reservation_object *obj,
258 bool wait_all, bool intr, 261 bool wait_all, bool intr,
259 unsigned long timeout); 262 unsigned long timeout);