162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Fence mechanism for dma-buf and to allow for asynchronous dma access
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2012 Canonical Ltd
662306a36Sopenharmony_ci * Copyright (C) 2012 Texas Instruments
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * Authors:
962306a36Sopenharmony_ci * Rob Clark <robdclark@gmail.com>
1062306a36Sopenharmony_ci * Maarten Lankhorst <maarten.lankhorst@canonical.com>
1162306a36Sopenharmony_ci */
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include <linux/slab.h>
1462306a36Sopenharmony_ci#include <linux/export.h>
1562306a36Sopenharmony_ci#include <linux/atomic.h>
1662306a36Sopenharmony_ci#include <linux/dma-fence.h>
1762306a36Sopenharmony_ci#include <linux/sched/signal.h>
1862306a36Sopenharmony_ci#include <linux/seq_file.h>
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci#define CREATE_TRACE_POINTS
2162306a36Sopenharmony_ci#include <trace/events/dma_fence.h>
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ciEXPORT_TRACEPOINT_SYMBOL(dma_fence_emit);
2462306a36Sopenharmony_ciEXPORT_TRACEPOINT_SYMBOL(dma_fence_enable_signal);
2562306a36Sopenharmony_ciEXPORT_TRACEPOINT_SYMBOL(dma_fence_signaled);
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_cistatic DEFINE_SPINLOCK(dma_fence_stub_lock);
2862306a36Sopenharmony_cistatic struct dma_fence dma_fence_stub;
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci/*
3162306a36Sopenharmony_ci * fence context counter: each execution context should have its own
3262306a36Sopenharmony_ci * fence context, this allows checking if fences belong to the same
3362306a36Sopenharmony_ci * context or not. One device can have multiple separate contexts,
3462306a36Sopenharmony_ci * and they're used if some engine can run independently of another.
3562306a36Sopenharmony_ci */
3662306a36Sopenharmony_cistatic atomic64_t dma_fence_context_counter = ATOMIC64_INIT(1);
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci/**
3962306a36Sopenharmony_ci * DOC: DMA fences overview
4062306a36Sopenharmony_ci *
4162306a36Sopenharmony_ci * DMA fences, represented by &struct dma_fence, are the kernel internal
4262306a36Sopenharmony_ci * synchronization primitive for DMA operations like GPU rendering, video
4362306a36Sopenharmony_ci * encoding/decoding, or displaying buffers on a screen.
4462306a36Sopenharmony_ci *
4562306a36Sopenharmony_ci * A fence is initialized using dma_fence_init() and completed using
4662306a36Sopenharmony_ci * dma_fence_signal(). Fences are associated with a context, allocated through
4762306a36Sopenharmony_ci * dma_fence_context_alloc(), and all fences on the same context are
4862306a36Sopenharmony_ci * fully ordered.
4962306a36Sopenharmony_ci *
5062306a36Sopenharmony_ci * Since the purposes of fences is to facilitate cross-device and
5162306a36Sopenharmony_ci * cross-application synchronization, there's multiple ways to use one:
5262306a36Sopenharmony_ci *
5362306a36Sopenharmony_ci * - Individual fences can be exposed as a &sync_file, accessed as a file
5462306a36Sopenharmony_ci *   descriptor from userspace, created by calling sync_file_create(). This is
5562306a36Sopenharmony_ci *   called explicit fencing, since userspace passes around explicit
5662306a36Sopenharmony_ci *   synchronization points.
5762306a36Sopenharmony_ci *
5862306a36Sopenharmony_ci * - Some subsystems also have their own explicit fencing primitives, like
5962306a36Sopenharmony_ci *   &drm_syncobj. Compared to &sync_file, a &drm_syncobj allows the underlying
6062306a36Sopenharmony_ci *   fence to be updated.
6162306a36Sopenharmony_ci *
6262306a36Sopenharmony_ci * - Then there's also implicit fencing, where the synchronization points are
6362306a36Sopenharmony_ci *   implicitly passed around as part of shared &dma_buf instances. Such
6462306a36Sopenharmony_ci *   implicit fences are stored in &struct dma_resv through the
6562306a36Sopenharmony_ci *   &dma_buf.resv pointer.
6662306a36Sopenharmony_ci */
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci/**
6962306a36Sopenharmony_ci * DOC: fence cross-driver contract
7062306a36Sopenharmony_ci *
7162306a36Sopenharmony_ci * Since &dma_fence provide a cross driver contract, all drivers must follow the
7262306a36Sopenharmony_ci * same rules:
7362306a36Sopenharmony_ci *
7462306a36Sopenharmony_ci * * Fences must complete in a reasonable time. Fences which represent kernels
7562306a36Sopenharmony_ci *   and shaders submitted by userspace, which could run forever, must be backed
7662306a36Sopenharmony_ci *   up by timeout and gpu hang recovery code. Minimally that code must prevent
7762306a36Sopenharmony_ci *   further command submission and force complete all in-flight fences, e.g.
7862306a36Sopenharmony_ci *   when the driver or hardware do not support gpu reset, or if the gpu reset
7962306a36Sopenharmony_ci *   failed for some reason. Ideally the driver supports gpu recovery which only
8062306a36Sopenharmony_ci *   affects the offending userspace context, and no other userspace
8162306a36Sopenharmony_ci *   submissions.
8262306a36Sopenharmony_ci *
8362306a36Sopenharmony_ci * * Drivers may have different ideas of what completion within a reasonable
8462306a36Sopenharmony_ci *   time means. Some hang recovery code uses a fixed timeout, others a mix
8562306a36Sopenharmony_ci *   between observing forward progress and increasingly strict timeouts.
8662306a36Sopenharmony_ci *   Drivers should not try to second guess timeout handling of fences from
8762306a36Sopenharmony_ci *   other drivers.
8862306a36Sopenharmony_ci *
8962306a36Sopenharmony_ci * * To ensure there's no deadlocks of dma_fence_wait() against other locks
9062306a36Sopenharmony_ci *   drivers should annotate all code required to reach dma_fence_signal(),
9162306a36Sopenharmony_ci *   which completes the fences, with dma_fence_begin_signalling() and
9262306a36Sopenharmony_ci *   dma_fence_end_signalling().
9362306a36Sopenharmony_ci *
9462306a36Sopenharmony_ci * * Drivers are allowed to call dma_fence_wait() while holding dma_resv_lock().
9562306a36Sopenharmony_ci *   This means any code required for fence completion cannot acquire a
9662306a36Sopenharmony_ci *   &dma_resv lock. Note that this also pulls in the entire established
9762306a36Sopenharmony_ci *   locking hierarchy around dma_resv_lock() and dma_resv_unlock().
9862306a36Sopenharmony_ci *
9962306a36Sopenharmony_ci * * Drivers are allowed to call dma_fence_wait() from their &shrinker
10062306a36Sopenharmony_ci *   callbacks. This means any code required for fence completion cannot
10162306a36Sopenharmony_ci *   allocate memory with GFP_KERNEL.
10262306a36Sopenharmony_ci *
10362306a36Sopenharmony_ci * * Drivers are allowed to call dma_fence_wait() from their &mmu_notifier
10462306a36Sopenharmony_ci *   respectively &mmu_interval_notifier callbacks. This means any code required
10562306a36Sopenharmony_ci *   for fence completeion cannot allocate memory with GFP_NOFS or GFP_NOIO.
10662306a36Sopenharmony_ci *   Only GFP_ATOMIC is permissible, which might fail.
10762306a36Sopenharmony_ci *
10862306a36Sopenharmony_ci * Note that only GPU drivers have a reasonable excuse for both requiring
10962306a36Sopenharmony_ci * &mmu_interval_notifier and &shrinker callbacks at the same time as having to
11062306a36Sopenharmony_ci * track asynchronous compute work using &dma_fence. No driver outside of
11162306a36Sopenharmony_ci * drivers/gpu should ever call dma_fence_wait() in such contexts.
11262306a36Sopenharmony_ci */
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_cistatic const char *dma_fence_stub_get_name(struct dma_fence *fence)
11562306a36Sopenharmony_ci{
11662306a36Sopenharmony_ci        return "stub";
11762306a36Sopenharmony_ci}
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_cistatic const struct dma_fence_ops dma_fence_stub_ops = {
12062306a36Sopenharmony_ci	.get_driver_name = dma_fence_stub_get_name,
12162306a36Sopenharmony_ci	.get_timeline_name = dma_fence_stub_get_name,
12262306a36Sopenharmony_ci};
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci/**
12562306a36Sopenharmony_ci * dma_fence_get_stub - return a signaled fence
12662306a36Sopenharmony_ci *
12762306a36Sopenharmony_ci * Return a stub fence which is already signaled. The fence's
12862306a36Sopenharmony_ci * timestamp corresponds to the first time after boot this
12962306a36Sopenharmony_ci * function is called.
13062306a36Sopenharmony_ci */
13162306a36Sopenharmony_cistruct dma_fence *dma_fence_get_stub(void)
13262306a36Sopenharmony_ci{
13362306a36Sopenharmony_ci	spin_lock(&dma_fence_stub_lock);
13462306a36Sopenharmony_ci	if (!dma_fence_stub.ops) {
13562306a36Sopenharmony_ci		dma_fence_init(&dma_fence_stub,
13662306a36Sopenharmony_ci			       &dma_fence_stub_ops,
13762306a36Sopenharmony_ci			       &dma_fence_stub_lock,
13862306a36Sopenharmony_ci			       0, 0);
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci		set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT,
14162306a36Sopenharmony_ci			&dma_fence_stub.flags);
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci		dma_fence_signal_locked(&dma_fence_stub);
14462306a36Sopenharmony_ci	}
14562306a36Sopenharmony_ci	spin_unlock(&dma_fence_stub_lock);
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci	return dma_fence_get(&dma_fence_stub);
14862306a36Sopenharmony_ci}
14962306a36Sopenharmony_ciEXPORT_SYMBOL(dma_fence_get_stub);
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci/**
15262306a36Sopenharmony_ci * dma_fence_allocate_private_stub - return a private, signaled fence
15362306a36Sopenharmony_ci * @timestamp: timestamp when the fence was signaled
15462306a36Sopenharmony_ci *
15562306a36Sopenharmony_ci * Return a newly allocated and signaled stub fence.
15662306a36Sopenharmony_ci */
15762306a36Sopenharmony_cistruct dma_fence *dma_fence_allocate_private_stub(ktime_t timestamp)
15862306a36Sopenharmony_ci{
15962306a36Sopenharmony_ci	struct dma_fence *fence;
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci	fence = kzalloc(sizeof(*fence), GFP_KERNEL);
16262306a36Sopenharmony_ci	if (fence == NULL)
16362306a36Sopenharmony_ci		return NULL;
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ci	dma_fence_init(fence,
16662306a36Sopenharmony_ci		       &dma_fence_stub_ops,
16762306a36Sopenharmony_ci		       &dma_fence_stub_lock,
16862306a36Sopenharmony_ci		       0, 0);
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci	set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT,
17162306a36Sopenharmony_ci		&fence->flags);
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci	dma_fence_signal_timestamp(fence, timestamp);
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci	return fence;
17662306a36Sopenharmony_ci}
17762306a36Sopenharmony_ciEXPORT_SYMBOL(dma_fence_allocate_private_stub);
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci/**
18062306a36Sopenharmony_ci * dma_fence_context_alloc - allocate an array of fence contexts
18162306a36Sopenharmony_ci * @num: amount of contexts to allocate
18262306a36Sopenharmony_ci *
18362306a36Sopenharmony_ci * This function will return the first index of the number of fence contexts
18462306a36Sopenharmony_ci * allocated.  The fence context is used for setting &dma_fence.context to a
18562306a36Sopenharmony_ci * unique number by passing the context to dma_fence_init().
18662306a36Sopenharmony_ci */
18762306a36Sopenharmony_ciu64 dma_fence_context_alloc(unsigned num)
18862306a36Sopenharmony_ci{
18962306a36Sopenharmony_ci	WARN_ON(!num);
19062306a36Sopenharmony_ci	return atomic64_fetch_add(num, &dma_fence_context_counter);
19162306a36Sopenharmony_ci}
19262306a36Sopenharmony_ciEXPORT_SYMBOL(dma_fence_context_alloc);
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ci/**
19562306a36Sopenharmony_ci * DOC: fence signalling annotation
19662306a36Sopenharmony_ci *
19762306a36Sopenharmony_ci * Proving correctness of all the kernel code around &dma_fence through code
19862306a36Sopenharmony_ci * review and testing is tricky for a few reasons:
19962306a36Sopenharmony_ci *
20062306a36Sopenharmony_ci * * It is a cross-driver contract, and therefore all drivers must follow the
20162306a36Sopenharmony_ci *   same rules for lock nesting order, calling contexts for various functions
20262306a36Sopenharmony_ci *   and anything else significant for in-kernel interfaces. But it is also
20362306a36Sopenharmony_ci *   impossible to test all drivers in a single machine, hence brute-force N vs.
20462306a36Sopenharmony_ci *   N testing of all combinations is impossible. Even just limiting to the
20562306a36Sopenharmony_ci *   possible combinations is infeasible.
20662306a36Sopenharmony_ci *
20762306a36Sopenharmony_ci * * There is an enormous amount of driver code involved. For render drivers
20862306a36Sopenharmony_ci *   there's the tail of command submission, after fences are published,
20962306a36Sopenharmony_ci *   scheduler code, interrupt and workers to process job completion,
21062306a36Sopenharmony_ci *   and timeout, gpu reset and gpu hang recovery code. Plus for integration
21162306a36Sopenharmony_ci *   with core mm with have &mmu_notifier, respectively &mmu_interval_notifier,
21262306a36Sopenharmony_ci *   and &shrinker. For modesetting drivers there's the commit tail functions
21362306a36Sopenharmony_ci *   between when fences for an atomic modeset are published, and when the
21462306a36Sopenharmony_ci *   corresponding vblank completes, including any interrupt processing and
21562306a36Sopenharmony_ci *   related workers. Auditing all that code, across all drivers, is not
21662306a36Sopenharmony_ci *   feasible.
21762306a36Sopenharmony_ci *
21862306a36Sopenharmony_ci * * Due to how many other subsystems are involved and the locking hierarchies
21962306a36Sopenharmony_ci *   this pulls in there is extremely thin wiggle-room for driver-specific
22062306a36Sopenharmony_ci *   differences. &dma_fence interacts with almost all of the core memory
22162306a36Sopenharmony_ci *   handling through page fault handlers via &dma_resv, dma_resv_lock() and
22262306a36Sopenharmony_ci *   dma_resv_unlock(). On the other side it also interacts through all
22362306a36Sopenharmony_ci *   allocation sites through &mmu_notifier and &shrinker.
22462306a36Sopenharmony_ci *
22562306a36Sopenharmony_ci * Furthermore lockdep does not handle cross-release dependencies, which means
22662306a36Sopenharmony_ci * any deadlocks between dma_fence_wait() and dma_fence_signal() can't be caught
22762306a36Sopenharmony_ci * at runtime with some quick testing. The simplest example is one thread
22862306a36Sopenharmony_ci * waiting on a &dma_fence while holding a lock::
22962306a36Sopenharmony_ci *
23062306a36Sopenharmony_ci *     lock(A);
23162306a36Sopenharmony_ci *     dma_fence_wait(B);
23262306a36Sopenharmony_ci *     unlock(A);
23362306a36Sopenharmony_ci *
23462306a36Sopenharmony_ci * while the other thread is stuck trying to acquire the same lock, which
23562306a36Sopenharmony_ci * prevents it from signalling the fence the previous thread is stuck waiting
23662306a36Sopenharmony_ci * on::
23762306a36Sopenharmony_ci *
23862306a36Sopenharmony_ci *     lock(A);
23962306a36Sopenharmony_ci *     unlock(A);
24062306a36Sopenharmony_ci *     dma_fence_signal(B);
24162306a36Sopenharmony_ci *
24262306a36Sopenharmony_ci * By manually annotating all code relevant to signalling a &dma_fence we can
24362306a36Sopenharmony_ci * teach lockdep about these dependencies, which also helps with the validation
24462306a36Sopenharmony_ci * headache since now lockdep can check all the rules for us::
24562306a36Sopenharmony_ci *
24662306a36Sopenharmony_ci *    cookie = dma_fence_begin_signalling();
24762306a36Sopenharmony_ci *    lock(A);
24862306a36Sopenharmony_ci *    unlock(A);
24962306a36Sopenharmony_ci *    dma_fence_signal(B);
25062306a36Sopenharmony_ci *    dma_fence_end_signalling(cookie);
25162306a36Sopenharmony_ci *
25262306a36Sopenharmony_ci * For using dma_fence_begin_signalling() and dma_fence_end_signalling() to
25362306a36Sopenharmony_ci * annotate critical sections the following rules need to be observed:
25462306a36Sopenharmony_ci *
25562306a36Sopenharmony_ci * * All code necessary to complete a &dma_fence must be annotated, from the
25662306a36Sopenharmony_ci *   point where a fence is accessible to other threads, to the point where
25762306a36Sopenharmony_ci *   dma_fence_signal() is called. Un-annotated code can contain deadlock issues,
25862306a36Sopenharmony_ci *   and due to the very strict rules and many corner cases it is infeasible to
25962306a36Sopenharmony_ci *   catch these just with review or normal stress testing.
26062306a36Sopenharmony_ci *
26162306a36Sopenharmony_ci * * &struct dma_resv deserves a special note, since the readers are only
26262306a36Sopenharmony_ci *   protected by rcu. This means the signalling critical section starts as soon
26362306a36Sopenharmony_ci *   as the new fences are installed, even before dma_resv_unlock() is called.
26462306a36Sopenharmony_ci *
26562306a36Sopenharmony_ci * * The only exception are fast paths and opportunistic signalling code, which
26662306a36Sopenharmony_ci *   calls dma_fence_signal() purely as an optimization, but is not required to
26762306a36Sopenharmony_ci *   guarantee completion of a &dma_fence. The usual example is a wait IOCTL
26862306a36Sopenharmony_ci *   which calls dma_fence_signal(), while the mandatory completion path goes
26962306a36Sopenharmony_ci *   through a hardware interrupt and possible job completion worker.
27062306a36Sopenharmony_ci *
27162306a36Sopenharmony_ci * * To aid composability of code, the annotations can be freely nested, as long
27262306a36Sopenharmony_ci *   as the overall locking hierarchy is consistent. The annotations also work
27362306a36Sopenharmony_ci *   both in interrupt and process context. Due to implementation details this
27462306a36Sopenharmony_ci *   requires that callers pass an opaque cookie from
27562306a36Sopenharmony_ci *   dma_fence_begin_signalling() to dma_fence_end_signalling().
27662306a36Sopenharmony_ci *
27762306a36Sopenharmony_ci * * Validation against the cross driver contract is implemented by priming
27862306a36Sopenharmony_ci *   lockdep with the relevant hierarchy at boot-up. This means even just
27962306a36Sopenharmony_ci *   testing with a single device is enough to validate a driver, at least as
28062306a36Sopenharmony_ci *   far as deadlocks with dma_fence_wait() against dma_fence_signal() are
28162306a36Sopenharmony_ci *   concerned.
28262306a36Sopenharmony_ci */
28362306a36Sopenharmony_ci#ifdef CONFIG_LOCKDEP
28462306a36Sopenharmony_cistatic struct lockdep_map dma_fence_lockdep_map = {
28562306a36Sopenharmony_ci	.name = "dma_fence_map"
28662306a36Sopenharmony_ci};
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci/**
28962306a36Sopenharmony_ci * dma_fence_begin_signalling - begin a critical DMA fence signalling section
29062306a36Sopenharmony_ci *
29162306a36Sopenharmony_ci * Drivers should use this to annotate the beginning of any code section
29262306a36Sopenharmony_ci * required to eventually complete &dma_fence by calling dma_fence_signal().
29362306a36Sopenharmony_ci *
29462306a36Sopenharmony_ci * The end of these critical sections are annotated with
29562306a36Sopenharmony_ci * dma_fence_end_signalling().
29662306a36Sopenharmony_ci *
29762306a36Sopenharmony_ci * Returns:
29862306a36Sopenharmony_ci *
29962306a36Sopenharmony_ci * Opaque cookie needed by the implementation, which needs to be passed to
30062306a36Sopenharmony_ci * dma_fence_end_signalling().
30162306a36Sopenharmony_ci */
30262306a36Sopenharmony_cibool dma_fence_begin_signalling(void)
30362306a36Sopenharmony_ci{
30462306a36Sopenharmony_ci	/* explicitly nesting ... */
30562306a36Sopenharmony_ci	if (lock_is_held_type(&dma_fence_lockdep_map, 1))
30662306a36Sopenharmony_ci		return true;
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ci	/* rely on might_sleep check for soft/hardirq locks */
30962306a36Sopenharmony_ci	if (in_atomic())
31062306a36Sopenharmony_ci		return true;
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_ci	/* ... and non-recursive readlock */
31362306a36Sopenharmony_ci	lock_acquire(&dma_fence_lockdep_map, 0, 0, 1, 1, NULL, _RET_IP_);
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_ci	return false;
31662306a36Sopenharmony_ci}
31762306a36Sopenharmony_ciEXPORT_SYMBOL(dma_fence_begin_signalling);
31862306a36Sopenharmony_ci
31962306a36Sopenharmony_ci/**
32062306a36Sopenharmony_ci * dma_fence_end_signalling - end a critical DMA fence signalling section
32162306a36Sopenharmony_ci * @cookie: opaque cookie from dma_fence_begin_signalling()
32262306a36Sopenharmony_ci *
32362306a36Sopenharmony_ci * Closes a critical section annotation opened by dma_fence_begin_signalling().
32462306a36Sopenharmony_ci */
32562306a36Sopenharmony_civoid dma_fence_end_signalling(bool cookie)
32662306a36Sopenharmony_ci{
32762306a36Sopenharmony_ci	if (cookie)
32862306a36Sopenharmony_ci		return;
32962306a36Sopenharmony_ci
33062306a36Sopenharmony_ci	lock_release(&dma_fence_lockdep_map, _RET_IP_);
33162306a36Sopenharmony_ci}
33262306a36Sopenharmony_ciEXPORT_SYMBOL(dma_fence_end_signalling);
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_civoid __dma_fence_might_wait(void)
33562306a36Sopenharmony_ci{
33662306a36Sopenharmony_ci	bool tmp;
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_ci	tmp = lock_is_held_type(&dma_fence_lockdep_map, 1);
33962306a36Sopenharmony_ci	if (tmp)
34062306a36Sopenharmony_ci		lock_release(&dma_fence_lockdep_map, _THIS_IP_);
34162306a36Sopenharmony_ci	lock_map_acquire(&dma_fence_lockdep_map);
34262306a36Sopenharmony_ci	lock_map_release(&dma_fence_lockdep_map);
34362306a36Sopenharmony_ci	if (tmp)
34462306a36Sopenharmony_ci		lock_acquire(&dma_fence_lockdep_map, 0, 0, 1, 1, NULL, _THIS_IP_);
34562306a36Sopenharmony_ci}
34662306a36Sopenharmony_ci#endif
34762306a36Sopenharmony_ci
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ci/**
35062306a36Sopenharmony_ci * dma_fence_signal_timestamp_locked - signal completion of a fence
35162306a36Sopenharmony_ci * @fence: the fence to signal
35262306a36Sopenharmony_ci * @timestamp: fence signal timestamp in kernel's CLOCK_MONOTONIC time domain
35362306a36Sopenharmony_ci *
35462306a36Sopenharmony_ci * Signal completion for software callbacks on a fence, this will unblock
35562306a36Sopenharmony_ci * dma_fence_wait() calls and run all the callbacks added with
35662306a36Sopenharmony_ci * dma_fence_add_callback(). Can be called multiple times, but since a fence
35762306a36Sopenharmony_ci * can only go from the unsignaled to the signaled state and not back, it will
35862306a36Sopenharmony_ci * only be effective the first time. Set the timestamp provided as the fence
35962306a36Sopenharmony_ci * signal timestamp.
36062306a36Sopenharmony_ci *
36162306a36Sopenharmony_ci * Unlike dma_fence_signal_timestamp(), this function must be called with
36262306a36Sopenharmony_ci * &dma_fence.lock held.
36362306a36Sopenharmony_ci *
36462306a36Sopenharmony_ci * Returns 0 on success and a negative error value when @fence has been
36562306a36Sopenharmony_ci * signalled already.
36662306a36Sopenharmony_ci */
36762306a36Sopenharmony_ciint dma_fence_signal_timestamp_locked(struct dma_fence *fence,
36862306a36Sopenharmony_ci				      ktime_t timestamp)
36962306a36Sopenharmony_ci{
37062306a36Sopenharmony_ci	struct dma_fence_cb *cur, *tmp;
37162306a36Sopenharmony_ci	struct list_head cb_list;
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci	lockdep_assert_held(fence->lock);
37462306a36Sopenharmony_ci
37562306a36Sopenharmony_ci	if (unlikely(test_and_set_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
37662306a36Sopenharmony_ci				      &fence->flags)))
37762306a36Sopenharmony_ci		return -EINVAL;
37862306a36Sopenharmony_ci
37962306a36Sopenharmony_ci	/* Stash the cb_list before replacing it with the timestamp */
38062306a36Sopenharmony_ci	list_replace(&fence->cb_list, &cb_list);
38162306a36Sopenharmony_ci
38262306a36Sopenharmony_ci	fence->timestamp = timestamp;
38362306a36Sopenharmony_ci	set_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags);
38462306a36Sopenharmony_ci	trace_dma_fence_signaled(fence);
38562306a36Sopenharmony_ci
38662306a36Sopenharmony_ci	list_for_each_entry_safe(cur, tmp, &cb_list, node) {
38762306a36Sopenharmony_ci		INIT_LIST_HEAD(&cur->node);
38862306a36Sopenharmony_ci		cur->func(fence, cur);
38962306a36Sopenharmony_ci	}
39062306a36Sopenharmony_ci
39162306a36Sopenharmony_ci	return 0;
39262306a36Sopenharmony_ci}
39362306a36Sopenharmony_ciEXPORT_SYMBOL(dma_fence_signal_timestamp_locked);
39462306a36Sopenharmony_ci
39562306a36Sopenharmony_ci/**
39662306a36Sopenharmony_ci * dma_fence_signal_timestamp - signal completion of a fence
39762306a36Sopenharmony_ci * @fence: the fence to signal
39862306a36Sopenharmony_ci * @timestamp: fence signal timestamp in kernel's CLOCK_MONOTONIC time domain
39962306a36Sopenharmony_ci *
40062306a36Sopenharmony_ci * Signal completion for software callbacks on a fence, this will unblock
40162306a36Sopenharmony_ci * dma_fence_wait() calls and run all the callbacks added with
40262306a36Sopenharmony_ci * dma_fence_add_callback(). Can be called multiple times, but since a fence
40362306a36Sopenharmony_ci * can only go from the unsignaled to the signaled state and not back, it will
40462306a36Sopenharmony_ci * only be effective the first time. Set the timestamp provided as the fence
40562306a36Sopenharmony_ci * signal timestamp.
40662306a36Sopenharmony_ci *
40762306a36Sopenharmony_ci * Returns 0 on success and a negative error value when @fence has been
40862306a36Sopenharmony_ci * signalled already.
40962306a36Sopenharmony_ci */
41062306a36Sopenharmony_ciint dma_fence_signal_timestamp(struct dma_fence *fence, ktime_t timestamp)
41162306a36Sopenharmony_ci{
41262306a36Sopenharmony_ci	unsigned long flags;
41362306a36Sopenharmony_ci	int ret;
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_ci	if (!fence)
41662306a36Sopenharmony_ci		return -EINVAL;
41762306a36Sopenharmony_ci
41862306a36Sopenharmony_ci	spin_lock_irqsave(fence->lock, flags);
41962306a36Sopenharmony_ci	ret = dma_fence_signal_timestamp_locked(fence, timestamp);
42062306a36Sopenharmony_ci	spin_unlock_irqrestore(fence->lock, flags);
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ci	return ret;
42362306a36Sopenharmony_ci}
42462306a36Sopenharmony_ciEXPORT_SYMBOL(dma_fence_signal_timestamp);
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_ci/**
42762306a36Sopenharmony_ci * dma_fence_signal_locked - signal completion of a fence
42862306a36Sopenharmony_ci * @fence: the fence to signal
42962306a36Sopenharmony_ci *
43062306a36Sopenharmony_ci * Signal completion for software callbacks on a fence, this will unblock
43162306a36Sopenharmony_ci * dma_fence_wait() calls and run all the callbacks added with
43262306a36Sopenharmony_ci * dma_fence_add_callback(). Can be called multiple times, but since a fence
43362306a36Sopenharmony_ci * can only go from the unsignaled to the signaled state and not back, it will
43462306a36Sopenharmony_ci * only be effective the first time.
43562306a36Sopenharmony_ci *
43662306a36Sopenharmony_ci * Unlike dma_fence_signal(), this function must be called with &dma_fence.lock
43762306a36Sopenharmony_ci * held.
43862306a36Sopenharmony_ci *
43962306a36Sopenharmony_ci * Returns 0 on success and a negative error value when @fence has been
44062306a36Sopenharmony_ci * signalled already.
44162306a36Sopenharmony_ci */
44262306a36Sopenharmony_ciint dma_fence_signal_locked(struct dma_fence *fence)
44362306a36Sopenharmony_ci{
44462306a36Sopenharmony_ci	return dma_fence_signal_timestamp_locked(fence, ktime_get());
44562306a36Sopenharmony_ci}
44662306a36Sopenharmony_ciEXPORT_SYMBOL(dma_fence_signal_locked);
44762306a36Sopenharmony_ci
44862306a36Sopenharmony_ci/**
44962306a36Sopenharmony_ci * dma_fence_signal - signal completion of a fence
45062306a36Sopenharmony_ci * @fence: the fence to signal
45162306a36Sopenharmony_ci *
45262306a36Sopenharmony_ci * Signal completion for software callbacks on a fence, this will unblock
45362306a36Sopenharmony_ci * dma_fence_wait() calls and run all the callbacks added with
45462306a36Sopenharmony_ci * dma_fence_add_callback(). Can be called multiple times, but since a fence
45562306a36Sopenharmony_ci * can only go from the unsignaled to the signaled state and not back, it will
45662306a36Sopenharmony_ci * only be effective the first time.
45762306a36Sopenharmony_ci *
45862306a36Sopenharmony_ci * Returns 0 on success and a negative error value when @fence has been
45962306a36Sopenharmony_ci * signalled already.
46062306a36Sopenharmony_ci */
46162306a36Sopenharmony_ciint dma_fence_signal(struct dma_fence *fence)
46262306a36Sopenharmony_ci{
46362306a36Sopenharmony_ci	unsigned long flags;
46462306a36Sopenharmony_ci	int ret;
46562306a36Sopenharmony_ci	bool tmp;
46662306a36Sopenharmony_ci
46762306a36Sopenharmony_ci	if (!fence)
46862306a36Sopenharmony_ci		return -EINVAL;
46962306a36Sopenharmony_ci
47062306a36Sopenharmony_ci	tmp = dma_fence_begin_signalling();
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_ci	spin_lock_irqsave(fence->lock, flags);
47362306a36Sopenharmony_ci	ret = dma_fence_signal_timestamp_locked(fence, ktime_get());
47462306a36Sopenharmony_ci	spin_unlock_irqrestore(fence->lock, flags);
47562306a36Sopenharmony_ci
47662306a36Sopenharmony_ci	dma_fence_end_signalling(tmp);
47762306a36Sopenharmony_ci
47862306a36Sopenharmony_ci	return ret;
47962306a36Sopenharmony_ci}
48062306a36Sopenharmony_ciEXPORT_SYMBOL(dma_fence_signal);
48162306a36Sopenharmony_ci
48262306a36Sopenharmony_ci/**
48362306a36Sopenharmony_ci * dma_fence_wait_timeout - sleep until the fence gets signaled
48462306a36Sopenharmony_ci * or until timeout elapses
48562306a36Sopenharmony_ci * @fence: the fence to wait on
48662306a36Sopenharmony_ci * @intr: if true, do an interruptible wait
48762306a36Sopenharmony_ci * @timeout: timeout value in jiffies, or MAX_SCHEDULE_TIMEOUT
48862306a36Sopenharmony_ci *
48962306a36Sopenharmony_ci * Returns -ERESTARTSYS if interrupted, 0 if the wait timed out, or the
49062306a36Sopenharmony_ci * remaining timeout in jiffies on success. Other error values may be
49162306a36Sopenharmony_ci * returned on custom implementations.
49262306a36Sopenharmony_ci *
49362306a36Sopenharmony_ci * Performs a synchronous wait on this fence. It is assumed the caller
49462306a36Sopenharmony_ci * directly or indirectly (buf-mgr between reservation and committing)
49562306a36Sopenharmony_ci * holds a reference to the fence, otherwise the fence might be
49662306a36Sopenharmony_ci * freed before return, resulting in undefined behavior.
49762306a36Sopenharmony_ci *
49862306a36Sopenharmony_ci * See also dma_fence_wait() and dma_fence_wait_any_timeout().
49962306a36Sopenharmony_ci */
50062306a36Sopenharmony_cisigned long
50162306a36Sopenharmony_cidma_fence_wait_timeout(struct dma_fence *fence, bool intr, signed long timeout)
50262306a36Sopenharmony_ci{
50362306a36Sopenharmony_ci	signed long ret;
50462306a36Sopenharmony_ci
50562306a36Sopenharmony_ci	if (WARN_ON(timeout < 0))
50662306a36Sopenharmony_ci		return -EINVAL;
50762306a36Sopenharmony_ci
50862306a36Sopenharmony_ci	might_sleep();
50962306a36Sopenharmony_ci
51062306a36Sopenharmony_ci	__dma_fence_might_wait();
51162306a36Sopenharmony_ci
51262306a36Sopenharmony_ci	dma_fence_enable_sw_signaling(fence);
51362306a36Sopenharmony_ci
51462306a36Sopenharmony_ci	trace_dma_fence_wait_start(fence);
51562306a36Sopenharmony_ci	if (fence->ops->wait)
51662306a36Sopenharmony_ci		ret = fence->ops->wait(fence, intr, timeout);
51762306a36Sopenharmony_ci	else
51862306a36Sopenharmony_ci		ret = dma_fence_default_wait(fence, intr, timeout);
51962306a36Sopenharmony_ci	trace_dma_fence_wait_end(fence);
52062306a36Sopenharmony_ci	return ret;
52162306a36Sopenharmony_ci}
52262306a36Sopenharmony_ciEXPORT_SYMBOL(dma_fence_wait_timeout);
52362306a36Sopenharmony_ci
52462306a36Sopenharmony_ci/**
52562306a36Sopenharmony_ci * dma_fence_release - default relese function for fences
52662306a36Sopenharmony_ci * @kref: &dma_fence.recfount
52762306a36Sopenharmony_ci *
52862306a36Sopenharmony_ci * This is the default release functions for &dma_fence. Drivers shouldn't call
52962306a36Sopenharmony_ci * this directly, but instead call dma_fence_put().
53062306a36Sopenharmony_ci */
53162306a36Sopenharmony_civoid dma_fence_release(struct kref *kref)
53262306a36Sopenharmony_ci{
53362306a36Sopenharmony_ci	struct dma_fence *fence =
53462306a36Sopenharmony_ci		container_of(kref, struct dma_fence, refcount);
53562306a36Sopenharmony_ci
53662306a36Sopenharmony_ci	trace_dma_fence_destroy(fence);
53762306a36Sopenharmony_ci
53862306a36Sopenharmony_ci	if (WARN(!list_empty(&fence->cb_list) &&
53962306a36Sopenharmony_ci		 !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags),
54062306a36Sopenharmony_ci		 "Fence %s:%s:%llx:%llx released with pending signals!\n",
54162306a36Sopenharmony_ci		 fence->ops->get_driver_name(fence),
54262306a36Sopenharmony_ci		 fence->ops->get_timeline_name(fence),
54362306a36Sopenharmony_ci		 fence->context, fence->seqno)) {
54462306a36Sopenharmony_ci		unsigned long flags;
54562306a36Sopenharmony_ci
54662306a36Sopenharmony_ci		/*
54762306a36Sopenharmony_ci		 * Failed to signal before release, likely a refcounting issue.
54862306a36Sopenharmony_ci		 *
54962306a36Sopenharmony_ci		 * This should never happen, but if it does make sure that we
55062306a36Sopenharmony_ci		 * don't leave chains dangling. We set the error flag first
55162306a36Sopenharmony_ci		 * so that the callbacks know this signal is due to an error.
55262306a36Sopenharmony_ci		 */
55362306a36Sopenharmony_ci		spin_lock_irqsave(fence->lock, flags);
55462306a36Sopenharmony_ci		fence->error = -EDEADLK;
55562306a36Sopenharmony_ci		dma_fence_signal_locked(fence);
55662306a36Sopenharmony_ci		spin_unlock_irqrestore(fence->lock, flags);
55762306a36Sopenharmony_ci	}
55862306a36Sopenharmony_ci
55962306a36Sopenharmony_ci	if (fence->ops->release)
56062306a36Sopenharmony_ci		fence->ops->release(fence);
56162306a36Sopenharmony_ci	else
56262306a36Sopenharmony_ci		dma_fence_free(fence);
56362306a36Sopenharmony_ci}
56462306a36Sopenharmony_ciEXPORT_SYMBOL(dma_fence_release);
56562306a36Sopenharmony_ci
56662306a36Sopenharmony_ci/**
56762306a36Sopenharmony_ci * dma_fence_free - default release function for &dma_fence.
56862306a36Sopenharmony_ci * @fence: fence to release
56962306a36Sopenharmony_ci *
57062306a36Sopenharmony_ci * This is the default implementation for &dma_fence_ops.release. It calls
57162306a36Sopenharmony_ci * kfree_rcu() on @fence.
57262306a36Sopenharmony_ci */
57362306a36Sopenharmony_civoid dma_fence_free(struct dma_fence *fence)
57462306a36Sopenharmony_ci{
57562306a36Sopenharmony_ci	kfree_rcu(fence, rcu);
57662306a36Sopenharmony_ci}
57762306a36Sopenharmony_ciEXPORT_SYMBOL(dma_fence_free);
57862306a36Sopenharmony_ci
57962306a36Sopenharmony_cistatic bool __dma_fence_enable_signaling(struct dma_fence *fence)
58062306a36Sopenharmony_ci{
58162306a36Sopenharmony_ci	bool was_set;
58262306a36Sopenharmony_ci
58362306a36Sopenharmony_ci	lockdep_assert_held(fence->lock);
58462306a36Sopenharmony_ci
58562306a36Sopenharmony_ci	was_set = test_and_set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT,
58662306a36Sopenharmony_ci				   &fence->flags);
58762306a36Sopenharmony_ci
58862306a36Sopenharmony_ci	if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
58962306a36Sopenharmony_ci		return false;
59062306a36Sopenharmony_ci
59162306a36Sopenharmony_ci	if (!was_set && fence->ops->enable_signaling) {
59262306a36Sopenharmony_ci		trace_dma_fence_enable_signal(fence);
59362306a36Sopenharmony_ci
59462306a36Sopenharmony_ci		if (!fence->ops->enable_signaling(fence)) {
59562306a36Sopenharmony_ci			dma_fence_signal_locked(fence);
59662306a36Sopenharmony_ci			return false;
59762306a36Sopenharmony_ci		}
59862306a36Sopenharmony_ci	}
59962306a36Sopenharmony_ci
60062306a36Sopenharmony_ci	return true;
60162306a36Sopenharmony_ci}
60262306a36Sopenharmony_ci
60362306a36Sopenharmony_ci/**
60462306a36Sopenharmony_ci * dma_fence_enable_sw_signaling - enable signaling on fence
60562306a36Sopenharmony_ci * @fence: the fence to enable
60662306a36Sopenharmony_ci *
60762306a36Sopenharmony_ci * This will request for sw signaling to be enabled, to make the fence
60862306a36Sopenharmony_ci * complete as soon as possible. This calls &dma_fence_ops.enable_signaling
60962306a36Sopenharmony_ci * internally.
61062306a36Sopenharmony_ci */
61162306a36Sopenharmony_civoid dma_fence_enable_sw_signaling(struct dma_fence *fence)
61262306a36Sopenharmony_ci{
61362306a36Sopenharmony_ci	unsigned long flags;
61462306a36Sopenharmony_ci
61562306a36Sopenharmony_ci	spin_lock_irqsave(fence->lock, flags);
61662306a36Sopenharmony_ci	__dma_fence_enable_signaling(fence);
61762306a36Sopenharmony_ci	spin_unlock_irqrestore(fence->lock, flags);
61862306a36Sopenharmony_ci}
61962306a36Sopenharmony_ciEXPORT_SYMBOL(dma_fence_enable_sw_signaling);
62062306a36Sopenharmony_ci
62162306a36Sopenharmony_ci/**
62262306a36Sopenharmony_ci * dma_fence_add_callback - add a callback to be called when the fence
62362306a36Sopenharmony_ci * is signaled
62462306a36Sopenharmony_ci * @fence: the fence to wait on
62562306a36Sopenharmony_ci * @cb: the callback to register
62662306a36Sopenharmony_ci * @func: the function to call
62762306a36Sopenharmony_ci *
62862306a36Sopenharmony_ci * Add a software callback to the fence. The caller should keep a reference to
62962306a36Sopenharmony_ci * the fence.
63062306a36Sopenharmony_ci *
63162306a36Sopenharmony_ci * @cb will be initialized by dma_fence_add_callback(), no initialization
63262306a36Sopenharmony_ci * by the caller is required. Any number of callbacks can be registered
63362306a36Sopenharmony_ci * to a fence, but a callback can only be registered to one fence at a time.
63462306a36Sopenharmony_ci *
63562306a36Sopenharmony_ci * If fence is already signaled, this function will return -ENOENT (and
63662306a36Sopenharmony_ci * *not* call the callback).
63762306a36Sopenharmony_ci *
63862306a36Sopenharmony_ci * Note that the callback can be called from an atomic context or irq context.
63962306a36Sopenharmony_ci *
64062306a36Sopenharmony_ci * Returns 0 in case of success, -ENOENT if the fence is already signaled
64162306a36Sopenharmony_ci * and -EINVAL in case of error.
64262306a36Sopenharmony_ci */
64362306a36Sopenharmony_ciint dma_fence_add_callback(struct dma_fence *fence, struct dma_fence_cb *cb,
64462306a36Sopenharmony_ci			   dma_fence_func_t func)
64562306a36Sopenharmony_ci{
64662306a36Sopenharmony_ci	unsigned long flags;
64762306a36Sopenharmony_ci	int ret = 0;
64862306a36Sopenharmony_ci
64962306a36Sopenharmony_ci	if (WARN_ON(!fence || !func))
65062306a36Sopenharmony_ci		return -EINVAL;
65162306a36Sopenharmony_ci
65262306a36Sopenharmony_ci	if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) {
65362306a36Sopenharmony_ci		INIT_LIST_HEAD(&cb->node);
65462306a36Sopenharmony_ci		return -ENOENT;
65562306a36Sopenharmony_ci	}
65662306a36Sopenharmony_ci
65762306a36Sopenharmony_ci	spin_lock_irqsave(fence->lock, flags);
65862306a36Sopenharmony_ci
65962306a36Sopenharmony_ci	if (__dma_fence_enable_signaling(fence)) {
66062306a36Sopenharmony_ci		cb->func = func;
66162306a36Sopenharmony_ci		list_add_tail(&cb->node, &fence->cb_list);
66262306a36Sopenharmony_ci	} else {
66362306a36Sopenharmony_ci		INIT_LIST_HEAD(&cb->node);
66462306a36Sopenharmony_ci		ret = -ENOENT;
66562306a36Sopenharmony_ci	}
66662306a36Sopenharmony_ci
66762306a36Sopenharmony_ci	spin_unlock_irqrestore(fence->lock, flags);
66862306a36Sopenharmony_ci
66962306a36Sopenharmony_ci	return ret;
67062306a36Sopenharmony_ci}
67162306a36Sopenharmony_ciEXPORT_SYMBOL(dma_fence_add_callback);
67262306a36Sopenharmony_ci
67362306a36Sopenharmony_ci/**
67462306a36Sopenharmony_ci * dma_fence_get_status - returns the status upon completion
67562306a36Sopenharmony_ci * @fence: the dma_fence to query
67662306a36Sopenharmony_ci *
67762306a36Sopenharmony_ci * This wraps dma_fence_get_status_locked() to return the error status
67862306a36Sopenharmony_ci * condition on a signaled fence. See dma_fence_get_status_locked() for more
67962306a36Sopenharmony_ci * details.
68062306a36Sopenharmony_ci *
68162306a36Sopenharmony_ci * Returns 0 if the fence has not yet been signaled, 1 if the fence has
68262306a36Sopenharmony_ci * been signaled without an error condition, or a negative error code
68362306a36Sopenharmony_ci * if the fence has been completed in err.
68462306a36Sopenharmony_ci */
68562306a36Sopenharmony_ciint dma_fence_get_status(struct dma_fence *fence)
68662306a36Sopenharmony_ci{
68762306a36Sopenharmony_ci	unsigned long flags;
68862306a36Sopenharmony_ci	int status;
68962306a36Sopenharmony_ci
69062306a36Sopenharmony_ci	spin_lock_irqsave(fence->lock, flags);
69162306a36Sopenharmony_ci	status = dma_fence_get_status_locked(fence);
69262306a36Sopenharmony_ci	spin_unlock_irqrestore(fence->lock, flags);
69362306a36Sopenharmony_ci
69462306a36Sopenharmony_ci	return status;
69562306a36Sopenharmony_ci}
69662306a36Sopenharmony_ciEXPORT_SYMBOL(dma_fence_get_status);
69762306a36Sopenharmony_ci
69862306a36Sopenharmony_ci/**
69962306a36Sopenharmony_ci * dma_fence_remove_callback - remove a callback from the signaling list
70062306a36Sopenharmony_ci * @fence: the fence to wait on
70162306a36Sopenharmony_ci * @cb: the callback to remove
70262306a36Sopenharmony_ci *
70362306a36Sopenharmony_ci * Remove a previously queued callback from the fence. This function returns
70462306a36Sopenharmony_ci * true if the callback is successfully removed, or false if the fence has
70562306a36Sopenharmony_ci * already been signaled.
70662306a36Sopenharmony_ci *
70762306a36Sopenharmony_ci * *WARNING*:
70862306a36Sopenharmony_ci * Cancelling a callback should only be done if you really know what you're
70962306a36Sopenharmony_ci * doing, since deadlocks and race conditions could occur all too easily. For
71062306a36Sopenharmony_ci * this reason, it should only ever be done on hardware lockup recovery,
71162306a36Sopenharmony_ci * with a reference held to the fence.
71262306a36Sopenharmony_ci *
71362306a36Sopenharmony_ci * Behaviour is undefined if @cb has not been added to @fence using
71462306a36Sopenharmony_ci * dma_fence_add_callback() beforehand.
71562306a36Sopenharmony_ci */
71662306a36Sopenharmony_cibool
71762306a36Sopenharmony_cidma_fence_remove_callback(struct dma_fence *fence, struct dma_fence_cb *cb)
71862306a36Sopenharmony_ci{
71962306a36Sopenharmony_ci	unsigned long flags;
72062306a36Sopenharmony_ci	bool ret;
72162306a36Sopenharmony_ci
72262306a36Sopenharmony_ci	spin_lock_irqsave(fence->lock, flags);
72362306a36Sopenharmony_ci
72462306a36Sopenharmony_ci	ret = !list_empty(&cb->node);
72562306a36Sopenharmony_ci	if (ret)
72662306a36Sopenharmony_ci		list_del_init(&cb->node);
72762306a36Sopenharmony_ci
72862306a36Sopenharmony_ci	spin_unlock_irqrestore(fence->lock, flags);
72962306a36Sopenharmony_ci
73062306a36Sopenharmony_ci	return ret;
73162306a36Sopenharmony_ci}
73262306a36Sopenharmony_ciEXPORT_SYMBOL(dma_fence_remove_callback);
73362306a36Sopenharmony_ci
73462306a36Sopenharmony_cistruct default_wait_cb {
73562306a36Sopenharmony_ci	struct dma_fence_cb base;
73662306a36Sopenharmony_ci	struct task_struct *task;
73762306a36Sopenharmony_ci};
73862306a36Sopenharmony_ci
73962306a36Sopenharmony_cistatic void
74062306a36Sopenharmony_cidma_fence_default_wait_cb(struct dma_fence *fence, struct dma_fence_cb *cb)
74162306a36Sopenharmony_ci{
74262306a36Sopenharmony_ci	struct default_wait_cb *wait =
74362306a36Sopenharmony_ci		container_of(cb, struct default_wait_cb, base);
74462306a36Sopenharmony_ci
74562306a36Sopenharmony_ci	wake_up_state(wait->task, TASK_NORMAL);
74662306a36Sopenharmony_ci}
74762306a36Sopenharmony_ci
74862306a36Sopenharmony_ci/**
74962306a36Sopenharmony_ci * dma_fence_default_wait - default sleep until the fence gets signaled
75062306a36Sopenharmony_ci * or until timeout elapses
75162306a36Sopenharmony_ci * @fence: the fence to wait on
75262306a36Sopenharmony_ci * @intr: if true, do an interruptible wait
75362306a36Sopenharmony_ci * @timeout: timeout value in jiffies, or MAX_SCHEDULE_TIMEOUT
75462306a36Sopenharmony_ci *
75562306a36Sopenharmony_ci * Returns -ERESTARTSYS if interrupted, 0 if the wait timed out, or the
75662306a36Sopenharmony_ci * remaining timeout in jiffies on success. If timeout is zero the value one is
75762306a36Sopenharmony_ci * returned if the fence is already signaled for consistency with other
75862306a36Sopenharmony_ci * functions taking a jiffies timeout.
75962306a36Sopenharmony_ci */
76062306a36Sopenharmony_cisigned long
76162306a36Sopenharmony_cidma_fence_default_wait(struct dma_fence *fence, bool intr, signed long timeout)
76262306a36Sopenharmony_ci{
76362306a36Sopenharmony_ci	struct default_wait_cb cb;
76462306a36Sopenharmony_ci	unsigned long flags;
76562306a36Sopenharmony_ci	signed long ret = timeout ? timeout : 1;
76662306a36Sopenharmony_ci
76762306a36Sopenharmony_ci	spin_lock_irqsave(fence->lock, flags);
76862306a36Sopenharmony_ci
76962306a36Sopenharmony_ci	if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
77062306a36Sopenharmony_ci		goto out;
77162306a36Sopenharmony_ci
77262306a36Sopenharmony_ci	if (intr && signal_pending(current)) {
77362306a36Sopenharmony_ci		ret = -ERESTARTSYS;
77462306a36Sopenharmony_ci		goto out;
77562306a36Sopenharmony_ci	}
77662306a36Sopenharmony_ci
77762306a36Sopenharmony_ci	if (!timeout) {
77862306a36Sopenharmony_ci		ret = 0;
77962306a36Sopenharmony_ci		goto out;
78062306a36Sopenharmony_ci	}
78162306a36Sopenharmony_ci
78262306a36Sopenharmony_ci	cb.base.func = dma_fence_default_wait_cb;
78362306a36Sopenharmony_ci	cb.task = current;
78462306a36Sopenharmony_ci	list_add(&cb.base.node, &fence->cb_list);
78562306a36Sopenharmony_ci
78662306a36Sopenharmony_ci	while (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags) && ret > 0) {
78762306a36Sopenharmony_ci		if (intr)
78862306a36Sopenharmony_ci			__set_current_state(TASK_INTERRUPTIBLE);
78962306a36Sopenharmony_ci		else
79062306a36Sopenharmony_ci			__set_current_state(TASK_UNINTERRUPTIBLE);
79162306a36Sopenharmony_ci		spin_unlock_irqrestore(fence->lock, flags);
79262306a36Sopenharmony_ci
79362306a36Sopenharmony_ci		ret = schedule_timeout(ret);
79462306a36Sopenharmony_ci
79562306a36Sopenharmony_ci		spin_lock_irqsave(fence->lock, flags);
79662306a36Sopenharmony_ci		if (ret > 0 && intr && signal_pending(current))
79762306a36Sopenharmony_ci			ret = -ERESTARTSYS;
79862306a36Sopenharmony_ci	}
79962306a36Sopenharmony_ci
80062306a36Sopenharmony_ci	if (!list_empty(&cb.base.node))
80162306a36Sopenharmony_ci		list_del(&cb.base.node);
80262306a36Sopenharmony_ci	__set_current_state(TASK_RUNNING);
80362306a36Sopenharmony_ci
80462306a36Sopenharmony_ciout:
80562306a36Sopenharmony_ci	spin_unlock_irqrestore(fence->lock, flags);
80662306a36Sopenharmony_ci	return ret;
80762306a36Sopenharmony_ci}
80862306a36Sopenharmony_ciEXPORT_SYMBOL(dma_fence_default_wait);
80962306a36Sopenharmony_ci
81062306a36Sopenharmony_cistatic bool
81162306a36Sopenharmony_cidma_fence_test_signaled_any(struct dma_fence **fences, uint32_t count,
81262306a36Sopenharmony_ci			    uint32_t *idx)
81362306a36Sopenharmony_ci{
81462306a36Sopenharmony_ci	int i;
81562306a36Sopenharmony_ci
81662306a36Sopenharmony_ci	for (i = 0; i < count; ++i) {
81762306a36Sopenharmony_ci		struct dma_fence *fence = fences[i];
81862306a36Sopenharmony_ci		if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) {
81962306a36Sopenharmony_ci			if (idx)
82062306a36Sopenharmony_ci				*idx = i;
82162306a36Sopenharmony_ci			return true;
82262306a36Sopenharmony_ci		}
82362306a36Sopenharmony_ci	}
82462306a36Sopenharmony_ci	return false;
82562306a36Sopenharmony_ci}
82662306a36Sopenharmony_ci
82762306a36Sopenharmony_ci/**
82862306a36Sopenharmony_ci * dma_fence_wait_any_timeout - sleep until any fence gets signaled
82962306a36Sopenharmony_ci * or until timeout elapses
83062306a36Sopenharmony_ci * @fences: array of fences to wait on
83162306a36Sopenharmony_ci * @count: number of fences to wait on
83262306a36Sopenharmony_ci * @intr: if true, do an interruptible wait
83362306a36Sopenharmony_ci * @timeout: timeout value in jiffies, or MAX_SCHEDULE_TIMEOUT
83462306a36Sopenharmony_ci * @idx: used to store the first signaled fence index, meaningful only on
83562306a36Sopenharmony_ci *	positive return
83662306a36Sopenharmony_ci *
83762306a36Sopenharmony_ci * Returns -EINVAL on custom fence wait implementation, -ERESTARTSYS if
83862306a36Sopenharmony_ci * interrupted, 0 if the wait timed out, or the remaining timeout in jiffies
83962306a36Sopenharmony_ci * on success.
84062306a36Sopenharmony_ci *
84162306a36Sopenharmony_ci * Synchronous waits for the first fence in the array to be signaled. The
84262306a36Sopenharmony_ci * caller needs to hold a reference to all fences in the array, otherwise a
84362306a36Sopenharmony_ci * fence might be freed before return, resulting in undefined behavior.
84462306a36Sopenharmony_ci *
84562306a36Sopenharmony_ci * See also dma_fence_wait() and dma_fence_wait_timeout().
84662306a36Sopenharmony_ci */
84762306a36Sopenharmony_cisigned long
84862306a36Sopenharmony_cidma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count,
84962306a36Sopenharmony_ci			   bool intr, signed long timeout, uint32_t *idx)
85062306a36Sopenharmony_ci{
85162306a36Sopenharmony_ci	struct default_wait_cb *cb;
85262306a36Sopenharmony_ci	signed long ret = timeout;
85362306a36Sopenharmony_ci	unsigned i;
85462306a36Sopenharmony_ci
85562306a36Sopenharmony_ci	if (WARN_ON(!fences || !count || timeout < 0))
85662306a36Sopenharmony_ci		return -EINVAL;
85762306a36Sopenharmony_ci
85862306a36Sopenharmony_ci	if (timeout == 0) {
85962306a36Sopenharmony_ci		for (i = 0; i < count; ++i)
86062306a36Sopenharmony_ci			if (dma_fence_is_signaled(fences[i])) {
86162306a36Sopenharmony_ci				if (idx)
86262306a36Sopenharmony_ci					*idx = i;
86362306a36Sopenharmony_ci				return 1;
86462306a36Sopenharmony_ci			}
86562306a36Sopenharmony_ci
86662306a36Sopenharmony_ci		return 0;
86762306a36Sopenharmony_ci	}
86862306a36Sopenharmony_ci
86962306a36Sopenharmony_ci	cb = kcalloc(count, sizeof(struct default_wait_cb), GFP_KERNEL);
87062306a36Sopenharmony_ci	if (cb == NULL) {
87162306a36Sopenharmony_ci		ret = -ENOMEM;
87262306a36Sopenharmony_ci		goto err_free_cb;
87362306a36Sopenharmony_ci	}
87462306a36Sopenharmony_ci
87562306a36Sopenharmony_ci	for (i = 0; i < count; ++i) {
87662306a36Sopenharmony_ci		struct dma_fence *fence = fences[i];
87762306a36Sopenharmony_ci
87862306a36Sopenharmony_ci		cb[i].task = current;
87962306a36Sopenharmony_ci		if (dma_fence_add_callback(fence, &cb[i].base,
88062306a36Sopenharmony_ci					   dma_fence_default_wait_cb)) {
88162306a36Sopenharmony_ci			/* This fence is already signaled */
88262306a36Sopenharmony_ci			if (idx)
88362306a36Sopenharmony_ci				*idx = i;
88462306a36Sopenharmony_ci			goto fence_rm_cb;
88562306a36Sopenharmony_ci		}
88662306a36Sopenharmony_ci	}
88762306a36Sopenharmony_ci
88862306a36Sopenharmony_ci	while (ret > 0) {
88962306a36Sopenharmony_ci		if (intr)
89062306a36Sopenharmony_ci			set_current_state(TASK_INTERRUPTIBLE);
89162306a36Sopenharmony_ci		else
89262306a36Sopenharmony_ci			set_current_state(TASK_UNINTERRUPTIBLE);
89362306a36Sopenharmony_ci
89462306a36Sopenharmony_ci		if (dma_fence_test_signaled_any(fences, count, idx))
89562306a36Sopenharmony_ci			break;
89662306a36Sopenharmony_ci
89762306a36Sopenharmony_ci		ret = schedule_timeout(ret);
89862306a36Sopenharmony_ci
89962306a36Sopenharmony_ci		if (ret > 0 && intr && signal_pending(current))
90062306a36Sopenharmony_ci			ret = -ERESTARTSYS;
90162306a36Sopenharmony_ci	}
90262306a36Sopenharmony_ci
90362306a36Sopenharmony_ci	__set_current_state(TASK_RUNNING);
90462306a36Sopenharmony_ci
90562306a36Sopenharmony_cifence_rm_cb:
90662306a36Sopenharmony_ci	while (i-- > 0)
90762306a36Sopenharmony_ci		dma_fence_remove_callback(fences[i], &cb[i].base);
90862306a36Sopenharmony_ci
90962306a36Sopenharmony_cierr_free_cb:
91062306a36Sopenharmony_ci	kfree(cb);
91162306a36Sopenharmony_ci
91262306a36Sopenharmony_ci	return ret;
91362306a36Sopenharmony_ci}
91462306a36Sopenharmony_ciEXPORT_SYMBOL(dma_fence_wait_any_timeout);
91562306a36Sopenharmony_ci
91662306a36Sopenharmony_ci/**
91762306a36Sopenharmony_ci * DOC: deadline hints
91862306a36Sopenharmony_ci *
91962306a36Sopenharmony_ci * In an ideal world, it would be possible to pipeline a workload sufficiently
92062306a36Sopenharmony_ci * that a utilization based device frequency governor could arrive at a minimum
92162306a36Sopenharmony_ci * frequency that meets the requirements of the use-case, in order to minimize
92262306a36Sopenharmony_ci * power consumption.  But in the real world there are many workloads which
92362306a36Sopenharmony_ci * defy this ideal.  For example, but not limited to:
92462306a36Sopenharmony_ci *
92562306a36Sopenharmony_ci * * Workloads that ping-pong between device and CPU, with alternating periods
92662306a36Sopenharmony_ci *   of CPU waiting for device, and device waiting on CPU.  This can result in
92762306a36Sopenharmony_ci *   devfreq and cpufreq seeing idle time in their respective domains and in
92862306a36Sopenharmony_ci *   result reduce frequency.
92962306a36Sopenharmony_ci *
93062306a36Sopenharmony_ci * * Workloads that interact with a periodic time based deadline, such as double
93162306a36Sopenharmony_ci *   buffered GPU rendering vs vblank sync'd page flipping.  In this scenario,
93262306a36Sopenharmony_ci *   missing a vblank deadline results in an *increase* in idle time on the GPU
93362306a36Sopenharmony_ci *   (since it has to wait an additional vblank period), sending a signal to
93462306a36Sopenharmony_ci *   the GPU's devfreq to reduce frequency, when in fact the opposite is what is
93562306a36Sopenharmony_ci *   needed.
93662306a36Sopenharmony_ci *
93762306a36Sopenharmony_ci * To this end, deadline hint(s) can be set on a &dma_fence via &dma_fence_set_deadline.
93862306a36Sopenharmony_ci * The deadline hint provides a way for the waiting driver, or userspace, to
93962306a36Sopenharmony_ci * convey an appropriate sense of urgency to the signaling driver.
94062306a36Sopenharmony_ci *
94162306a36Sopenharmony_ci * A deadline hint is given in absolute ktime (CLOCK_MONOTONIC for userspace
94262306a36Sopenharmony_ci * facing APIs).  The time could either be some point in the future (such as
94362306a36Sopenharmony_ci * the vblank based deadline for page-flipping, or the start of a compositor's
94462306a36Sopenharmony_ci * composition cycle), or the current time to indicate an immediate deadline
94562306a36Sopenharmony_ci * hint (Ie. forward progress cannot be made until this fence is signaled).
94662306a36Sopenharmony_ci *
94762306a36Sopenharmony_ci * Multiple deadlines may be set on a given fence, even in parallel.  See the
94862306a36Sopenharmony_ci * documentation for &dma_fence_ops.set_deadline.
94962306a36Sopenharmony_ci *
95062306a36Sopenharmony_ci * The deadline hint is just that, a hint.  The driver that created the fence
95162306a36Sopenharmony_ci * may react by increasing frequency, making different scheduling choices, etc.
95262306a36Sopenharmony_ci * Or doing nothing at all.
95362306a36Sopenharmony_ci */
95462306a36Sopenharmony_ci
95562306a36Sopenharmony_ci/**
95662306a36Sopenharmony_ci * dma_fence_set_deadline - set desired fence-wait deadline hint
95762306a36Sopenharmony_ci * @fence:    the fence that is to be waited on
95862306a36Sopenharmony_ci * @deadline: the time by which the waiter hopes for the fence to be
95962306a36Sopenharmony_ci *            signaled
96062306a36Sopenharmony_ci *
96162306a36Sopenharmony_ci * Give the fence signaler a hint about an upcoming deadline, such as
96262306a36Sopenharmony_ci * vblank, by which point the waiter would prefer the fence to be
96362306a36Sopenharmony_ci * signaled by.  This is intended to give feedback to the fence signaler
96462306a36Sopenharmony_ci * to aid in power management decisions, such as boosting GPU frequency
96562306a36Sopenharmony_ci * if a periodic vblank deadline is approaching but the fence is not
96662306a36Sopenharmony_ci * yet signaled..
96762306a36Sopenharmony_ci */
96862306a36Sopenharmony_civoid dma_fence_set_deadline(struct dma_fence *fence, ktime_t deadline)
96962306a36Sopenharmony_ci{
97062306a36Sopenharmony_ci	if (fence->ops->set_deadline && !dma_fence_is_signaled(fence))
97162306a36Sopenharmony_ci		fence->ops->set_deadline(fence, deadline);
97262306a36Sopenharmony_ci}
97362306a36Sopenharmony_ciEXPORT_SYMBOL(dma_fence_set_deadline);
97462306a36Sopenharmony_ci
97562306a36Sopenharmony_ci/**
97662306a36Sopenharmony_ci * dma_fence_describe - Dump fence describtion into seq_file
97762306a36Sopenharmony_ci * @fence: the 6fence to describe
97862306a36Sopenharmony_ci * @seq: the seq_file to put the textual description into
97962306a36Sopenharmony_ci *
98062306a36Sopenharmony_ci * Dump a textual description of the fence and it's state into the seq_file.
98162306a36Sopenharmony_ci */
98262306a36Sopenharmony_civoid dma_fence_describe(struct dma_fence *fence, struct seq_file *seq)
98362306a36Sopenharmony_ci{
98462306a36Sopenharmony_ci	seq_printf(seq, "%s %s seq %llu %ssignalled\n",
98562306a36Sopenharmony_ci		   fence->ops->get_driver_name(fence),
98662306a36Sopenharmony_ci		   fence->ops->get_timeline_name(fence), fence->seqno,
98762306a36Sopenharmony_ci		   dma_fence_is_signaled(fence) ? "" : "un");
98862306a36Sopenharmony_ci}
98962306a36Sopenharmony_ciEXPORT_SYMBOL(dma_fence_describe);
99062306a36Sopenharmony_ci
99162306a36Sopenharmony_ci/**
99262306a36Sopenharmony_ci * dma_fence_init - Initialize a custom fence.
99362306a36Sopenharmony_ci * @fence: the fence to initialize
99462306a36Sopenharmony_ci * @ops: the dma_fence_ops for operations on this fence
99562306a36Sopenharmony_ci * @lock: the irqsafe spinlock to use for locking this fence
99662306a36Sopenharmony_ci * @context: the execution context this fence is run on
99762306a36Sopenharmony_ci * @seqno: a linear increasing sequence number for this context
99862306a36Sopenharmony_ci *
99962306a36Sopenharmony_ci * Initializes an allocated fence, the caller doesn't have to keep its
100062306a36Sopenharmony_ci * refcount after committing with this fence, but it will need to hold a
100162306a36Sopenharmony_ci * refcount again if &dma_fence_ops.enable_signaling gets called.
100262306a36Sopenharmony_ci *
100362306a36Sopenharmony_ci * context and seqno are used for easy comparison between fences, allowing
100462306a36Sopenharmony_ci * to check which fence is later by simply using dma_fence_later().
100562306a36Sopenharmony_ci */
100662306a36Sopenharmony_civoid
100762306a36Sopenharmony_cidma_fence_init(struct dma_fence *fence, const struct dma_fence_ops *ops,
100862306a36Sopenharmony_ci	       spinlock_t *lock, u64 context, u64 seqno)
100962306a36Sopenharmony_ci{
101062306a36Sopenharmony_ci	BUG_ON(!lock);
101162306a36Sopenharmony_ci	BUG_ON(!ops || !ops->get_driver_name || !ops->get_timeline_name);
101262306a36Sopenharmony_ci
101362306a36Sopenharmony_ci	kref_init(&fence->refcount);
101462306a36Sopenharmony_ci	fence->ops = ops;
101562306a36Sopenharmony_ci	INIT_LIST_HEAD(&fence->cb_list);
101662306a36Sopenharmony_ci	fence->lock = lock;
101762306a36Sopenharmony_ci	fence->context = context;
101862306a36Sopenharmony_ci	fence->seqno = seqno;
101962306a36Sopenharmony_ci	fence->flags = 0UL;
102062306a36Sopenharmony_ci	fence->error = 0;
102162306a36Sopenharmony_ci
102262306a36Sopenharmony_ci	trace_dma_fence_init(fence);
102362306a36Sopenharmony_ci}
102462306a36Sopenharmony_ciEXPORT_SYMBOL(dma_fence_init);
1025