1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright 2009 Jerome Glisse.
3*4882a593Smuzhiyun * All Rights Reserved.
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Permission is hereby granted, free of charge, to any person obtaining a
6*4882a593Smuzhiyun * copy of this software and associated documentation files (the
7*4882a593Smuzhiyun * "Software"), to deal in the Software without restriction, including
8*4882a593Smuzhiyun * without limitation the rights to use, copy, modify, merge, publish,
9*4882a593Smuzhiyun * distribute, sub license, and/or sell copies of the Software, and to
10*4882a593Smuzhiyun * permit persons to whom the Software is furnished to do so, subject to
11*4882a593Smuzhiyun * the following conditions:
12*4882a593Smuzhiyun *
13*4882a593Smuzhiyun * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14*4882a593Smuzhiyun * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15*4882a593Smuzhiyun * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
16*4882a593Smuzhiyun * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
17*4882a593Smuzhiyun * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
18*4882a593Smuzhiyun * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19*4882a593Smuzhiyun * USE OR OTHER DEALINGS IN THE SOFTWARE.
20*4882a593Smuzhiyun *
21*4882a593Smuzhiyun * The above copyright notice and this permission notice (including the
22*4882a593Smuzhiyun * next paragraph) shall be included in all copies or substantial portions
23*4882a593Smuzhiyun * of the Software.
24*4882a593Smuzhiyun *
25*4882a593Smuzhiyun */
26*4882a593Smuzhiyun /*
27*4882a593Smuzhiyun * Authors:
28*4882a593Smuzhiyun * Jerome Glisse <glisse@freedesktop.org>
29*4882a593Smuzhiyun * Dave Airlie
30*4882a593Smuzhiyun */
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun #include <linux/atomic.h>
33*4882a593Smuzhiyun #include <linux/firmware.h>
34*4882a593Smuzhiyun #include <linux/kref.h>
35*4882a593Smuzhiyun #include <linux/sched/signal.h>
36*4882a593Smuzhiyun #include <linux/seq_file.h>
37*4882a593Smuzhiyun #include <linux/slab.h>
38*4882a593Smuzhiyun #include <linux/wait.h>
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun #include <drm/drm_debugfs.h>
41*4882a593Smuzhiyun #include <drm/drm_device.h>
42*4882a593Smuzhiyun #include <drm/drm_file.h>
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun #include "radeon.h"
45*4882a593Smuzhiyun #include "radeon_reg.h"
46*4882a593Smuzhiyun #include "radeon_trace.h"
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun /*
49*4882a593Smuzhiyun * Fences
50*4882a593Smuzhiyun * Fences mark an event in the GPUs pipeline and are used
51*4882a593Smuzhiyun * for GPU/CPU synchronization. When the fence is written,
52*4882a593Smuzhiyun * it is expected that all buffers associated with that fence
53*4882a593Smuzhiyun * are no longer in use by the associated ring on the GPU and
54*4882a593Smuzhiyun * that the the relevant GPU caches have been flushed. Whether
55*4882a593Smuzhiyun * we use a scratch register or memory location depends on the asic
56*4882a593Smuzhiyun * and whether writeback is enabled.
57*4882a593Smuzhiyun */
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun /**
60*4882a593Smuzhiyun * radeon_fence_write - write a fence value
61*4882a593Smuzhiyun *
62*4882a593Smuzhiyun * @rdev: radeon_device pointer
63*4882a593Smuzhiyun * @seq: sequence number to write
64*4882a593Smuzhiyun * @ring: ring index the fence is associated with
65*4882a593Smuzhiyun *
66*4882a593Smuzhiyun * Writes a fence value to memory or a scratch register (all asics).
67*4882a593Smuzhiyun */
radeon_fence_write(struct radeon_device * rdev,u32 seq,int ring)68*4882a593Smuzhiyun static void radeon_fence_write(struct radeon_device *rdev, u32 seq, int ring)
69*4882a593Smuzhiyun {
70*4882a593Smuzhiyun struct radeon_fence_driver *drv = &rdev->fence_drv[ring];
71*4882a593Smuzhiyun if (likely(rdev->wb.enabled || !drv->scratch_reg)) {
72*4882a593Smuzhiyun if (drv->cpu_addr) {
73*4882a593Smuzhiyun *drv->cpu_addr = cpu_to_le32(seq);
74*4882a593Smuzhiyun }
75*4882a593Smuzhiyun } else {
76*4882a593Smuzhiyun WREG32(drv->scratch_reg, seq);
77*4882a593Smuzhiyun }
78*4882a593Smuzhiyun }
79*4882a593Smuzhiyun
80*4882a593Smuzhiyun /**
81*4882a593Smuzhiyun * radeon_fence_read - read a fence value
82*4882a593Smuzhiyun *
83*4882a593Smuzhiyun * @rdev: radeon_device pointer
84*4882a593Smuzhiyun * @ring: ring index the fence is associated with
85*4882a593Smuzhiyun *
86*4882a593Smuzhiyun * Reads a fence value from memory or a scratch register (all asics).
87*4882a593Smuzhiyun * Returns the value of the fence read from memory or register.
88*4882a593Smuzhiyun */
radeon_fence_read(struct radeon_device * rdev,int ring)89*4882a593Smuzhiyun static u32 radeon_fence_read(struct radeon_device *rdev, int ring)
90*4882a593Smuzhiyun {
91*4882a593Smuzhiyun struct radeon_fence_driver *drv = &rdev->fence_drv[ring];
92*4882a593Smuzhiyun u32 seq = 0;
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun if (likely(rdev->wb.enabled || !drv->scratch_reg)) {
95*4882a593Smuzhiyun if (drv->cpu_addr) {
96*4882a593Smuzhiyun seq = le32_to_cpu(*drv->cpu_addr);
97*4882a593Smuzhiyun } else {
98*4882a593Smuzhiyun seq = lower_32_bits(atomic64_read(&drv->last_seq));
99*4882a593Smuzhiyun }
100*4882a593Smuzhiyun } else {
101*4882a593Smuzhiyun seq = RREG32(drv->scratch_reg);
102*4882a593Smuzhiyun }
103*4882a593Smuzhiyun return seq;
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun /**
107*4882a593Smuzhiyun * radeon_fence_schedule_check - schedule lockup check
108*4882a593Smuzhiyun *
109*4882a593Smuzhiyun * @rdev: radeon_device pointer
110*4882a593Smuzhiyun * @ring: ring index we should work with
111*4882a593Smuzhiyun *
112*4882a593Smuzhiyun * Queues a delayed work item to check for lockups.
113*4882a593Smuzhiyun */
radeon_fence_schedule_check(struct radeon_device * rdev,int ring)114*4882a593Smuzhiyun static void radeon_fence_schedule_check(struct radeon_device *rdev, int ring)
115*4882a593Smuzhiyun {
116*4882a593Smuzhiyun /*
117*4882a593Smuzhiyun * Do not reset the timer here with mod_delayed_work,
118*4882a593Smuzhiyun * this can livelock in an interaction with TTM delayed destroy.
119*4882a593Smuzhiyun */
120*4882a593Smuzhiyun queue_delayed_work(system_power_efficient_wq,
121*4882a593Smuzhiyun &rdev->fence_drv[ring].lockup_work,
122*4882a593Smuzhiyun RADEON_FENCE_JIFFIES_TIMEOUT);
123*4882a593Smuzhiyun }
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun /**
126*4882a593Smuzhiyun * radeon_fence_emit - emit a fence on the requested ring
127*4882a593Smuzhiyun *
128*4882a593Smuzhiyun * @rdev: radeon_device pointer
129*4882a593Smuzhiyun * @fence: radeon fence object
130*4882a593Smuzhiyun * @ring: ring index the fence is associated with
131*4882a593Smuzhiyun *
132*4882a593Smuzhiyun * Emits a fence command on the requested ring (all asics).
133*4882a593Smuzhiyun * Returns 0 on success, -ENOMEM on failure.
134*4882a593Smuzhiyun */
radeon_fence_emit(struct radeon_device * rdev,struct radeon_fence ** fence,int ring)135*4882a593Smuzhiyun int radeon_fence_emit(struct radeon_device *rdev,
136*4882a593Smuzhiyun struct radeon_fence **fence,
137*4882a593Smuzhiyun int ring)
138*4882a593Smuzhiyun {
139*4882a593Smuzhiyun u64 seq;
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun /* we are protected by the ring emission mutex */
142*4882a593Smuzhiyun *fence = kmalloc(sizeof(struct radeon_fence), GFP_KERNEL);
143*4882a593Smuzhiyun if ((*fence) == NULL) {
144*4882a593Smuzhiyun return -ENOMEM;
145*4882a593Smuzhiyun }
146*4882a593Smuzhiyun (*fence)->rdev = rdev;
147*4882a593Smuzhiyun (*fence)->seq = seq = ++rdev->fence_drv[ring].sync_seq[ring];
148*4882a593Smuzhiyun (*fence)->ring = ring;
149*4882a593Smuzhiyun (*fence)->is_vm_update = false;
150*4882a593Smuzhiyun dma_fence_init(&(*fence)->base, &radeon_fence_ops,
151*4882a593Smuzhiyun &rdev->fence_queue.lock,
152*4882a593Smuzhiyun rdev->fence_context + ring,
153*4882a593Smuzhiyun seq);
154*4882a593Smuzhiyun radeon_fence_ring_emit(rdev, ring, *fence);
155*4882a593Smuzhiyun trace_radeon_fence_emit(rdev->ddev, ring, (*fence)->seq);
156*4882a593Smuzhiyun radeon_fence_schedule_check(rdev, ring);
157*4882a593Smuzhiyun return 0;
158*4882a593Smuzhiyun }
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun /**
161*4882a593Smuzhiyun * radeon_fence_check_signaled - callback from fence_queue
162*4882a593Smuzhiyun *
163*4882a593Smuzhiyun * this function is called with fence_queue lock held, which is also used
164*4882a593Smuzhiyun * for the fence locking itself, so unlocked variants are used for
165*4882a593Smuzhiyun * fence_signal, and remove_wait_queue.
166*4882a593Smuzhiyun */
radeon_fence_check_signaled(wait_queue_entry_t * wait,unsigned mode,int flags,void * key)167*4882a593Smuzhiyun static int radeon_fence_check_signaled(wait_queue_entry_t *wait, unsigned mode, int flags, void *key)
168*4882a593Smuzhiyun {
169*4882a593Smuzhiyun struct radeon_fence *fence;
170*4882a593Smuzhiyun u64 seq;
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun fence = container_of(wait, struct radeon_fence, fence_wake);
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun /*
175*4882a593Smuzhiyun * We cannot use radeon_fence_process here because we're already
176*4882a593Smuzhiyun * in the waitqueue, in a call from wake_up_all.
177*4882a593Smuzhiyun */
178*4882a593Smuzhiyun seq = atomic64_read(&fence->rdev->fence_drv[fence->ring].last_seq);
179*4882a593Smuzhiyun if (seq >= fence->seq) {
180*4882a593Smuzhiyun int ret = dma_fence_signal_locked(&fence->base);
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun if (!ret)
183*4882a593Smuzhiyun DMA_FENCE_TRACE(&fence->base, "signaled from irq context\n");
184*4882a593Smuzhiyun else
185*4882a593Smuzhiyun DMA_FENCE_TRACE(&fence->base, "was already signaled\n");
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun radeon_irq_kms_sw_irq_put(fence->rdev, fence->ring);
188*4882a593Smuzhiyun __remove_wait_queue(&fence->rdev->fence_queue, &fence->fence_wake);
189*4882a593Smuzhiyun dma_fence_put(&fence->base);
190*4882a593Smuzhiyun } else
191*4882a593Smuzhiyun DMA_FENCE_TRACE(&fence->base, "pending\n");
192*4882a593Smuzhiyun return 0;
193*4882a593Smuzhiyun }
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun /**
196*4882a593Smuzhiyun * radeon_fence_activity - check for fence activity
197*4882a593Smuzhiyun *
198*4882a593Smuzhiyun * @rdev: radeon_device pointer
199*4882a593Smuzhiyun * @ring: ring index the fence is associated with
200*4882a593Smuzhiyun *
201*4882a593Smuzhiyun * Checks the current fence value and calculates the last
202*4882a593Smuzhiyun * signalled fence value. Returns true if activity occured
203*4882a593Smuzhiyun * on the ring, and the fence_queue should be waken up.
204*4882a593Smuzhiyun */
radeon_fence_activity(struct radeon_device * rdev,int ring)205*4882a593Smuzhiyun static bool radeon_fence_activity(struct radeon_device *rdev, int ring)
206*4882a593Smuzhiyun {
207*4882a593Smuzhiyun uint64_t seq, last_seq, last_emitted;
208*4882a593Smuzhiyun unsigned count_loop = 0;
209*4882a593Smuzhiyun bool wake = false;
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun /* Note there is a scenario here for an infinite loop but it's
212*4882a593Smuzhiyun * very unlikely to happen. For it to happen, the current polling
213*4882a593Smuzhiyun * process need to be interrupted by another process and another
214*4882a593Smuzhiyun * process needs to update the last_seq btw the atomic read and
215*4882a593Smuzhiyun * xchg of the current process.
216*4882a593Smuzhiyun *
217*4882a593Smuzhiyun * More over for this to go in infinite loop there need to be
218*4882a593Smuzhiyun * continuously new fence signaled ie radeon_fence_read needs
219*4882a593Smuzhiyun * to return a different value each time for both the currently
220*4882a593Smuzhiyun * polling process and the other process that xchg the last_seq
221*4882a593Smuzhiyun * btw atomic read and xchg of the current process. And the
222*4882a593Smuzhiyun * value the other process set as last seq must be higher than
223*4882a593Smuzhiyun * the seq value we just read. Which means that current process
224*4882a593Smuzhiyun * need to be interrupted after radeon_fence_read and before
225*4882a593Smuzhiyun * atomic xchg.
226*4882a593Smuzhiyun *
227*4882a593Smuzhiyun * To be even more safe we count the number of time we loop and
228*4882a593Smuzhiyun * we bail after 10 loop just accepting the fact that we might
229*4882a593Smuzhiyun * have temporarly set the last_seq not to the true real last
230*4882a593Smuzhiyun * seq but to an older one.
231*4882a593Smuzhiyun */
232*4882a593Smuzhiyun last_seq = atomic64_read(&rdev->fence_drv[ring].last_seq);
233*4882a593Smuzhiyun do {
234*4882a593Smuzhiyun last_emitted = rdev->fence_drv[ring].sync_seq[ring];
235*4882a593Smuzhiyun seq = radeon_fence_read(rdev, ring);
236*4882a593Smuzhiyun seq |= last_seq & 0xffffffff00000000LL;
237*4882a593Smuzhiyun if (seq < last_seq) {
238*4882a593Smuzhiyun seq &= 0xffffffff;
239*4882a593Smuzhiyun seq |= last_emitted & 0xffffffff00000000LL;
240*4882a593Smuzhiyun }
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun if (seq <= last_seq || seq > last_emitted) {
243*4882a593Smuzhiyun break;
244*4882a593Smuzhiyun }
245*4882a593Smuzhiyun /* If we loop over we don't want to return without
246*4882a593Smuzhiyun * checking if a fence is signaled as it means that the
247*4882a593Smuzhiyun * seq we just read is different from the previous on.
248*4882a593Smuzhiyun */
249*4882a593Smuzhiyun wake = true;
250*4882a593Smuzhiyun last_seq = seq;
251*4882a593Smuzhiyun if ((count_loop++) > 10) {
252*4882a593Smuzhiyun /* We looped over too many time leave with the
253*4882a593Smuzhiyun * fact that we might have set an older fence
254*4882a593Smuzhiyun * seq then the current real last seq as signaled
255*4882a593Smuzhiyun * by the hw.
256*4882a593Smuzhiyun */
257*4882a593Smuzhiyun break;
258*4882a593Smuzhiyun }
259*4882a593Smuzhiyun } while (atomic64_xchg(&rdev->fence_drv[ring].last_seq, seq) > seq);
260*4882a593Smuzhiyun
261*4882a593Smuzhiyun if (seq < last_emitted)
262*4882a593Smuzhiyun radeon_fence_schedule_check(rdev, ring);
263*4882a593Smuzhiyun
264*4882a593Smuzhiyun return wake;
265*4882a593Smuzhiyun }
266*4882a593Smuzhiyun
267*4882a593Smuzhiyun /**
268*4882a593Smuzhiyun * radeon_fence_check_lockup - check for hardware lockup
269*4882a593Smuzhiyun *
270*4882a593Smuzhiyun * @work: delayed work item
271*4882a593Smuzhiyun *
272*4882a593Smuzhiyun * Checks for fence activity and if there is none probe
273*4882a593Smuzhiyun * the hardware if a lockup occured.
274*4882a593Smuzhiyun */
radeon_fence_check_lockup(struct work_struct * work)275*4882a593Smuzhiyun static void radeon_fence_check_lockup(struct work_struct *work)
276*4882a593Smuzhiyun {
277*4882a593Smuzhiyun struct radeon_fence_driver *fence_drv;
278*4882a593Smuzhiyun struct radeon_device *rdev;
279*4882a593Smuzhiyun int ring;
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun fence_drv = container_of(work, struct radeon_fence_driver,
282*4882a593Smuzhiyun lockup_work.work);
283*4882a593Smuzhiyun rdev = fence_drv->rdev;
284*4882a593Smuzhiyun ring = fence_drv - &rdev->fence_drv[0];
285*4882a593Smuzhiyun
286*4882a593Smuzhiyun if (!down_read_trylock(&rdev->exclusive_lock)) {
287*4882a593Smuzhiyun /* just reschedule the check if a reset is going on */
288*4882a593Smuzhiyun radeon_fence_schedule_check(rdev, ring);
289*4882a593Smuzhiyun return;
290*4882a593Smuzhiyun }
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun if (fence_drv->delayed_irq && rdev->ddev->irq_enabled) {
293*4882a593Smuzhiyun unsigned long irqflags;
294*4882a593Smuzhiyun
295*4882a593Smuzhiyun fence_drv->delayed_irq = false;
296*4882a593Smuzhiyun spin_lock_irqsave(&rdev->irq.lock, irqflags);
297*4882a593Smuzhiyun radeon_irq_set(rdev);
298*4882a593Smuzhiyun spin_unlock_irqrestore(&rdev->irq.lock, irqflags);
299*4882a593Smuzhiyun }
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun if (radeon_fence_activity(rdev, ring))
302*4882a593Smuzhiyun wake_up_all(&rdev->fence_queue);
303*4882a593Smuzhiyun
304*4882a593Smuzhiyun else if (radeon_ring_is_lockup(rdev, ring, &rdev->ring[ring])) {
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun /* good news we believe it's a lockup */
307*4882a593Smuzhiyun dev_warn(rdev->dev, "GPU lockup (current fence id "
308*4882a593Smuzhiyun "0x%016llx last fence id 0x%016llx on ring %d)\n",
309*4882a593Smuzhiyun (uint64_t)atomic64_read(&fence_drv->last_seq),
310*4882a593Smuzhiyun fence_drv->sync_seq[ring], ring);
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun /* remember that we need an reset */
313*4882a593Smuzhiyun rdev->needs_reset = true;
314*4882a593Smuzhiyun wake_up_all(&rdev->fence_queue);
315*4882a593Smuzhiyun }
316*4882a593Smuzhiyun up_read(&rdev->exclusive_lock);
317*4882a593Smuzhiyun }
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun /**
320*4882a593Smuzhiyun * radeon_fence_process - process a fence
321*4882a593Smuzhiyun *
322*4882a593Smuzhiyun * @rdev: radeon_device pointer
323*4882a593Smuzhiyun * @ring: ring index the fence is associated with
324*4882a593Smuzhiyun *
325*4882a593Smuzhiyun * Checks the current fence value and wakes the fence queue
326*4882a593Smuzhiyun * if the sequence number has increased (all asics).
327*4882a593Smuzhiyun */
radeon_fence_process(struct radeon_device * rdev,int ring)328*4882a593Smuzhiyun void radeon_fence_process(struct radeon_device *rdev, int ring)
329*4882a593Smuzhiyun {
330*4882a593Smuzhiyun if (radeon_fence_activity(rdev, ring))
331*4882a593Smuzhiyun wake_up_all(&rdev->fence_queue);
332*4882a593Smuzhiyun }
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun /**
335*4882a593Smuzhiyun * radeon_fence_seq_signaled - check if a fence sequence number has signaled
336*4882a593Smuzhiyun *
337*4882a593Smuzhiyun * @rdev: radeon device pointer
338*4882a593Smuzhiyun * @seq: sequence number
339*4882a593Smuzhiyun * @ring: ring index the fence is associated with
340*4882a593Smuzhiyun *
341*4882a593Smuzhiyun * Check if the last signaled fence sequnce number is >= the requested
342*4882a593Smuzhiyun * sequence number (all asics).
343*4882a593Smuzhiyun * Returns true if the fence has signaled (current fence value
344*4882a593Smuzhiyun * is >= requested value) or false if it has not (current fence
345*4882a593Smuzhiyun * value is < the requested value. Helper function for
346*4882a593Smuzhiyun * radeon_fence_signaled().
347*4882a593Smuzhiyun */
radeon_fence_seq_signaled(struct radeon_device * rdev,u64 seq,unsigned ring)348*4882a593Smuzhiyun static bool radeon_fence_seq_signaled(struct radeon_device *rdev,
349*4882a593Smuzhiyun u64 seq, unsigned ring)
350*4882a593Smuzhiyun {
351*4882a593Smuzhiyun if (atomic64_read(&rdev->fence_drv[ring].last_seq) >= seq) {
352*4882a593Smuzhiyun return true;
353*4882a593Smuzhiyun }
354*4882a593Smuzhiyun /* poll new last sequence at least once */
355*4882a593Smuzhiyun radeon_fence_process(rdev, ring);
356*4882a593Smuzhiyun if (atomic64_read(&rdev->fence_drv[ring].last_seq) >= seq) {
357*4882a593Smuzhiyun return true;
358*4882a593Smuzhiyun }
359*4882a593Smuzhiyun return false;
360*4882a593Smuzhiyun }
361*4882a593Smuzhiyun
radeon_fence_is_signaled(struct dma_fence * f)362*4882a593Smuzhiyun static bool radeon_fence_is_signaled(struct dma_fence *f)
363*4882a593Smuzhiyun {
364*4882a593Smuzhiyun struct radeon_fence *fence = to_radeon_fence(f);
365*4882a593Smuzhiyun struct radeon_device *rdev = fence->rdev;
366*4882a593Smuzhiyun unsigned ring = fence->ring;
367*4882a593Smuzhiyun u64 seq = fence->seq;
368*4882a593Smuzhiyun
369*4882a593Smuzhiyun if (atomic64_read(&rdev->fence_drv[ring].last_seq) >= seq) {
370*4882a593Smuzhiyun return true;
371*4882a593Smuzhiyun }
372*4882a593Smuzhiyun
373*4882a593Smuzhiyun if (down_read_trylock(&rdev->exclusive_lock)) {
374*4882a593Smuzhiyun radeon_fence_process(rdev, ring);
375*4882a593Smuzhiyun up_read(&rdev->exclusive_lock);
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun if (atomic64_read(&rdev->fence_drv[ring].last_seq) >= seq) {
378*4882a593Smuzhiyun return true;
379*4882a593Smuzhiyun }
380*4882a593Smuzhiyun }
381*4882a593Smuzhiyun return false;
382*4882a593Smuzhiyun }
383*4882a593Smuzhiyun
384*4882a593Smuzhiyun /**
385*4882a593Smuzhiyun * radeon_fence_enable_signaling - enable signalling on fence
386*4882a593Smuzhiyun * @fence: fence
387*4882a593Smuzhiyun *
388*4882a593Smuzhiyun * This function is called with fence_queue lock held, and adds a callback
389*4882a593Smuzhiyun * to fence_queue that checks if this fence is signaled, and if so it
390*4882a593Smuzhiyun * signals the fence and removes itself.
391*4882a593Smuzhiyun */
radeon_fence_enable_signaling(struct dma_fence * f)392*4882a593Smuzhiyun static bool radeon_fence_enable_signaling(struct dma_fence *f)
393*4882a593Smuzhiyun {
394*4882a593Smuzhiyun struct radeon_fence *fence = to_radeon_fence(f);
395*4882a593Smuzhiyun struct radeon_device *rdev = fence->rdev;
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun if (atomic64_read(&rdev->fence_drv[fence->ring].last_seq) >= fence->seq)
398*4882a593Smuzhiyun return false;
399*4882a593Smuzhiyun
400*4882a593Smuzhiyun if (down_read_trylock(&rdev->exclusive_lock)) {
401*4882a593Smuzhiyun radeon_irq_kms_sw_irq_get(rdev, fence->ring);
402*4882a593Smuzhiyun
403*4882a593Smuzhiyun if (radeon_fence_activity(rdev, fence->ring))
404*4882a593Smuzhiyun wake_up_all_locked(&rdev->fence_queue);
405*4882a593Smuzhiyun
406*4882a593Smuzhiyun /* did fence get signaled after we enabled the sw irq? */
407*4882a593Smuzhiyun if (atomic64_read(&rdev->fence_drv[fence->ring].last_seq) >= fence->seq) {
408*4882a593Smuzhiyun radeon_irq_kms_sw_irq_put(rdev, fence->ring);
409*4882a593Smuzhiyun up_read(&rdev->exclusive_lock);
410*4882a593Smuzhiyun return false;
411*4882a593Smuzhiyun }
412*4882a593Smuzhiyun
413*4882a593Smuzhiyun up_read(&rdev->exclusive_lock);
414*4882a593Smuzhiyun } else {
415*4882a593Smuzhiyun /* we're probably in a lockup, lets not fiddle too much */
416*4882a593Smuzhiyun if (radeon_irq_kms_sw_irq_get_delayed(rdev, fence->ring))
417*4882a593Smuzhiyun rdev->fence_drv[fence->ring].delayed_irq = true;
418*4882a593Smuzhiyun radeon_fence_schedule_check(rdev, fence->ring);
419*4882a593Smuzhiyun }
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun fence->fence_wake.flags = 0;
422*4882a593Smuzhiyun fence->fence_wake.private = NULL;
423*4882a593Smuzhiyun fence->fence_wake.func = radeon_fence_check_signaled;
424*4882a593Smuzhiyun __add_wait_queue(&rdev->fence_queue, &fence->fence_wake);
425*4882a593Smuzhiyun dma_fence_get(f);
426*4882a593Smuzhiyun
427*4882a593Smuzhiyun DMA_FENCE_TRACE(&fence->base, "armed on ring %i!\n", fence->ring);
428*4882a593Smuzhiyun return true;
429*4882a593Smuzhiyun }
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun /**
432*4882a593Smuzhiyun * radeon_fence_signaled - check if a fence has signaled
433*4882a593Smuzhiyun *
434*4882a593Smuzhiyun * @fence: radeon fence object
435*4882a593Smuzhiyun *
436*4882a593Smuzhiyun * Check if the requested fence has signaled (all asics).
437*4882a593Smuzhiyun * Returns true if the fence has signaled or false if it has not.
438*4882a593Smuzhiyun */
radeon_fence_signaled(struct radeon_fence * fence)439*4882a593Smuzhiyun bool radeon_fence_signaled(struct radeon_fence *fence)
440*4882a593Smuzhiyun {
441*4882a593Smuzhiyun if (!fence)
442*4882a593Smuzhiyun return true;
443*4882a593Smuzhiyun
444*4882a593Smuzhiyun if (radeon_fence_seq_signaled(fence->rdev, fence->seq, fence->ring)) {
445*4882a593Smuzhiyun int ret;
446*4882a593Smuzhiyun
447*4882a593Smuzhiyun ret = dma_fence_signal(&fence->base);
448*4882a593Smuzhiyun if (!ret)
449*4882a593Smuzhiyun DMA_FENCE_TRACE(&fence->base, "signaled from radeon_fence_signaled\n");
450*4882a593Smuzhiyun return true;
451*4882a593Smuzhiyun }
452*4882a593Smuzhiyun return false;
453*4882a593Smuzhiyun }
454*4882a593Smuzhiyun
455*4882a593Smuzhiyun /**
456*4882a593Smuzhiyun * radeon_fence_any_seq_signaled - check if any sequence number is signaled
457*4882a593Smuzhiyun *
458*4882a593Smuzhiyun * @rdev: radeon device pointer
459*4882a593Smuzhiyun * @seq: sequence numbers
460*4882a593Smuzhiyun *
461*4882a593Smuzhiyun * Check if the last signaled fence sequnce number is >= the requested
462*4882a593Smuzhiyun * sequence number (all asics).
463*4882a593Smuzhiyun * Returns true if any has signaled (current value is >= requested value)
464*4882a593Smuzhiyun * or false if it has not. Helper function for radeon_fence_wait_seq.
465*4882a593Smuzhiyun */
radeon_fence_any_seq_signaled(struct radeon_device * rdev,u64 * seq)466*4882a593Smuzhiyun static bool radeon_fence_any_seq_signaled(struct radeon_device *rdev, u64 *seq)
467*4882a593Smuzhiyun {
468*4882a593Smuzhiyun unsigned i;
469*4882a593Smuzhiyun
470*4882a593Smuzhiyun for (i = 0; i < RADEON_NUM_RINGS; ++i) {
471*4882a593Smuzhiyun if (seq[i] && radeon_fence_seq_signaled(rdev, seq[i], i))
472*4882a593Smuzhiyun return true;
473*4882a593Smuzhiyun }
474*4882a593Smuzhiyun return false;
475*4882a593Smuzhiyun }
476*4882a593Smuzhiyun
477*4882a593Smuzhiyun /**
478*4882a593Smuzhiyun * radeon_fence_wait_seq_timeout - wait for a specific sequence numbers
479*4882a593Smuzhiyun *
480*4882a593Smuzhiyun * @rdev: radeon device pointer
481*4882a593Smuzhiyun * @target_seq: sequence number(s) we want to wait for
482*4882a593Smuzhiyun * @intr: use interruptable sleep
483*4882a593Smuzhiyun * @timeout: maximum time to wait, or MAX_SCHEDULE_TIMEOUT for infinite wait
484*4882a593Smuzhiyun *
485*4882a593Smuzhiyun * Wait for the requested sequence number(s) to be written by any ring
486*4882a593Smuzhiyun * (all asics). Sequnce number array is indexed by ring id.
487*4882a593Smuzhiyun * @intr selects whether to use interruptable (true) or non-interruptable
488*4882a593Smuzhiyun * (false) sleep when waiting for the sequence number. Helper function
489*4882a593Smuzhiyun * for radeon_fence_wait_*().
490*4882a593Smuzhiyun * Returns remaining time if the sequence number has passed, 0 when
491*4882a593Smuzhiyun * the wait timeout, or an error for all other cases.
492*4882a593Smuzhiyun * -EDEADLK is returned when a GPU lockup has been detected.
493*4882a593Smuzhiyun */
radeon_fence_wait_seq_timeout(struct radeon_device * rdev,u64 * target_seq,bool intr,long timeout)494*4882a593Smuzhiyun static long radeon_fence_wait_seq_timeout(struct radeon_device *rdev,
495*4882a593Smuzhiyun u64 *target_seq, bool intr,
496*4882a593Smuzhiyun long timeout)
497*4882a593Smuzhiyun {
498*4882a593Smuzhiyun long r;
499*4882a593Smuzhiyun int i;
500*4882a593Smuzhiyun
501*4882a593Smuzhiyun if (radeon_fence_any_seq_signaled(rdev, target_seq))
502*4882a593Smuzhiyun return timeout;
503*4882a593Smuzhiyun
504*4882a593Smuzhiyun /* enable IRQs and tracing */
505*4882a593Smuzhiyun for (i = 0; i < RADEON_NUM_RINGS; ++i) {
506*4882a593Smuzhiyun if (!target_seq[i])
507*4882a593Smuzhiyun continue;
508*4882a593Smuzhiyun
509*4882a593Smuzhiyun trace_radeon_fence_wait_begin(rdev->ddev, i, target_seq[i]);
510*4882a593Smuzhiyun radeon_irq_kms_sw_irq_get(rdev, i);
511*4882a593Smuzhiyun }
512*4882a593Smuzhiyun
513*4882a593Smuzhiyun if (intr) {
514*4882a593Smuzhiyun r = wait_event_interruptible_timeout(rdev->fence_queue, (
515*4882a593Smuzhiyun radeon_fence_any_seq_signaled(rdev, target_seq)
516*4882a593Smuzhiyun || rdev->needs_reset), timeout);
517*4882a593Smuzhiyun } else {
518*4882a593Smuzhiyun r = wait_event_timeout(rdev->fence_queue, (
519*4882a593Smuzhiyun radeon_fence_any_seq_signaled(rdev, target_seq)
520*4882a593Smuzhiyun || rdev->needs_reset), timeout);
521*4882a593Smuzhiyun }
522*4882a593Smuzhiyun
523*4882a593Smuzhiyun if (rdev->needs_reset)
524*4882a593Smuzhiyun r = -EDEADLK;
525*4882a593Smuzhiyun
526*4882a593Smuzhiyun for (i = 0; i < RADEON_NUM_RINGS; ++i) {
527*4882a593Smuzhiyun if (!target_seq[i])
528*4882a593Smuzhiyun continue;
529*4882a593Smuzhiyun
530*4882a593Smuzhiyun radeon_irq_kms_sw_irq_put(rdev, i);
531*4882a593Smuzhiyun trace_radeon_fence_wait_end(rdev->ddev, i, target_seq[i]);
532*4882a593Smuzhiyun }
533*4882a593Smuzhiyun
534*4882a593Smuzhiyun return r;
535*4882a593Smuzhiyun }
536*4882a593Smuzhiyun
537*4882a593Smuzhiyun /**
538*4882a593Smuzhiyun * radeon_fence_wait_timeout - wait for a fence to signal with timeout
539*4882a593Smuzhiyun *
540*4882a593Smuzhiyun * @fence: radeon fence object
541*4882a593Smuzhiyun * @intr: use interruptible sleep
542*4882a593Smuzhiyun *
543*4882a593Smuzhiyun * Wait for the requested fence to signal (all asics).
544*4882a593Smuzhiyun * @intr selects whether to use interruptable (true) or non-interruptable
545*4882a593Smuzhiyun * (false) sleep when waiting for the fence.
546*4882a593Smuzhiyun * @timeout: maximum time to wait, or MAX_SCHEDULE_TIMEOUT for infinite wait
547*4882a593Smuzhiyun * Returns remaining time if the sequence number has passed, 0 when
548*4882a593Smuzhiyun * the wait timeout, or an error for all other cases.
549*4882a593Smuzhiyun */
radeon_fence_wait_timeout(struct radeon_fence * fence,bool intr,long timeout)550*4882a593Smuzhiyun long radeon_fence_wait_timeout(struct radeon_fence *fence, bool intr, long timeout)
551*4882a593Smuzhiyun {
552*4882a593Smuzhiyun uint64_t seq[RADEON_NUM_RINGS] = {};
553*4882a593Smuzhiyun long r;
554*4882a593Smuzhiyun int r_sig;
555*4882a593Smuzhiyun
556*4882a593Smuzhiyun /*
557*4882a593Smuzhiyun * This function should not be called on !radeon fences.
558*4882a593Smuzhiyun * If this is the case, it would mean this function can
559*4882a593Smuzhiyun * also be called on radeon fences belonging to another card.
560*4882a593Smuzhiyun * exclusive_lock is not held in that case.
561*4882a593Smuzhiyun */
562*4882a593Smuzhiyun if (WARN_ON_ONCE(!to_radeon_fence(&fence->base)))
563*4882a593Smuzhiyun return dma_fence_wait(&fence->base, intr);
564*4882a593Smuzhiyun
565*4882a593Smuzhiyun seq[fence->ring] = fence->seq;
566*4882a593Smuzhiyun r = radeon_fence_wait_seq_timeout(fence->rdev, seq, intr, timeout);
567*4882a593Smuzhiyun if (r <= 0) {
568*4882a593Smuzhiyun return r;
569*4882a593Smuzhiyun }
570*4882a593Smuzhiyun
571*4882a593Smuzhiyun r_sig = dma_fence_signal(&fence->base);
572*4882a593Smuzhiyun if (!r_sig)
573*4882a593Smuzhiyun DMA_FENCE_TRACE(&fence->base, "signaled from fence_wait\n");
574*4882a593Smuzhiyun return r;
575*4882a593Smuzhiyun }
576*4882a593Smuzhiyun
577*4882a593Smuzhiyun /**
578*4882a593Smuzhiyun * radeon_fence_wait - wait for a fence to signal
579*4882a593Smuzhiyun *
580*4882a593Smuzhiyun * @fence: radeon fence object
581*4882a593Smuzhiyun * @intr: use interruptible sleep
582*4882a593Smuzhiyun *
583*4882a593Smuzhiyun * Wait for the requested fence to signal (all asics).
584*4882a593Smuzhiyun * @intr selects whether to use interruptable (true) or non-interruptable
585*4882a593Smuzhiyun * (false) sleep when waiting for the fence.
586*4882a593Smuzhiyun * Returns 0 if the fence has passed, error for all other cases.
587*4882a593Smuzhiyun */
radeon_fence_wait(struct radeon_fence * fence,bool intr)588*4882a593Smuzhiyun int radeon_fence_wait(struct radeon_fence *fence, bool intr)
589*4882a593Smuzhiyun {
590*4882a593Smuzhiyun long r = radeon_fence_wait_timeout(fence, intr, MAX_SCHEDULE_TIMEOUT);
591*4882a593Smuzhiyun if (r > 0) {
592*4882a593Smuzhiyun return 0;
593*4882a593Smuzhiyun } else {
594*4882a593Smuzhiyun return r;
595*4882a593Smuzhiyun }
596*4882a593Smuzhiyun }
597*4882a593Smuzhiyun
598*4882a593Smuzhiyun /**
599*4882a593Smuzhiyun * radeon_fence_wait_any - wait for a fence to signal on any ring
600*4882a593Smuzhiyun *
601*4882a593Smuzhiyun * @rdev: radeon device pointer
602*4882a593Smuzhiyun * @fences: radeon fence object(s)
603*4882a593Smuzhiyun * @intr: use interruptable sleep
604*4882a593Smuzhiyun *
605*4882a593Smuzhiyun * Wait for any requested fence to signal (all asics). Fence
606*4882a593Smuzhiyun * array is indexed by ring id. @intr selects whether to use
607*4882a593Smuzhiyun * interruptable (true) or non-interruptable (false) sleep when
608*4882a593Smuzhiyun * waiting for the fences. Used by the suballocator.
609*4882a593Smuzhiyun * Returns 0 if any fence has passed, error for all other cases.
610*4882a593Smuzhiyun */
radeon_fence_wait_any(struct radeon_device * rdev,struct radeon_fence ** fences,bool intr)611*4882a593Smuzhiyun int radeon_fence_wait_any(struct radeon_device *rdev,
612*4882a593Smuzhiyun struct radeon_fence **fences,
613*4882a593Smuzhiyun bool intr)
614*4882a593Smuzhiyun {
615*4882a593Smuzhiyun uint64_t seq[RADEON_NUM_RINGS];
616*4882a593Smuzhiyun unsigned i, num_rings = 0;
617*4882a593Smuzhiyun long r;
618*4882a593Smuzhiyun
619*4882a593Smuzhiyun for (i = 0; i < RADEON_NUM_RINGS; ++i) {
620*4882a593Smuzhiyun seq[i] = 0;
621*4882a593Smuzhiyun
622*4882a593Smuzhiyun if (!fences[i]) {
623*4882a593Smuzhiyun continue;
624*4882a593Smuzhiyun }
625*4882a593Smuzhiyun
626*4882a593Smuzhiyun seq[i] = fences[i]->seq;
627*4882a593Smuzhiyun ++num_rings;
628*4882a593Smuzhiyun }
629*4882a593Smuzhiyun
630*4882a593Smuzhiyun /* nothing to wait for ? */
631*4882a593Smuzhiyun if (num_rings == 0)
632*4882a593Smuzhiyun return -ENOENT;
633*4882a593Smuzhiyun
634*4882a593Smuzhiyun r = radeon_fence_wait_seq_timeout(rdev, seq, intr, MAX_SCHEDULE_TIMEOUT);
635*4882a593Smuzhiyun if (r < 0) {
636*4882a593Smuzhiyun return r;
637*4882a593Smuzhiyun }
638*4882a593Smuzhiyun return 0;
639*4882a593Smuzhiyun }
640*4882a593Smuzhiyun
641*4882a593Smuzhiyun /**
642*4882a593Smuzhiyun * radeon_fence_wait_next - wait for the next fence to signal
643*4882a593Smuzhiyun *
644*4882a593Smuzhiyun * @rdev: radeon device pointer
645*4882a593Smuzhiyun * @ring: ring index the fence is associated with
646*4882a593Smuzhiyun *
647*4882a593Smuzhiyun * Wait for the next fence on the requested ring to signal (all asics).
648*4882a593Smuzhiyun * Returns 0 if the next fence has passed, error for all other cases.
649*4882a593Smuzhiyun * Caller must hold ring lock.
650*4882a593Smuzhiyun */
radeon_fence_wait_next(struct radeon_device * rdev,int ring)651*4882a593Smuzhiyun int radeon_fence_wait_next(struct radeon_device *rdev, int ring)
652*4882a593Smuzhiyun {
653*4882a593Smuzhiyun uint64_t seq[RADEON_NUM_RINGS] = {};
654*4882a593Smuzhiyun long r;
655*4882a593Smuzhiyun
656*4882a593Smuzhiyun seq[ring] = atomic64_read(&rdev->fence_drv[ring].last_seq) + 1ULL;
657*4882a593Smuzhiyun if (seq[ring] >= rdev->fence_drv[ring].sync_seq[ring]) {
658*4882a593Smuzhiyun /* nothing to wait for, last_seq is
659*4882a593Smuzhiyun already the last emited fence */
660*4882a593Smuzhiyun return -ENOENT;
661*4882a593Smuzhiyun }
662*4882a593Smuzhiyun r = radeon_fence_wait_seq_timeout(rdev, seq, false, MAX_SCHEDULE_TIMEOUT);
663*4882a593Smuzhiyun if (r < 0)
664*4882a593Smuzhiyun return r;
665*4882a593Smuzhiyun return 0;
666*4882a593Smuzhiyun }
667*4882a593Smuzhiyun
668*4882a593Smuzhiyun /**
669*4882a593Smuzhiyun * radeon_fence_wait_empty - wait for all fences to signal
670*4882a593Smuzhiyun *
671*4882a593Smuzhiyun * @rdev: radeon device pointer
672*4882a593Smuzhiyun * @ring: ring index the fence is associated with
673*4882a593Smuzhiyun *
674*4882a593Smuzhiyun * Wait for all fences on the requested ring to signal (all asics).
675*4882a593Smuzhiyun * Returns 0 if the fences have passed, error for all other cases.
676*4882a593Smuzhiyun * Caller must hold ring lock.
677*4882a593Smuzhiyun */
radeon_fence_wait_empty(struct radeon_device * rdev,int ring)678*4882a593Smuzhiyun int radeon_fence_wait_empty(struct radeon_device *rdev, int ring)
679*4882a593Smuzhiyun {
680*4882a593Smuzhiyun uint64_t seq[RADEON_NUM_RINGS] = {};
681*4882a593Smuzhiyun long r;
682*4882a593Smuzhiyun
683*4882a593Smuzhiyun seq[ring] = rdev->fence_drv[ring].sync_seq[ring];
684*4882a593Smuzhiyun if (!seq[ring])
685*4882a593Smuzhiyun return 0;
686*4882a593Smuzhiyun
687*4882a593Smuzhiyun r = radeon_fence_wait_seq_timeout(rdev, seq, false, MAX_SCHEDULE_TIMEOUT);
688*4882a593Smuzhiyun if (r < 0) {
689*4882a593Smuzhiyun if (r == -EDEADLK)
690*4882a593Smuzhiyun return -EDEADLK;
691*4882a593Smuzhiyun
692*4882a593Smuzhiyun dev_err(rdev->dev, "error waiting for ring[%d] to become idle (%ld)\n",
693*4882a593Smuzhiyun ring, r);
694*4882a593Smuzhiyun }
695*4882a593Smuzhiyun return 0;
696*4882a593Smuzhiyun }
697*4882a593Smuzhiyun
698*4882a593Smuzhiyun /**
699*4882a593Smuzhiyun * radeon_fence_ref - take a ref on a fence
700*4882a593Smuzhiyun *
701*4882a593Smuzhiyun * @fence: radeon fence object
702*4882a593Smuzhiyun *
703*4882a593Smuzhiyun * Take a reference on a fence (all asics).
704*4882a593Smuzhiyun * Returns the fence.
705*4882a593Smuzhiyun */
radeon_fence_ref(struct radeon_fence * fence)706*4882a593Smuzhiyun struct radeon_fence *radeon_fence_ref(struct radeon_fence *fence)
707*4882a593Smuzhiyun {
708*4882a593Smuzhiyun dma_fence_get(&fence->base);
709*4882a593Smuzhiyun return fence;
710*4882a593Smuzhiyun }
711*4882a593Smuzhiyun
712*4882a593Smuzhiyun /**
713*4882a593Smuzhiyun * radeon_fence_unref - remove a ref on a fence
714*4882a593Smuzhiyun *
715*4882a593Smuzhiyun * @fence: radeon fence object
716*4882a593Smuzhiyun *
717*4882a593Smuzhiyun * Remove a reference on a fence (all asics).
718*4882a593Smuzhiyun */
radeon_fence_unref(struct radeon_fence ** fence)719*4882a593Smuzhiyun void radeon_fence_unref(struct radeon_fence **fence)
720*4882a593Smuzhiyun {
721*4882a593Smuzhiyun struct radeon_fence *tmp = *fence;
722*4882a593Smuzhiyun
723*4882a593Smuzhiyun *fence = NULL;
724*4882a593Smuzhiyun if (tmp) {
725*4882a593Smuzhiyun dma_fence_put(&tmp->base);
726*4882a593Smuzhiyun }
727*4882a593Smuzhiyun }
728*4882a593Smuzhiyun
729*4882a593Smuzhiyun /**
730*4882a593Smuzhiyun * radeon_fence_count_emitted - get the count of emitted fences
731*4882a593Smuzhiyun *
732*4882a593Smuzhiyun * @rdev: radeon device pointer
733*4882a593Smuzhiyun * @ring: ring index the fence is associated with
734*4882a593Smuzhiyun *
735*4882a593Smuzhiyun * Get the number of fences emitted on the requested ring (all asics).
736*4882a593Smuzhiyun * Returns the number of emitted fences on the ring. Used by the
737*4882a593Smuzhiyun * dynpm code to ring track activity.
738*4882a593Smuzhiyun */
radeon_fence_count_emitted(struct radeon_device * rdev,int ring)739*4882a593Smuzhiyun unsigned radeon_fence_count_emitted(struct radeon_device *rdev, int ring)
740*4882a593Smuzhiyun {
741*4882a593Smuzhiyun uint64_t emitted;
742*4882a593Smuzhiyun
743*4882a593Smuzhiyun /* We are not protected by ring lock when reading the last sequence
744*4882a593Smuzhiyun * but it's ok to report slightly wrong fence count here.
745*4882a593Smuzhiyun */
746*4882a593Smuzhiyun radeon_fence_process(rdev, ring);
747*4882a593Smuzhiyun emitted = rdev->fence_drv[ring].sync_seq[ring]
748*4882a593Smuzhiyun - atomic64_read(&rdev->fence_drv[ring].last_seq);
749*4882a593Smuzhiyun /* to avoid 32bits warp around */
750*4882a593Smuzhiyun if (emitted > 0x10000000) {
751*4882a593Smuzhiyun emitted = 0x10000000;
752*4882a593Smuzhiyun }
753*4882a593Smuzhiyun return (unsigned)emitted;
754*4882a593Smuzhiyun }
755*4882a593Smuzhiyun
756*4882a593Smuzhiyun /**
757*4882a593Smuzhiyun * radeon_fence_need_sync - do we need a semaphore
758*4882a593Smuzhiyun *
759*4882a593Smuzhiyun * @fence: radeon fence object
760*4882a593Smuzhiyun * @dst_ring: which ring to check against
761*4882a593Smuzhiyun *
762*4882a593Smuzhiyun * Check if the fence needs to be synced against another ring
763*4882a593Smuzhiyun * (all asics). If so, we need to emit a semaphore.
764*4882a593Smuzhiyun * Returns true if we need to sync with another ring, false if
765*4882a593Smuzhiyun * not.
766*4882a593Smuzhiyun */
radeon_fence_need_sync(struct radeon_fence * fence,int dst_ring)767*4882a593Smuzhiyun bool radeon_fence_need_sync(struct radeon_fence *fence, int dst_ring)
768*4882a593Smuzhiyun {
769*4882a593Smuzhiyun struct radeon_fence_driver *fdrv;
770*4882a593Smuzhiyun
771*4882a593Smuzhiyun if (!fence) {
772*4882a593Smuzhiyun return false;
773*4882a593Smuzhiyun }
774*4882a593Smuzhiyun
775*4882a593Smuzhiyun if (fence->ring == dst_ring) {
776*4882a593Smuzhiyun return false;
777*4882a593Smuzhiyun }
778*4882a593Smuzhiyun
779*4882a593Smuzhiyun /* we are protected by the ring mutex */
780*4882a593Smuzhiyun fdrv = &fence->rdev->fence_drv[dst_ring];
781*4882a593Smuzhiyun if (fence->seq <= fdrv->sync_seq[fence->ring]) {
782*4882a593Smuzhiyun return false;
783*4882a593Smuzhiyun }
784*4882a593Smuzhiyun
785*4882a593Smuzhiyun return true;
786*4882a593Smuzhiyun }
787*4882a593Smuzhiyun
788*4882a593Smuzhiyun /**
789*4882a593Smuzhiyun * radeon_fence_note_sync - record the sync point
790*4882a593Smuzhiyun *
791*4882a593Smuzhiyun * @fence: radeon fence object
792*4882a593Smuzhiyun * @dst_ring: which ring to check against
793*4882a593Smuzhiyun *
794*4882a593Smuzhiyun * Note the sequence number at which point the fence will
795*4882a593Smuzhiyun * be synced with the requested ring (all asics).
796*4882a593Smuzhiyun */
radeon_fence_note_sync(struct radeon_fence * fence,int dst_ring)797*4882a593Smuzhiyun void radeon_fence_note_sync(struct radeon_fence *fence, int dst_ring)
798*4882a593Smuzhiyun {
799*4882a593Smuzhiyun struct radeon_fence_driver *dst, *src;
800*4882a593Smuzhiyun unsigned i;
801*4882a593Smuzhiyun
802*4882a593Smuzhiyun if (!fence) {
803*4882a593Smuzhiyun return;
804*4882a593Smuzhiyun }
805*4882a593Smuzhiyun
806*4882a593Smuzhiyun if (fence->ring == dst_ring) {
807*4882a593Smuzhiyun return;
808*4882a593Smuzhiyun }
809*4882a593Smuzhiyun
810*4882a593Smuzhiyun /* we are protected by the ring mutex */
811*4882a593Smuzhiyun src = &fence->rdev->fence_drv[fence->ring];
812*4882a593Smuzhiyun dst = &fence->rdev->fence_drv[dst_ring];
813*4882a593Smuzhiyun for (i = 0; i < RADEON_NUM_RINGS; ++i) {
814*4882a593Smuzhiyun if (i == dst_ring) {
815*4882a593Smuzhiyun continue;
816*4882a593Smuzhiyun }
817*4882a593Smuzhiyun dst->sync_seq[i] = max(dst->sync_seq[i], src->sync_seq[i]);
818*4882a593Smuzhiyun }
819*4882a593Smuzhiyun }
820*4882a593Smuzhiyun
821*4882a593Smuzhiyun /**
822*4882a593Smuzhiyun * radeon_fence_driver_start_ring - make the fence driver
823*4882a593Smuzhiyun * ready for use on the requested ring.
824*4882a593Smuzhiyun *
825*4882a593Smuzhiyun * @rdev: radeon device pointer
826*4882a593Smuzhiyun * @ring: ring index to start the fence driver on
827*4882a593Smuzhiyun *
828*4882a593Smuzhiyun * Make the fence driver ready for processing (all asics).
829*4882a593Smuzhiyun * Not all asics have all rings, so each asic will only
830*4882a593Smuzhiyun * start the fence driver on the rings it has.
831*4882a593Smuzhiyun * Returns 0 for success, errors for failure.
832*4882a593Smuzhiyun */
radeon_fence_driver_start_ring(struct radeon_device * rdev,int ring)833*4882a593Smuzhiyun int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring)
834*4882a593Smuzhiyun {
835*4882a593Smuzhiyun uint64_t index;
836*4882a593Smuzhiyun int r;
837*4882a593Smuzhiyun
838*4882a593Smuzhiyun radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg);
839*4882a593Smuzhiyun if (rdev->wb.use_event || !radeon_ring_supports_scratch_reg(rdev, &rdev->ring[ring])) {
840*4882a593Smuzhiyun rdev->fence_drv[ring].scratch_reg = 0;
841*4882a593Smuzhiyun if (ring != R600_RING_TYPE_UVD_INDEX) {
842*4882a593Smuzhiyun index = R600_WB_EVENT_OFFSET + ring * 4;
843*4882a593Smuzhiyun rdev->fence_drv[ring].cpu_addr = &rdev->wb.wb[index/4];
844*4882a593Smuzhiyun rdev->fence_drv[ring].gpu_addr = rdev->wb.gpu_addr +
845*4882a593Smuzhiyun index;
846*4882a593Smuzhiyun
847*4882a593Smuzhiyun } else {
848*4882a593Smuzhiyun /* put fence directly behind firmware */
849*4882a593Smuzhiyun index = ALIGN(rdev->uvd_fw->size, 8);
850*4882a593Smuzhiyun rdev->fence_drv[ring].cpu_addr = rdev->uvd.cpu_addr + index;
851*4882a593Smuzhiyun rdev->fence_drv[ring].gpu_addr = rdev->uvd.gpu_addr + index;
852*4882a593Smuzhiyun }
853*4882a593Smuzhiyun
854*4882a593Smuzhiyun } else {
855*4882a593Smuzhiyun r = radeon_scratch_get(rdev, &rdev->fence_drv[ring].scratch_reg);
856*4882a593Smuzhiyun if (r) {
857*4882a593Smuzhiyun dev_err(rdev->dev, "fence failed to get scratch register\n");
858*4882a593Smuzhiyun return r;
859*4882a593Smuzhiyun }
860*4882a593Smuzhiyun index = RADEON_WB_SCRATCH_OFFSET +
861*4882a593Smuzhiyun rdev->fence_drv[ring].scratch_reg -
862*4882a593Smuzhiyun rdev->scratch.reg_base;
863*4882a593Smuzhiyun rdev->fence_drv[ring].cpu_addr = &rdev->wb.wb[index/4];
864*4882a593Smuzhiyun rdev->fence_drv[ring].gpu_addr = rdev->wb.gpu_addr + index;
865*4882a593Smuzhiyun }
866*4882a593Smuzhiyun radeon_fence_write(rdev, atomic64_read(&rdev->fence_drv[ring].last_seq), ring);
867*4882a593Smuzhiyun rdev->fence_drv[ring].initialized = true;
868*4882a593Smuzhiyun dev_info(rdev->dev, "fence driver on ring %d use gpu addr 0x%016llx\n",
869*4882a593Smuzhiyun ring, rdev->fence_drv[ring].gpu_addr);
870*4882a593Smuzhiyun return 0;
871*4882a593Smuzhiyun }
872*4882a593Smuzhiyun
873*4882a593Smuzhiyun /**
874*4882a593Smuzhiyun * radeon_fence_driver_init_ring - init the fence driver
875*4882a593Smuzhiyun * for the requested ring.
876*4882a593Smuzhiyun *
877*4882a593Smuzhiyun * @rdev: radeon device pointer
878*4882a593Smuzhiyun * @ring: ring index to start the fence driver on
879*4882a593Smuzhiyun *
880*4882a593Smuzhiyun * Init the fence driver for the requested ring (all asics).
881*4882a593Smuzhiyun * Helper function for radeon_fence_driver_init().
882*4882a593Smuzhiyun */
radeon_fence_driver_init_ring(struct radeon_device * rdev,int ring)883*4882a593Smuzhiyun static void radeon_fence_driver_init_ring(struct radeon_device *rdev, int ring)
884*4882a593Smuzhiyun {
885*4882a593Smuzhiyun int i;
886*4882a593Smuzhiyun
887*4882a593Smuzhiyun rdev->fence_drv[ring].scratch_reg = -1;
888*4882a593Smuzhiyun rdev->fence_drv[ring].cpu_addr = NULL;
889*4882a593Smuzhiyun rdev->fence_drv[ring].gpu_addr = 0;
890*4882a593Smuzhiyun for (i = 0; i < RADEON_NUM_RINGS; ++i)
891*4882a593Smuzhiyun rdev->fence_drv[ring].sync_seq[i] = 0;
892*4882a593Smuzhiyun atomic64_set(&rdev->fence_drv[ring].last_seq, 0);
893*4882a593Smuzhiyun rdev->fence_drv[ring].initialized = false;
894*4882a593Smuzhiyun INIT_DELAYED_WORK(&rdev->fence_drv[ring].lockup_work,
895*4882a593Smuzhiyun radeon_fence_check_lockup);
896*4882a593Smuzhiyun rdev->fence_drv[ring].rdev = rdev;
897*4882a593Smuzhiyun }
898*4882a593Smuzhiyun
899*4882a593Smuzhiyun /**
900*4882a593Smuzhiyun * radeon_fence_driver_init - init the fence driver
901*4882a593Smuzhiyun * for all possible rings.
902*4882a593Smuzhiyun *
903*4882a593Smuzhiyun * @rdev: radeon device pointer
904*4882a593Smuzhiyun *
905*4882a593Smuzhiyun * Init the fence driver for all possible rings (all asics).
906*4882a593Smuzhiyun * Not all asics have all rings, so each asic will only
907*4882a593Smuzhiyun * start the fence driver on the rings it has using
908*4882a593Smuzhiyun * radeon_fence_driver_start_ring().
909*4882a593Smuzhiyun * Returns 0 for success.
910*4882a593Smuzhiyun */
radeon_fence_driver_init(struct radeon_device * rdev)911*4882a593Smuzhiyun int radeon_fence_driver_init(struct radeon_device *rdev)
912*4882a593Smuzhiyun {
913*4882a593Smuzhiyun int ring;
914*4882a593Smuzhiyun
915*4882a593Smuzhiyun init_waitqueue_head(&rdev->fence_queue);
916*4882a593Smuzhiyun for (ring = 0; ring < RADEON_NUM_RINGS; ring++) {
917*4882a593Smuzhiyun radeon_fence_driver_init_ring(rdev, ring);
918*4882a593Smuzhiyun }
919*4882a593Smuzhiyun if (radeon_debugfs_fence_init(rdev)) {
920*4882a593Smuzhiyun dev_err(rdev->dev, "fence debugfs file creation failed\n");
921*4882a593Smuzhiyun }
922*4882a593Smuzhiyun return 0;
923*4882a593Smuzhiyun }
924*4882a593Smuzhiyun
925*4882a593Smuzhiyun /**
926*4882a593Smuzhiyun * radeon_fence_driver_fini - tear down the fence driver
927*4882a593Smuzhiyun * for all possible rings.
928*4882a593Smuzhiyun *
929*4882a593Smuzhiyun * @rdev: radeon device pointer
930*4882a593Smuzhiyun *
931*4882a593Smuzhiyun * Tear down the fence driver for all possible rings (all asics).
932*4882a593Smuzhiyun */
radeon_fence_driver_fini(struct radeon_device * rdev)933*4882a593Smuzhiyun void radeon_fence_driver_fini(struct radeon_device *rdev)
934*4882a593Smuzhiyun {
935*4882a593Smuzhiyun int ring, r;
936*4882a593Smuzhiyun
937*4882a593Smuzhiyun mutex_lock(&rdev->ring_lock);
938*4882a593Smuzhiyun for (ring = 0; ring < RADEON_NUM_RINGS; ring++) {
939*4882a593Smuzhiyun if (!rdev->fence_drv[ring].initialized)
940*4882a593Smuzhiyun continue;
941*4882a593Smuzhiyun r = radeon_fence_wait_empty(rdev, ring);
942*4882a593Smuzhiyun if (r) {
943*4882a593Smuzhiyun /* no need to trigger GPU reset as we are unloading */
944*4882a593Smuzhiyun radeon_fence_driver_force_completion(rdev, ring);
945*4882a593Smuzhiyun }
946*4882a593Smuzhiyun cancel_delayed_work_sync(&rdev->fence_drv[ring].lockup_work);
947*4882a593Smuzhiyun wake_up_all(&rdev->fence_queue);
948*4882a593Smuzhiyun radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg);
949*4882a593Smuzhiyun rdev->fence_drv[ring].initialized = false;
950*4882a593Smuzhiyun }
951*4882a593Smuzhiyun mutex_unlock(&rdev->ring_lock);
952*4882a593Smuzhiyun }
953*4882a593Smuzhiyun
954*4882a593Smuzhiyun /**
955*4882a593Smuzhiyun * radeon_fence_driver_force_completion - force all fence waiter to complete
956*4882a593Smuzhiyun *
957*4882a593Smuzhiyun * @rdev: radeon device pointer
958*4882a593Smuzhiyun * @ring: the ring to complete
959*4882a593Smuzhiyun *
960*4882a593Smuzhiyun * In case of GPU reset failure make sure no process keep waiting on fence
961*4882a593Smuzhiyun * that will never complete.
962*4882a593Smuzhiyun */
radeon_fence_driver_force_completion(struct radeon_device * rdev,int ring)963*4882a593Smuzhiyun void radeon_fence_driver_force_completion(struct radeon_device *rdev, int ring)
964*4882a593Smuzhiyun {
965*4882a593Smuzhiyun if (rdev->fence_drv[ring].initialized) {
966*4882a593Smuzhiyun radeon_fence_write(rdev, rdev->fence_drv[ring].sync_seq[ring], ring);
967*4882a593Smuzhiyun cancel_delayed_work_sync(&rdev->fence_drv[ring].lockup_work);
968*4882a593Smuzhiyun }
969*4882a593Smuzhiyun }
970*4882a593Smuzhiyun
971*4882a593Smuzhiyun
972*4882a593Smuzhiyun /*
973*4882a593Smuzhiyun * Fence debugfs
974*4882a593Smuzhiyun */
975*4882a593Smuzhiyun #if defined(CONFIG_DEBUG_FS)
radeon_debugfs_fence_info(struct seq_file * m,void * data)976*4882a593Smuzhiyun static int radeon_debugfs_fence_info(struct seq_file *m, void *data)
977*4882a593Smuzhiyun {
978*4882a593Smuzhiyun struct drm_info_node *node = (struct drm_info_node *)m->private;
979*4882a593Smuzhiyun struct drm_device *dev = node->minor->dev;
980*4882a593Smuzhiyun struct radeon_device *rdev = dev->dev_private;
981*4882a593Smuzhiyun int i, j;
982*4882a593Smuzhiyun
983*4882a593Smuzhiyun for (i = 0; i < RADEON_NUM_RINGS; ++i) {
984*4882a593Smuzhiyun if (!rdev->fence_drv[i].initialized)
985*4882a593Smuzhiyun continue;
986*4882a593Smuzhiyun
987*4882a593Smuzhiyun radeon_fence_process(rdev, i);
988*4882a593Smuzhiyun
989*4882a593Smuzhiyun seq_printf(m, "--- ring %d ---\n", i);
990*4882a593Smuzhiyun seq_printf(m, "Last signaled fence 0x%016llx\n",
991*4882a593Smuzhiyun (unsigned long long)atomic64_read(&rdev->fence_drv[i].last_seq));
992*4882a593Smuzhiyun seq_printf(m, "Last emitted 0x%016llx\n",
993*4882a593Smuzhiyun rdev->fence_drv[i].sync_seq[i]);
994*4882a593Smuzhiyun
995*4882a593Smuzhiyun for (j = 0; j < RADEON_NUM_RINGS; ++j) {
996*4882a593Smuzhiyun if (i != j && rdev->fence_drv[j].initialized)
997*4882a593Smuzhiyun seq_printf(m, "Last sync to ring %d 0x%016llx\n",
998*4882a593Smuzhiyun j, rdev->fence_drv[i].sync_seq[j]);
999*4882a593Smuzhiyun }
1000*4882a593Smuzhiyun }
1001*4882a593Smuzhiyun return 0;
1002*4882a593Smuzhiyun }
1003*4882a593Smuzhiyun
1004*4882a593Smuzhiyun /**
1005*4882a593Smuzhiyun * radeon_debugfs_gpu_reset - manually trigger a gpu reset
1006*4882a593Smuzhiyun *
1007*4882a593Smuzhiyun * Manually trigger a gpu reset at the next fence wait.
1008*4882a593Smuzhiyun */
radeon_debugfs_gpu_reset(struct seq_file * m,void * data)1009*4882a593Smuzhiyun static int radeon_debugfs_gpu_reset(struct seq_file *m, void *data)
1010*4882a593Smuzhiyun {
1011*4882a593Smuzhiyun struct drm_info_node *node = (struct drm_info_node *) m->private;
1012*4882a593Smuzhiyun struct drm_device *dev = node->minor->dev;
1013*4882a593Smuzhiyun struct radeon_device *rdev = dev->dev_private;
1014*4882a593Smuzhiyun
1015*4882a593Smuzhiyun down_read(&rdev->exclusive_lock);
1016*4882a593Smuzhiyun seq_printf(m, "%d\n", rdev->needs_reset);
1017*4882a593Smuzhiyun rdev->needs_reset = true;
1018*4882a593Smuzhiyun wake_up_all(&rdev->fence_queue);
1019*4882a593Smuzhiyun up_read(&rdev->exclusive_lock);
1020*4882a593Smuzhiyun
1021*4882a593Smuzhiyun return 0;
1022*4882a593Smuzhiyun }
1023*4882a593Smuzhiyun
1024*4882a593Smuzhiyun static struct drm_info_list radeon_debugfs_fence_list[] = {
1025*4882a593Smuzhiyun {"radeon_fence_info", &radeon_debugfs_fence_info, 0, NULL},
1026*4882a593Smuzhiyun {"radeon_gpu_reset", &radeon_debugfs_gpu_reset, 0, NULL}
1027*4882a593Smuzhiyun };
1028*4882a593Smuzhiyun #endif
1029*4882a593Smuzhiyun
radeon_debugfs_fence_init(struct radeon_device * rdev)1030*4882a593Smuzhiyun int radeon_debugfs_fence_init(struct radeon_device *rdev)
1031*4882a593Smuzhiyun {
1032*4882a593Smuzhiyun #if defined(CONFIG_DEBUG_FS)
1033*4882a593Smuzhiyun return radeon_debugfs_add_files(rdev, radeon_debugfs_fence_list, 2);
1034*4882a593Smuzhiyun #else
1035*4882a593Smuzhiyun return 0;
1036*4882a593Smuzhiyun #endif
1037*4882a593Smuzhiyun }
1038*4882a593Smuzhiyun
radeon_fence_get_driver_name(struct dma_fence * fence)1039*4882a593Smuzhiyun static const char *radeon_fence_get_driver_name(struct dma_fence *fence)
1040*4882a593Smuzhiyun {
1041*4882a593Smuzhiyun return "radeon";
1042*4882a593Smuzhiyun }
1043*4882a593Smuzhiyun
radeon_fence_get_timeline_name(struct dma_fence * f)1044*4882a593Smuzhiyun static const char *radeon_fence_get_timeline_name(struct dma_fence *f)
1045*4882a593Smuzhiyun {
1046*4882a593Smuzhiyun struct radeon_fence *fence = to_radeon_fence(f);
1047*4882a593Smuzhiyun switch (fence->ring) {
1048*4882a593Smuzhiyun case RADEON_RING_TYPE_GFX_INDEX: return "radeon.gfx";
1049*4882a593Smuzhiyun case CAYMAN_RING_TYPE_CP1_INDEX: return "radeon.cp1";
1050*4882a593Smuzhiyun case CAYMAN_RING_TYPE_CP2_INDEX: return "radeon.cp2";
1051*4882a593Smuzhiyun case R600_RING_TYPE_DMA_INDEX: return "radeon.dma";
1052*4882a593Smuzhiyun case CAYMAN_RING_TYPE_DMA1_INDEX: return "radeon.dma1";
1053*4882a593Smuzhiyun case R600_RING_TYPE_UVD_INDEX: return "radeon.uvd";
1054*4882a593Smuzhiyun case TN_RING_TYPE_VCE1_INDEX: return "radeon.vce1";
1055*4882a593Smuzhiyun case TN_RING_TYPE_VCE2_INDEX: return "radeon.vce2";
1056*4882a593Smuzhiyun default: WARN_ON_ONCE(1); return "radeon.unk";
1057*4882a593Smuzhiyun }
1058*4882a593Smuzhiyun }
1059*4882a593Smuzhiyun
radeon_test_signaled(struct radeon_fence * fence)1060*4882a593Smuzhiyun static inline bool radeon_test_signaled(struct radeon_fence *fence)
1061*4882a593Smuzhiyun {
1062*4882a593Smuzhiyun return test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->base.flags);
1063*4882a593Smuzhiyun }
1064*4882a593Smuzhiyun
1065*4882a593Smuzhiyun struct radeon_wait_cb {
1066*4882a593Smuzhiyun struct dma_fence_cb base;
1067*4882a593Smuzhiyun struct task_struct *task;
1068*4882a593Smuzhiyun };
1069*4882a593Smuzhiyun
1070*4882a593Smuzhiyun static void
radeon_fence_wait_cb(struct dma_fence * fence,struct dma_fence_cb * cb)1071*4882a593Smuzhiyun radeon_fence_wait_cb(struct dma_fence *fence, struct dma_fence_cb *cb)
1072*4882a593Smuzhiyun {
1073*4882a593Smuzhiyun struct radeon_wait_cb *wait =
1074*4882a593Smuzhiyun container_of(cb, struct radeon_wait_cb, base);
1075*4882a593Smuzhiyun
1076*4882a593Smuzhiyun wake_up_process(wait->task);
1077*4882a593Smuzhiyun }
1078*4882a593Smuzhiyun
radeon_fence_default_wait(struct dma_fence * f,bool intr,signed long t)1079*4882a593Smuzhiyun static signed long radeon_fence_default_wait(struct dma_fence *f, bool intr,
1080*4882a593Smuzhiyun signed long t)
1081*4882a593Smuzhiyun {
1082*4882a593Smuzhiyun struct radeon_fence *fence = to_radeon_fence(f);
1083*4882a593Smuzhiyun struct radeon_device *rdev = fence->rdev;
1084*4882a593Smuzhiyun struct radeon_wait_cb cb;
1085*4882a593Smuzhiyun
1086*4882a593Smuzhiyun cb.task = current;
1087*4882a593Smuzhiyun
1088*4882a593Smuzhiyun if (dma_fence_add_callback(f, &cb.base, radeon_fence_wait_cb))
1089*4882a593Smuzhiyun return t;
1090*4882a593Smuzhiyun
1091*4882a593Smuzhiyun while (t > 0) {
1092*4882a593Smuzhiyun if (intr)
1093*4882a593Smuzhiyun set_current_state(TASK_INTERRUPTIBLE);
1094*4882a593Smuzhiyun else
1095*4882a593Smuzhiyun set_current_state(TASK_UNINTERRUPTIBLE);
1096*4882a593Smuzhiyun
1097*4882a593Smuzhiyun /*
1098*4882a593Smuzhiyun * radeon_test_signaled must be called after
1099*4882a593Smuzhiyun * set_current_state to prevent a race with wake_up_process
1100*4882a593Smuzhiyun */
1101*4882a593Smuzhiyun if (radeon_test_signaled(fence))
1102*4882a593Smuzhiyun break;
1103*4882a593Smuzhiyun
1104*4882a593Smuzhiyun if (rdev->needs_reset) {
1105*4882a593Smuzhiyun t = -EDEADLK;
1106*4882a593Smuzhiyun break;
1107*4882a593Smuzhiyun }
1108*4882a593Smuzhiyun
1109*4882a593Smuzhiyun t = schedule_timeout(t);
1110*4882a593Smuzhiyun
1111*4882a593Smuzhiyun if (t > 0 && intr && signal_pending(current))
1112*4882a593Smuzhiyun t = -ERESTARTSYS;
1113*4882a593Smuzhiyun }
1114*4882a593Smuzhiyun
1115*4882a593Smuzhiyun __set_current_state(TASK_RUNNING);
1116*4882a593Smuzhiyun dma_fence_remove_callback(f, &cb.base);
1117*4882a593Smuzhiyun
1118*4882a593Smuzhiyun return t;
1119*4882a593Smuzhiyun }
1120*4882a593Smuzhiyun
1121*4882a593Smuzhiyun const struct dma_fence_ops radeon_fence_ops = {
1122*4882a593Smuzhiyun .get_driver_name = radeon_fence_get_driver_name,
1123*4882a593Smuzhiyun .get_timeline_name = radeon_fence_get_timeline_name,
1124*4882a593Smuzhiyun .enable_signaling = radeon_fence_enable_signaling,
1125*4882a593Smuzhiyun .signaled = radeon_fence_is_signaled,
1126*4882a593Smuzhiyun .wait = radeon_fence_default_wait,
1127*4882a593Smuzhiyun .release = NULL,
1128*4882a593Smuzhiyun };
1129