aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2012-05-09 09:34:46 -0400
committerDave Airlie <airlied@redhat.com>2012-05-09 12:22:17 -0400
commitbb635567291482a87e4cc46e6683419c1f365ddf (patch)
tree661f5a7a50310126ef035be87c4ae092752e1705 /drivers/gpu
parentd6999bc7b5f4b4554ebba5b48377903fa20198db (diff)
drm/radeon: convert fence to uint64_t v4
This convert fence to use uint64_t sequence number intention is to use the fact that uin64_t is big enough that we don't need to care about wrap around. Tested with and without writeback using 0xFFFFF000 as initial fence sequence and thus allowing to test the wrap around from 32bits to 64bits. v2: Add comment about possible race btw CPU & GPU, add comment stressing that we need 2 dword aligned for R600_WB_EVENT_OFFSET Read fence sequenc in reverse order of GPU write them so we mitigate the race btw CPU and GPU. v3: Drop the need for ring to emit the 64bits fence, and just have each ring emit the lower 32bits of the fence sequence. We handle the wrap over 32bits in fence_process. v4: Just a small optimization: Don't reread the last_seq value if loop restarts, since we already know its value anyway. Also start at zero not one for seq value and use pre instead of post increment in emmit, otherwise wait_empty will deadlock. 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')
-rw-r--r--drivers/gpu/drm/radeon/radeon.h39
-rw-r--r--drivers/gpu/drm/radeon/radeon_fence.c116
-rw-r--r--drivers/gpu/drm/radeon/radeon_ring.c9
3 files changed, 107 insertions, 57 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index e99ea816d8c9..cdf46bc6dcc4 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -100,28 +100,32 @@ extern int radeon_lockup_timeout;
100 * Copy from radeon_drv.h so we don't have to include both and have conflicting 100 * Copy from radeon_drv.h so we don't have to include both and have conflicting
101 * symbol; 101 * symbol;
102 */ 102 */
103#define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */ 103#define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */
104#define RADEON_FENCE_JIFFIES_TIMEOUT (HZ / 2) 104#define RADEON_FENCE_JIFFIES_TIMEOUT (HZ / 2)
105/* RADEON_IB_POOL_SIZE must be a power of 2 */ 105/* RADEON_IB_POOL_SIZE must be a power of 2 */
106#define RADEON_IB_POOL_SIZE 16 106#define RADEON_IB_POOL_SIZE 16
107#define RADEON_DEBUGFS_MAX_COMPONENTS 32 107#define RADEON_DEBUGFS_MAX_COMPONENTS 32
108#define RADEONFB_CONN_LIMIT 4 108#define RADEONFB_CONN_LIMIT 4
109#define RADEON_BIOS_NUM_SCRATCH 8 109#define RADEON_BIOS_NUM_SCRATCH 8
110 110
111/* max number of rings */ 111/* max number of rings */
112#define RADEON_NUM_RINGS 3 112#define RADEON_NUM_RINGS 3
113
114/* fence seq are set to this number when signaled */
115#define RADEON_FENCE_SIGNALED_SEQ 0LL
116#define RADEON_FENCE_NOTEMITED_SEQ (~0LL)
113 117
114/* internal ring indices */ 118/* internal ring indices */
115/* r1xx+ has gfx CP ring */ 119/* r1xx+ has gfx CP ring */
116#define RADEON_RING_TYPE_GFX_INDEX 0 120#define RADEON_RING_TYPE_GFX_INDEX 0
117 121
118/* cayman has 2 compute CP rings */ 122/* cayman has 2 compute CP rings */
119#define CAYMAN_RING_TYPE_CP1_INDEX 1 123#define CAYMAN_RING_TYPE_CP1_INDEX 1
120#define CAYMAN_RING_TYPE_CP2_INDEX 2 124#define CAYMAN_RING_TYPE_CP2_INDEX 2
121 125
122/* hardcode those limit for now */ 126/* hardcode those limit for now */
123#define RADEON_VA_RESERVED_SIZE (8 << 20) 127#define RADEON_VA_RESERVED_SIZE (8 << 20)
124#define RADEON_IB_VM_MAX_SIZE (64 << 10) 128#define RADEON_IB_VM_MAX_SIZE (64 << 10)
125 129
126/* 130/*
127 * Errata workarounds. 131 * Errata workarounds.
@@ -254,8 +258,9 @@ struct radeon_fence_driver {
254 uint32_t scratch_reg; 258 uint32_t scratch_reg;
255 uint64_t gpu_addr; 259 uint64_t gpu_addr;
256 volatile uint32_t *cpu_addr; 260 volatile uint32_t *cpu_addr;
257 atomic_t seq; 261 /* seq is protected by ring emission lock */
258 uint32_t last_seq; 262 uint64_t seq;
263 atomic64_t last_seq;
259 unsigned long last_activity; 264 unsigned long last_activity;
260 wait_queue_head_t queue; 265 wait_queue_head_t queue;
261 struct list_head emitted; 266 struct list_head emitted;
@@ -268,11 +273,9 @@ struct radeon_fence {
268 struct kref kref; 273 struct kref kref;
269 struct list_head list; 274 struct list_head list;
270 /* protected by radeon_fence.lock */ 275 /* protected by radeon_fence.lock */
271 uint32_t seq; 276 uint64_t seq;
272 bool emitted;
273 bool signaled;
274 /* RB, DMA, etc. */ 277 /* RB, DMA, etc. */
275 int ring; 278 unsigned ring;
276 struct radeon_semaphore *semaphore; 279 struct radeon_semaphore *semaphore;
277}; 280};
278 281
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c
index 5bb78bf547ea..feb2bbc6ef6d 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -66,14 +66,14 @@ int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence)
66 unsigned long irq_flags; 66 unsigned long irq_flags;
67 67
68 write_lock_irqsave(&rdev->fence_lock, irq_flags); 68 write_lock_irqsave(&rdev->fence_lock, irq_flags);
69 if (fence->emitted) { 69 if (fence->seq && fence->seq < RADEON_FENCE_NOTEMITED_SEQ) {
70 write_unlock_irqrestore(&rdev->fence_lock, irq_flags); 70 write_unlock_irqrestore(&rdev->fence_lock, irq_flags);
71 return 0; 71 return 0;
72 } 72 }
73 fence->seq = atomic_add_return(1, &rdev->fence_drv[fence->ring].seq); 73 /* we are protected by the ring emission mutex */
74 fence->seq = ++rdev->fence_drv[fence->ring].seq;
74 radeon_fence_ring_emit(rdev, fence->ring, fence); 75 radeon_fence_ring_emit(rdev, fence->ring, fence);
75 trace_radeon_fence_emit(rdev->ddev, fence->seq); 76 trace_radeon_fence_emit(rdev->ddev, fence->seq);
76 fence->emitted = true;
77 /* are we the first fence on a previusly idle ring? */ 77 /* are we the first fence on a previusly idle ring? */
78 if (list_empty(&rdev->fence_drv[fence->ring].emitted)) { 78 if (list_empty(&rdev->fence_drv[fence->ring].emitted)) {
79 rdev->fence_drv[fence->ring].last_activity = jiffies; 79 rdev->fence_drv[fence->ring].last_activity = jiffies;
@@ -87,14 +87,60 @@ static bool radeon_fence_poll_locked(struct radeon_device *rdev, int ring)
87{ 87{
88 struct radeon_fence *fence; 88 struct radeon_fence *fence;
89 struct list_head *i, *n; 89 struct list_head *i, *n;
90 uint32_t seq; 90 uint64_t seq, last_seq;
91 unsigned count_loop = 0;
91 bool wake = false; 92 bool wake = false;
92 93
93 seq = radeon_fence_read(rdev, ring); 94 /* Note there is a scenario here for an infinite loop but it's
94 if (seq == rdev->fence_drv[ring].last_seq) 95 * very unlikely to happen. For it to happen, the current polling
95 return false; 96 * process need to be interrupted by another process and another
97 * process needs to update the last_seq btw the atomic read and
98 * xchg of the current process.
99 *
100 * More over for this to go in infinite loop there need to be
101 * continuously new fence signaled ie radeon_fence_read needs
102 * to return a different value each time for both the currently
103 * polling process and the other process that xchg the last_seq
104 * btw atomic read and xchg of the current process. And the
105 * value the other process set as last seq must be higher than
106 * the seq value we just read. Which means that current process
107 * need to be interrupted after radeon_fence_read and before
108 * atomic xchg.
109 *
110 * To be even more safe we count the number of time we loop and
111 * we bail after 10 loop just accepting the fact that we might
112 * have temporarly set the last_seq not to the true real last
113 * seq but to an older one.
114 */
115 last_seq = atomic64_read(&rdev->fence_drv[ring].last_seq);
116 do {
117 seq = radeon_fence_read(rdev, ring);
118 seq |= last_seq & 0xffffffff00000000LL;
119 if (seq < last_seq) {
120 seq += 0x100000000LL;
121 }
96 122
97 rdev->fence_drv[ring].last_seq = seq; 123 if (!wake && seq == last_seq) {
124 return false;
125 }
126 /* If we loop over we don't want to return without
127 * checking if a fence is signaled as it means that the
128 * seq we just read is different from the previous on.
129 */
130 wake = true;
131 if ((count_loop++) > 10) {
132 /* We looped over too many time leave with the
133 * fact that we might have set an older fence
134 * seq then the current real last seq as signaled
135 * by the hw.
136 */
137 break;
138 }
139 last_seq = seq;
140 } while (atomic64_xchg(&rdev->fence_drv[ring].last_seq, seq) > seq);
141
142 /* reset wake to false */
143 wake = false;
98 rdev->fence_drv[ring].last_activity = jiffies; 144 rdev->fence_drv[ring].last_activity = jiffies;
99 145
100 n = NULL; 146 n = NULL;
@@ -112,7 +158,7 @@ static bool radeon_fence_poll_locked(struct radeon_device *rdev, int ring)
112 n = i->prev; 158 n = i->prev;
113 list_move_tail(i, &rdev->fence_drv[ring].signaled); 159 list_move_tail(i, &rdev->fence_drv[ring].signaled);
114 fence = list_entry(i, struct radeon_fence, list); 160 fence = list_entry(i, struct radeon_fence, list);
115 fence->signaled = true; 161 fence->seq = RADEON_FENCE_SIGNALED_SEQ;
116 i = n; 162 i = n;
117 } while (i != &rdev->fence_drv[ring].emitted); 163 } while (i != &rdev->fence_drv[ring].emitted);
118 wake = true; 164 wake = true;
@@ -128,7 +174,7 @@ static void radeon_fence_destroy(struct kref *kref)
128 fence = container_of(kref, struct radeon_fence, kref); 174 fence = container_of(kref, struct radeon_fence, kref);
129 write_lock_irqsave(&fence->rdev->fence_lock, irq_flags); 175 write_lock_irqsave(&fence->rdev->fence_lock, irq_flags);
130 list_del(&fence->list); 176 list_del(&fence->list);
131 fence->emitted = false; 177 fence->seq = RADEON_FENCE_NOTEMITED_SEQ;
132 write_unlock_irqrestore(&fence->rdev->fence_lock, irq_flags); 178 write_unlock_irqrestore(&fence->rdev->fence_lock, irq_flags);
133 if (fence->semaphore) 179 if (fence->semaphore)
134 radeon_semaphore_free(fence->rdev, fence->semaphore); 180 radeon_semaphore_free(fence->rdev, fence->semaphore);
@@ -145,9 +191,7 @@ int radeon_fence_create(struct radeon_device *rdev,
145 } 191 }
146 kref_init(&((*fence)->kref)); 192 kref_init(&((*fence)->kref));
147 (*fence)->rdev = rdev; 193 (*fence)->rdev = rdev;
148 (*fence)->emitted = false; 194 (*fence)->seq = RADEON_FENCE_NOTEMITED_SEQ;
149 (*fence)->signaled = false;
150 (*fence)->seq = 0;
151 (*fence)->ring = ring; 195 (*fence)->ring = ring;
152 (*fence)->semaphore = NULL; 196 (*fence)->semaphore = NULL;
153 INIT_LIST_HEAD(&(*fence)->list); 197 INIT_LIST_HEAD(&(*fence)->list);
@@ -163,18 +207,18 @@ bool radeon_fence_signaled(struct radeon_fence *fence)
163 return true; 207 return true;
164 208
165 write_lock_irqsave(&fence->rdev->fence_lock, irq_flags); 209 write_lock_irqsave(&fence->rdev->fence_lock, irq_flags);
166 signaled = fence->signaled; 210 signaled = (fence->seq == RADEON_FENCE_SIGNALED_SEQ);
167 /* if we are shuting down report all fence as signaled */ 211 /* if we are shuting down report all fence as signaled */
168 if (fence->rdev->shutdown) { 212 if (fence->rdev->shutdown) {
169 signaled = true; 213 signaled = true;
170 } 214 }
171 if (!fence->emitted) { 215 if (fence->seq == RADEON_FENCE_NOTEMITED_SEQ) {
172 WARN(1, "Querying an unemitted fence : %p !\n", fence); 216 WARN(1, "Querying an unemitted fence : %p !\n", fence);
173 signaled = true; 217 signaled = true;
174 } 218 }
175 if (!signaled) { 219 if (!signaled) {
176 radeon_fence_poll_locked(fence->rdev, fence->ring); 220 radeon_fence_poll_locked(fence->rdev, fence->ring);
177 signaled = fence->signaled; 221 signaled = (fence->seq == RADEON_FENCE_SIGNALED_SEQ);
178 } 222 }
179 write_unlock_irqrestore(&fence->rdev->fence_lock, irq_flags); 223 write_unlock_irqrestore(&fence->rdev->fence_lock, irq_flags);
180 return signaled; 224 return signaled;
@@ -183,8 +227,8 @@ bool radeon_fence_signaled(struct radeon_fence *fence)
183int radeon_fence_wait(struct radeon_fence *fence, bool intr) 227int radeon_fence_wait(struct radeon_fence *fence, bool intr)
184{ 228{
185 struct radeon_device *rdev; 229 struct radeon_device *rdev;
186 unsigned long irq_flags, timeout; 230 unsigned long irq_flags, timeout, last_activity;
187 u32 seq; 231 uint64_t seq;
188 int i, r; 232 int i, r;
189 bool signaled; 233 bool signaled;
190 234
@@ -207,7 +251,9 @@ int radeon_fence_wait(struct radeon_fence *fence, bool intr)
207 timeout = 1; 251 timeout = 1;
208 } 252 }
209 /* save current sequence value used to check for GPU lockups */ 253 /* save current sequence value used to check for GPU lockups */
210 seq = rdev->fence_drv[fence->ring].last_seq; 254 seq = atomic64_read(&rdev->fence_drv[fence->ring].last_seq);
255 /* Save current last activity valuee, used to check for GPU lockups */
256 last_activity = rdev->fence_drv[fence->ring].last_activity;
211 read_unlock_irqrestore(&rdev->fence_lock, irq_flags); 257 read_unlock_irqrestore(&rdev->fence_lock, irq_flags);
212 258
213 trace_radeon_fence_wait_begin(rdev->ddev, seq); 259 trace_radeon_fence_wait_begin(rdev->ddev, seq);
@@ -235,24 +281,23 @@ int radeon_fence_wait(struct radeon_fence *fence, bool intr)
235 } 281 }
236 282
237 write_lock_irqsave(&rdev->fence_lock, irq_flags); 283 write_lock_irqsave(&rdev->fence_lock, irq_flags);
238 /* check if sequence value has changed since last_activity */ 284 /* test if somebody else has already decided that this is a lockup */
239 if (seq != rdev->fence_drv[fence->ring].last_seq) { 285 if (last_activity != rdev->fence_drv[fence->ring].last_activity) {
240 write_unlock_irqrestore(&rdev->fence_lock, irq_flags); 286 write_unlock_irqrestore(&rdev->fence_lock, irq_flags);
241 continue; 287 continue;
242 } 288 }
243 289
244 /* change sequence value on all rings, so nobody else things there is a lockup */
245 for (i = 0; i < RADEON_NUM_RINGS; ++i)
246 rdev->fence_drv[i].last_seq -= 0x10000;
247
248 rdev->fence_drv[fence->ring].last_activity = jiffies;
249 write_unlock_irqrestore(&rdev->fence_lock, irq_flags); 290 write_unlock_irqrestore(&rdev->fence_lock, irq_flags);
250 291
251 if (radeon_ring_is_lockup(rdev, fence->ring, &rdev->ring[fence->ring])) { 292 if (radeon_ring_is_lockup(rdev, fence->ring, &rdev->ring[fence->ring])) {
252
253 /* good news we believe it's a lockup */ 293 /* good news we believe it's a lockup */
254 printk(KERN_WARNING "GPU lockup (waiting for 0x%08X last fence id 0x%08X)\n", 294 dev_warn(rdev->dev, "GPU lockup (waiting for 0x%016llx last fence id 0x%016llx)\n",
255 fence->seq, seq); 295 fence->seq, seq);
296
297 /* change last activity so nobody else think there is a lockup */
298 for (i = 0; i < RADEON_NUM_RINGS; ++i) {
299 rdev->fence_drv[i].last_activity = jiffies;
300 }
256 301
257 /* mark the ring as not ready any more */ 302 /* mark the ring as not ready any more */
258 rdev->ring[fence->ring].ready = false; 303 rdev->ring[fence->ring].ready = false;
@@ -387,9 +432,9 @@ int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring)
387 } 432 }
388 rdev->fence_drv[ring].cpu_addr = &rdev->wb.wb[index/4]; 433 rdev->fence_drv[ring].cpu_addr = &rdev->wb.wb[index/4];
389 rdev->fence_drv[ring].gpu_addr = rdev->wb.gpu_addr + index; 434 rdev->fence_drv[ring].gpu_addr = rdev->wb.gpu_addr + index;
390 radeon_fence_write(rdev, atomic_read(&rdev->fence_drv[ring].seq), ring); 435 radeon_fence_write(rdev, rdev->fence_drv[ring].seq, ring);
391 rdev->fence_drv[ring].initialized = true; 436 rdev->fence_drv[ring].initialized = true;
392 DRM_INFO("fence driver on ring %d use gpu addr 0x%08Lx and cpu addr 0x%p\n", 437 DRM_INFO("fence driver on ring %d use gpu addr 0x%016llx and cpu addr 0x%p\n",
393 ring, rdev->fence_drv[ring].gpu_addr, rdev->fence_drv[ring].cpu_addr); 438 ring, rdev->fence_drv[ring].gpu_addr, rdev->fence_drv[ring].cpu_addr);
394 write_unlock_irqrestore(&rdev->fence_lock, irq_flags); 439 write_unlock_irqrestore(&rdev->fence_lock, irq_flags);
395 return 0; 440 return 0;
@@ -400,7 +445,8 @@ static void radeon_fence_driver_init_ring(struct radeon_device *rdev, int ring)
400 rdev->fence_drv[ring].scratch_reg = -1; 445 rdev->fence_drv[ring].scratch_reg = -1;
401 rdev->fence_drv[ring].cpu_addr = NULL; 446 rdev->fence_drv[ring].cpu_addr = NULL;
402 rdev->fence_drv[ring].gpu_addr = 0; 447 rdev->fence_drv[ring].gpu_addr = 0;
403 atomic_set(&rdev->fence_drv[ring].seq, 0); 448 rdev->fence_drv[ring].seq = 0;
449 atomic64_set(&rdev->fence_drv[ring].last_seq, 0);
404 INIT_LIST_HEAD(&rdev->fence_drv[ring].emitted); 450 INIT_LIST_HEAD(&rdev->fence_drv[ring].emitted);
405 INIT_LIST_HEAD(&rdev->fence_drv[ring].signaled); 451 INIT_LIST_HEAD(&rdev->fence_drv[ring].signaled);
406 init_waitqueue_head(&rdev->fence_drv[ring].queue); 452 init_waitqueue_head(&rdev->fence_drv[ring].queue);
@@ -458,12 +504,12 @@ static int radeon_debugfs_fence_info(struct seq_file *m, void *data)
458 continue; 504 continue;
459 505
460 seq_printf(m, "--- ring %d ---\n", i); 506 seq_printf(m, "--- ring %d ---\n", i);
461 seq_printf(m, "Last signaled fence 0x%08X\n", 507 seq_printf(m, "Last signaled fence 0x%016lx\n",
462 radeon_fence_read(rdev, i)); 508 atomic64_read(&rdev->fence_drv[i].last_seq));
463 if (!list_empty(&rdev->fence_drv[i].emitted)) { 509 if (!list_empty(&rdev->fence_drv[i].emitted)) {
464 fence = list_entry(rdev->fence_drv[i].emitted.prev, 510 fence = list_entry(rdev->fence_drv[i].emitted.prev,
465 struct radeon_fence, list); 511 struct radeon_fence, list);
466 seq_printf(m, "Last emitted fence %p with 0x%08X\n", 512 seq_printf(m, "Last emitted fence %p with 0x%016llx\n",
467 fence, fence->seq); 513 fence, fence->seq);
468 } 514 }
469 } 515 }
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
index a4d60ae524b1..4ae222bb3ec5 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -82,7 +82,7 @@ bool radeon_ib_try_free(struct radeon_device *rdev, struct radeon_ib *ib)
82 bool done = false; 82 bool done = false;
83 83
84 /* only free ib which have been emited */ 84 /* only free ib which have been emited */
85 if (ib->fence && ib->fence->emitted) { 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);
@@ -149,8 +149,9 @@ retry:
149 /* this should be rare event, ie all ib scheduled none signaled yet. 149 /* this should be rare event, ie all ib scheduled none signaled yet.
150 */ 150 */
151 for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { 151 for (i = 0; i < RADEON_IB_POOL_SIZE; i++) {
152 if (rdev->ib_pool.ibs[idx].fence && rdev->ib_pool.ibs[idx].fence->emitted) { 152 struct radeon_fence *fence = rdev->ib_pool.ibs[idx].fence;
153 r = radeon_fence_wait(rdev->ib_pool.ibs[idx].fence, false); 153 if (fence && fence->seq < RADEON_FENCE_NOTEMITED_SEQ) {
154 r = radeon_fence_wait(fence, false);
154 if (!r) { 155 if (!r) {
155 goto retry; 156 goto retry;
156 } 157 }
@@ -173,7 +174,7 @@ void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib)
173 return; 174 return;
174 } 175 }
175 radeon_mutex_lock(&rdev->ib_pool.mutex); 176 radeon_mutex_lock(&rdev->ib_pool.mutex);
176 if (tmp->fence && !tmp->fence->emitted) { 177 if (tmp->fence && tmp->fence->seq == RADEON_FENCE_NOTEMITED_SEQ) {
177 radeon_sa_bo_free(rdev, &tmp->sa_bo); 178 radeon_sa_bo_free(rdev, &tmp->sa_bo);
178 radeon_fence_unref(&tmp->fence); 179 radeon_fence_unref(&tmp->fence);
179 } 180 }