[PATCH 2/2] dma-buf/fence-chain: Access test chain fences via API
Janusz Krzysztofik
janusz.krzysztofik at linux.intel.com
Tue Aug 12 08:38:04 UTC 2025
Test cases which iterate over each node of a chain now access the nodes
via a locally maintained table of chain fences. That uncommon way of
accessing the nodes can make the picture less clear when issues are
reported for those test cases, raising doubts on whether such use patterns
aren't broken, or apply to DMA fence arrays rather than to chains.
Refer to individual chain links via the dma_fence_chain API wherever
possible, leaving the local table of chains and fences for post-test
cleanup use.
Suggested-by: Christian König <christian.koenig at amd.com>
Signed-off-by: Janusz Krzysztofik <janusz.krzysztofik at linux.intel.com>
---
drivers/dma-buf/st-dma-fence-chain.c | 113 +++++++++++++++++++++------
1 file changed, 89 insertions(+), 24 deletions(-)
diff --git a/drivers/dma-buf/st-dma-fence-chain.c b/drivers/dma-buf/st-dma-fence-chain.c
index 80598da9237af..3fc05f0853e57 100644
--- a/drivers/dma-buf/st-dma-fence-chain.c
+++ b/drivers/dma-buf/st-dma-fence-chain.c
@@ -495,26 +495,54 @@ static int find_race(void *arg)
static int signal_forward(void *arg)
{
+ uint64_t (*seqno_fn)(unsigned int) = seqno_inc;
struct fence_chains fc;
int err;
int i;
- err = fence_chains_init(&fc, 64, seqno_inc);
+ err = fence_chains_init(&fc, 64, seqno_fn);
if (err)
return err;
for (i = 0; i < fc.chain_length; i++) {
- dma_fence_signal(fc.fences[i]);
+ struct dma_fence *chain = dma_fence_get(fc.tail);
+ uint64_t seqno = seqno_fn(i);
+ int fence_err = dma_fence_chain_find_seqno(&chain, seqno);
+
+ dma_fence_put(chain);
+ if (fence_err) {
+ pr_err("Reported %d for dma_fence_chain_find_seqno(%llu)!\n",
+ fence_err, seqno);
+ if (!err)
+ err = fence_err;
+ continue;
+ }
- if (!dma_fence_is_signaled(fc.chains[i])) {
- pr_err("chain[%d] not signaled!\n", i);
+ dma_fence_signal(dma_fence_chain_contained(chain));
+
+ if (!dma_fence_is_signaled(chain)) {
+ pr_err("chain[seqno:%llu] not signaled!\n", seqno);
err = -EINVAL;
goto err;
}
- if (i + 1 < fc.chain_length &&
- dma_fence_is_signaled(fc.chains[i + 1])) {
- pr_err("chain[%d] is signaled!\n", i);
+ if (i + 1 >= fc.chain_length)
+ continue;
+
+ chain = dma_fence_get(fc.tail);
+ seqno = seqno_fn(i + 1);
+ fence_err = dma_fence_chain_find_seqno(&chain, seqno);
+ dma_fence_put(chain);
+ if (fence_err) {
+ pr_err("Reported %d for dma_fence_chain_find_seqno(%llu)!\n",
+ fence_err, seqno);
+ if (!err)
+ err = fence_err;
+ continue;
+ }
+
+ if (dma_fence_is_signaled(chain)) {
+ pr_err("chain[seqno:%llu] is signaled!\n", seqno);
err = -EINVAL;
goto err;
}
@@ -527,32 +555,35 @@ static int signal_forward(void *arg)
static int signal_backward(void *arg)
{
+ uint64_t (*seqno_fn)(unsigned int) = seqno_inc;
+ struct dma_fence *chain;
struct fence_chains fc;
+ uint64_t seqno;
int err;
int i;
- err = fence_chains_init(&fc, 64, seqno_inc);
+ err = fence_chains_init(&fc, 64, seqno_fn);
if (err)
return err;
- for (i = fc.chain_length; i--; ) {
- dma_fence_signal(fc.fences[i]);
+ seqno = seqno_fn(0);
+ dma_fence_chain_for_each(chain, fc.tail) {
+ dma_fence_signal(dma_fence_chain_contained(chain));
- if (i > 0 && dma_fence_is_signaled(fc.chains[i])) {
- pr_err("chain[%d] is signaled!\n", i);
+ if (chain->seqno > seqno && dma_fence_is_signaled(chain)) {
+ pr_err("chain[seqno:%llu] is signaled!\n", chain->seqno);
err = -EINVAL;
goto err;
}
}
-
for (i = 0; i < fc.chain_length; i++) {
+ seqno = seqno_fn(i);
if (!dma_fence_is_signaled(fc.chains[i])) {
- pr_err("chain[%d] was not signaled!\n", i);
+ pr_err("chain[seqno:%llu] was not signaled!\n", seqno);
err = -EINVAL;
goto err;
}
}
-
err:
fence_chains_fini(&fc);
return err;
@@ -570,13 +601,15 @@ static int __wait_fence_chains(void *arg)
static int wait_forward(void *arg)
{
+ uint64_t (*seqno_fn)(unsigned int) = seqno_inc;
+ struct dma_fence *chain;
struct fence_chains fc;
struct task_struct *tsk;
ktime_t dt;
int err;
int i;
- err = fence_chains_init(&fc, CHAIN_SZ, seqno_inc);
+ err = fence_chains_init(&fc, CHAIN_SZ, seqno_fn);
if (err)
return err;
@@ -589,8 +622,23 @@ static int wait_forward(void *arg)
yield_to(tsk, true);
dt = -ktime_get();
- for (i = 0; i < fc.chain_length; i++)
- dma_fence_signal(fc.fences[i]);
+ for (i = 0; i < fc.chain_length; i++) {
+ uint64_t seqno = seqno_fn(i);
+ int fence_err;
+
+ chain = dma_fence_get(fc.tail);
+ fence_err = dma_fence_chain_find_seqno(&chain, seqno);
+ dma_fence_put(chain);
+ if (fence_err) {
+ pr_err("Reported %d for dma_fence_chain_find_seqno(%llu)!\n",
+ fence_err, seqno);
+ if (!err)
+ err = fence_err;
+ continue;
+ }
+
+ dma_fence_signal(dma_fence_chain_contained(chain));
+ }
dt += ktime_get();
pr_info("%s: %d signals in %llu ns\n", __func__, fc.chain_length, ktime_to_ns(dt));
@@ -604,11 +652,11 @@ static int wait_forward(void *arg)
static int wait_backward(void *arg)
{
+ struct dma_fence *chain;
struct fence_chains fc;
struct task_struct *tsk;
ktime_t dt;
int err;
- int i;
err = fence_chains_init(&fc, CHAIN_SZ, seqno_inc);
if (err)
@@ -623,8 +671,9 @@ static int wait_backward(void *arg)
yield_to(tsk, true);
dt = -ktime_get();
- for (i = fc.chain_length; i--; )
- dma_fence_signal(fc.fences[i]);
+ dma_fence_chain_for_each(chain, fc.tail)
+ dma_fence_signal(dma_fence_chain_contained(chain));
+ dma_fence_put(chain);
dt += ktime_get();
pr_info("%s: %d signals in %llu ns\n", __func__, fc.chain_length, ktime_to_ns(dt));
@@ -648,12 +697,13 @@ static void randomise_fences(struct fence_chains *fc)
if (swp == count)
continue;
- swap(fc->fences[count], fc->fences[swp]);
+ swap(fc->chains[count], fc->chains[swp]);
}
}
static int wait_random(void *arg)
{
+ struct dma_fence *chain;
struct fence_chains fc;
struct task_struct *tsk;
ktime_t dt;
@@ -675,8 +725,23 @@ static int wait_random(void *arg)
yield_to(tsk, true);
dt = -ktime_get();
- for (i = 0; i < fc.chain_length; i++)
- dma_fence_signal(fc.fences[i]);
+ for (i = 0; i < fc.chain_length; i++) {
+ uint64_t seqno = fc.chains[i]->seqno;
+ int fence_err;
+
+ chain = dma_fence_get(fc.tail);
+ fence_err = dma_fence_chain_find_seqno(&chain, seqno);
+ dma_fence_put(chain);
+ if (fence_err) {
+ pr_err("Reported %d for dma_fence_chain_find_seqno(%llu)!\n",
+ fence_err, seqno);
+ if (!err)
+ err = fence_err;
+ continue;
+ }
+
+ dma_fence_signal(dma_fence_chain_contained(chain));
+ }
dt += ktime_get();
pr_info("%s: %d signals in %llu ns\n", __func__, fc.chain_length, ktime_to_ns(dt));
--
2.50.1
More information about the Intel-gfx-trybot
mailing list