aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2018-11-08 11:04:22 -0500
committerChristian König <christian.koenig@amd.com>2018-11-12 06:54:21 -0500
commit131280a162e7fc2a539bb939efd28dd0b964c62c (patch)
treebb1553618a976dc27dbe1e467917103bd5c22ece /drivers
parenteb8dd3abeb4dffab6c373e87d09fc3b5858ac158 (diff)
drm: Revert syncobj timeline changes.
Daniel suggested I submit this, since we're still seeing regressions from it. This is a revert to before 48197bc564c7 ("drm: add syncobj timeline support v9") and its followon fixes. Fixes this on first V3D testcase execution: [ 48.767088] ============================================ [ 48.772410] WARNING: possible recursive locking detected [ 48.777739] 4.19.0-rc6+ #489 Not tainted [ 48.781668] -------------------------------------------- [ 48.786993] shader_runner/3284 is trying to acquire lock: [ 48.792408] ce309d7f (&(&array->lock)->rlock){....}, at: dma_fence_add_callback+0x30/0x23c [ 48.800714] [ 48.800714] but task is already holding lock: [ 48.806559] c5952bd3 (&(&array->lock)->rlock){....}, at: dma_fence_add_callback+0x30/0x23c [ 48.814862] [ 48.814862] other info that might help us debug this: [ 48.821410] Possible unsafe locking scenario: [ 48.821410] [ 48.827338] CPU0 [ 48.829788] ---- [ 48.832239] lock(&(&array->lock)->rlock); [ 48.836434] lock(&(&array->lock)->rlock); [ 48.840640] [ 48.840640] *** DEADLOCK *** [ 48.840640] [ 48.846582] May be due to missing lock nesting notation [ 130.763560] 1 lock held by cts-runner/3270: [ 130.767745] #0: 7834b793 (&(&array->lock)->rlock){-...}, at: dma_fence_add_callback+0x30/0x23c [ 130.776461] stack backtrace: [ 130.780825] CPU: 1 PID: 3270 Comm: cts-runner Not tainted 4.19.0-rc6+ #486 [ 130.787706] Hardware name: Broadcom STB (Flattened Device Tree) [ 130.793645] [<c021269c>] (unwind_backtrace) from [<c020db1c>] (show_stack+0x10/0x14) [ 130.801404] [<c020db1c>] (show_stack) from [<c0c2c4b0>] (dump_stack+0xa8/0xd4) [ 130.808642] [<c0c2c4b0>] (dump_stack) from [<c0281a84>] (__lock_acquire+0x848/0x1a68) [ 130.816483] [<c0281a84>] (__lock_acquire) from [<c02835d8>] (lock_acquire+0xd8/0x22c) [ 130.824326] [<c02835d8>] (lock_acquire) from [<c0c49948>] (_raw_spin_lock_irqsave+0x54/0x68) [ 130.832777] [<c0c49948>] (_raw_spin_lock_irqsave) from [<c086bf54>] (dma_fence_add_callback+0x30/0x23c) [ 130.842183] [<c086bf54>] (dma_fence_add_callback) from [<c086d4c8>] (dma_fence_array_enable_signaling+0x58/0xec) [ 130.852371] [<c086d4c8>] (dma_fence_array_enable_signaling) from [<c086c00c>] (dma_fence_add_callback+0xe8/0x23c) [ 130.862647] [<c086c00c>] (dma_fence_add_callback) from [<c06d8774>] (drm_syncobj_wait_ioctl+0x518/0x614) [ 130.872143] [<c06d8774>] (drm_syncobj_wait_ioctl) from [<c06b8458>] (drm_ioctl_kernel+0xb0/0xf0) [ 130.880940] [<c06b8458>] (drm_ioctl_kernel) from [<c06b8818>] (drm_ioctl+0x1d8/0x390) [ 130.888782] [<c06b8818>] (drm_ioctl) from [<c03a4510>] (do_vfs_ioctl+0xb0/0x8ac) [ 130.896187] [<c03a4510>] (do_vfs_ioctl) from [<c03a4d40>] (ksys_ioctl+0x34/0x60) [ 130.903593] [<c03a4d40>] (ksys_ioctl) from [<c0201000>] (ret_fast_syscall+0x0/0x28) Cc: Chunming Zhou <david1.zhou@amd.com> Cc: Christian König <christian.koenig@amd.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Eric Anholt <eric@anholt.net> Acked-by: Christian König <christian.koenig@amd.com> Signed-off-by: Christian König <christian.koenig@amd.com> Link: https://patchwork.freedesktop.org/patch/261044/
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/drm_syncobj.c359
1 files changed, 71 insertions, 288 deletions
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index da2b85eec6cf..90e0a6dce086 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -56,9 +56,6 @@
56#include "drm_internal.h" 56#include "drm_internal.h"
57#include <drm/drm_syncobj.h> 57#include <drm/drm_syncobj.h>
58 58
59/* merge normal syncobj to timeline syncobj, the point interval is 1 */
60#define DRM_SYNCOBJ_BINARY_POINT 1
61
62struct drm_syncobj_stub_fence { 59struct drm_syncobj_stub_fence {
63 struct dma_fence base; 60 struct dma_fence base;
64 spinlock_t lock; 61 spinlock_t lock;
@@ -74,29 +71,7 @@ static const struct dma_fence_ops drm_syncobj_stub_fence_ops = {
74 .get_timeline_name = drm_syncobj_stub_fence_get_name, 71 .get_timeline_name = drm_syncobj_stub_fence_get_name,
75}; 72};
76 73
77struct drm_syncobj_signal_pt {
78 struct dma_fence_array *fence_array;
79 u64 value;
80 struct list_head list;
81};
82
83static DEFINE_SPINLOCK(signaled_fence_lock);
84static struct dma_fence signaled_fence;
85 74
86static struct dma_fence *drm_syncobj_get_stub_fence(void)
87{
88 spin_lock(&signaled_fence_lock);
89 if (!signaled_fence.ops) {
90 dma_fence_init(&signaled_fence,
91 &drm_syncobj_stub_fence_ops,
92 &signaled_fence_lock,
93 0, 0);
94 dma_fence_signal_locked(&signaled_fence);
95 }
96 spin_unlock(&signaled_fence_lock);
97
98 return dma_fence_get(&signaled_fence);
99}
100/** 75/**
101 * drm_syncobj_find - lookup and reference a sync object. 76 * drm_syncobj_find - lookup and reference a sync object.
102 * @file_private: drm file private pointer 77 * @file_private: drm file private pointer
@@ -123,27 +98,6 @@ struct drm_syncobj *drm_syncobj_find(struct drm_file *file_private,
123} 98}
124EXPORT_SYMBOL(drm_syncobj_find); 99EXPORT_SYMBOL(drm_syncobj_find);
125 100
126static struct dma_fence *
127drm_syncobj_find_signal_pt_for_point(struct drm_syncobj *syncobj,
128 uint64_t point)
129{
130 struct drm_syncobj_signal_pt *signal_pt;
131
132 if ((syncobj->type == DRM_SYNCOBJ_TYPE_TIMELINE) &&
133 (point <= syncobj->timeline))
134 return drm_syncobj_get_stub_fence();
135
136 list_for_each_entry(signal_pt, &syncobj->signal_pt_list, list) {
137 if (point > signal_pt->value)
138 continue;
139 if ((syncobj->type == DRM_SYNCOBJ_TYPE_BINARY) &&
140 (point != signal_pt->value))
141 continue;
142 return dma_fence_get(&signal_pt->fence_array->base);
143 }
144 return NULL;
145}
146
147static void drm_syncobj_add_callback_locked(struct drm_syncobj *syncobj, 101static void drm_syncobj_add_callback_locked(struct drm_syncobj *syncobj,
148 struct drm_syncobj_cb *cb, 102 struct drm_syncobj_cb *cb,
149 drm_syncobj_func_t func) 103 drm_syncobj_func_t func)
@@ -152,158 +106,53 @@ static void drm_syncobj_add_callback_locked(struct drm_syncobj *syncobj,
152 list_add_tail(&cb->node, &syncobj->cb_list); 106 list_add_tail(&cb->node, &syncobj->cb_list);
153} 107}
154 108
155static void drm_syncobj_fence_get_or_add_callback(struct drm_syncobj *syncobj, 109static int drm_syncobj_fence_get_or_add_callback(struct drm_syncobj *syncobj,
156 struct dma_fence **fence, 110 struct dma_fence **fence,
157 struct drm_syncobj_cb *cb, 111 struct drm_syncobj_cb *cb,
158 drm_syncobj_func_t func) 112 drm_syncobj_func_t func)
159{ 113{
160 u64 pt_value = 0; 114 int ret;
161
162 WARN_ON(*fence);
163 115
164 if (syncobj->type == DRM_SYNCOBJ_TYPE_BINARY) { 116 *fence = drm_syncobj_fence_get(syncobj);
165 /*BINARY syncobj always wait on last pt */ 117 if (*fence)
166 pt_value = syncobj->signal_point; 118 return 1;
167 119
168 if (pt_value == 0) 120 spin_lock(&syncobj->lock);
169 pt_value += DRM_SYNCOBJ_BINARY_POINT; 121 /* We've already tried once to get a fence and failed. Now that we
170 } 122 * have the lock, try one more time just to be sure we don't add a
171 123 * callback when a fence has already been set.
172 mutex_lock(&syncobj->cb_mutex); 124 */
173 spin_lock(&syncobj->pt_lock); 125 if (syncobj->fence) {
174 *fence = drm_syncobj_find_signal_pt_for_point(syncobj, pt_value); 126 *fence = dma_fence_get(rcu_dereference_protected(syncobj->fence,
175 spin_unlock(&syncobj->pt_lock); 127 lockdep_is_held(&syncobj->lock)));
176 if (!*fence) 128 ret = 1;
129 } else {
130 *fence = NULL;
177 drm_syncobj_add_callback_locked(syncobj, cb, func); 131 drm_syncobj_add_callback_locked(syncobj, cb, func);
178 mutex_unlock(&syncobj->cb_mutex); 132 ret = 0;
179} 133 }
180 134 spin_unlock(&syncobj->lock);
181static void drm_syncobj_remove_callback(struct drm_syncobj *syncobj,
182 struct drm_syncobj_cb *cb)
183{
184 mutex_lock(&syncobj->cb_mutex);
185 list_del_init(&cb->node);
186 mutex_unlock(&syncobj->cb_mutex);
187}
188 135
189static void drm_syncobj_init(struct drm_syncobj *syncobj) 136 return ret;
190{
191 spin_lock(&syncobj->pt_lock);
192 syncobj->timeline_context = dma_fence_context_alloc(1);
193 syncobj->timeline = 0;
194 syncobj->signal_point = 0;
195 init_waitqueue_head(&syncobj->wq);
196
197 INIT_LIST_HEAD(&syncobj->signal_pt_list);
198 spin_unlock(&syncobj->pt_lock);
199} 137}
200 138
201static void drm_syncobj_fini(struct drm_syncobj *syncobj) 139void drm_syncobj_add_callback(struct drm_syncobj *syncobj,
140 struct drm_syncobj_cb *cb,
141 drm_syncobj_func_t func)
202{ 142{
203 struct drm_syncobj_signal_pt *signal_pt = NULL, *tmp; 143 spin_lock(&syncobj->lock);
204 144 drm_syncobj_add_callback_locked(syncobj, cb, func);
205 spin_lock(&syncobj->pt_lock); 145 spin_unlock(&syncobj->lock);
206 list_for_each_entry_safe(signal_pt, tmp,
207 &syncobj->signal_pt_list, list) {
208 list_del(&signal_pt->list);
209 dma_fence_put(&signal_pt->fence_array->base);
210 kfree(signal_pt);
211 }
212 spin_unlock(&syncobj->pt_lock);
213} 146}
214 147
215static int drm_syncobj_create_signal_pt(struct drm_syncobj *syncobj, 148void drm_syncobj_remove_callback(struct drm_syncobj *syncobj,
216 struct dma_fence *fence, 149 struct drm_syncobj_cb *cb)
217 u64 point)
218{ 150{
219 struct drm_syncobj_signal_pt *signal_pt = 151 spin_lock(&syncobj->lock);
220 kzalloc(sizeof(struct drm_syncobj_signal_pt), GFP_KERNEL); 152 list_del_init(&cb->node);
221 struct drm_syncobj_signal_pt *tail_pt; 153 spin_unlock(&syncobj->lock);
222 struct dma_fence **fences;
223 int num_fences = 0;
224 int ret = 0, i;
225
226 if (!signal_pt)
227 return -ENOMEM;
228 if (!fence)
229 goto out;
230
231 fences = kmalloc_array(sizeof(void *), 2, GFP_KERNEL);
232 if (!fences) {
233 ret = -ENOMEM;
234 goto out;
235 }
236 fences[num_fences++] = dma_fence_get(fence);
237 /* timeline syncobj must take this dependency */
238 if (syncobj->type == DRM_SYNCOBJ_TYPE_TIMELINE) {
239 spin_lock(&syncobj->pt_lock);
240 if (!list_empty(&syncobj->signal_pt_list)) {
241 tail_pt = list_last_entry(&syncobj->signal_pt_list,
242 struct drm_syncobj_signal_pt, list);
243 fences[num_fences++] =
244 dma_fence_get(&tail_pt->fence_array->base);
245 }
246 spin_unlock(&syncobj->pt_lock);
247 }
248 signal_pt->fence_array = dma_fence_array_create(num_fences, fences,
249 syncobj->timeline_context,
250 point, false);
251 if (!signal_pt->fence_array) {
252 ret = -ENOMEM;
253 goto fail;
254 }
255
256 spin_lock(&syncobj->pt_lock);
257 if (syncobj->signal_point >= point) {
258 DRM_WARN("A later signal is ready!");
259 spin_unlock(&syncobj->pt_lock);
260 goto exist;
261 }
262 signal_pt->value = point;
263 list_add_tail(&signal_pt->list, &syncobj->signal_pt_list);
264 syncobj->signal_point = point;
265 spin_unlock(&syncobj->pt_lock);
266 wake_up_all(&syncobj->wq);
267
268 return 0;
269exist:
270 dma_fence_put(&signal_pt->fence_array->base);
271fail:
272 for (i = 0; i < num_fences; i++)
273 dma_fence_put(fences[i]);
274 kfree(fences);
275out:
276 kfree(signal_pt);
277 return ret;
278} 154}
279 155
280static void drm_syncobj_garbage_collection(struct drm_syncobj *syncobj)
281{
282 struct drm_syncobj_signal_pt *signal_pt, *tmp, *tail_pt;
283
284 spin_lock(&syncobj->pt_lock);
285 tail_pt = list_last_entry(&syncobj->signal_pt_list,
286 struct drm_syncobj_signal_pt,
287 list);
288 list_for_each_entry_safe(signal_pt, tmp,
289 &syncobj->signal_pt_list, list) {
290 if (syncobj->type == DRM_SYNCOBJ_TYPE_BINARY &&
291 signal_pt == tail_pt)
292 continue;
293 if (dma_fence_is_signaled(&signal_pt->fence_array->base)) {
294 syncobj->timeline = signal_pt->value;
295 list_del(&signal_pt->list);
296 dma_fence_put(&signal_pt->fence_array->base);
297 kfree(signal_pt);
298 } else {
299 /*signal_pt is in order in list, from small to big, so
300 * the later must not be signal either */
301 break;
302 }
303 }
304
305 spin_unlock(&syncobj->pt_lock);
306}
307/** 156/**
308 * drm_syncobj_replace_fence - replace fence in a sync object. 157 * drm_syncobj_replace_fence - replace fence in a sync object.
309 * @syncobj: Sync object to replace fence in 158 * @syncobj: Sync object to replace fence in
@@ -316,30 +165,28 @@ void drm_syncobj_replace_fence(struct drm_syncobj *syncobj,
316 u64 point, 165 u64 point,
317 struct dma_fence *fence) 166 struct dma_fence *fence)
318{ 167{
319 u64 pt_value = point; 168 struct dma_fence *old_fence;
320 169 struct drm_syncobj_cb *cur, *tmp;
321 drm_syncobj_garbage_collection(syncobj); 170
322 if (syncobj->type == DRM_SYNCOBJ_TYPE_BINARY) { 171 if (fence)
323 if (!fence) { 172 dma_fence_get(fence);
324 drm_syncobj_fini(syncobj); 173
325 drm_syncobj_init(syncobj); 174 spin_lock(&syncobj->lock);
326 return; 175
327 } 176 old_fence = rcu_dereference_protected(syncobj->fence,
328 pt_value = syncobj->signal_point + 177 lockdep_is_held(&syncobj->lock));
329 DRM_SYNCOBJ_BINARY_POINT; 178 rcu_assign_pointer(syncobj->fence, fence);
330 }
331 drm_syncobj_create_signal_pt(syncobj, fence, pt_value);
332 if (fence) {
333 struct drm_syncobj_cb *cur, *tmp;
334 LIST_HEAD(cb_list);
335 179
336 mutex_lock(&syncobj->cb_mutex); 180 if (fence != old_fence) {
337 list_for_each_entry_safe(cur, tmp, &syncobj->cb_list, node) { 181 list_for_each_entry_safe(cur, tmp, &syncobj->cb_list, node) {
338 list_del_init(&cur->node); 182 list_del_init(&cur->node);
339 cur->func(syncobj, cur); 183 cur->func(syncobj, cur);
340 } 184 }
341 mutex_unlock(&syncobj->cb_mutex);
342 } 185 }
186
187 spin_unlock(&syncobj->lock);
188
189 dma_fence_put(old_fence);
343} 190}
344EXPORT_SYMBOL(drm_syncobj_replace_fence); 191EXPORT_SYMBOL(drm_syncobj_replace_fence);
345 192
@@ -362,64 +209,6 @@ static int drm_syncobj_assign_null_handle(struct drm_syncobj *syncobj)
362 return 0; 209 return 0;
363} 210}
364 211
365static int
366drm_syncobj_point_get(struct drm_syncobj *syncobj, u64 point, u64 flags,
367 struct dma_fence **fence)
368{
369 int ret = 0;
370
371 if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) {
372 ret = wait_event_interruptible(syncobj->wq,
373 point <= syncobj->signal_point);
374 if (ret < 0)
375 return ret;
376 }
377 spin_lock(&syncobj->pt_lock);
378 *fence = drm_syncobj_find_signal_pt_for_point(syncobj, point);
379 if (!*fence)
380 ret = -EINVAL;
381 spin_unlock(&syncobj->pt_lock);
382 return ret;
383}
384
385/**
386 * drm_syncobj_search_fence - lookup and reference the fence in a sync object or
387 * in a timeline point
388 * @syncobj: sync object pointer
389 * @point: timeline point
390 * @flags: DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT or not
391 * @fence: out parameter for the fence
392 *
393 * if flags is DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT, the function will block
394 * here until specific timeline points is reached.
395 * if not, you need a submit thread and block in userspace until all future
396 * timeline points have materialized, only then you can submit to the kernel,
397 * otherwise, function will fail to return fence.
398 *
399 * Returns 0 on success or a negative error value on failure. On success @fence
400 * contains a reference to the fence, which must be released by calling
401 * dma_fence_put().
402 */
403int drm_syncobj_search_fence(struct drm_syncobj *syncobj, u64 point,
404 u64 flags, struct dma_fence **fence)
405{
406 u64 pt_value = point;
407
408 if (!syncobj)
409 return -ENOENT;
410
411 drm_syncobj_garbage_collection(syncobj);
412 if (syncobj->type == DRM_SYNCOBJ_TYPE_BINARY) {
413 /*BINARY syncobj always wait on last pt */
414 pt_value = syncobj->signal_point;
415
416 if (pt_value == 0)
417 pt_value += DRM_SYNCOBJ_BINARY_POINT;
418 }
419 return drm_syncobj_point_get(syncobj, pt_value, flags, fence);
420}
421EXPORT_SYMBOL(drm_syncobj_search_fence);
422
423/** 212/**
424 * drm_syncobj_find_fence - lookup and reference the fence in a sync object 213 * drm_syncobj_find_fence - lookup and reference the fence in a sync object
425 * @file_private: drm file private pointer 214 * @file_private: drm file private pointer
@@ -429,7 +218,7 @@ EXPORT_SYMBOL(drm_syncobj_search_fence);
429 * @fence: out parameter for the fence 218 * @fence: out parameter for the fence
430 * 219 *
431 * This is just a convenience function that combines drm_syncobj_find() and 220 * This is just a convenience function that combines drm_syncobj_find() and
432 * drm_syncobj_lookup_fence(). 221 * drm_syncobj_fence_get().
433 * 222 *
434 * Returns 0 on success or a negative error value on failure. On success @fence 223 * Returns 0 on success or a negative error value on failure. On success @fence
435 * contains a reference to the fence, which must be released by calling 224 * contains a reference to the fence, which must be released by calling
@@ -440,11 +229,16 @@ int drm_syncobj_find_fence(struct drm_file *file_private,
440 struct dma_fence **fence) 229 struct dma_fence **fence)
441{ 230{
442 struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle); 231 struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle);
443 int ret; 232 int ret = 0;
444 233
445 ret = drm_syncobj_search_fence(syncobj, point, flags, fence); 234 if (!syncobj)
446 if (syncobj) 235 return -ENOENT;
447 drm_syncobj_put(syncobj); 236
237 *fence = drm_syncobj_fence_get(syncobj);
238 if (!*fence) {
239 ret = -EINVAL;
240 }
241 drm_syncobj_put(syncobj);
448 return ret; 242 return ret;
449} 243}
450EXPORT_SYMBOL(drm_syncobj_find_fence); 244EXPORT_SYMBOL(drm_syncobj_find_fence);
@@ -460,7 +254,7 @@ void drm_syncobj_free(struct kref *kref)
460 struct drm_syncobj *syncobj = container_of(kref, 254 struct drm_syncobj *syncobj = container_of(kref,
461 struct drm_syncobj, 255 struct drm_syncobj,
462 refcount); 256 refcount);
463 drm_syncobj_fini(syncobj); 257 drm_syncobj_replace_fence(syncobj, 0, NULL);
464 kfree(syncobj); 258 kfree(syncobj);
465} 259}
466EXPORT_SYMBOL(drm_syncobj_free); 260EXPORT_SYMBOL(drm_syncobj_free);
@@ -493,13 +287,7 @@ int drm_syncobj_create(struct drm_syncobj **out_syncobj, uint32_t flags,
493 287
494 kref_init(&syncobj->refcount); 288 kref_init(&syncobj->refcount);
495 INIT_LIST_HEAD(&syncobj->cb_list); 289 INIT_LIST_HEAD(&syncobj->cb_list);
496 spin_lock_init(&syncobj->pt_lock); 290 spin_lock_init(&syncobj->lock);
497 mutex_init(&syncobj->cb_mutex);
498 if (flags & DRM_SYNCOBJ_CREATE_TYPE_TIMELINE)
499 syncobj->type = DRM_SYNCOBJ_TYPE_TIMELINE;
500 else
501 syncobj->type = DRM_SYNCOBJ_TYPE_BINARY;
502 drm_syncobj_init(syncobj);
503 291
504 if (flags & DRM_SYNCOBJ_CREATE_SIGNALED) { 292 if (flags & DRM_SYNCOBJ_CREATE_SIGNALED) {
505 ret = drm_syncobj_assign_null_handle(syncobj); 293 ret = drm_syncobj_assign_null_handle(syncobj);
@@ -782,8 +570,7 @@ drm_syncobj_create_ioctl(struct drm_device *dev, void *data,
782 return -EOPNOTSUPP; 570 return -EOPNOTSUPP;
783 571
784 /* no valid flags yet */ 572 /* no valid flags yet */
785 if (args->flags & ~(DRM_SYNCOBJ_CREATE_SIGNALED | 573 if (args->flags & ~DRM_SYNCOBJ_CREATE_SIGNALED)
786 DRM_SYNCOBJ_CREATE_TYPE_TIMELINE))
787 return -EINVAL; 574 return -EINVAL;
788 575
789 return drm_syncobj_create_as_handle(file_private, 576 return drm_syncobj_create_as_handle(file_private,
@@ -876,8 +663,9 @@ static void syncobj_wait_syncobj_func(struct drm_syncobj *syncobj,
876 struct syncobj_wait_entry *wait = 663 struct syncobj_wait_entry *wait =
877 container_of(cb, struct syncobj_wait_entry, syncobj_cb); 664 container_of(cb, struct syncobj_wait_entry, syncobj_cb);
878 665
879 drm_syncobj_search_fence(syncobj, 0, 0, &wait->fence); 666 /* This happens inside the syncobj lock */
880 667 wait->fence = dma_fence_get(rcu_dereference_protected(syncobj->fence,
668 lockdep_is_held(&syncobj->lock)));
881 wake_up_process(wait->task); 669 wake_up_process(wait->task);
882} 670}
883 671
@@ -903,8 +691,7 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
903 signaled_count = 0; 691 signaled_count = 0;
904 for (i = 0; i < count; ++i) { 692 for (i = 0; i < count; ++i) {
905 entries[i].task = current; 693 entries[i].task = current;
906 drm_syncobj_search_fence(syncobjs[i], 0, 0, 694 entries[i].fence = drm_syncobj_fence_get(syncobjs[i]);
907 &entries[i].fence);
908 if (!entries[i].fence) { 695 if (!entries[i].fence) {
909 if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) { 696 if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) {
910 continue; 697 continue;
@@ -935,9 +722,6 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
935 722
936 if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) { 723 if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) {
937 for (i = 0; i < count; ++i) { 724 for (i = 0; i < count; ++i) {
938 if (entries[i].fence)
939 continue;
940
941 drm_syncobj_fence_get_or_add_callback(syncobjs[i], 725 drm_syncobj_fence_get_or_add_callback(syncobjs[i],
942 &entries[i].fence, 726 &entries[i].fence,
943 &entries[i].syncobj_cb, 727 &entries[i].syncobj_cb,
@@ -1169,13 +953,12 @@ drm_syncobj_reset_ioctl(struct drm_device *dev, void *data,
1169 if (ret < 0) 953 if (ret < 0)
1170 return ret; 954 return ret;
1171 955
1172 for (i = 0; i < args->count_handles; i++) { 956 for (i = 0; i < args->count_handles; i++)
1173 drm_syncobj_fini(syncobjs[i]); 957 drm_syncobj_replace_fence(syncobjs[i], 0, NULL);
1174 drm_syncobj_init(syncobjs[i]); 958
1175 }
1176 drm_syncobj_array_free(syncobjs, args->count_handles); 959 drm_syncobj_array_free(syncobjs, args->count_handles);
1177 960
1178 return ret; 961 return 0;
1179} 962}
1180 963
1181int 964int