Lines Matching +full:align +full:- +full:size

1 // SPDX-License-Identifier: GPL-2.0 OR MIT
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
48 #include <linux/dma-fence.h>
54 * drm_suballoc_manager_init() - Initialise the drm_suballoc_manager
56 * @size: number of bytes we want to suballocate
57 * @align: alignment for each suballocated chunk
62 size_t size, size_t align) in drm_suballoc_manager_init() argument
68 if (!align) in drm_suballoc_manager_init()
69 align = 1; in drm_suballoc_manager_init()
72 if (WARN_ON_ONCE(align & (align - 1))) in drm_suballoc_manager_init()
73 align = roundup_pow_of_two(align); in drm_suballoc_manager_init()
75 init_waitqueue_head(&sa_manager->wq); in drm_suballoc_manager_init()
76 sa_manager->size = size; in drm_suballoc_manager_init()
77 sa_manager->align = align; in drm_suballoc_manager_init()
78 sa_manager->hole = &sa_manager->olist; in drm_suballoc_manager_init()
79 INIT_LIST_HEAD(&sa_manager->olist); in drm_suballoc_manager_init()
81 INIT_LIST_HEAD(&sa_manager->flist[i]); in drm_suballoc_manager_init()
86 * drm_suballoc_manager_fini() - Destroy the drm_suballoc_manager
97 if (!sa_manager->size) in drm_suballoc_manager_fini()
100 if (!list_empty(&sa_manager->olist)) { in drm_suballoc_manager_fini()
101 sa_manager->hole = &sa_manager->olist; in drm_suballoc_manager_fini()
103 if (!list_empty(&sa_manager->olist)) in drm_suballoc_manager_fini()
106 list_for_each_entry_safe(sa, tmp, &sa_manager->olist, olist) { in drm_suballoc_manager_fini()
110 sa_manager->size = 0; in drm_suballoc_manager_fini()
116 struct drm_suballoc_manager *sa_manager = sa->manager; in drm_suballoc_remove_locked()
118 if (sa_manager->hole == &sa->olist) in drm_suballoc_remove_locked()
119 sa_manager->hole = sa->olist.prev; in drm_suballoc_remove_locked()
121 list_del_init(&sa->olist); in drm_suballoc_remove_locked()
122 list_del_init(&sa->flist); in drm_suballoc_remove_locked()
123 dma_fence_put(sa->fence); in drm_suballoc_remove_locked()
131 if (sa_manager->hole->next == &sa_manager->olist) in drm_suballoc_try_free()
134 sa = list_entry(sa_manager->hole->next, struct drm_suballoc, olist); in drm_suballoc_try_free()
135 list_for_each_entry_safe_from(sa, tmp, &sa_manager->olist, olist) { in drm_suballoc_try_free()
136 if (!sa->fence || !dma_fence_is_signaled(sa->fence)) in drm_suballoc_try_free()
145 struct list_head *hole = sa_manager->hole; in drm_suballoc_hole_soffset()
147 if (hole != &sa_manager->olist) in drm_suballoc_hole_soffset()
148 return list_entry(hole, struct drm_suballoc, olist)->eoffset; in drm_suballoc_hole_soffset()
155 struct list_head *hole = sa_manager->hole; in drm_suballoc_hole_eoffset()
157 if (hole->next != &sa_manager->olist) in drm_suballoc_hole_eoffset()
158 return list_entry(hole->next, struct drm_suballoc, olist)->soffset; in drm_suballoc_hole_eoffset()
159 return sa_manager->size; in drm_suballoc_hole_eoffset()
164 size_t size, size_t align) in drm_suballoc_try_alloc() argument
170 wasted = round_up(soffset, align) - soffset; in drm_suballoc_try_alloc()
172 if ((eoffset - soffset) >= (size + wasted)) { in drm_suballoc_try_alloc()
175 sa->manager = sa_manager; in drm_suballoc_try_alloc()
176 sa->soffset = soffset; in drm_suballoc_try_alloc()
177 sa->eoffset = soffset + size; in drm_suballoc_try_alloc()
178 list_add(&sa->olist, sa_manager->hole); in drm_suballoc_try_alloc()
179 INIT_LIST_HEAD(&sa->flist); in drm_suballoc_try_alloc()
180 sa_manager->hole = &sa->olist; in drm_suballoc_try_alloc()
187 size_t size, size_t align) in __drm_suballoc_event() argument
193 if (!list_empty(&sa_manager->flist[i])) in __drm_suballoc_event()
198 wasted = round_up(soffset, align) - soffset; in __drm_suballoc_event()
200 return ((eoffset - soffset) >= (size + wasted)); in __drm_suballoc_event()
204 * drm_suballoc_event() - Check if we can stop waiting
206 * @size: number of bytes we want to allocate
207 * @align: alignment we need to match
214 size_t size, size_t align) in drm_suballoc_event() argument
218 spin_lock(&sa_manager->wq.lock); in drm_suballoc_event()
219 ret = __drm_suballoc_event(sa_manager, size, align); in drm_suballoc_event()
220 spin_unlock(&sa_manager->wq.lock); in drm_suballoc_event()
233 if (sa_manager->hole->next == &sa_manager->olist) { in drm_suballoc_next_hole()
235 sa_manager->hole = &sa_manager->olist; in drm_suballoc_next_hole()
240 /* to handle wrap around we add sa_manager->size */ in drm_suballoc_next_hole()
241 best = sa_manager->size * 2; in drm_suballoc_next_hole()
250 if (list_empty(&sa_manager->flist[i])) in drm_suballoc_next_hole()
253 sa = list_first_entry(&sa_manager->flist[i], in drm_suballoc_next_hole()
256 if (!dma_fence_is_signaled(sa->fence)) { in drm_suballoc_next_hole()
257 fences[i] = sa->fence; in drm_suballoc_next_hole()
265 tmp = sa->soffset; in drm_suballoc_next_hole()
268 tmp += sa_manager->size; in drm_suballoc_next_hole()
270 tmp -= soffset; in drm_suballoc_next_hole()
281 sa_manager->hole = best_bo->olist.prev; in drm_suballoc_next_hole()
294 * drm_suballoc_new() - Make a suballocation.
296 * @size: number of bytes we want to suballocate.
303 * non-interruptible context from above layers.
304 * @align: Alignment. Must not exceed the default manager alignment.
305 * If @align is zero, then the manager alignment is used.
307 * Try to make a suballocation of size @size, which will be rounded
313 drm_suballoc_new(struct drm_suballoc_manager *sa_manager, size_t size, in drm_suballoc_new() argument
314 gfp_t gfp, bool intr, size_t align) in drm_suballoc_new() argument
322 if (WARN_ON_ONCE(align > sa_manager->align)) in drm_suballoc_new()
323 return ERR_PTR(-EINVAL); in drm_suballoc_new()
324 if (WARN_ON_ONCE(size > sa_manager->size || !size)) in drm_suballoc_new()
325 return ERR_PTR(-EINVAL); in drm_suballoc_new()
327 if (!align) in drm_suballoc_new()
328 align = sa_manager->align; in drm_suballoc_new()
332 return ERR_PTR(-ENOMEM); in drm_suballoc_new()
333 sa->manager = sa_manager; in drm_suballoc_new()
334 sa->fence = NULL; in drm_suballoc_new()
335 INIT_LIST_HEAD(&sa->olist); in drm_suballoc_new()
336 INIT_LIST_HEAD(&sa->flist); in drm_suballoc_new()
338 spin_lock(&sa_manager->wq.lock); in drm_suballoc_new()
347 size, align)) { in drm_suballoc_new()
348 spin_unlock(&sa_manager->wq.lock); in drm_suballoc_new()
362 spin_unlock(&sa_manager->wq.lock); in drm_suballoc_new()
370 spin_lock(&sa_manager->wq.lock); in drm_suballoc_new()
374 (sa_manager->wq, in drm_suballoc_new()
375 __drm_suballoc_event(sa_manager, size, align)); in drm_suballoc_new()
377 spin_unlock(&sa_manager->wq.lock); in drm_suballoc_new()
378 wait_event(sa_manager->wq, in drm_suballoc_new()
379 drm_suballoc_event(sa_manager, size, align)); in drm_suballoc_new()
381 spin_lock(&sa_manager->wq.lock); in drm_suballoc_new()
385 spin_unlock(&sa_manager->wq.lock); in drm_suballoc_new()
392 * drm_suballoc_free - Free a suballocation
396 * Free the suballocation. The suballocation can be re-used after @fence signals.
406 sa_manager = suballoc->manager; in drm_suballoc_free()
408 spin_lock(&sa_manager->wq.lock); in drm_suballoc_free()
412 suballoc->fence = dma_fence_get(fence); in drm_suballoc_free()
413 idx = fence->context & (DRM_SUBALLOC_MAX_QUEUES - 1); in drm_suballoc_free()
414 list_add_tail(&suballoc->flist, &sa_manager->flist[idx]); in drm_suballoc_free()
418 wake_up_all_locked(&sa_manager->wq); in drm_suballoc_free()
419 spin_unlock(&sa_manager->wq.lock); in drm_suballoc_free()
430 spin_lock(&sa_manager->wq.lock); in drm_suballoc_dump_debug_info()
431 list_for_each_entry(i, &sa_manager->olist, olist) { in drm_suballoc_dump_debug_info()
432 unsigned long long soffset = i->soffset; in drm_suballoc_dump_debug_info()
433 unsigned long long eoffset = i->eoffset; in drm_suballoc_dump_debug_info()
435 if (&i->olist == sa_manager->hole) in drm_suballoc_dump_debug_info()
440 drm_printf(p, "[0x%010llx 0x%010llx] size %8lld", in drm_suballoc_dump_debug_info()
442 eoffset - soffset); in drm_suballoc_dump_debug_info()
444 if (i->fence) in drm_suballoc_dump_debug_info()
446 (unsigned long long)i->fence->seqno, in drm_suballoc_dump_debug_info()
447 (unsigned long long)i->fence->context); in drm_suballoc_dump_debug_info()
451 spin_unlock(&sa_manager->wq.lock); in drm_suballoc_dump_debug_info()