22/* SPDX-FileCopyrightText: Copyright Amazon.com, Inc. or its affiliates. All rights reserved. */
33
44#include "efa_unit_tests.h"
5+ #include "rdm/efa_rdm_pke_cmd.h"
6+ #include "rdm/efa_rdm_pke_nonreq.h"
57
68typedef void (* efa_rdm_ope_handle_error_func_t )(struct efa_rdm_ope * ope , int err , int prov_errno );
79
@@ -1176,3 +1178,97 @@ void test_efa_rdm_atomic_compare_desc_persistence(struct efa_resource **state)
11761178 efa_unit_test_buff_destruct (& result_buff );
11771179 efa_unit_test_buff_destruct (& compare_buff );
11781180}
1181+ /**
1182+ * @brief Common helper for DC packet TXE release testing
1183+ *
1184+ * Sets up test environment and packet entries for DC packet testing.
1185+ * Tests the specified completion order and verifies TXE release behavior.
1186+ *
1187+ * @param[in] resource Test resource structure
1188+ * @param[in] send_first If true, send completion happens first; if false, receipt first
1189+ */
1190+ static void test_efa_rdm_txe_dc_release_common (struct efa_resource * resource , bool send_first )
1191+ {
1192+ struct efa_rdm_ep * efa_rdm_ep ;
1193+ struct efa_rdm_ope * txe ;
1194+ struct efa_rdm_pke * dc_pkt_entry , * receipt_pkt_entry ;
1195+
1196+ efa_unit_test_resource_construct (resource , FI_EP_RDM , EFA_FABRIC_NAME );
1197+
1198+ efa_rdm_ep = container_of (resource -> ep , struct efa_rdm_ep , base_ep .util_ep .ep_fid );
1199+
1200+ /* Allocate TXE and set up for DC operation */
1201+ txe = efa_unit_test_alloc_txe (resource , ofi_op_msg );
1202+ assert_non_null (txe );
1203+ txe -> internal_flags |= EFA_RDM_TXE_DELIVERY_COMPLETE_REQUESTED ;
1204+ txe -> efa_outstanding_tx_ops = 1 ;
1205+
1206+ /* Create fake DC packet entry */
1207+ dc_pkt_entry = efa_rdm_pke_alloc (efa_rdm_ep , efa_rdm_ep -> efa_tx_pkt_pool , EFA_RDM_PKE_FROM_EFA_TX_POOL );
1208+ assert_non_null (dc_pkt_entry );
1209+ dc_pkt_entry -> ope = txe ;
1210+ dc_pkt_entry -> ep = efa_rdm_ep ;
1211+ dc_pkt_entry -> peer = txe -> peer ;
1212+ /* Set DC packet type in wiredata */
1213+ struct efa_rdm_base_hdr * base_hdr = (struct efa_rdm_base_hdr * )dc_pkt_entry -> wiredata ;
1214+ base_hdr -> type = EFA_RDM_DC_EAGER_MSGRTM_PKT ;
1215+
1216+ /* Create fake receipt packet entry */
1217+ receipt_pkt_entry = efa_rdm_pke_alloc (efa_rdm_ep , efa_rdm_ep -> efa_rx_pkt_pool , EFA_RDM_PKE_FROM_EFA_RX_POOL );
1218+ assert_non_null (receipt_pkt_entry );
1219+ receipt_pkt_entry -> ope = txe ;
1220+ receipt_pkt_entry -> ep = efa_rdm_ep ;
1221+
1222+ /* Verify TXE is not ready for release initially */
1223+ assert_false (efa_rdm_txe_dc_ready_for_release (txe ));
1224+ assert_int_equal (efa_unit_test_get_dlist_length (& efa_rdm_ep -> txe_list ), 1 );
1225+
1226+ if (send_first ) {
1227+ /* Send completion first - should not release TXE yet */
1228+ efa_rdm_pke_handle_send_completion (dc_pkt_entry );
1229+ assert_int_equal (efa_unit_test_get_dlist_length (& efa_rdm_ep -> txe_list ), 1 );
1230+ assert_false (efa_rdm_txe_dc_ready_for_release (txe ));
1231+
1232+ /* Receipt handling - should now release TXE */
1233+ efa_rdm_pke_handle_receipt_recv (receipt_pkt_entry );
1234+ } else {
1235+ /* Receipt handling first - should not release TXE yet */
1236+ efa_rdm_pke_handle_receipt_recv (receipt_pkt_entry );
1237+ assert_int_equal (efa_unit_test_get_dlist_length (& efa_rdm_ep -> txe_list ), 1 );
1238+ assert_true (txe -> internal_flags & EFA_RDM_TXE_RECEIPT_RECEIVED );
1239+ assert_false (efa_rdm_txe_dc_ready_for_release (txe ));
1240+
1241+ /* Send completion - should now release TXE */
1242+ efa_rdm_pke_handle_send_completion (dc_pkt_entry );
1243+ }
1244+
1245+ /* Verify TXE is released */
1246+ assert_int_equal (efa_unit_test_get_dlist_length (& efa_rdm_ep -> txe_list ), 0 );
1247+ }
1248+
1249+ /**
1250+ * @brief Test DC packet TXE release with send completion first
1251+ *
1252+ * This test verifies the DC (Delivery Complete) TXE release logic when
1253+ * send completion arrives before receipt acknowledgment.
1254+ *
1255+ * @param[in] state cmocka state variable
1256+ */
1257+ void test_efa_rdm_txe_dc_send_first (struct efa_resource * * state )
1258+ {
1259+ test_efa_rdm_txe_dc_release_common (* state , true);
1260+ }
1261+
1262+ /**
1263+ * @brief Test DC packet TXE release with receipt completion first
1264+ *
1265+ * This test verifies the race condition fix where receipt acknowledgment
1266+ * arrives before send completion. The TXE should only be released when
1267+ * both conditions are met, regardless of order.
1268+ *
1269+ * @param[in] state cmocka state variable
1270+ */
1271+ void test_efa_rdm_txe_dc_receipt_first (struct efa_resource * * state )
1272+ {
1273+ test_efa_rdm_txe_dc_release_common (* state , false);
1274+ }
0 commit comments