aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Deucher2015-04-20 11:04:22 -0500
committerAlex Deucher2015-08-05 12:47:48 -0500
commit09361395363805b5892d48d7bc10cf717e4d2927 (patch)
treec81192a93843d2f9af16df2b9ec71a66579314d5 /amdgpu/amdgpu_vamgr.c
parenta3c89dda5b519f6b217bebe97f6795b820931b78 (diff)
downloadexternal-libdrm-09361395363805b5892d48d7bc10cf717e4d2927.tar.gz
external-libdrm-09361395363805b5892d48d7bc10cf717e4d2927.tar.xz
external-libdrm-09361395363805b5892d48d7bc10cf717e4d2927.zip
drm: add libdrm_amdgpu (v7)
This is the new ioctl wrapper used by the new admgpu driver. It's primarily used by xf86-video-amdgpu and mesa. v2: fix amdgpu_drm.h install v3: Integrate some of the sugestions from Emil: clean up Makefile.am, configure.ac capitalize header guards fix _FILE_OFFSET_BITS with config.h use drm_mmap/drm_munmap Remove unused ARRAY_SIZE macro use shared list implementation use shared math implementation use drmGetNodeTypeFromFd helper v4: remove unused tiling defines v5: include amdgpu.h in Makefile.am v6: update amdgpu_drm.h v7: libdrm.h -> libdrm_macros.h Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'amdgpu/amdgpu_vamgr.c')
-rw-r--r--amdgpu/amdgpu_vamgr.c169
1 files changed, 169 insertions, 0 deletions
diff --git a/amdgpu/amdgpu_vamgr.c b/amdgpu/amdgpu_vamgr.c
new file mode 100644
index 00000000..23359122
--- /dev/null
+++ b/amdgpu/amdgpu_vamgr.c
@@ -0,0 +1,169 @@
1/*
2 * Copyright 2014 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22*/
23
24#include <stdlib.h>
25#include <string.h>
26#include "amdgpu.h"
27#include "amdgpu_drm.h"
28#include "amdgpu_internal.h"
29#include "util_math.h"
30
31void amdgpu_vamgr_init(struct amdgpu_device *dev)
32{
33 struct amdgpu_bo_va_mgr *vamgr = &dev->vamgr;
34
35 vamgr->va_offset = dev->dev_info.virtual_address_offset;
36 vamgr->va_alignment = dev->dev_info.virtual_address_alignment;
37
38 list_inithead(&vamgr->va_holes);
39 pthread_mutex_init(&vamgr->bo_va_mutex, NULL);
40}
41
42uint64_t amdgpu_vamgr_find_va(struct amdgpu_bo_va_mgr *mgr,
43 uint64_t size, uint64_t alignment)
44{
45 struct amdgpu_bo_va_hole *hole, *n;
46 uint64_t offset = 0, waste = 0;
47
48 alignment = MAX2(alignment, mgr->va_alignment);
49 size = ALIGN(size, mgr->va_alignment);
50
51 pthread_mutex_lock(&mgr->bo_va_mutex);
52 /* TODO: using more appropriate way to track the holes */
53 /* first look for a hole */
54 LIST_FOR_EACH_ENTRY_SAFE(hole, n, &mgr->va_holes, list) {
55 offset = hole->offset;
56 waste = offset % alignment;
57 waste = waste ? alignment - waste : 0;
58 offset += waste;
59 if (offset >= (hole->offset + hole->size)) {
60 continue;
61 }
62 if (!waste && hole->size == size) {
63 offset = hole->offset;
64 list_del(&hole->list);
65 free(hole);
66 pthread_mutex_unlock(&mgr->bo_va_mutex);
67 return offset;
68 }
69 if ((hole->size - waste) > size) {
70 if (waste) {
71 n = calloc(1,
72 sizeof(struct amdgpu_bo_va_hole));
73 n->size = waste;
74 n->offset = hole->offset;
75 list_add(&n->list, &hole->list);
76 }
77 hole->size -= (size + waste);
78 hole->offset += size + waste;
79 pthread_mutex_unlock(&mgr->bo_va_mutex);
80 return offset;
81 }
82 if ((hole->size - waste) == size) {
83 hole->size = waste;
84 pthread_mutex_unlock(&mgr->bo_va_mutex);
85 return offset;
86 }
87 }
88
89 offset = mgr->va_offset;
90 waste = offset % alignment;
91 waste = waste ? alignment - waste : 0;
92 if (waste) {
93 n = calloc(1, sizeof(struct amdgpu_bo_va_hole));
94 n->size = waste;
95 n->offset = offset;
96 list_add(&n->list, &mgr->va_holes);
97 }
98 offset += waste;
99 mgr->va_offset += size + waste;
100 pthread_mutex_unlock(&mgr->bo_va_mutex);
101 return offset;
102}
103
104void amdgpu_vamgr_free_va(struct amdgpu_bo_va_mgr *mgr, uint64_t va,
105 uint64_t size)
106{
107 struct amdgpu_bo_va_hole *hole;
108
109 size = ALIGN(size, mgr->va_alignment);
110
111 pthread_mutex_lock(&mgr->bo_va_mutex);
112 if ((va + size) == mgr->va_offset) {
113 mgr->va_offset = va;
114 /* Delete uppermost hole if it reaches the new top */
115 if (!LIST_IS_EMPTY(&mgr->va_holes)) {
116 hole = container_of(mgr->va_holes.next, hole, list);
117 if ((hole->offset + hole->size) == va) {
118 mgr->va_offset = hole->offset;
119 list_del(&hole->list);
120 free(hole);
121 }
122 }
123 } else {
124 struct amdgpu_bo_va_hole *next;
125
126 hole = container_of(&mgr->va_holes, hole, list);
127 LIST_FOR_EACH_ENTRY(next, &mgr->va_holes, list) {
128 if (next->offset < va)
129 break;
130 hole = next;
131 }
132
133 if (&hole->list != &mgr->va_holes) {
134 /* Grow upper hole if it's adjacent */
135 if (hole->offset == (va + size)) {
136 hole->offset = va;
137 hole->size += size;
138 /* Merge lower hole if it's adjacent */
139 if (next != hole
140 && &next->list != &mgr->va_holes
141 && (next->offset + next->size) == va) {
142 next->size += hole->size;
143 list_del(&hole->list);
144 free(hole);
145 }
146 goto out;
147 }
148 }
149
150 /* Grow lower hole if it's adjacent */
151 if (next != hole && &next->list != &mgr->va_holes &&
152 (next->offset + next->size) == va) {
153 next->size += size;
154 goto out;
155 }
156
157 /* FIXME on allocation failure we just lose virtual address space
158 * maybe print a warning
159 */
160 next = calloc(1, sizeof(struct amdgpu_bo_va_hole));
161 if (next) {
162 next->size = size;
163 next->offset = va;
164 list_add(&next->list, &hole->list);
165 }
166 }
167out:
168 pthread_mutex_unlock(&mgr->bo_va_mutex);
169}