Skip to content

Commit d8782e5

Browse files
author
Nicolas Pitre
committed
tests: lib: lockfree: Fix MPSC test consumer node return logic
The MPSC test consumer was incorrectly handling node returns to producer free queues. It called spsc_acquire() without checking the return value, then unconditionally called spsc_produce(). When the SPSC free queue was full, spsc_acquire() would return NULL and not increment the acquire counter, causing spsc_produce() to silently do nothing (it only produces if acquire > 0). This resulted in lost nodes. At least on QEMU, a 4-CPU configuration is needed for this bug to manifest. Producers put all nodes in flight simultaneously with the single consumer unable to keep up, causing frequent SPSC queue full conditions. The Fix: Loop on spsc_acquire() until it succeeds before calling spsc_produce(). This ensures nodes are always successfully returned to producer queues. Added board overlay for qemu_cortex_a53/smp to enable 4-CPU testing, which reproduces the issue and validates the fix. Signed-off-by: Nicolas Pitre <[email protected]>
1 parent 86a46c4 commit d8782e5

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Configuration overlay for 4-CPU testing on QEMU Cortex-A53
2+
CONFIG_MP_MAX_NUM_CPUS=4
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* Device tree overlay to add 2 more CPUs to QEMU Cortex-A53 SMP
5+
* for testing 4-CPU configurations
6+
*/
7+
8+
/ {
9+
cpus {
10+
cpu@2 {
11+
device_type = "cpu";
12+
compatible = "arm,cortex-a53";
13+
reg = <2>;
14+
};
15+
16+
cpu@3 {
17+
device_type = "cpu";
18+
compatible = "arm,cortex-a53";
19+
reg = <3>;
20+
};
21+
};
22+
};

tests/lib/lockfree/src/test_mpsc.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,10 @@ static void mpsc_consumer(void *p1, void *p2, void *p3)
127127

128128
nn = CONTAINER_OF(n, struct test_mpsc_node, n);
129129

130-
spsc_acquire(node_q[nn->id]);
130+
/* Return node to producer's free queue - must retry if queue is full */
131+
while (spsc_acquire(node_q[nn->id]) == NULL) {
132+
k_yield();
133+
}
131134
spsc_produce(node_q[nn->id]);
132135
}
133136
}

0 commit comments

Comments
 (0)