xref: /linux/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c (revision fbf5df34a4dbcd09d433dd4f0916bf9b2ddb16de)
1 // SPDX-License-Identifier: GPL-2.0 OR MIT
2 /**************************************************************************
3  *
4  * Copyright (c) 2009-2025 Broadcom. All Rights Reserved. The term
5  * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
6  *
7  **************************************************************************/
8 
9 #include "vmwgfx_drv.h"
10 
11 #define VMW_FENCE_WRAP (1 << 31)
12 
13 struct vmw_fence_manager {
14 	struct vmw_private *dev_priv;
15 	spinlock_t lock;
16 	struct list_head fence_list;
17 	bool fifo_down;
18 	u64 ctx;
19 };
20 
21 struct vmw_user_fence {
22 	struct ttm_base_object base;
23 	struct vmw_fence_obj fence;
24 };
25 
26 /**
27  * struct vmw_event_fence_action - fence callback that delivers a DRM event.
28  *
29  * @base:  For use with dma_fence_add_callback(...)
30  * @event: A pointer to the pending event.
31  * @dev: Pointer to a struct drm_device so we can access the event stuff.
32  * @tv_sec: If non-null, the variable pointed to will be assigned
33  * current time tv_sec val when the fence signals.
34  * @tv_usec: Must be set if @tv_sec is set, and the variable pointed to will
35  * be assigned the current time tv_usec val when the fence signals.
36  */
37 struct vmw_event_fence_action {
38 	struct dma_fence_cb base;
39 
40 	struct drm_pending_event *event;
41 	struct drm_device *dev;
42 
43 	uint32_t *tv_sec;
44 	uint32_t *tv_usec;
45 };
46 
47 static struct vmw_fence_manager *
48 fman_from_fence(struct vmw_fence_obj *fence)
49 {
50 	return container_of(fence->base.extern_lock, struct vmw_fence_manager,
51 			    lock);
52 }
53 
54 static void vmw_fence_obj_destroy(struct dma_fence *f)
55 {
56 	struct vmw_fence_obj *fence =
57 		container_of(f, struct vmw_fence_obj, base);
58 	struct vmw_fence_manager *fman = fman_from_fence(fence);
59 
60 	if (!list_empty(&fence->head)) {
61 		/* The fence manager still has an implicit reference to this
62 		 * fence via the fence list if head is set. Because the lock is
63 		 * required to be held when the fence manager updates the fence
64 		 * list either the fence will have been removed after we get
65 		 * the lock below or we can safely remove it and the fence
66 		 * manager will never see it. This implies the fence is being
67 		 * deleted without being signaled which is dubious but valid
68 		 * if there are no callbacks. The dma_fence code that calls
69 		 * this hook will warn about deleted unsignaled with callbacks
70 		 * so no need to warn again here.
71 		 */
72 		spin_lock(&fman->lock);
73 		list_del_init(&fence->head);
74 		if (fence->waiter_added)
75 			vmw_seqno_waiter_remove(fman->dev_priv);
76 		spin_unlock(&fman->lock);
77 	}
78 	fence->destroy(fence);
79 }
80 
81 static const char *vmw_fence_get_driver_name(struct dma_fence *f)
82 {
83 	return "vmwgfx";
84 }
85 
86 static const char *vmw_fence_get_timeline_name(struct dma_fence *f)
87 {
88 	return "svga";
89 }
90 
91 /* When we toggle signaling for the SVGA device there is a race period from
92  * the time we first read the fence seqno to the time we enable interrupts.
93  * If we miss the interrupt for a fence during this period its likely the driver
94  * will stall. As a result we need to re-read the seqno after interrupts are
95  * enabled. If interrupts were already enabled we just increment the number of
96  * seqno waiters.
97  */
98 static bool vmw_fence_enable_signaling(struct dma_fence *f)
99 {
100 	u32 seqno;
101 	struct vmw_fence_obj *fence =
102 		container_of(f, struct vmw_fence_obj, base);
103 
104 	struct vmw_fence_manager *fman = fman_from_fence(fence);
105 	struct vmw_private *dev_priv = fman->dev_priv;
106 check_for_race:
107 	seqno = vmw_fence_read(dev_priv);
108 	if (seqno - fence->base.seqno < VMW_FENCE_WRAP) {
109 		if (fence->waiter_added) {
110 			vmw_seqno_waiter_remove(dev_priv);
111 			fence->waiter_added = false;
112 		}
113 		return false;
114 	} else if (!fence->waiter_added) {
115 		fence->waiter_added = true;
116 		if (vmw_seqno_waiter_add(dev_priv))
117 			goto check_for_race;
118 	}
119 	return true;
120 }
121 
122 static u32 __vmw_fences_update(struct vmw_fence_manager *fman);
123 
124 static const struct dma_fence_ops vmw_fence_ops = {
125 	.get_driver_name = vmw_fence_get_driver_name,
126 	.get_timeline_name = vmw_fence_get_timeline_name,
127 	.enable_signaling = vmw_fence_enable_signaling,
128 	.release = vmw_fence_obj_destroy,
129 };
130 
131 struct vmw_fence_manager *vmw_fence_manager_init(struct vmw_private *dev_priv)
132 {
133 	struct vmw_fence_manager *fman = kzalloc_obj(*fman);
134 
135 	if (unlikely(!fman))
136 		return NULL;
137 
138 	fman->dev_priv = dev_priv;
139 	spin_lock_init(&fman->lock);
140 	INIT_LIST_HEAD(&fman->fence_list);
141 	fman->fifo_down = true;
142 	fman->ctx = dma_fence_context_alloc(1);
143 
144 	return fman;
145 }
146 
147 void vmw_fence_manager_takedown(struct vmw_fence_manager *fman)
148 {
149 	bool lists_empty;
150 
151 	spin_lock(&fman->lock);
152 	lists_empty = list_empty(&fman->fence_list);
153 	spin_unlock(&fman->lock);
154 
155 	BUG_ON(!lists_empty);
156 	kfree(fman);
157 }
158 
159 static int vmw_fence_obj_init(struct vmw_fence_manager *fman,
160 			      struct vmw_fence_obj *fence, u32 seqno,
161 			      void (*destroy) (struct vmw_fence_obj *fence))
162 {
163 	int ret = 0;
164 
165 	dma_fence_init(&fence->base, &vmw_fence_ops, &fman->lock,
166 		       fman->ctx, seqno);
167 	fence->destroy = destroy;
168 
169 	spin_lock(&fman->lock);
170 	if (unlikely(fman->fifo_down)) {
171 		ret = -EBUSY;
172 		goto out_unlock;
173 	}
174 	/* This creates an implicit reference to the fence from the fence
175 	 * manager. It will be dropped when the fence is signaled which is
176 	 * expected to happen before deletion. The dtor has code to catch
177 	 * the rare deletion before signaling case.
178 	 */
179 	list_add_tail(&fence->head, &fman->fence_list);
180 
181 out_unlock:
182 	spin_unlock(&fman->lock);
183 	return ret;
184 
185 }
186 
187 static u32 __vmw_fences_update(struct vmw_fence_manager *fman)
188 {
189 	struct vmw_fence_obj *fence, *next_fence;
190 	const bool cookie = dma_fence_begin_signalling();
191 	const u32 seqno = vmw_fence_read(fman->dev_priv);
192 
193 	list_for_each_entry_safe(fence, next_fence, &fman->fence_list, head) {
194 		if (seqno - fence->base.seqno < VMW_FENCE_WRAP) {
195 			list_del_init(&fence->head);
196 			if (fence->waiter_added) {
197 				vmw_seqno_waiter_remove(fman->dev_priv);
198 				fence->waiter_added = false;
199 			}
200 			dma_fence_signal_locked(&fence->base);
201 		} else
202 			break;
203 	}
204 	dma_fence_end_signalling(cookie);
205 	atomic_set_release(&fman->dev_priv->last_read_seqno, seqno);
206 	return seqno;
207 }
208 
209 u32 vmw_fences_update(struct vmw_fence_manager *fman)
210 {
211 	u32 seqno;
212 	spin_lock(&fman->lock);
213 	seqno = __vmw_fences_update(fman);
214 	spin_unlock(&fman->lock);
215 	return seqno;
216 }
217 
218 bool vmw_fence_obj_signaled(struct vmw_fence_obj *fence)
219 {
220 	struct vmw_fence_manager *fman = fman_from_fence(fence);
221 
222 	if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->base.flags))
223 		return true;
224 
225 	vmw_fences_update(fman);
226 
227 	return dma_fence_is_signaled(&fence->base);
228 }
229 
230 int vmw_fence_obj_wait(struct vmw_fence_obj *fence, bool lazy,
231 		       bool interruptible, unsigned long timeout)
232 {
233 	long ret = dma_fence_wait_timeout(&fence->base, interruptible, timeout);
234 
235 	if (likely(ret > 0))
236 		return 0;
237 	else if (ret == 0)
238 		return -EBUSY;
239 	else
240 		return ret;
241 }
242 
243 static void vmw_fence_destroy(struct vmw_fence_obj *fence)
244 {
245 	dma_fence_free(&fence->base);
246 }
247 
248 int vmw_fence_create(struct vmw_fence_manager *fman,
249 		     uint32_t seqno,
250 		     struct vmw_fence_obj **p_fence)
251 {
252 	struct vmw_fence_obj *fence;
253 	int ret;
254 
255 	fence = kzalloc_obj(*fence);
256 	if (unlikely(!fence))
257 		return -ENOMEM;
258 
259 	ret = vmw_fence_obj_init(fman, fence, seqno, vmw_fence_destroy);
260 	if (unlikely(ret != 0))
261 		goto out_err_init;
262 
263 	*p_fence = fence;
264 	return 0;
265 
266 out_err_init:
267 	kfree(fence);
268 	return ret;
269 }
270 
271 
272 static void vmw_user_fence_destroy(struct vmw_fence_obj *fence)
273 {
274 	struct vmw_user_fence *ufence =
275 		container_of(fence, struct vmw_user_fence, fence);
276 
277 	ttm_base_object_kfree(ufence, base);
278 }
279 
280 static void vmw_user_fence_base_release(struct ttm_base_object **p_base)
281 {
282 	struct ttm_base_object *base = *p_base;
283 	struct vmw_user_fence *ufence =
284 		container_of(base, struct vmw_user_fence, base);
285 	struct vmw_fence_obj *fence = &ufence->fence;
286 
287 	*p_base = NULL;
288 	vmw_fence_obj_unreference(&fence);
289 }
290 
291 int vmw_user_fence_create(struct drm_file *file_priv,
292 			  struct vmw_fence_manager *fman,
293 			  uint32_t seqno,
294 			  struct vmw_fence_obj **p_fence,
295 			  uint32_t *p_handle)
296 {
297 	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
298 	struct vmw_user_fence *ufence;
299 	struct vmw_fence_obj *tmp;
300 	int ret;
301 
302 	ufence = kzalloc_obj(*ufence);
303 	if (unlikely(!ufence)) {
304 		ret = -ENOMEM;
305 		goto out_no_object;
306 	}
307 
308 	ret = vmw_fence_obj_init(fman, &ufence->fence, seqno,
309 				 vmw_user_fence_destroy);
310 	if (unlikely(ret != 0)) {
311 		kfree(ufence);
312 		goto out_no_object;
313 	}
314 
315 	/*
316 	 * The base object holds a reference which is freed in
317 	 * vmw_user_fence_base_release.
318 	 */
319 	tmp = vmw_fence_obj_reference(&ufence->fence);
320 
321 	ret = ttm_base_object_init(tfile, &ufence->base, false,
322 				   VMW_RES_FENCE,
323 				   &vmw_user_fence_base_release);
324 
325 
326 	if (unlikely(ret != 0)) {
327 		/*
328 		 * Free the base object's reference
329 		 */
330 		vmw_fence_obj_unreference(&tmp);
331 		goto out_err;
332 	}
333 
334 	*p_fence = &ufence->fence;
335 	*p_handle = ufence->base.handle;
336 
337 	return 0;
338 out_err:
339 	tmp = &ufence->fence;
340 	vmw_fence_obj_unreference(&tmp);
341 out_no_object:
342 	return ret;
343 }
344 
345 /*
346  * vmw_fence_fifo_down - signal all unsignaled fence objects.
347  */
348 
349 void vmw_fence_fifo_down(struct vmw_fence_manager *fman)
350 {
351 	int ret;
352 
353 	/*
354 	 * The list may be altered while we traverse it, so always
355 	 * restart when we've released the fman->lock.
356 	 */
357 
358 	spin_lock(&fman->lock);
359 	fman->fifo_down = true;
360 	while (!list_empty(&fman->fence_list)) {
361 		struct vmw_fence_obj *fence =
362 			list_entry(fman->fence_list.prev, struct vmw_fence_obj,
363 				   head);
364 		dma_fence_get(&fence->base);
365 		spin_unlock(&fman->lock);
366 
367 		ret = vmw_fence_obj_wait(fence, false, false,
368 					 VMW_FENCE_WAIT_TIMEOUT);
369 
370 		if (unlikely(ret != 0)) {
371 			list_del_init(&fence->head);
372 			dma_fence_signal(&fence->base);
373 		}
374 
375 		BUG_ON(!list_empty(&fence->head));
376 		dma_fence_put(&fence->base);
377 		spin_lock(&fman->lock);
378 	}
379 	spin_unlock(&fman->lock);
380 }
381 
382 void vmw_fence_fifo_up(struct vmw_fence_manager *fman)
383 {
384 	spin_lock(&fman->lock);
385 	fman->fifo_down = false;
386 	spin_unlock(&fman->lock);
387 }
388 
389 
390 /**
391  * vmw_fence_obj_lookup - Look up a user-space fence object
392  *
393  * @tfile: A struct ttm_object_file identifying the caller.
394  * @handle: A handle identifying the fence object.
395  * @return: A struct vmw_user_fence base ttm object on success or
396  * an error pointer on failure.
397  *
398  * The fence object is looked up and type-checked. The caller needs
399  * to have opened the fence object first, but since that happens on
400  * creation and fence objects aren't shareable, that's not an
401  * issue currently.
402  */
403 static struct ttm_base_object *
404 vmw_fence_obj_lookup(struct ttm_object_file *tfile, u32 handle)
405 {
406 	struct ttm_base_object *base = ttm_base_object_lookup(tfile, handle);
407 
408 	if (!base) {
409 		pr_err("Invalid fence object handle 0x%08lx.\n",
410 		       (unsigned long)handle);
411 		return ERR_PTR(-EINVAL);
412 	}
413 
414 	if (base->refcount_release != vmw_user_fence_base_release) {
415 		pr_err("Invalid fence object handle 0x%08lx.\n",
416 		       (unsigned long)handle);
417 		ttm_base_object_unref(&base);
418 		return ERR_PTR(-EINVAL);
419 	}
420 
421 	return base;
422 }
423 
424 
425 int vmw_fence_obj_wait_ioctl(struct drm_device *dev, void *data,
426 			     struct drm_file *file_priv)
427 {
428 	struct drm_vmw_fence_wait_arg *arg =
429 	    (struct drm_vmw_fence_wait_arg *)data;
430 	unsigned long timeout;
431 	struct ttm_base_object *base;
432 	struct vmw_fence_obj *fence;
433 	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
434 	int ret;
435 	uint64_t wait_timeout = ((uint64_t)arg->timeout_us * HZ);
436 
437 	/*
438 	 * 64-bit division not present on 32-bit systems, so do an
439 	 * approximation. (Divide by 1000000).
440 	 */
441 
442 	wait_timeout = (wait_timeout >> 20) + (wait_timeout >> 24) -
443 	  (wait_timeout >> 26);
444 
445 	if (!arg->cookie_valid) {
446 		arg->cookie_valid = 1;
447 		arg->kernel_cookie = jiffies + wait_timeout;
448 	}
449 
450 	base = vmw_fence_obj_lookup(tfile, arg->handle);
451 	if (IS_ERR(base))
452 		return PTR_ERR(base);
453 
454 	fence = &(container_of(base, struct vmw_user_fence, base)->fence);
455 
456 	timeout = jiffies;
457 	if (time_after_eq(timeout, (unsigned long)arg->kernel_cookie)) {
458 		ret = ((vmw_fence_obj_signaled(fence)) ?
459 		       0 : -EBUSY);
460 		goto out;
461 	}
462 
463 	timeout = (unsigned long)arg->kernel_cookie - timeout;
464 
465 	ret = vmw_fence_obj_wait(fence, arg->lazy, true, timeout);
466 
467 out:
468 	ttm_base_object_unref(&base);
469 
470 	/*
471 	 * Optionally unref the fence object.
472 	 */
473 
474 	if (ret == 0 && (arg->wait_options & DRM_VMW_WAIT_OPTION_UNREF))
475 		return ttm_ref_object_base_unref(tfile, arg->handle);
476 	return ret;
477 }
478 
479 int vmw_fence_obj_signaled_ioctl(struct drm_device *dev, void *data,
480 				 struct drm_file *file_priv)
481 {
482 	struct drm_vmw_fence_signaled_arg *arg =
483 		(struct drm_vmw_fence_signaled_arg *) data;
484 	struct ttm_base_object *base;
485 	struct vmw_fence_obj *fence;
486 	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
487 	struct vmw_private *dev_priv = vmw_priv(dev);
488 
489 	base = vmw_fence_obj_lookup(tfile, arg->handle);
490 	if (IS_ERR(base))
491 		return PTR_ERR(base);
492 
493 	fence = &(container_of(base, struct vmw_user_fence, base)->fence);
494 
495 	arg->signaled = vmw_fence_obj_signaled(fence);
496 
497 	arg->signaled_flags = arg->flags;
498 	arg->passed_seqno = atomic_read_acquire(&dev_priv->last_read_seqno);
499 
500 	ttm_base_object_unref(&base);
501 
502 	return 0;
503 }
504 
505 
506 int vmw_fence_obj_unref_ioctl(struct drm_device *dev, void *data,
507 			      struct drm_file *file_priv)
508 {
509 	struct drm_vmw_fence_arg *arg =
510 		(struct drm_vmw_fence_arg *) data;
511 
512 	return ttm_ref_object_base_unref(vmw_fpriv(file_priv)->tfile,
513 					 arg->handle);
514 }
515 
516 /**
517  * vmw_event_fence_action_seq_passed
518  *
519  * @f: The struct dma_fence which provides timestamp for the action event
520  * @cb: The struct dma_fence_cb callback for the action event.
521  *
522  * This function is called when the seqno of the fence has passed
523  * and it is always called from atomic context.
524  * It queues the event on the submitter's event list.
525  */
526 static void vmw_event_fence_action_seq_passed(struct dma_fence *f,
527 					      struct dma_fence_cb *cb)
528 {
529 	struct vmw_event_fence_action *eaction =
530 		container_of(cb, struct vmw_event_fence_action, base);
531 	struct drm_device *dev = eaction->dev;
532 	struct drm_pending_event *event = eaction->event;
533 
534 	if (unlikely(event == NULL))
535 		return;
536 
537 	spin_lock_irq(&dev->event_lock);
538 
539 	if (likely(eaction->tv_sec != NULL)) {
540 		struct timespec64 ts;
541 
542 		ts = ktime_to_timespec64(f->timestamp);
543 		/* monotonic time, so no y2038 overflow */
544 		*eaction->tv_sec = ts.tv_sec;
545 		*eaction->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
546 	}
547 
548 	drm_send_event_locked(dev, eaction->event);
549 	eaction->event = NULL;
550 	spin_unlock_irq(&dev->event_lock);
551 	dma_fence_put(f);
552 	kfree(eaction);
553 }
554 
555 /**
556  * vmw_event_fence_action_queue - Post an event for sending when a fence
557  * object seqno has passed.
558  *
559  * @file_priv: The file connection on which the event should be posted.
560  * @fence: The fence object on which to post the event.
561  * @event: Event to be posted. This event should've been alloced
562  * using k[mz]alloc, and should've been completely initialized.
563  * @tv_sec: If non-null, the variable pointed to will be assigned
564  * current time tv_sec val when the fence signals.
565  * @tv_usec: Must be set if @tv_sec is set, and the variable pointed to will
566  * be assigned the current time tv_usec val when the fence signals.
567  * @interruptible: Interruptible waits if possible.
568  *
569  * As a side effect, the object pointed to by @event may have been
570  * freed when this function returns. If this function returns with
571  * an error code, the caller needs to free that object.
572  */
573 
574 int vmw_event_fence_action_queue(struct drm_file *file_priv,
575 				 struct vmw_fence_obj *fence,
576 				 struct drm_pending_event *event,
577 				 uint32_t *tv_sec,
578 				 uint32_t *tv_usec,
579 				 bool interruptible)
580 {
581 	struct vmw_event_fence_action *eaction;
582 	struct vmw_fence_manager *fman = fman_from_fence(fence);
583 
584 	eaction = kzalloc_obj(*eaction);
585 	if (unlikely(!eaction))
586 		return -ENOMEM;
587 
588 	eaction->event = event;
589 	eaction->dev = &fman->dev_priv->drm;
590 	eaction->tv_sec = tv_sec;
591 	eaction->tv_usec = tv_usec;
592 
593 	vmw_fence_obj_reference(fence); // Dropped in CB
594 	if (dma_fence_add_callback(&fence->base, &eaction->base,
595 				   vmw_event_fence_action_seq_passed) < 0)
596 		vmw_event_fence_action_seq_passed(&fence->base, &eaction->base);
597 	return 0;
598 }
599 
600 struct vmw_event_fence_pending {
601 	struct drm_pending_event base;
602 	struct drm_vmw_event_fence event;
603 };
604 
605 static int vmw_event_fence_action_create(struct drm_file *file_priv,
606 				  struct vmw_fence_obj *fence,
607 				  uint32_t flags,
608 				  uint64_t user_data,
609 				  bool interruptible)
610 {
611 	struct vmw_event_fence_pending *event;
612 	struct vmw_fence_manager *fman = fman_from_fence(fence);
613 	struct drm_device *dev = &fman->dev_priv->drm;
614 	int ret;
615 
616 	event = kzalloc_obj(*event);
617 	if (unlikely(!event)) {
618 		DRM_ERROR("Failed to allocate an event.\n");
619 		ret = -ENOMEM;
620 		goto out_no_space;
621 	}
622 
623 	event->event.base.type = DRM_VMW_EVENT_FENCE_SIGNALED;
624 	event->event.base.length = sizeof(event->event);
625 	event->event.user_data = user_data;
626 
627 	ret = drm_event_reserve_init(dev, file_priv, &event->base, &event->event.base);
628 
629 	if (unlikely(ret != 0)) {
630 		DRM_ERROR("Failed to allocate event space for this file.\n");
631 		kfree(event);
632 		goto out_no_space;
633 	}
634 
635 	if (flags & DRM_VMW_FE_FLAG_REQ_TIME)
636 		ret = vmw_event_fence_action_queue(file_priv, fence,
637 						   &event->base,
638 						   &event->event.tv_sec,
639 						   &event->event.tv_usec,
640 						   interruptible);
641 	else
642 		ret = vmw_event_fence_action_queue(file_priv, fence,
643 						   &event->base,
644 						   NULL,
645 						   NULL,
646 						   interruptible);
647 	if (ret != 0)
648 		goto out_no_queue;
649 
650 	return 0;
651 
652 out_no_queue:
653 	drm_event_cancel_free(dev, &event->base);
654 out_no_space:
655 	return ret;
656 }
657 
658 int vmw_fence_event_ioctl(struct drm_device *dev, void *data,
659 			  struct drm_file *file_priv)
660 {
661 	struct vmw_private *dev_priv = vmw_priv(dev);
662 	struct drm_vmw_fence_event_arg *arg =
663 		(struct drm_vmw_fence_event_arg *) data;
664 	struct vmw_fence_obj *fence = NULL;
665 	struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv);
666 	struct ttm_object_file *tfile = vmw_fp->tfile;
667 	struct drm_vmw_fence_rep __user *user_fence_rep =
668 		(struct drm_vmw_fence_rep __user *)(unsigned long)
669 		arg->fence_rep;
670 	uint32_t handle;
671 	int ret;
672 
673 	/*
674 	 * Look up an existing fence object,
675 	 * and if user-space wants a new reference,
676 	 * add one.
677 	 */
678 	if (arg->handle) {
679 		struct ttm_base_object *base =
680 			vmw_fence_obj_lookup(tfile, arg->handle);
681 
682 		if (IS_ERR(base))
683 			return PTR_ERR(base);
684 
685 		fence = &(container_of(base, struct vmw_user_fence,
686 				       base)->fence);
687 		(void) vmw_fence_obj_reference(fence);
688 
689 		if (user_fence_rep != NULL) {
690 			ret = ttm_ref_object_add(vmw_fp->tfile, base,
691 						 NULL, false);
692 			if (unlikely(ret != 0)) {
693 				DRM_ERROR("Failed to reference a fence "
694 					  "object.\n");
695 				goto out_no_ref_obj;
696 			}
697 			handle = base->handle;
698 		}
699 		ttm_base_object_unref(&base);
700 	}
701 
702 	/*
703 	 * Create a new fence object.
704 	 */
705 	if (!fence) {
706 		ret = vmw_execbuf_fence_commands(file_priv, dev_priv,
707 						 &fence,
708 						 (user_fence_rep) ?
709 						 &handle : NULL);
710 		if (unlikely(ret != 0)) {
711 			DRM_ERROR("Fence event failed to create fence.\n");
712 			return ret;
713 		}
714 	}
715 
716 	BUG_ON(fence == NULL);
717 
718 	ret = vmw_event_fence_action_create(file_priv, fence,
719 					    arg->flags,
720 					    arg->user_data,
721 					    true);
722 	if (unlikely(ret != 0)) {
723 		if (ret != -ERESTARTSYS)
724 			DRM_ERROR("Failed to attach event to fence.\n");
725 		goto out_no_create;
726 	}
727 
728 	vmw_execbuf_copy_fence_user(dev_priv, vmw_fp, 0, user_fence_rep, fence,
729 				    handle, -1);
730 	vmw_fence_obj_unreference(&fence);
731 	return 0;
732 out_no_create:
733 	if (user_fence_rep != NULL)
734 		ttm_ref_object_base_unref(tfile, handle);
735 out_no_ref_obj:
736 	vmw_fence_obj_unreference(&fence);
737 	return ret;
738 }
739