1 /* SPDX-License-Identifier: GPL-2.0 OR MIT */ 2 /* 3 * Copyright 2011 Red Hat Inc. 4 * Copyright © 2022 Intel Corporation 5 */ 6 #ifndef _DRM_SUBALLOC_H_ 7 #define _DRM_SUBALLOC_H_ 8 9 #include <drm/drm_mm.h> 10 11 #include <linux/dma-fence.h> 12 #include <linux/types.h> 13 14 #define DRM_SUBALLOC_MAX_QUEUES 32 15 /** 16 * struct drm_suballoc_manager - fenced range allocations 17 * @wq: Wait queue for sleeping allocations on contention. 18 * @hole: Pointer to first hole node. 19 * @olist: List of allocated ranges. 20 * @flist: Array[fence context hash] of queues of fenced allocated ranges. 21 * @size: Size of the managed range. 22 * @align: Default alignment for the managed range. 23 */ 24 struct drm_suballoc_manager { 25 wait_queue_head_t wq; 26 struct list_head *hole; 27 struct list_head olist; 28 struct list_head flist[DRM_SUBALLOC_MAX_QUEUES]; 29 size_t size; 30 size_t align; 31 }; 32 33 /** 34 * struct drm_suballoc - Sub-allocated range 35 * @olist: List link for list of allocated ranges. 36 * @flist: List linkk for the manager fenced allocated ranges queues. 37 * @manager: The drm_suballoc_manager. 38 * @soffset: Start offset. 39 * @eoffset: End offset + 1 so that @eoffset - @soffset = size. 40 * @fence: The fence protecting the allocation. 41 */ 42 struct drm_suballoc { 43 struct list_head olist; 44 struct list_head flist; 45 struct drm_suballoc_manager *manager; 46 size_t soffset; 47 size_t eoffset; 48 struct dma_fence *fence; 49 }; 50 51 void drm_suballoc_manager_init(struct drm_suballoc_manager *sa_manager, 52 size_t size, size_t align); 53 54 void drm_suballoc_manager_fini(struct drm_suballoc_manager *sa_manager); 55 56 struct drm_suballoc *drm_suballoc_alloc(gfp_t gfp); 57 58 int drm_suballoc_insert(struct drm_suballoc_manager *sa_manager, 59 struct drm_suballoc *sa, size_t size, bool intr, 60 size_t align); 61 62 struct drm_suballoc * 63 drm_suballoc_new(struct drm_suballoc_manager *sa_manager, size_t size, 64 gfp_t gfp, bool intr, size_t align); 65 66 void drm_suballoc_free(struct drm_suballoc *sa, struct dma_fence *fence); 67 68 /** 69 * drm_suballoc_soffset - Range start. 70 * @sa: The struct drm_suballoc. 71 * 72 * Return: The start of the allocated range. 73 */ 74 static inline size_t drm_suballoc_soffset(struct drm_suballoc *sa) 75 { 76 return sa->soffset; 77 } 78 79 /** 80 * drm_suballoc_eoffset - Range end. 81 * @sa: The struct drm_suballoc. 82 * 83 * Return: The end of the allocated range + 1. 84 */ 85 static inline size_t drm_suballoc_eoffset(struct drm_suballoc *sa) 86 { 87 return sa->eoffset; 88 } 89 90 /** 91 * drm_suballoc_size - Range size. 92 * @sa: The struct drm_suballoc. 93 * 94 * Return: The size of the allocated range. 95 */ 96 static inline size_t drm_suballoc_size(struct drm_suballoc *sa) 97 { 98 return sa->eoffset - sa->soffset; 99 } 100 101 #ifdef CONFIG_DEBUG_FS 102 void drm_suballoc_dump_debug_info(struct drm_suballoc_manager *sa_manager, 103 struct drm_printer *p, 104 unsigned long long suballoc_base); 105 #else 106 static inline void 107 drm_suballoc_dump_debug_info(struct drm_suballoc_manager *sa_manager, 108 struct drm_printer *p, 109 unsigned long long suballoc_base) 110 { } 111 112 #endif 113 114 #endif /* _DRM_SUBALLOC_H_ */ 115