xref: /openbmc/linux/drivers/dma-buf/dma-resv.c (revision aa0dc6a7)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright (C) 2012-2014 Canonical Ltd (Maarten Lankhorst)
4  *
5  * Based on bo.c which bears the following copyright notice,
6  * but is dual licensed:
7  *
8  * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
9  * All Rights Reserved.
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a
12  * copy of this software and associated documentation files (the
13  * "Software"), to deal in the Software without restriction, including
14  * without limitation the rights to use, copy, modify, merge, publish,
15  * distribute, sub license, and/or sell copies of the Software, and to
16  * permit persons to whom the Software is furnished to do so, subject to
17  * the following conditions:
18  *
19  * The above copyright notice and this permission notice (including the
20  * next paragraph) shall be included in all copies or substantial portions
21  * of the Software.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
26  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
27  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
28  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
29  * USE OR OTHER DEALINGS IN THE SOFTWARE.
30  *
31  **************************************************************************/
32 /*
33  * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
34  */
35 
36 #include <linux/dma-resv.h>
37 #include <linux/export.h>
38 #include <linux/mm.h>
39 #include <linux/sched/mm.h>
40 #include <linux/mmu_notifier.h>
41 
42 /**
43  * DOC: Reservation Object Overview
44  *
45  * The reservation object provides a mechanism to manage shared and
46  * exclusive fences associated with a buffer.  A reservation object
47  * can have attached one exclusive fence (normally associated with
48  * write operations) or N shared fences (read operations).  The RCU
49  * mechanism is used to protect read access to fences from locked
50  * write-side updates.
51  */
52 
53 DEFINE_WD_CLASS(reservation_ww_class);
54 EXPORT_SYMBOL(reservation_ww_class);
55 
56 /**
57  * dma_resv_list_alloc - allocate fence list
58  * @shared_max: number of fences we need space for
59  *
60  * Allocate a new dma_resv_list and make sure to correctly initialize
61  * shared_max.
62  */
63 static struct dma_resv_list *dma_resv_list_alloc(unsigned int shared_max)
64 {
65 	struct dma_resv_list *list;
66 
67 	list = kmalloc(struct_size(list, shared, shared_max), GFP_KERNEL);
68 	if (!list)
69 		return NULL;
70 
71 	list->shared_max = (ksize(list) - offsetof(typeof(*list), shared)) /
72 		sizeof(*list->shared);
73 
74 	return list;
75 }
76 
77 /**
78  * dma_resv_list_free - free fence list
79  * @list: list to free
80  *
81  * Free a dma_resv_list and make sure to drop all references.
82  */
83 static void dma_resv_list_free(struct dma_resv_list *list)
84 {
85 	unsigned int i;
86 
87 	if (!list)
88 		return;
89 
90 	for (i = 0; i < list->shared_count; ++i)
91 		dma_fence_put(rcu_dereference_protected(list->shared[i], true));
92 
93 	kfree_rcu(list, rcu);
94 }
95 
96 /**
97  * dma_resv_init - initialize a reservation object
98  * @obj: the reservation object
99  */
100 void dma_resv_init(struct dma_resv *obj)
101 {
102 	ww_mutex_init(&obj->lock, &reservation_ww_class);
103 	seqcount_ww_mutex_init(&obj->seq, &obj->lock);
104 
105 	RCU_INIT_POINTER(obj->fence, NULL);
106 	RCU_INIT_POINTER(obj->fence_excl, NULL);
107 }
108 EXPORT_SYMBOL(dma_resv_init);
109 
110 /**
111  * dma_resv_fini - destroys a reservation object
112  * @obj: the reservation object
113  */
114 void dma_resv_fini(struct dma_resv *obj)
115 {
116 	struct dma_resv_list *fobj;
117 	struct dma_fence *excl;
118 
119 	/*
120 	 * This object should be dead and all references must have
121 	 * been released to it, so no need to be protected with rcu.
122 	 */
123 	excl = rcu_dereference_protected(obj->fence_excl, 1);
124 	if (excl)
125 		dma_fence_put(excl);
126 
127 	fobj = rcu_dereference_protected(obj->fence, 1);
128 	dma_resv_list_free(fobj);
129 	ww_mutex_destroy(&obj->lock);
130 }
131 EXPORT_SYMBOL(dma_resv_fini);
132 
133 /**
134  * dma_resv_reserve_shared - Reserve space to add shared fences to
135  * a dma_resv.
136  * @obj: reservation object
137  * @num_fences: number of fences we want to add
138  *
139  * Should be called before dma_resv_add_shared_fence().  Must
140  * be called with obj->lock held.
141  *
142  * RETURNS
143  * Zero for success, or -errno
144  */
145 int dma_resv_reserve_shared(struct dma_resv *obj, unsigned int num_fences)
146 {
147 	struct dma_resv_list *old, *new;
148 	unsigned int i, j, k, max;
149 
150 	dma_resv_assert_held(obj);
151 
152 	old = dma_resv_shared_list(obj);
153 	if (old && old->shared_max) {
154 		if ((old->shared_count + num_fences) <= old->shared_max)
155 			return 0;
156 		max = max(old->shared_count + num_fences, old->shared_max * 2);
157 	} else {
158 		max = max(4ul, roundup_pow_of_two(num_fences));
159 	}
160 
161 	new = dma_resv_list_alloc(max);
162 	if (!new)
163 		return -ENOMEM;
164 
165 	/*
166 	 * no need to bump fence refcounts, rcu_read access
167 	 * requires the use of kref_get_unless_zero, and the
168 	 * references from the old struct are carried over to
169 	 * the new.
170 	 */
171 	for (i = 0, j = 0, k = max; i < (old ? old->shared_count : 0); ++i) {
172 		struct dma_fence *fence;
173 
174 		fence = rcu_dereference_protected(old->shared[i],
175 						  dma_resv_held(obj));
176 		if (dma_fence_is_signaled(fence))
177 			RCU_INIT_POINTER(new->shared[--k], fence);
178 		else
179 			RCU_INIT_POINTER(new->shared[j++], fence);
180 	}
181 	new->shared_count = j;
182 
183 	/*
184 	 * We are not changing the effective set of fences here so can
185 	 * merely update the pointer to the new array; both existing
186 	 * readers and new readers will see exactly the same set of
187 	 * active (unsignaled) shared fences. Individual fences and the
188 	 * old array are protected by RCU and so will not vanish under
189 	 * the gaze of the rcu_read_lock() readers.
190 	 */
191 	rcu_assign_pointer(obj->fence, new);
192 
193 	if (!old)
194 		return 0;
195 
196 	/* Drop the references to the signaled fences */
197 	for (i = k; i < max; ++i) {
198 		struct dma_fence *fence;
199 
200 		fence = rcu_dereference_protected(new->shared[i],
201 						  dma_resv_held(obj));
202 		dma_fence_put(fence);
203 	}
204 	kfree_rcu(old, rcu);
205 
206 	return 0;
207 }
208 EXPORT_SYMBOL(dma_resv_reserve_shared);
209 
210 #ifdef CONFIG_DEBUG_MUTEXES
211 /**
212  * dma_resv_reset_shared_max - reset shared fences for debugging
213  * @obj: the dma_resv object to reset
214  *
215  * Reset the number of pre-reserved shared slots to test that drivers do
216  * correct slot allocation using dma_resv_reserve_shared(). See also
217  * &dma_resv_list.shared_max.
218  */
219 void dma_resv_reset_shared_max(struct dma_resv *obj)
220 {
221 	struct dma_resv_list *fences = dma_resv_shared_list(obj);
222 
223 	dma_resv_assert_held(obj);
224 
225 	/* Test shared fence slot reservation */
226 	if (fences)
227 		fences->shared_max = fences->shared_count;
228 }
229 EXPORT_SYMBOL(dma_resv_reset_shared_max);
230 #endif
231 
232 /**
233  * dma_resv_add_shared_fence - Add a fence to a shared slot
234  * @obj: the reservation object
235  * @fence: the shared fence to add
236  *
237  * Add a fence to a shared slot, obj->lock must be held, and
238  * dma_resv_reserve_shared() has been called.
239  */
240 void dma_resv_add_shared_fence(struct dma_resv *obj, struct dma_fence *fence)
241 {
242 	struct dma_resv_list *fobj;
243 	struct dma_fence *old;
244 	unsigned int i, count;
245 
246 	dma_fence_get(fence);
247 
248 	dma_resv_assert_held(obj);
249 
250 	fobj = dma_resv_shared_list(obj);
251 	count = fobj->shared_count;
252 
253 	write_seqcount_begin(&obj->seq);
254 
255 	for (i = 0; i < count; ++i) {
256 
257 		old = rcu_dereference_protected(fobj->shared[i],
258 						dma_resv_held(obj));
259 		if (old->context == fence->context ||
260 		    dma_fence_is_signaled(old))
261 			goto replace;
262 	}
263 
264 	BUG_ON(fobj->shared_count >= fobj->shared_max);
265 	old = NULL;
266 	count++;
267 
268 replace:
269 	RCU_INIT_POINTER(fobj->shared[i], fence);
270 	/* pointer update must be visible before we extend the shared_count */
271 	smp_store_mb(fobj->shared_count, count);
272 
273 	write_seqcount_end(&obj->seq);
274 	dma_fence_put(old);
275 }
276 EXPORT_SYMBOL(dma_resv_add_shared_fence);
277 
278 /**
279  * dma_resv_add_excl_fence - Add an exclusive fence.
280  * @obj: the reservation object
281  * @fence: the shared fence to add
282  *
283  * Add a fence to the exclusive slot.  The obj->lock must be held.
284  */
285 void dma_resv_add_excl_fence(struct dma_resv *obj, struct dma_fence *fence)
286 {
287 	struct dma_fence *old_fence = dma_resv_excl_fence(obj);
288 	struct dma_resv_list *old;
289 	u32 i = 0;
290 
291 	dma_resv_assert_held(obj);
292 
293 	old = dma_resv_shared_list(obj);
294 	if (old)
295 		i = old->shared_count;
296 
297 	if (fence)
298 		dma_fence_get(fence);
299 
300 	write_seqcount_begin(&obj->seq);
301 	/* write_seqcount_begin provides the necessary memory barrier */
302 	RCU_INIT_POINTER(obj->fence_excl, fence);
303 	if (old)
304 		old->shared_count = 0;
305 	write_seqcount_end(&obj->seq);
306 
307 	/* inplace update, no shared fences */
308 	while (i--)
309 		dma_fence_put(rcu_dereference_protected(old->shared[i],
310 						dma_resv_held(obj)));
311 
312 	dma_fence_put(old_fence);
313 }
314 EXPORT_SYMBOL(dma_resv_add_excl_fence);
315 
316 /**
317  * dma_resv_copy_fences - Copy all fences from src to dst.
318  * @dst: the destination reservation object
319  * @src: the source reservation object
320  *
321  * Copy all fences from src to dst. dst-lock must be held.
322  */
323 int dma_resv_copy_fences(struct dma_resv *dst, struct dma_resv *src)
324 {
325 	struct dma_resv_list *src_list, *dst_list;
326 	struct dma_fence *old, *new;
327 	unsigned int i;
328 
329 	dma_resv_assert_held(dst);
330 
331 	rcu_read_lock();
332 	src_list = dma_resv_shared_list(src);
333 
334 retry:
335 	if (src_list) {
336 		unsigned int shared_count = src_list->shared_count;
337 
338 		rcu_read_unlock();
339 
340 		dst_list = dma_resv_list_alloc(shared_count);
341 		if (!dst_list)
342 			return -ENOMEM;
343 
344 		rcu_read_lock();
345 		src_list = dma_resv_shared_list(src);
346 		if (!src_list || src_list->shared_count > shared_count) {
347 			kfree(dst_list);
348 			goto retry;
349 		}
350 
351 		dst_list->shared_count = 0;
352 		for (i = 0; i < src_list->shared_count; ++i) {
353 			struct dma_fence __rcu **dst;
354 			struct dma_fence *fence;
355 
356 			fence = rcu_dereference(src_list->shared[i]);
357 			if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
358 				     &fence->flags))
359 				continue;
360 
361 			if (!dma_fence_get_rcu(fence)) {
362 				dma_resv_list_free(dst_list);
363 				src_list = dma_resv_shared_list(src);
364 				goto retry;
365 			}
366 
367 			if (dma_fence_is_signaled(fence)) {
368 				dma_fence_put(fence);
369 				continue;
370 			}
371 
372 			dst = &dst_list->shared[dst_list->shared_count++];
373 			rcu_assign_pointer(*dst, fence);
374 		}
375 	} else {
376 		dst_list = NULL;
377 	}
378 
379 	new = dma_fence_get_rcu_safe(&src->fence_excl);
380 	rcu_read_unlock();
381 
382 	src_list = dma_resv_shared_list(dst);
383 	old = dma_resv_excl_fence(dst);
384 
385 	write_seqcount_begin(&dst->seq);
386 	/* write_seqcount_begin provides the necessary memory barrier */
387 	RCU_INIT_POINTER(dst->fence_excl, new);
388 	RCU_INIT_POINTER(dst->fence, dst_list);
389 	write_seqcount_end(&dst->seq);
390 
391 	dma_resv_list_free(src_list);
392 	dma_fence_put(old);
393 
394 	return 0;
395 }
396 EXPORT_SYMBOL(dma_resv_copy_fences);
397 
398 /**
399  * dma_resv_get_fences - Get an object's shared and exclusive
400  * fences without update side lock held
401  * @obj: the reservation object
402  * @pfence_excl: the returned exclusive fence (or NULL)
403  * @pshared_count: the number of shared fences returned
404  * @pshared: the array of shared fence ptrs returned (array is krealloc'd to
405  * the required size, and must be freed by caller)
406  *
407  * Retrieve all fences from the reservation object. If the pointer for the
408  * exclusive fence is not specified the fence is put into the array of the
409  * shared fences as well. Returns either zero or -ENOMEM.
410  */
411 int dma_resv_get_fences(struct dma_resv *obj, struct dma_fence **pfence_excl,
412 			unsigned int *pshared_count,
413 			struct dma_fence ***pshared)
414 {
415 	struct dma_fence **shared = NULL;
416 	struct dma_fence *fence_excl;
417 	unsigned int shared_count;
418 	int ret = 1;
419 
420 	do {
421 		struct dma_resv_list *fobj;
422 		unsigned int i, seq;
423 		size_t sz = 0;
424 
425 		shared_count = i = 0;
426 
427 		rcu_read_lock();
428 		seq = read_seqcount_begin(&obj->seq);
429 
430 		fence_excl = dma_resv_excl_fence(obj);
431 		if (fence_excl && !dma_fence_get_rcu(fence_excl))
432 			goto unlock;
433 
434 		fobj = dma_resv_shared_list(obj);
435 		if (fobj)
436 			sz += sizeof(*shared) * fobj->shared_max;
437 
438 		if (!pfence_excl && fence_excl)
439 			sz += sizeof(*shared);
440 
441 		if (sz) {
442 			struct dma_fence **nshared;
443 
444 			nshared = krealloc(shared, sz,
445 					   GFP_NOWAIT | __GFP_NOWARN);
446 			if (!nshared) {
447 				rcu_read_unlock();
448 
449 				dma_fence_put(fence_excl);
450 				fence_excl = NULL;
451 
452 				nshared = krealloc(shared, sz, GFP_KERNEL);
453 				if (nshared) {
454 					shared = nshared;
455 					continue;
456 				}
457 
458 				ret = -ENOMEM;
459 				break;
460 			}
461 			shared = nshared;
462 			shared_count = fobj ? fobj->shared_count : 0;
463 			for (i = 0; i < shared_count; ++i) {
464 				shared[i] = rcu_dereference(fobj->shared[i]);
465 				if (!dma_fence_get_rcu(shared[i]))
466 					break;
467 			}
468 		}
469 
470 		if (i != shared_count || read_seqcount_retry(&obj->seq, seq)) {
471 			while (i--)
472 				dma_fence_put(shared[i]);
473 			dma_fence_put(fence_excl);
474 			goto unlock;
475 		}
476 
477 		ret = 0;
478 unlock:
479 		rcu_read_unlock();
480 	} while (ret);
481 
482 	if (pfence_excl)
483 		*pfence_excl = fence_excl;
484 	else if (fence_excl)
485 		shared[shared_count++] = fence_excl;
486 
487 	if (!shared_count) {
488 		kfree(shared);
489 		shared = NULL;
490 	}
491 
492 	*pshared_count = shared_count;
493 	*pshared = shared;
494 	return ret;
495 }
496 EXPORT_SYMBOL_GPL(dma_resv_get_fences);
497 
498 /**
499  * dma_resv_wait_timeout - Wait on reservation's objects
500  * shared and/or exclusive fences.
501  * @obj: the reservation object
502  * @wait_all: if true, wait on all fences, else wait on just exclusive fence
503  * @intr: if true, do interruptible wait
504  * @timeout: timeout value in jiffies or zero to return immediately
505  *
506  * Callers are not required to hold specific locks, but maybe hold
507  * dma_resv_lock() already
508  * RETURNS
509  * Returns -ERESTARTSYS if interrupted, 0 if the wait timed out, or
510  * greater than zer on success.
511  */
512 long dma_resv_wait_timeout(struct dma_resv *obj, bool wait_all, bool intr,
513 			   unsigned long timeout)
514 {
515 	long ret = timeout ? timeout : 1;
516 	unsigned int seq, shared_count;
517 	struct dma_fence *fence;
518 	int i;
519 
520 retry:
521 	shared_count = 0;
522 	seq = read_seqcount_begin(&obj->seq);
523 	rcu_read_lock();
524 	i = -1;
525 
526 	fence = dma_resv_excl_fence(obj);
527 	if (fence && !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) {
528 		if (!dma_fence_get_rcu(fence))
529 			goto unlock_retry;
530 
531 		if (dma_fence_is_signaled(fence)) {
532 			dma_fence_put(fence);
533 			fence = NULL;
534 		}
535 
536 	} else {
537 		fence = NULL;
538 	}
539 
540 	if (wait_all) {
541 		struct dma_resv_list *fobj = dma_resv_shared_list(obj);
542 
543 		if (fobj)
544 			shared_count = fobj->shared_count;
545 
546 		for (i = 0; !fence && i < shared_count; ++i) {
547 			struct dma_fence *lfence;
548 
549 			lfence = rcu_dereference(fobj->shared[i]);
550 			if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
551 				     &lfence->flags))
552 				continue;
553 
554 			if (!dma_fence_get_rcu(lfence))
555 				goto unlock_retry;
556 
557 			if (dma_fence_is_signaled(lfence)) {
558 				dma_fence_put(lfence);
559 				continue;
560 			}
561 
562 			fence = lfence;
563 			break;
564 		}
565 	}
566 
567 	rcu_read_unlock();
568 	if (fence) {
569 		if (read_seqcount_retry(&obj->seq, seq)) {
570 			dma_fence_put(fence);
571 			goto retry;
572 		}
573 
574 		ret = dma_fence_wait_timeout(fence, intr, ret);
575 		dma_fence_put(fence);
576 		if (ret > 0 && wait_all && (i + 1 < shared_count))
577 			goto retry;
578 	}
579 	return ret;
580 
581 unlock_retry:
582 	rcu_read_unlock();
583 	goto retry;
584 }
585 EXPORT_SYMBOL_GPL(dma_resv_wait_timeout);
586 
587 
588 static inline int dma_resv_test_signaled_single(struct dma_fence *passed_fence)
589 {
590 	struct dma_fence *fence, *lfence = passed_fence;
591 	int ret = 1;
592 
593 	if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &lfence->flags)) {
594 		fence = dma_fence_get_rcu(lfence);
595 		if (!fence)
596 			return -1;
597 
598 		ret = !!dma_fence_is_signaled(fence);
599 		dma_fence_put(fence);
600 	}
601 	return ret;
602 }
603 
604 /**
605  * dma_resv_test_signaled - Test if a reservation object's fences have been
606  * signaled.
607  * @obj: the reservation object
608  * @test_all: if true, test all fences, otherwise only test the exclusive
609  * fence
610  *
611  * Callers are not required to hold specific locks, but maybe hold
612  * dma_resv_lock() already
613  * RETURNS
614  * true if all fences signaled, else false
615  */
616 bool dma_resv_test_signaled(struct dma_resv *obj, bool test_all)
617 {
618 	unsigned int seq, shared_count;
619 	int ret;
620 
621 	rcu_read_lock();
622 retry:
623 	ret = true;
624 	shared_count = 0;
625 	seq = read_seqcount_begin(&obj->seq);
626 
627 	if (test_all) {
628 		struct dma_resv_list *fobj = dma_resv_shared_list(obj);
629 		unsigned int i;
630 
631 		if (fobj)
632 			shared_count = fobj->shared_count;
633 
634 		for (i = 0; i < shared_count; ++i) {
635 			struct dma_fence *fence;
636 
637 			fence = rcu_dereference(fobj->shared[i]);
638 			ret = dma_resv_test_signaled_single(fence);
639 			if (ret < 0)
640 				goto retry;
641 			else if (!ret)
642 				break;
643 		}
644 
645 		if (read_seqcount_retry(&obj->seq, seq))
646 			goto retry;
647 	}
648 
649 	if (!shared_count) {
650 		struct dma_fence *fence_excl = dma_resv_excl_fence(obj);
651 
652 		if (fence_excl) {
653 			ret = dma_resv_test_signaled_single(fence_excl);
654 			if (ret < 0)
655 				goto retry;
656 
657 			if (read_seqcount_retry(&obj->seq, seq))
658 				goto retry;
659 		}
660 	}
661 
662 	rcu_read_unlock();
663 	return ret;
664 }
665 EXPORT_SYMBOL_GPL(dma_resv_test_signaled);
666 
667 #if IS_ENABLED(CONFIG_LOCKDEP)
668 static int __init dma_resv_lockdep(void)
669 {
670 	struct mm_struct *mm = mm_alloc();
671 	struct ww_acquire_ctx ctx;
672 	struct dma_resv obj;
673 	struct address_space mapping;
674 	int ret;
675 
676 	if (!mm)
677 		return -ENOMEM;
678 
679 	dma_resv_init(&obj);
680 	address_space_init_once(&mapping);
681 
682 	mmap_read_lock(mm);
683 	ww_acquire_init(&ctx, &reservation_ww_class);
684 	ret = dma_resv_lock(&obj, &ctx);
685 	if (ret == -EDEADLK)
686 		dma_resv_lock_slow(&obj, &ctx);
687 	fs_reclaim_acquire(GFP_KERNEL);
688 	/* for unmap_mapping_range on trylocked buffer objects in shrinkers */
689 	i_mmap_lock_write(&mapping);
690 	i_mmap_unlock_write(&mapping);
691 #ifdef CONFIG_MMU_NOTIFIER
692 	lock_map_acquire(&__mmu_notifier_invalidate_range_start_map);
693 	__dma_fence_might_wait();
694 	lock_map_release(&__mmu_notifier_invalidate_range_start_map);
695 #else
696 	__dma_fence_might_wait();
697 #endif
698 	fs_reclaim_release(GFP_KERNEL);
699 	ww_mutex_unlock(&obj.lock);
700 	ww_acquire_fini(&ctx);
701 	mmap_read_unlock(mm);
702 
703 	mmput(mm);
704 
705 	return 0;
706 }
707 subsys_initcall(dma_resv_lockdep);
708 #endif
709