diff options
author | Christian König <deathsimple@vodafone.de> | 2012-05-09 09:34:54 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2012-05-09 12:22:37 -0400 |
commit | 557017a0e219b2a466a71a8d72332a715d460416 (patch) | |
tree | 42edbacba20652c9b7106f0abcce772fb70cb3d2 /drivers/gpu/drm/radeon | |
parent | 2e0d99103e7b62ad27dcbc8c92337687dd8294e6 (diff) |
drm/radeon: define new SA interface v3
Define the interface without modifying the allocation
algorithm in any way.
v2: rebase on top of fence new uint64 patch
v3: add ring to debugfs output
Signed-off-by: Jerome Glisse <jglisse@redhat.com>
Signed-off-by: Christian König <deathsimple@vodafone.de>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_gart.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_object.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_ring.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_sa.c | 60 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_semaphore.c | 2 |
6 files changed, 63 insertions, 19 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 9374ab1b4264..ada70d157e13 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -398,6 +398,7 @@ struct radeon_sa_bo { | |||
398 | struct radeon_sa_manager *manager; | 398 | struct radeon_sa_manager *manager; |
399 | unsigned soffset; | 399 | unsigned soffset; |
400 | unsigned eoffset; | 400 | unsigned eoffset; |
401 | struct radeon_fence *fence; | ||
401 | }; | 402 | }; |
402 | 403 | ||
403 | /* | 404 | /* |
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index c5789efb78a5..53dba8e5942f 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
@@ -326,7 +326,7 @@ static void radeon_vm_unbind_locked(struct radeon_device *rdev, | |||
326 | rdev->vm_manager.use_bitmap &= ~(1 << vm->id); | 326 | rdev->vm_manager.use_bitmap &= ~(1 << vm->id); |
327 | list_del_init(&vm->list); | 327 | list_del_init(&vm->list); |
328 | vm->id = -1; | 328 | vm->id = -1; |
329 | radeon_sa_bo_free(rdev, &vm->sa_bo); | 329 | radeon_sa_bo_free(rdev, &vm->sa_bo, NULL); |
330 | vm->pt = NULL; | 330 | vm->pt = NULL; |
331 | 331 | ||
332 | list_for_each_entry(bo_va, &vm->va, vm_list) { | 332 | list_for_each_entry(bo_va, &vm->va, vm_list) { |
@@ -395,7 +395,7 @@ int radeon_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm) | |||
395 | retry: | 395 | retry: |
396 | r = radeon_sa_bo_new(rdev, &rdev->vm_manager.sa_manager, &vm->sa_bo, | 396 | r = radeon_sa_bo_new(rdev, &rdev->vm_manager.sa_manager, &vm->sa_bo, |
397 | RADEON_GPU_PAGE_ALIGN(vm->last_pfn * 8), | 397 | RADEON_GPU_PAGE_ALIGN(vm->last_pfn * 8), |
398 | RADEON_GPU_PAGE_SIZE); | 398 | RADEON_GPU_PAGE_SIZE, false); |
399 | if (r) { | 399 | if (r) { |
400 | if (list_empty(&rdev->vm_manager.lru_vm)) { | 400 | if (list_empty(&rdev->vm_manager.lru_vm)) { |
401 | return r; | 401 | return r; |
@@ -426,7 +426,7 @@ retry_id: | |||
426 | /* do hw bind */ | 426 | /* do hw bind */ |
427 | r = rdev->vm_manager.funcs->bind(rdev, vm, id); | 427 | r = rdev->vm_manager.funcs->bind(rdev, vm, id); |
428 | if (r) { | 428 | if (r) { |
429 | radeon_sa_bo_free(rdev, &vm->sa_bo); | 429 | radeon_sa_bo_free(rdev, &vm->sa_bo, NULL); |
430 | return r; | 430 | return r; |
431 | } | 431 | } |
432 | rdev->vm_manager.use_bitmap |= 1 << id; | 432 | rdev->vm_manager.use_bitmap |= 1 << id; |
diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h index 4fc7f07e06d1..befec7d12132 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h | |||
@@ -169,9 +169,10 @@ extern int radeon_sa_bo_manager_suspend(struct radeon_device *rdev, | |||
169 | extern int radeon_sa_bo_new(struct radeon_device *rdev, | 169 | extern int radeon_sa_bo_new(struct radeon_device *rdev, |
170 | struct radeon_sa_manager *sa_manager, | 170 | struct radeon_sa_manager *sa_manager, |
171 | struct radeon_sa_bo **sa_bo, | 171 | struct radeon_sa_bo **sa_bo, |
172 | unsigned size, unsigned align); | 172 | unsigned size, unsigned align, bool block); |
173 | extern void radeon_sa_bo_free(struct radeon_device *rdev, | 173 | extern void radeon_sa_bo_free(struct radeon_device *rdev, |
174 | struct radeon_sa_bo **sa_bo); | 174 | struct radeon_sa_bo **sa_bo, |
175 | struct radeon_fence *fence); | ||
175 | #if defined(CONFIG_DEBUG_FS) | 176 | #if defined(CONFIG_DEBUG_FS) |
176 | extern void radeon_sa_bo_dump_debug_info(struct radeon_sa_manager *sa_manager, | 177 | extern void radeon_sa_bo_dump_debug_info(struct radeon_sa_manager *sa_manager, |
177 | struct seq_file *m); | 178 | struct seq_file *m); |
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 45adb37152e1..1748d939657c 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c | |||
@@ -85,7 +85,7 @@ bool radeon_ib_try_free(struct radeon_device *rdev, struct radeon_ib *ib) | |||
85 | if (ib->fence && ib->fence->seq < RADEON_FENCE_NOTEMITED_SEQ) { | 85 | if (ib->fence && ib->fence->seq < RADEON_FENCE_NOTEMITED_SEQ) { |
86 | if (radeon_fence_signaled(ib->fence)) { | 86 | if (radeon_fence_signaled(ib->fence)) { |
87 | radeon_fence_unref(&ib->fence); | 87 | radeon_fence_unref(&ib->fence); |
88 | radeon_sa_bo_free(rdev, &ib->sa_bo); | 88 | radeon_sa_bo_free(rdev, &ib->sa_bo, NULL); |
89 | done = true; | 89 | done = true; |
90 | } | 90 | } |
91 | } | 91 | } |
@@ -124,7 +124,7 @@ retry: | |||
124 | if (rdev->ib_pool.ibs[idx].fence == NULL) { | 124 | if (rdev->ib_pool.ibs[idx].fence == NULL) { |
125 | r = radeon_sa_bo_new(rdev, &rdev->ib_pool.sa_manager, | 125 | r = radeon_sa_bo_new(rdev, &rdev->ib_pool.sa_manager, |
126 | &rdev->ib_pool.ibs[idx].sa_bo, | 126 | &rdev->ib_pool.ibs[idx].sa_bo, |
127 | size, 256); | 127 | size, 256, false); |
128 | if (!r) { | 128 | if (!r) { |
129 | *ib = &rdev->ib_pool.ibs[idx]; | 129 | *ib = &rdev->ib_pool.ibs[idx]; |
130 | (*ib)->ptr = radeon_sa_bo_cpu_addr((*ib)->sa_bo); | 130 | (*ib)->ptr = radeon_sa_bo_cpu_addr((*ib)->sa_bo); |
@@ -173,7 +173,7 @@ void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib) | |||
173 | } | 173 | } |
174 | radeon_mutex_lock(&rdev->ib_pool.mutex); | 174 | radeon_mutex_lock(&rdev->ib_pool.mutex); |
175 | if (tmp->fence && tmp->fence->seq == RADEON_FENCE_NOTEMITED_SEQ) { | 175 | if (tmp->fence && tmp->fence->seq == RADEON_FENCE_NOTEMITED_SEQ) { |
176 | radeon_sa_bo_free(rdev, &tmp->sa_bo); | 176 | radeon_sa_bo_free(rdev, &tmp->sa_bo, NULL); |
177 | radeon_fence_unref(&tmp->fence); | 177 | radeon_fence_unref(&tmp->fence); |
178 | } | 178 | } |
179 | radeon_mutex_unlock(&rdev->ib_pool.mutex); | 179 | radeon_mutex_unlock(&rdev->ib_pool.mutex); |
@@ -247,7 +247,7 @@ void radeon_ib_pool_fini(struct radeon_device *rdev) | |||
247 | radeon_mutex_lock(&rdev->ib_pool.mutex); | 247 | radeon_mutex_lock(&rdev->ib_pool.mutex); |
248 | if (rdev->ib_pool.ready) { | 248 | if (rdev->ib_pool.ready) { |
249 | for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { | 249 | for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { |
250 | radeon_sa_bo_free(rdev, &rdev->ib_pool.ibs[i].sa_bo); | 250 | radeon_sa_bo_free(rdev, &rdev->ib_pool.ibs[i].sa_bo, NULL); |
251 | radeon_fence_unref(&rdev->ib_pool.ibs[i].fence); | 251 | radeon_fence_unref(&rdev->ib_pool.ibs[i].fence); |
252 | } | 252 | } |
253 | radeon_sa_bo_manager_fini(rdev, &rdev->ib_pool.sa_manager); | 253 | radeon_sa_bo_manager_fini(rdev, &rdev->ib_pool.sa_manager); |
diff --git a/drivers/gpu/drm/radeon/radeon_sa.c b/drivers/gpu/drm/radeon/radeon_sa.c index 625f2d4f638a..90ee8add2443 100644 --- a/drivers/gpu/drm/radeon/radeon_sa.c +++ b/drivers/gpu/drm/radeon/radeon_sa.c | |||
@@ -129,20 +129,32 @@ int radeon_sa_bo_manager_suspend(struct radeon_device *rdev, | |||
129 | * | 129 | * |
130 | * Alignment can't be bigger than page size | 130 | * Alignment can't be bigger than page size |
131 | */ | 131 | */ |
132 | |||
133 | static void radeon_sa_bo_remove_locked(struct radeon_sa_bo *sa_bo) | ||
134 | { | ||
135 | list_del(&sa_bo->list); | ||
136 | radeon_fence_unref(&sa_bo->fence); | ||
137 | kfree(sa_bo); | ||
138 | } | ||
139 | |||
132 | int radeon_sa_bo_new(struct radeon_device *rdev, | 140 | int radeon_sa_bo_new(struct radeon_device *rdev, |
133 | struct radeon_sa_manager *sa_manager, | 141 | struct radeon_sa_manager *sa_manager, |
134 | struct radeon_sa_bo **sa_bo, | 142 | struct radeon_sa_bo **sa_bo, |
135 | unsigned size, unsigned align) | 143 | unsigned size, unsigned align, bool block) |
136 | { | 144 | { |
137 | struct radeon_sa_bo *tmp; | 145 | struct radeon_fence *fence = NULL; |
146 | struct radeon_sa_bo *tmp, *next; | ||
138 | struct list_head *head; | 147 | struct list_head *head; |
139 | unsigned offset = 0, wasted = 0; | 148 | unsigned offset = 0, wasted = 0; |
149 | int r; | ||
140 | 150 | ||
141 | BUG_ON(align > RADEON_GPU_PAGE_SIZE); | 151 | BUG_ON(align > RADEON_GPU_PAGE_SIZE); |
142 | BUG_ON(size > sa_manager->size); | 152 | BUG_ON(size > sa_manager->size); |
143 | 153 | ||
144 | *sa_bo = kmalloc(sizeof(struct radeon_sa_bo), GFP_KERNEL); | 154 | *sa_bo = kmalloc(sizeof(struct radeon_sa_bo), GFP_KERNEL); |
145 | 155 | ||
156 | retry: | ||
157 | |||
146 | spin_lock(&sa_manager->lock); | 158 | spin_lock(&sa_manager->lock); |
147 | 159 | ||
148 | /* no one ? */ | 160 | /* no one ? */ |
@@ -153,7 +165,17 @@ int radeon_sa_bo_new(struct radeon_device *rdev, | |||
153 | 165 | ||
154 | /* look for a hole big enough */ | 166 | /* look for a hole big enough */ |
155 | offset = 0; | 167 | offset = 0; |
156 | list_for_each_entry(tmp, &sa_manager->sa_bo, list) { | 168 | list_for_each_entry_safe(tmp, next, &sa_manager->sa_bo, list) { |
169 | /* try to free this object */ | ||
170 | if (tmp->fence) { | ||
171 | if (radeon_fence_signaled(tmp->fence)) { | ||
172 | radeon_sa_bo_remove_locked(tmp); | ||
173 | continue; | ||
174 | } else { | ||
175 | fence = tmp->fence; | ||
176 | } | ||
177 | } | ||
178 | |||
157 | /* room before this object ? */ | 179 | /* room before this object ? */ |
158 | if (offset < tmp->soffset && (tmp->soffset - offset) >= size) { | 180 | if (offset < tmp->soffset && (tmp->soffset - offset) >= size) { |
159 | head = tmp->list.prev; | 181 | head = tmp->list.prev; |
@@ -178,6 +200,13 @@ int radeon_sa_bo_new(struct radeon_device *rdev, | |||
178 | if ((sa_manager->size - offset) < size) { | 200 | if ((sa_manager->size - offset) < size) { |
179 | /* failed to find somethings big enough */ | 201 | /* failed to find somethings big enough */ |
180 | spin_unlock(&sa_manager->lock); | 202 | spin_unlock(&sa_manager->lock); |
203 | if (block && fence) { | ||
204 | r = radeon_fence_wait(fence, false); | ||
205 | if (r) | ||
206 | return r; | ||
207 | |||
208 | goto retry; | ||
209 | } | ||
181 | kfree(*sa_bo); | 210 | kfree(*sa_bo); |
182 | *sa_bo = NULL; | 211 | *sa_bo = NULL; |
183 | return -ENOMEM; | 212 | return -ENOMEM; |
@@ -192,15 +221,22 @@ out: | |||
192 | return 0; | 221 | return 0; |
193 | } | 222 | } |
194 | 223 | ||
195 | void radeon_sa_bo_free(struct radeon_device *rdev, struct radeon_sa_bo **sa_bo) | 224 | void radeon_sa_bo_free(struct radeon_device *rdev, struct radeon_sa_bo **sa_bo, |
225 | struct radeon_fence *fence) | ||
196 | { | 226 | { |
227 | struct radeon_sa_manager *sa_manager; | ||
228 | |||
197 | if (!sa_bo || !*sa_bo) | 229 | if (!sa_bo || !*sa_bo) |
198 | return; | 230 | return; |
199 | 231 | ||
200 | spin_lock(&(*sa_bo)->manager->lock); | 232 | sa_manager = (*sa_bo)->manager; |
201 | list_del_init(&(*sa_bo)->list); | 233 | spin_lock(&sa_manager->lock); |
202 | spin_unlock(&(*sa_bo)->manager->lock); | 234 | if (fence && fence->seq && fence->seq < RADEON_FENCE_NOTEMITED_SEQ) { |
203 | kfree(*sa_bo); | 235 | (*sa_bo)->fence = radeon_fence_ref(fence); |
236 | } else { | ||
237 | radeon_sa_bo_remove_locked(*sa_bo); | ||
238 | } | ||
239 | spin_unlock(&sa_manager->lock); | ||
204 | *sa_bo = NULL; | 240 | *sa_bo = NULL; |
205 | } | 241 | } |
206 | 242 | ||
@@ -212,8 +248,14 @@ void radeon_sa_bo_dump_debug_info(struct radeon_sa_manager *sa_manager, | |||
212 | 248 | ||
213 | spin_lock(&sa_manager->lock); | 249 | spin_lock(&sa_manager->lock); |
214 | list_for_each_entry(i, &sa_manager->sa_bo, list) { | 250 | list_for_each_entry(i, &sa_manager->sa_bo, list) { |
215 | seq_printf(m, "[%08x %08x] size %4d [%p]\n", | 251 | seq_printf(m, "[%08x %08x] size %4d (%p)", |
216 | i->soffset, i->eoffset, i->eoffset - i->soffset, i); | 252 | i->soffset, i->eoffset, i->eoffset - i->soffset, i); |
253 | if (i->fence) { | ||
254 | seq_printf(m, " protected by %Ld (%p) on ring %d\n", | ||
255 | i->fence->seq, i->fence, i->fence->ring); | ||
256 | } else { | ||
257 | seq_printf(m, "\n"); | ||
258 | } | ||
217 | } | 259 | } |
218 | spin_unlock(&sa_manager->lock); | 260 | spin_unlock(&sa_manager->lock); |
219 | } | 261 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c index d518d326235d..dbde874b2e5e 100644 --- a/drivers/gpu/drm/radeon/radeon_semaphore.c +++ b/drivers/gpu/drm/radeon/radeon_semaphore.c | |||
@@ -72,7 +72,7 @@ static int radeon_semaphore_add_bo(struct radeon_device *rdev) | |||
72 | static void radeon_semaphore_del_bo_locked(struct radeon_device *rdev, | 72 | static void radeon_semaphore_del_bo_locked(struct radeon_device *rdev, |
73 | struct radeon_semaphore_bo *bo) | 73 | struct radeon_semaphore_bo *bo) |
74 | { | 74 | { |
75 | radeon_sa_bo_free(rdev, &bo->ib->sa_bo); | 75 | radeon_sa_bo_free(rdev, &bo->ib->sa_bo, NULL); |
76 | radeon_fence_unref(&bo->ib->fence); | 76 | radeon_fence_unref(&bo->ib->fence); |
77 | list_del(&bo->list); | 77 | list_del(&bo->list); |
78 | kfree(bo); | 78 | kfree(bo); |