13d0407baSopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 23d0407baSopenharmony_ci/* 33d0407baSopenharmony_ci * Fence mechanism for dma-buf to allow for asynchronous dma access 43d0407baSopenharmony_ci * 53d0407baSopenharmony_ci * Copyright (C) 2012 Canonical Ltd 63d0407baSopenharmony_ci * Copyright (C) 2012 Texas Instruments 73d0407baSopenharmony_ci * 83d0407baSopenharmony_ci * Authors: 93d0407baSopenharmony_ci * Rob Clark <robdclark@gmail.com> 103d0407baSopenharmony_ci * Maarten Lankhorst <maarten.lankhorst@canonical.com> 113d0407baSopenharmony_ci */ 123d0407baSopenharmony_ci 133d0407baSopenharmony_ci#ifndef __LINUX_DMA_FENCE_H 143d0407baSopenharmony_ci#define __LINUX_DMA_FENCE_H 153d0407baSopenharmony_ci 163d0407baSopenharmony_ci#include <linux/err.h> 173d0407baSopenharmony_ci#include <linux/wait.h> 183d0407baSopenharmony_ci#include <linux/list.h> 193d0407baSopenharmony_ci#include <linux/bitops.h> 203d0407baSopenharmony_ci#include <linux/kref.h> 213d0407baSopenharmony_ci#include <linux/sched.h> 223d0407baSopenharmony_ci#include <linux/printk.h> 233d0407baSopenharmony_ci#include <linux/rcupdate.h> 243d0407baSopenharmony_ci 253d0407baSopenharmony_cistruct dma_fence; 263d0407baSopenharmony_cistruct dma_fence_ops; 273d0407baSopenharmony_cistruct dma_fence_cb; 283d0407baSopenharmony_ci 293d0407baSopenharmony_ci/** 303d0407baSopenharmony_ci * struct dma_fence - software synchronization primitive 313d0407baSopenharmony_ci * @refcount: refcount for this fence 323d0407baSopenharmony_ci * @ops: dma_fence_ops associated with this fence 333d0407baSopenharmony_ci * @rcu: used for releasing fence with kfree_rcu 343d0407baSopenharmony_ci * @cb_list: list of all callbacks to call 353d0407baSopenharmony_ci * @lock: spin_lock_irqsave used for locking 363d0407baSopenharmony_ci * @context: execution context this fence belongs to, returned by 373d0407baSopenharmony_ci * dma_fence_context_alloc() 383d0407baSopenharmony_ci * @seqno: the sequence number of this fence inside the execution context, 393d0407baSopenharmony_ci * can be compared to decide which fence would be signaled later. 403d0407baSopenharmony_ci * @flags: A mask of DMA_FENCE_FLAG_* defined below 413d0407baSopenharmony_ci * @timestamp: Timestamp when the fence was signaled. 423d0407baSopenharmony_ci * @error: Optional, only valid if < 0, must be set before calling 433d0407baSopenharmony_ci * dma_fence_signal, indicates that the fence has completed with an error. 443d0407baSopenharmony_ci * 453d0407baSopenharmony_ci * the flags member must be manipulated and read using the appropriate 463d0407baSopenharmony_ci * atomic ops (bit_*), so taking the spinlock will not be needed most 473d0407baSopenharmony_ci * of the time. 483d0407baSopenharmony_ci * 493d0407baSopenharmony_ci * DMA_FENCE_FLAG_SIGNALED_BIT - fence is already signaled 503d0407baSopenharmony_ci * DMA_FENCE_FLAG_TIMESTAMP_BIT - timestamp recorded for fence signaling 513d0407baSopenharmony_ci * DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT - enable_signaling might have been called 523d0407baSopenharmony_ci * DMA_FENCE_FLAG_USER_BITS - start of the unused bits, can be used by the 533d0407baSopenharmony_ci * implementer of the fence for its own purposes. Can be used in different 543d0407baSopenharmony_ci * ways by different fence implementers, so do not rely on this. 553d0407baSopenharmony_ci * 563d0407baSopenharmony_ci * Since atomic bitops are used, this is not guaranteed to be the case. 573d0407baSopenharmony_ci * Particularly, if the bit was set, but dma_fence_signal was called right 583d0407baSopenharmony_ci * before this bit was set, it would have been able to set the 593d0407baSopenharmony_ci * DMA_FENCE_FLAG_SIGNALED_BIT, before enable_signaling was called. 603d0407baSopenharmony_ci * Adding a check for DMA_FENCE_FLAG_SIGNALED_BIT after setting 613d0407baSopenharmony_ci * DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT closes this race, and makes sure that 623d0407baSopenharmony_ci * after dma_fence_signal was called, any enable_signaling call will have either 633d0407baSopenharmony_ci * been completed, or never called at all. 643d0407baSopenharmony_ci */ 653d0407baSopenharmony_cistruct dma_fence { 663d0407baSopenharmony_ci spinlock_t *lock; 673d0407baSopenharmony_ci const struct dma_fence_ops *ops; 683d0407baSopenharmony_ci /* 693d0407baSopenharmony_ci * We clear the callback list on kref_put so that by the time we 703d0407baSopenharmony_ci * release the fence it is unused. No one should be adding to the 713d0407baSopenharmony_ci * cb_list that they don't themselves hold a reference for. 723d0407baSopenharmony_ci * 733d0407baSopenharmony_ci * The lifetime of the timestamp is similarly tied to both the 743d0407baSopenharmony_ci * rcu freelist and the cb_list. The timestamp is only set upon 753d0407baSopenharmony_ci * signaling while simultaneously notifying the cb_list. Ergo, we 763d0407baSopenharmony_ci * only use either the cb_list of timestamp. Upon destruction, 773d0407baSopenharmony_ci * neither are accessible, and so we can use the rcu. This means 783d0407baSopenharmony_ci * that the cb_list is *only* valid until the signal bit is set, 793d0407baSopenharmony_ci * and to read either you *must* hold a reference to the fence, 803d0407baSopenharmony_ci * and not just the rcu_read_lock. 813d0407baSopenharmony_ci * 823d0407baSopenharmony_ci * Listed in chronological order. 833d0407baSopenharmony_ci */ 843d0407baSopenharmony_ci union { 853d0407baSopenharmony_ci struct list_head cb_list; 863d0407baSopenharmony_ci /* @cb_list replaced by @timestamp on dma_fence_signal() */ 873d0407baSopenharmony_ci ktime_t timestamp; 883d0407baSopenharmony_ci /* @timestamp replaced by @rcu on dma_fence_release() */ 893d0407baSopenharmony_ci struct rcu_head rcu; 903d0407baSopenharmony_ci }; 913d0407baSopenharmony_ci u64 context; 923d0407baSopenharmony_ci u64 seqno; 933d0407baSopenharmony_ci unsigned long flags; 943d0407baSopenharmony_ci struct kref refcount; 953d0407baSopenharmony_ci int error; 963d0407baSopenharmony_ci}; 973d0407baSopenharmony_ci 983d0407baSopenharmony_cienum dma_fence_flag_bits { 993d0407baSopenharmony_ci DMA_FENCE_FLAG_SIGNALED_BIT, 1003d0407baSopenharmony_ci DMA_FENCE_FLAG_TIMESTAMP_BIT, 1013d0407baSopenharmony_ci DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, 1023d0407baSopenharmony_ci DMA_FENCE_FLAG_USER_BITS, /* must always be last member */ 1033d0407baSopenharmony_ci}; 1043d0407baSopenharmony_ci 1053d0407baSopenharmony_citypedef void (*dma_fence_func_t)(struct dma_fence *fence, struct dma_fence_cb *cb); 1063d0407baSopenharmony_ci 1073d0407baSopenharmony_ci/** 1083d0407baSopenharmony_ci * struct dma_fence_cb - callback for dma_fence_add_callback() 1093d0407baSopenharmony_ci * @node: used by dma_fence_add_callback() to append this struct to fence::cb_list 1103d0407baSopenharmony_ci * @func: dma_fence_func_t to call 1113d0407baSopenharmony_ci * 1123d0407baSopenharmony_ci * This struct will be initialized by dma_fence_add_callback(), additional 1133d0407baSopenharmony_ci * data can be passed along by embedding dma_fence_cb in another struct. 1143d0407baSopenharmony_ci */ 1153d0407baSopenharmony_cistruct dma_fence_cb { 1163d0407baSopenharmony_ci struct list_head node; 1173d0407baSopenharmony_ci dma_fence_func_t func; 1183d0407baSopenharmony_ci}; 1193d0407baSopenharmony_ci 1203d0407baSopenharmony_ci/** 1213d0407baSopenharmony_ci * struct dma_fence_ops - operations implemented for fence 1223d0407baSopenharmony_ci * 1233d0407baSopenharmony_ci */ 1243d0407baSopenharmony_cistruct dma_fence_ops { 1253d0407baSopenharmony_ci /** 1263d0407baSopenharmony_ci * @use_64bit_seqno: 1273d0407baSopenharmony_ci * 1283d0407baSopenharmony_ci * True if this dma_fence implementation uses 64bit seqno, false 1293d0407baSopenharmony_ci * otherwise. 1303d0407baSopenharmony_ci */ 1313d0407baSopenharmony_ci bool use_64bit_seqno; 1323d0407baSopenharmony_ci 1333d0407baSopenharmony_ci /** 1343d0407baSopenharmony_ci * @get_driver_name 1353d0407baSopenharmony_ci * 1363d0407baSopenharmony_ci * Returns the driver name. This is a callback to allow drivers to 1373d0407baSopenharmony_ci * compute the name at runtime, without having it to store permanently 1383d0407baSopenharmony_ci * for each fence, or build a cache of some sort. 1393d0407baSopenharmony_ci * 1403d0407baSopenharmony_ci * This callback is mandatory. 1413d0407baSopenharmony_ci */ 1423d0407baSopenharmony_ci const char *(*get_driver_name)(struct dma_fence *fence); 1433d0407baSopenharmony_ci 1443d0407baSopenharmony_ci /** 1453d0407baSopenharmony_ci * @get_timeline_name 1463d0407baSopenharmony_ci * 1473d0407baSopenharmony_ci * Return the name of the context this fence belongs to. This is a 1483d0407baSopenharmony_ci * callback to allow drivers to compute the name at runtime, without 1493d0407baSopenharmony_ci * having it to store permanently for each fence, or build a cache of 1503d0407baSopenharmony_ci * some sort. 1513d0407baSopenharmony_ci * 1523d0407baSopenharmony_ci * This callback is mandatory. 1533d0407baSopenharmony_ci */ 1543d0407baSopenharmony_ci const char *(*get_timeline_name)(struct dma_fence *fence); 1553d0407baSopenharmony_ci 1563d0407baSopenharmony_ci /** 1573d0407baSopenharmony_ci * @enable_signaling 1583d0407baSopenharmony_ci * 1593d0407baSopenharmony_ci * Enable software signaling of fence. 1603d0407baSopenharmony_ci * 1613d0407baSopenharmony_ci * For fence implementations that have the capability for hw->hw 1623d0407baSopenharmony_ci * signaling, they can implement this op to enable the necessary 1633d0407baSopenharmony_ci * interrupts, or insert commands into cmdstream, etc, to avoid these 1643d0407baSopenharmony_ci * costly operations for the common case where only hw->hw 1653d0407baSopenharmony_ci * synchronization is required. This is called in the first 1663d0407baSopenharmony_ci * dma_fence_wait() or dma_fence_add_callback() path to let the fence 1673d0407baSopenharmony_ci * implementation know that there is another driver waiting on the 1683d0407baSopenharmony_ci * signal (ie. hw->sw case). 1693d0407baSopenharmony_ci * 1703d0407baSopenharmony_ci * This function can be called from atomic context, but not 1713d0407baSopenharmony_ci * from irq context, so normal spinlocks can be used. 1723d0407baSopenharmony_ci * 1733d0407baSopenharmony_ci * A return value of false indicates the fence already passed, 1743d0407baSopenharmony_ci * or some failure occurred that made it impossible to enable 1753d0407baSopenharmony_ci * signaling. True indicates successful enabling. 1763d0407baSopenharmony_ci * 1773d0407baSopenharmony_ci * &dma_fence.error may be set in enable_signaling, but only when false 1783d0407baSopenharmony_ci * is returned. 1793d0407baSopenharmony_ci * 1803d0407baSopenharmony_ci * Since many implementations can call dma_fence_signal() even when before 1813d0407baSopenharmony_ci * @enable_signaling has been called there's a race window, where the 1823d0407baSopenharmony_ci * dma_fence_signal() might result in the final fence reference being 1833d0407baSopenharmony_ci * released and its memory freed. To avoid this, implementations of this 1843d0407baSopenharmony_ci * callback should grab their own reference using dma_fence_get(), to be 1853d0407baSopenharmony_ci * released when the fence is signalled (through e.g. the interrupt 1863d0407baSopenharmony_ci * handler). 1873d0407baSopenharmony_ci * 1883d0407baSopenharmony_ci * This callback is optional. If this callback is not present, then the 1893d0407baSopenharmony_ci * driver must always have signaling enabled. 1903d0407baSopenharmony_ci */ 1913d0407baSopenharmony_ci bool (*enable_signaling)(struct dma_fence *fence); 1923d0407baSopenharmony_ci 1933d0407baSopenharmony_ci /** 1943d0407baSopenharmony_ci * @signaled 1953d0407baSopenharmony_ci * 1963d0407baSopenharmony_ci * Peek whether the fence is signaled, as a fastpath optimization for 1973d0407baSopenharmony_ci * e.g. dma_fence_wait() or dma_fence_add_callback(). Note that this 1983d0407baSopenharmony_ci * callback does not need to make any guarantees beyond that a fence 1993d0407baSopenharmony_ci * once indicates as signalled must always return true from this 2003d0407baSopenharmony_ci * callback. This callback may return false even if the fence has 2013d0407baSopenharmony_ci * completed already, in this case information hasn't propogated throug 2023d0407baSopenharmony_ci * the system yet. See also dma_fence_is_signaled(). 2033d0407baSopenharmony_ci * 2043d0407baSopenharmony_ci * May set &dma_fence.error if returning true. 2053d0407baSopenharmony_ci * 2063d0407baSopenharmony_ci * This callback is optional. 2073d0407baSopenharmony_ci */ 2083d0407baSopenharmony_ci bool (*signaled)(struct dma_fence *fence); 2093d0407baSopenharmony_ci 2103d0407baSopenharmony_ci /** 2113d0407baSopenharmony_ci * @wait 2123d0407baSopenharmony_ci * 2133d0407baSopenharmony_ci * Custom wait implementation, defaults to dma_fence_default_wait() if 2143d0407baSopenharmony_ci * not set. 2153d0407baSopenharmony_ci * 2163d0407baSopenharmony_ci * The dma_fence_default_wait implementation should work for any fence, as long 2173d0407baSopenharmony_ci * as @enable_signaling works correctly. This hook allows drivers to 2183d0407baSopenharmony_ci * have an optimized version for the case where a process context is 2193d0407baSopenharmony_ci * already available, e.g. if @enable_signaling for the general case 2203d0407baSopenharmony_ci * needs to set up a worker thread. 2213d0407baSopenharmony_ci * 2223d0407baSopenharmony_ci * Must return -ERESTARTSYS if the wait is intr = true and the wait was 2233d0407baSopenharmony_ci * interrupted, and remaining jiffies if fence has signaled, or 0 if wait 2243d0407baSopenharmony_ci * timed out. Can also return other error values on custom implementations, 2253d0407baSopenharmony_ci * which should be treated as if the fence is signaled. For example a hardware 2263d0407baSopenharmony_ci * lockup could be reported like that. 2273d0407baSopenharmony_ci * 2283d0407baSopenharmony_ci * This callback is optional. 2293d0407baSopenharmony_ci */ 2303d0407baSopenharmony_ci signed long (*wait)(struct dma_fence *fence, bool intr, signed long timeout); 2313d0407baSopenharmony_ci 2323d0407baSopenharmony_ci /** 2333d0407baSopenharmony_ci * @release 2343d0407baSopenharmony_ci * 2353d0407baSopenharmony_ci * Called on destruction of fence to release additional resources. 2363d0407baSopenharmony_ci * Can be called from irq context. This callback is optional. If it is 2373d0407baSopenharmony_ci * NULL, then dma_fence_free() is instead called as the default 2383d0407baSopenharmony_ci * implementation. 2393d0407baSopenharmony_ci */ 2403d0407baSopenharmony_ci void (*release)(struct dma_fence *fence); 2413d0407baSopenharmony_ci 2423d0407baSopenharmony_ci /** 2433d0407baSopenharmony_ci * @fence_value_str 2443d0407baSopenharmony_ci * 2453d0407baSopenharmony_ci * Callback to fill in free-form debug info specific to this fence, like 2463d0407baSopenharmony_ci * the sequence number. 2473d0407baSopenharmony_ci * 2483d0407baSopenharmony_ci * This callback is optional. 2493d0407baSopenharmony_ci */ 2503d0407baSopenharmony_ci void (*fence_value_str)(struct dma_fence *fence, char *str, int size); 2513d0407baSopenharmony_ci 2523d0407baSopenharmony_ci /** 2533d0407baSopenharmony_ci * @timeline_value_str 2543d0407baSopenharmony_ci * 2553d0407baSopenharmony_ci * Fills in the current value of the timeline as a string, like the 2563d0407baSopenharmony_ci * sequence number. Note that the specific fence passed to this function 2573d0407baSopenharmony_ci * should not matter, drivers should only use it to look up the 2583d0407baSopenharmony_ci * corresponding timeline structures. 2593d0407baSopenharmony_ci */ 2603d0407baSopenharmony_ci void (*timeline_value_str)(struct dma_fence *fence, char *str, int size); 2613d0407baSopenharmony_ci}; 2623d0407baSopenharmony_ci 2633d0407baSopenharmony_civoid dma_fence_init(struct dma_fence *fence, const struct dma_fence_ops *ops, spinlock_t *lock, u64 context, u64 seqno); 2643d0407baSopenharmony_ci 2653d0407baSopenharmony_civoid dma_fence_release(struct kref *kref); 2663d0407baSopenharmony_civoid dma_fence_free(struct dma_fence *fence); 2673d0407baSopenharmony_ci 2683d0407baSopenharmony_ci/** 2693d0407baSopenharmony_ci * dma_fence_put - decreases refcount of the fence 2703d0407baSopenharmony_ci * @fence: fence to reduce refcount of 2713d0407baSopenharmony_ci */ 2723d0407baSopenharmony_cistatic inline void dma_fence_put(struct dma_fence *fence) 2733d0407baSopenharmony_ci{ 2743d0407baSopenharmony_ci if (fence) { 2753d0407baSopenharmony_ci kref_put(&fence->refcount, dma_fence_release); 2763d0407baSopenharmony_ci } 2773d0407baSopenharmony_ci} 2783d0407baSopenharmony_ci 2793d0407baSopenharmony_ci/** 2803d0407baSopenharmony_ci * dma_fence_get - increases refcount of the fence 2813d0407baSopenharmony_ci * @fence: fence to increase refcount of 2823d0407baSopenharmony_ci * 2833d0407baSopenharmony_ci * Returns the same fence, with refcount increased by 1. 2843d0407baSopenharmony_ci */ 2853d0407baSopenharmony_cistatic inline struct dma_fence *dma_fence_get(struct dma_fence *fence) 2863d0407baSopenharmony_ci{ 2873d0407baSopenharmony_ci if (fence) { 2883d0407baSopenharmony_ci kref_get(&fence->refcount); 2893d0407baSopenharmony_ci } 2903d0407baSopenharmony_ci return fence; 2913d0407baSopenharmony_ci} 2923d0407baSopenharmony_ci 2933d0407baSopenharmony_ci/** 2943d0407baSopenharmony_ci * dma_fence_get_rcu - get a fence from a dma_resv_list with 2953d0407baSopenharmony_ci * rcu read lock 2963d0407baSopenharmony_ci * @fence: fence to increase refcount of 2973d0407baSopenharmony_ci * 2983d0407baSopenharmony_ci * Function returns NULL if no refcount could be obtained, or the fence. 2993d0407baSopenharmony_ci */ 3003d0407baSopenharmony_cistatic inline struct dma_fence *dma_fence_get_rcu(struct dma_fence *fence) 3013d0407baSopenharmony_ci{ 3023d0407baSopenharmony_ci if (kref_get_unless_zero(&fence->refcount)) { 3033d0407baSopenharmony_ci return fence; 3043d0407baSopenharmony_ci } else { 3053d0407baSopenharmony_ci return NULL; 3063d0407baSopenharmony_ci } 3073d0407baSopenharmony_ci} 3083d0407baSopenharmony_ci 3093d0407baSopenharmony_ci/** 3103d0407baSopenharmony_ci * dma_fence_get_rcu_safe - acquire a reference to an RCU tracked fence 3113d0407baSopenharmony_ci * @fencep: pointer to fence to increase refcount of 3123d0407baSopenharmony_ci * 3133d0407baSopenharmony_ci * Function returns NULL if no refcount could be obtained, or the fence. 3143d0407baSopenharmony_ci * This function handles acquiring a reference to a fence that may be 3153d0407baSopenharmony_ci * reallocated within the RCU grace period (such as with SLAB_TYPESAFE_BY_RCU), 3163d0407baSopenharmony_ci * so long as the caller is using RCU on the pointer to the fence. 3173d0407baSopenharmony_ci * 3183d0407baSopenharmony_ci * An alternative mechanism is to employ a seqlock to protect a bunch of 3193d0407baSopenharmony_ci * fences, such as used by struct dma_resv. When using a seqlock, 3203d0407baSopenharmony_ci * the seqlock must be taken before and checked after a reference to the 3213d0407baSopenharmony_ci * fence is acquired (as shown here). 3223d0407baSopenharmony_ci * 3233d0407baSopenharmony_ci * The caller is required to hold the RCU read lock. 3243d0407baSopenharmony_ci */ 3253d0407baSopenharmony_cistatic inline struct dma_fence *dma_fence_get_rcu_safe(struct dma_fence __rcu **fencep) 3263d0407baSopenharmony_ci{ 3273d0407baSopenharmony_ci do { 3283d0407baSopenharmony_ci struct dma_fence *fence; 3293d0407baSopenharmony_ci 3303d0407baSopenharmony_ci fence = rcu_dereference(*fencep); 3313d0407baSopenharmony_ci if (!fence) { 3323d0407baSopenharmony_ci return NULL; 3333d0407baSopenharmony_ci } 3343d0407baSopenharmony_ci 3353d0407baSopenharmony_ci if (!dma_fence_get_rcu(fence)) { 3363d0407baSopenharmony_ci continue; 3373d0407baSopenharmony_ci } 3383d0407baSopenharmony_ci 3393d0407baSopenharmony_ci /* The atomic_inc_not_zero() inside dma_fence_get_rcu() 3403d0407baSopenharmony_ci * provides a full memory barrier upon success (such as now). 3413d0407baSopenharmony_ci * This is paired with the write barrier from assigning 3423d0407baSopenharmony_ci * to the __rcu protected fence pointer so that if that 3433d0407baSopenharmony_ci * pointer still matches the current fence, we know we 3443d0407baSopenharmony_ci * have successfully acquire a reference to it. If it no 3453d0407baSopenharmony_ci * longer matches, we are holding a reference to some other 3463d0407baSopenharmony_ci * reallocated pointer. This is possible if the allocator 3473d0407baSopenharmony_ci * is using a freelist like SLAB_TYPESAFE_BY_RCU where the 3483d0407baSopenharmony_ci * fence remains valid for the RCU grace period, but it 3493d0407baSopenharmony_ci * may be reallocated. When using such allocators, we are 3503d0407baSopenharmony_ci * responsible for ensuring the reference we get is to 3513d0407baSopenharmony_ci * the right fence, as below. 3523d0407baSopenharmony_ci */ 3533d0407baSopenharmony_ci if (fence == rcu_access_pointer(*fencep)) { 3543d0407baSopenharmony_ci return rcu_pointer_handoff(fence); 3553d0407baSopenharmony_ci } 3563d0407baSopenharmony_ci 3573d0407baSopenharmony_ci dma_fence_put(fence); 3583d0407baSopenharmony_ci } while (1); 3593d0407baSopenharmony_ci} 3603d0407baSopenharmony_ci 3613d0407baSopenharmony_ci#ifdef CONFIG_LOCKDEP 3623d0407baSopenharmony_cibool dma_fence_begin_signalling(void); 3633d0407baSopenharmony_civoid dma_fence_end_signalling(bool cookie); 3643d0407baSopenharmony_civoid _dma_fence_might_wait(void); 3653d0407baSopenharmony_ci#else 3663d0407baSopenharmony_cistatic inline bool dma_fence_begin_signalling(void) 3673d0407baSopenharmony_ci{ 3683d0407baSopenharmony_ci return true; 3693d0407baSopenharmony_ci} 3703d0407baSopenharmony_cistatic inline void dma_fence_end_signalling(bool cookie) 3713d0407baSopenharmony_ci{ 3723d0407baSopenharmony_ci} 3733d0407baSopenharmony_cistatic inline void _dma_fence_might_wait(void) 3743d0407baSopenharmony_ci{ 3753d0407baSopenharmony_ci} 3763d0407baSopenharmony_ci#endif 3773d0407baSopenharmony_ci 3783d0407baSopenharmony_ciint dma_fence_signal(struct dma_fence *fence); 3793d0407baSopenharmony_ciint dma_fence_signal_locked(struct dma_fence *fence); 3803d0407baSopenharmony_ciint dma_fence_signal_timestamp(struct dma_fence *fence, ktime_t timestamp); 3813d0407baSopenharmony_ciint dma_fence_signal_timestamp_locked(struct dma_fence *fence, ktime_t timestamp); 3823d0407baSopenharmony_cisigned long dma_fence_default_wait(struct dma_fence *fence, bool intr, signed long timeout); 3833d0407baSopenharmony_ciint dma_fence_add_callback(struct dma_fence *fence, struct dma_fence_cb *cb, dma_fence_func_t func); 3843d0407baSopenharmony_cibool dma_fence_remove_callback(struct dma_fence *fence, struct dma_fence_cb *cb); 3853d0407baSopenharmony_civoid dma_fence_enable_sw_signaling(struct dma_fence *fence); 3863d0407baSopenharmony_ci 3873d0407baSopenharmony_ci/** 3883d0407baSopenharmony_ci * dma_fence_is_signaled_locked - Return an indication if the fence 3893d0407baSopenharmony_ci * is signaled yet. 3903d0407baSopenharmony_ci * @fence: the fence to check 3913d0407baSopenharmony_ci * 3923d0407baSopenharmony_ci * Returns true if the fence was already signaled, false if not. Since this 3933d0407baSopenharmony_ci * function doesn't enable signaling, it is not guaranteed to ever return 3943d0407baSopenharmony_ci * true if dma_fence_add_callback(), dma_fence_wait() or 3953d0407baSopenharmony_ci * dma_fence_enable_sw_signaling() haven't been called before. 3963d0407baSopenharmony_ci * 3973d0407baSopenharmony_ci * This function requires &dma_fence.lock to be held. 3983d0407baSopenharmony_ci * 3993d0407baSopenharmony_ci * See also dma_fence_is_signaled(). 4003d0407baSopenharmony_ci */ 4013d0407baSopenharmony_cistatic inline bool dma_fence_is_signaled_locked(struct dma_fence *fence) 4023d0407baSopenharmony_ci{ 4033d0407baSopenharmony_ci if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) { 4043d0407baSopenharmony_ci return true; 4053d0407baSopenharmony_ci } 4063d0407baSopenharmony_ci 4073d0407baSopenharmony_ci if (fence->ops->signaled && fence->ops->signaled(fence)) { 4083d0407baSopenharmony_ci dma_fence_signal_locked(fence); 4093d0407baSopenharmony_ci return true; 4103d0407baSopenharmony_ci } 4113d0407baSopenharmony_ci 4123d0407baSopenharmony_ci return false; 4133d0407baSopenharmony_ci} 4143d0407baSopenharmony_ci 4153d0407baSopenharmony_ci/** 4163d0407baSopenharmony_ci * dma_fence_is_signaled - Return an indication if the fence is signaled yet. 4173d0407baSopenharmony_ci * @fence: the fence to check 4183d0407baSopenharmony_ci * 4193d0407baSopenharmony_ci * Returns true if the fence was already signaled, false if not. Since this 4203d0407baSopenharmony_ci * function doesn't enable signaling, it is not guaranteed to ever return 4213d0407baSopenharmony_ci * true if dma_fence_add_callback(), dma_fence_wait() or 4223d0407baSopenharmony_ci * dma_fence_enable_sw_signaling() haven't been called before. 4233d0407baSopenharmony_ci * 4243d0407baSopenharmony_ci * It's recommended for seqno fences to call dma_fence_signal when the 4253d0407baSopenharmony_ci * operation is complete, it makes it possible to prevent issues from 4263d0407baSopenharmony_ci * wraparound between time of issue and time of use by checking the return 4273d0407baSopenharmony_ci * value of this function before calling hardware-specific wait instructions. 4283d0407baSopenharmony_ci * 4293d0407baSopenharmony_ci * See also dma_fence_is_signaled_locked(). 4303d0407baSopenharmony_ci */ 4313d0407baSopenharmony_cistatic inline bool dma_fence_is_signaled(struct dma_fence *fence) 4323d0407baSopenharmony_ci{ 4333d0407baSopenharmony_ci if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) { 4343d0407baSopenharmony_ci return true; 4353d0407baSopenharmony_ci } 4363d0407baSopenharmony_ci 4373d0407baSopenharmony_ci if (fence->ops->signaled && fence->ops->signaled(fence)) { 4383d0407baSopenharmony_ci dma_fence_signal(fence); 4393d0407baSopenharmony_ci return true; 4403d0407baSopenharmony_ci } 4413d0407baSopenharmony_ci 4423d0407baSopenharmony_ci return false; 4433d0407baSopenharmony_ci} 4443d0407baSopenharmony_ci 4453d0407baSopenharmony_ci/** 4463d0407baSopenharmony_ci * __dma_fence_is_later - return if f1 is chronologically later than f2 4473d0407baSopenharmony_ci * @f1: the first fence's seqno 4483d0407baSopenharmony_ci * @f2: the second fence's seqno from the same context 4493d0407baSopenharmony_ci * @ops: dma_fence_ops associated with the seqno 4503d0407baSopenharmony_ci * 4513d0407baSopenharmony_ci * Returns true if f1 is chronologically later than f2. Both fences must be 4523d0407baSopenharmony_ci * from the same context, since a seqno is not common across contexts. 4533d0407baSopenharmony_ci */ 4543d0407baSopenharmony_cistatic inline bool __dma_fence_is_later(u64 f1, u64 f2, const struct dma_fence_ops *ops) 4553d0407baSopenharmony_ci{ 4563d0407baSopenharmony_ci /* This is for backward compatibility with drivers which can only handle 4573d0407baSopenharmony_ci * 32bit sequence numbers. Use a 64bit compare when the driver says to 4583d0407baSopenharmony_ci * do so. 4593d0407baSopenharmony_ci */ 4603d0407baSopenharmony_ci if (ops->use_64bit_seqno) { 4613d0407baSopenharmony_ci return f1 > f2; 4623d0407baSopenharmony_ci } 4633d0407baSopenharmony_ci 4643d0407baSopenharmony_ci return (int)(lower_32_bits(f1) - lower_32_bits(f2)) > 0; 4653d0407baSopenharmony_ci} 4663d0407baSopenharmony_ci 4673d0407baSopenharmony_ci/** 4683d0407baSopenharmony_ci * dma_fence_is_later - return if f1 is chronologically later than f2 4693d0407baSopenharmony_ci * @f1: the first fence from the same context 4703d0407baSopenharmony_ci * @f2: the second fence from the same context 4713d0407baSopenharmony_ci * 4723d0407baSopenharmony_ci * Returns true if f1 is chronologically later than f2. Both fences must be 4733d0407baSopenharmony_ci * from the same context, since a seqno is not re-used across contexts. 4743d0407baSopenharmony_ci */ 4753d0407baSopenharmony_cistatic inline bool dma_fence_is_later(struct dma_fence *f1, struct dma_fence *f2) 4763d0407baSopenharmony_ci{ 4773d0407baSopenharmony_ci if (WARN_ON(f1->context != f2->context)) { 4783d0407baSopenharmony_ci return false; 4793d0407baSopenharmony_ci } 4803d0407baSopenharmony_ci 4813d0407baSopenharmony_ci return __dma_fence_is_later(f1->seqno, f2->seqno, f1->ops); 4823d0407baSopenharmony_ci} 4833d0407baSopenharmony_ci 4843d0407baSopenharmony_ci/** 4853d0407baSopenharmony_ci * dma_fence_later - return the chronologically later fence 4863d0407baSopenharmony_ci * @f1: the first fence from the same context 4873d0407baSopenharmony_ci * @f2: the second fence from the same context 4883d0407baSopenharmony_ci * 4893d0407baSopenharmony_ci * Returns NULL if both fences are signaled, otherwise the fence that would be 4903d0407baSopenharmony_ci * signaled last. Both fences must be from the same context, since a seqno is 4913d0407baSopenharmony_ci * not re-used across contexts. 4923d0407baSopenharmony_ci */ 4933d0407baSopenharmony_cistatic inline struct dma_fence *dma_fence_later(struct dma_fence *f1, struct dma_fence *f2) 4943d0407baSopenharmony_ci{ 4953d0407baSopenharmony_ci if (WARN_ON(f1->context != f2->context)) { 4963d0407baSopenharmony_ci return NULL; 4973d0407baSopenharmony_ci } 4983d0407baSopenharmony_ci 4993d0407baSopenharmony_ci /* 5003d0407baSopenharmony_ci * Can't check just DMA_FENCE_FLAG_SIGNALED_BIT here, it may never 5013d0407baSopenharmony_ci * have been set if enable_signaling wasn't called, and enabling that 5023d0407baSopenharmony_ci * here is overkill. 5033d0407baSopenharmony_ci */ 5043d0407baSopenharmony_ci if (dma_fence_is_later(f1, f2)) { 5053d0407baSopenharmony_ci return dma_fence_is_signaled(f1) ? NULL : f1; 5063d0407baSopenharmony_ci } else { 5073d0407baSopenharmony_ci return dma_fence_is_signaled(f2) ? NULL : f2; 5083d0407baSopenharmony_ci } 5093d0407baSopenharmony_ci} 5103d0407baSopenharmony_ci 5113d0407baSopenharmony_ci/** 5123d0407baSopenharmony_ci * dma_fence_get_status_locked - returns the status upon completion 5133d0407baSopenharmony_ci * @fence: the dma_fence to query 5143d0407baSopenharmony_ci * 5153d0407baSopenharmony_ci * Drivers can supply an optional error status condition before they signal 5163d0407baSopenharmony_ci * the fence (to indicate whether the fence was completed due to an error 5173d0407baSopenharmony_ci * rather than success). The value of the status condition is only valid 5183d0407baSopenharmony_ci * if the fence has been signaled, dma_fence_get_status_locked() first checks 5193d0407baSopenharmony_ci * the signal state before reporting the error status. 5203d0407baSopenharmony_ci * 5213d0407baSopenharmony_ci * Returns 0 if the fence has not yet been signaled, 1 if the fence has 5223d0407baSopenharmony_ci * been signaled without an error condition, or a negative error code 5233d0407baSopenharmony_ci * if the fence has been completed in err. 5243d0407baSopenharmony_ci */ 5253d0407baSopenharmony_cistatic inline int dma_fence_get_status_locked(struct dma_fence *fence) 5263d0407baSopenharmony_ci{ 5273d0407baSopenharmony_ci if (dma_fence_is_signaled_locked(fence)) { 5283d0407baSopenharmony_ci return fence->error ?: 1; 5293d0407baSopenharmony_ci } else { 5303d0407baSopenharmony_ci return 0; 5313d0407baSopenharmony_ci } 5323d0407baSopenharmony_ci} 5333d0407baSopenharmony_ci 5343d0407baSopenharmony_ciint dma_fence_get_status(struct dma_fence *fence); 5353d0407baSopenharmony_ci 5363d0407baSopenharmony_ci/** 5373d0407baSopenharmony_ci * dma_fence_set_error - flag an error condition on the fence 5383d0407baSopenharmony_ci * @fence: the dma_fence 5393d0407baSopenharmony_ci * @error: the error to store 5403d0407baSopenharmony_ci * 5413d0407baSopenharmony_ci * Drivers can supply an optional error status condition before they signal 5423d0407baSopenharmony_ci * the fence, to indicate that the fence was completed due to an error 5433d0407baSopenharmony_ci * rather than success. This must be set before signaling (so that the value 5443d0407baSopenharmony_ci * is visible before any waiters on the signal callback are woken). This 5453d0407baSopenharmony_ci * helper exists to help catching erroneous setting of #dma_fence.error. 5463d0407baSopenharmony_ci */ 5473d0407baSopenharmony_cistatic inline void dma_fence_set_error(struct dma_fence *fence, int error) 5483d0407baSopenharmony_ci{ 5493d0407baSopenharmony_ci WARN_ON(test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)); 5503d0407baSopenharmony_ci WARN_ON(error >= 0 || error < -MAX_ERRNO); 5513d0407baSopenharmony_ci 5523d0407baSopenharmony_ci fence->error = error; 5533d0407baSopenharmony_ci} 5543d0407baSopenharmony_ci 5553d0407baSopenharmony_cisigned long dma_fence_wait_timeout(struct dma_fence *, bool intr, signed long timeout); 5563d0407baSopenharmony_cisigned long dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count, bool intr, signed long timeout, 5573d0407baSopenharmony_ci uint32_t *idx); 5583d0407baSopenharmony_ci 5593d0407baSopenharmony_ci/** 5603d0407baSopenharmony_ci * dma_fence_wait - sleep until the fence gets signaled 5613d0407baSopenharmony_ci * @fence: the fence to wait on 5623d0407baSopenharmony_ci * @intr: if true, do an interruptible wait 5633d0407baSopenharmony_ci * 5643d0407baSopenharmony_ci * This function will return -ERESTARTSYS if interrupted by a signal, 5653d0407baSopenharmony_ci * or 0 if the fence was signaled. Other error values may be 5663d0407baSopenharmony_ci * returned on custom implementations. 5673d0407baSopenharmony_ci * 5683d0407baSopenharmony_ci * Performs a synchronous wait on this fence. It is assumed the caller 5693d0407baSopenharmony_ci * directly or indirectly holds a reference to the fence, otherwise the 5703d0407baSopenharmony_ci * fence might be freed before return, resulting in undefined behavior. 5713d0407baSopenharmony_ci * 5723d0407baSopenharmony_ci * See also dma_fence_wait_timeout() and dma_fence_wait_any_timeout(). 5733d0407baSopenharmony_ci */ 5743d0407baSopenharmony_cistatic inline signed long dma_fence_wait(struct dma_fence *fence, bool intr) 5753d0407baSopenharmony_ci{ 5763d0407baSopenharmony_ci signed long ret; 5773d0407baSopenharmony_ci 5783d0407baSopenharmony_ci /* Since dma_fence_wait_timeout cannot timeout with 5793d0407baSopenharmony_ci * MAX_SCHEDULE_TIMEOUT, only valid return values are 5803d0407baSopenharmony_ci * -ERESTARTSYS and MAX_SCHEDULE_TIMEOUT. 5813d0407baSopenharmony_ci */ 5823d0407baSopenharmony_ci ret = dma_fence_wait_timeout(fence, intr, MAX_SCHEDULE_TIMEOUT); 5833d0407baSopenharmony_ci 5843d0407baSopenharmony_ci return ret < 0 ? ret : 0; 5853d0407baSopenharmony_ci} 5863d0407baSopenharmony_ci 5873d0407baSopenharmony_cistruct dma_fence *dma_fence_get_stub(void); 5883d0407baSopenharmony_ciu64 dma_fence_context_alloc(unsigned num); 5893d0407baSopenharmony_ci 5903d0407baSopenharmony_ci#define DMA_FENCE_TRACE(f, fmt, args...) \ 5913d0407baSopenharmony_ci do { \ 5923d0407baSopenharmony_ci struct dma_fence *__ff = (f); \ 5933d0407baSopenharmony_ci if (IS_ENABLED(CONFIG_DMA_FENCE_TRACE)) \ 5943d0407baSopenharmony_ci pr_info("f %llu#%llu: " fmt, __ff->context, __ff->seqno, ##args); \ 5953d0407baSopenharmony_ci } while (0) 5963d0407baSopenharmony_ci 5973d0407baSopenharmony_ci#define DMA_FENCE_WARN(f, fmt, args...) \ 5983d0407baSopenharmony_ci do { \ 5993d0407baSopenharmony_ci struct dma_fence *__ff = (f); \ 6003d0407baSopenharmony_ci pr_warn("f %llu#%llu: " fmt, __ff->context, __ff->seqno, ##args); \ 6013d0407baSopenharmony_ci } while (0) 6023d0407baSopenharmony_ci 6033d0407baSopenharmony_ci#define DMA_FENCE_ERR(f, fmt, args...) \ 6043d0407baSopenharmony_ci do { \ 6053d0407baSopenharmony_ci struct dma_fence *__ff = (f); \ 6063d0407baSopenharmony_ci pr_err("f %llu#%llu: " fmt, __ff->context, __ff->seqno, ##args); \ 6073d0407baSopenharmony_ci } while (0) 6083d0407baSopenharmony_ci 6093d0407baSopenharmony_ci#endif /* __LINUX_DMA_FENCE_H */ 610