File Index
Files and directories
Sign in
FILE

vmwgfx_fence.c

File preview with syntax highlighting.

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