[PATCH 16/28] Documentation/litmus-tests: Add hazptr drain engage-wildcard test

From: Kunwu Chan

Date: Wed Nov 04 2026 - 12:11:18 EST


Model the drain engage's wildcard defer: if the engage reads a
slot holding a wildcard (an in-flight slow-path acquire), the
engage must not complete for the target address. The smp_mb()
pairing between the reader's wildcard publication and the
engage's slot read forbids the completion interleaving
(herd7: Never).

Signed-off-by: Kunwu Chan <kunwu.chan@xxxxxxxxx>
---
Documentation/litmus-tests/README | 5 +++
.../hazptr-drain-engage-wildcard.litmus | 44 +++++++++++++++++++
2 files changed, 49 insertions(+)
create mode 100644 Documentation/litmus-tests/hazptr/hazptr-drain-engage-wildcard.litmus

diff --git a/Documentation/litmus-tests/README b/Documentation/litmus-tests/README
index c2bf20fa4092..daab126e45a2 100644
--- a/Documentation/litmus-tests/README
+++ b/Documentation/litmus-tests/README
@@ -110,3 +110,8 @@ hazptr-wildcard-flip-escape.litmus
Test the in-flight wildcard window of the single-pass wildcard-flip
scan: a straggling acquire that published the old wildcard after
the final walk cannot still load the unpublished object.
+
+hazptr-drain-engage-wildcard.litmus
+ Test the drain engage's wildcard defer: an engage that reads a
+ slot holding a wildcard (an in-flight slow-path acquire) must
+ not complete for the target address.
diff --git a/Documentation/litmus-tests/hazptr/hazptr-drain-engage-wildcard.litmus b/Documentation/litmus-tests/hazptr/hazptr-drain-engage-wildcard.litmus
new file mode 100644
index 000000000000..0cee89893dad
--- /dev/null
+++ b/Documentation/litmus-tests/hazptr/hazptr-drain-engage-wildcard.litmus
@@ -0,0 +1,44 @@
+C hazptr-drain-engage-wildcard
+
+(*
+ * Result: Never
+ *
+ * Models the engage's wildcard defer: if the slot holds a
+ * wildcard (transient value 1) at the time the engage reads
+ * it, the engage must not complete for the target address.
+ *
+ * P0 (reclaimer): unpublishes head, then reads the slot.
+ * P1 (reader): publishes wildcard (1), then replaces with
+ * the target address (2).
+ *
+ * The smp_mb() pair ensures the engage cannot observe the
+ * target (2) while the reader still sees the pre-unpublish
+ * head. This verifies the publication ordering that the
+ * engage relies on to defer when it sees a wildcard.
+ *)
+
+{
+ head = 1;
+ slot = 0;
+}
+
+P0(int *head, int *slot)
+{
+ int r0;
+
+ WRITE_ONCE(*head, 0);
+ smp_mb();
+ r0 = READ_ONCE(*slot);
+}
+
+P1(int *slot, int *head)
+{
+ int r1;
+
+ WRITE_ONCE(*slot, 1);
+ smp_mb();
+ WRITE_ONCE(*slot, 2);
+ r1 = READ_ONCE(*head);
+}
+
+exists (0:r0=0 /\ 1:r1=1)
--
2.43.0