// SPDX-License-Identifier: GPL-2.0 OR MIT /************************************************************************** * * Copyright (c) 2009-2025 Broadcom. All Rights Reserved. The term * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
**************************************************************************/
/** * struct vmw_event_fence_action - fence callback that delivers a DRM event. * * @base: For use with dma_fence_add_callback(...) * @event: A pointer to the pending event. * @dev: Pointer to a struct drm_device so we can access the event stuff. * @tv_sec: If non-null, the variable pointed to will be assigned * current time tv_sec val when the fence signals. * @tv_usec: Must be set if @tv_sec is set, and the variable pointed to will * be assigned the current time tv_usec val when the fence signals.
*/ struct vmw_event_fence_action { struct dma_fence_cb base;
if (!list_empty(&fence->head)) { /* The fence manager still has an implicit reference to this * fence via the fence list if head is set. Because the lock is * required to be held when the fence manager updates the fence * list either the fence will have been removed after we get * the lock below or we can safely remove it and the fence * manager will never see it. This implies the fence is being * deleted without being signaled which is dubious but valid * if there are no callbacks. The dma_fence code that calls * this hook will warn about deleted unsignaled with callbacks * so no need to warn again here.
*/
spin_lock(&fman->lock);
list_del_init(&fence->head); if (fence->waiter_added)
vmw_seqno_waiter_remove(fman->dev_priv);
spin_unlock(&fman->lock);
}
fence->destroy(fence);
}
/* When we toggle signaling for the SVGA device there is a race period from * the time we first read the fence seqno to the time we enable interrupts. * If we miss the interrupt for a fence during this period its likely the driver * will stall. As a result we need to re-read the seqno after interrupts are * enabled. If interrupts were already enabled we just increment the number of * seqno waiters.
*/ staticbool vmw_fence_enable_signaling(struct dma_fence *f)
{
u32 seqno; struct vmw_fence_obj *fence =
container_of(f, struct vmw_fence_obj, base);
spin_lock(&fman->lock); if (unlikely(fman->fifo_down)) {
ret = -EBUSY; goto out_unlock;
} /* This creates an implicit reference to the fence from the fence * manager. It will be dropped when the fence is signaled which is * expected to happen before deletion. The dtor has code to catch * the rare deletion before signaling case.
*/
list_add_tail(&fence->head, &fman->fence_list);
/** * vmw_fence_obj_lookup - Look up a user-space fence object * * @tfile: A struct ttm_object_file identifying the caller. * @handle: A handle identifying the fence object. * @return: A struct vmw_user_fence base ttm object on success or * an error pointer on failure. * * The fence object is looked up and type-checked. The caller needs * to have opened the fence object first, but since that happens on * creation and fence objects aren't shareable, that's not an * issue currently.
*/ staticstruct ttm_base_object *
vmw_fence_obj_lookup(struct ttm_object_file *tfile, u32 handle)
{ struct ttm_base_object *base = ttm_base_object_lookup(tfile, handle);
/** * vmw_event_fence_action_seq_passed * * @action: The struct vmw_fence_action embedded in a struct * vmw_event_fence_action. * * This function is called when the seqno of the fence where @action is * attached has passed. It queues the event on the submitter's event list. * This function is always called from atomic context.
*/ staticvoid vmw_event_fence_action_seq_passed(struct dma_fence *f, struct dma_fence_cb *cb)
{ struct vmw_event_fence_action *eaction =
container_of(cb, struct vmw_event_fence_action, base); struct drm_device *dev = eaction->dev; struct drm_pending_event *event = eaction->event;
if (unlikely(event == NULL)) return;
spin_lock_irq(&dev->event_lock);
if (likely(eaction->tv_sec != NULL)) { struct timespec64 ts;
ts = ktime_to_timespec64(f->timestamp); /* monotonic time, so no y2038 overflow */
*eaction->tv_sec = ts.tv_sec;
*eaction->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
}
/** * vmw_event_fence_action_queue - Post an event for sending when a fence * object seqno has passed. * * @file_priv: The file connection on which the event should be posted. * @fence: The fence object on which to post the event. * @event: Event to be posted. This event should've been alloced * using k[mz]alloc, and should've been completely initialized. * @tv_sec: If non-null, the variable pointed to will be assigned * current time tv_sec val when the fence signals. * @tv_usec: Must be set if @tv_sec is set, and the variable pointed to will * be assigned the current time tv_usec val when the fence signals. * @interruptible: Interruptible waits if possible. * * As a side effect, the object pointed to by @event may have been * freed when this function returns. If this function returns with * an error code, the caller needs to free that object.
*/
/* * Look up an existing fence object, * and if user-space wants a new reference, * add one.
*/ if (arg->handle) { struct ttm_base_object *base =
vmw_fence_obj_lookup(tfile, arg->handle);
if (user_fence_rep != NULL) {
ret = ttm_ref_object_add(vmw_fp->tfile, base,
NULL, false); if (unlikely(ret != 0)) {
DRM_ERROR("Failed to reference a fence " "object.\n"); goto out_no_ref_obj;
}
handle = base->handle;
}
ttm_base_object_unref(&base);
}
/* * Create a new fence object.
*/ if (!fence) {
ret = vmw_execbuf_fence_commands(file_priv, dev_priv,
&fence,
(user_fence_rep) ?
&handle : NULL); if (unlikely(ret != 0)) {
DRM_ERROR("Fence event failed to create fence.\n"); return ret;
}
}
BUG_ON(fence == NULL);
ret = vmw_event_fence_action_create(file_priv, fence,
arg->flags,
arg->user_data, true); if (unlikely(ret != 0)) { if (ret != -ERESTARTSYS)
DRM_ERROR("Failed to attach event to fence.\n"); goto out_no_create;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.