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