@@ -163,6 +163,7 @@ static int usnic_component_open(void)
163163 mca_btl_usnic_component .usnic_all_modules = NULL ;
164164 mca_btl_usnic_component .usnic_active_modules = NULL ;
165165 mca_btl_usnic_component .transport_header_len = -1 ;
166+ mca_btl_usnic_component .prefix_send_offset = 0 ;
166167
167168 /* initialize objects */
168169 OBJ_CONSTRUCT (& mca_btl_usnic_component .usnic_procs , opal_list_t );
@@ -630,7 +631,29 @@ static mca_btl_base_module_t** usnic_component_init(int* num_btl_modules,
630631 hints .ep_attr = & ep_attr ;
631632 hints .fabric_attr = & fabric_attr ;
632633
633- ret = fi_getinfo (FI_VERSION (1 , 0 ), NULL , 0 , 0 , & hints , & info_list );
634+ /* This code understands libfabric API v1.0 and v1.1. Even if we
635+ were compiled with libfabric API v1.0, we still want to request
636+ v1.1 -- here's why:
637+
638+ - In libfabric v1.0.0 (i.e., API v1.0), the usnic provider did
639+ not check the value of the "version" parameter passed into
640+ fi_getinfo()
641+
642+ - If you pass FI_VERSION(1,0) to libfabric v1.1.0 (i.e., API
643+ v1.1), the usnic provider will disable FI_MSG_PREFIX support
644+ (on the assumption that the application will not handle
645+ FI_MSG_PREFIX properly). This can happen if you compile OMPI
646+ against libfabric v1.0.0 (i.e., API v1.0) and run OMPI
647+ against libfabric v1.1.0 (i.e., API v1.1).
648+
649+ So never request API v1.0 -- always request a minimum of
650+ v1.1. */
651+ uint32_t libfabric_api ;
652+ libfabric_api = FI_VERSION (FI_MAJOR_VERSION , FI_MINOR_VERSION );
653+ if (libfabric_api == FI_VERSION (1 , 0 )) {
654+ libfabric_api = FI_VERSION (1 , 1 );
655+ }
656+ ret = fi_getinfo (libfabric_api , NULL , 0 , 0 , & hints , & info_list );
634657 if (0 != ret ) {
635658 opal_output_verbose (5 , USNIC_OUT ,
636659 "btl:usnic: disqualifiying myself due to fi_getinfo failure: %s (%d)" , strerror (- ret ), ret );
@@ -664,6 +687,29 @@ static mca_btl_base_module_t** usnic_component_init(int* num_btl_modules,
664687 opal_output_verbose (5 , USNIC_OUT ,
665688 "btl:usnic: usNIC fabrics found" );
666689
690+ /* Due to ambiguities in documentation, in libfabric v1.0.0 (i.e.,
691+ API v1.0) the usnic provider returned sizeof(struct
692+ fi_cq_err_entry) from fi_cq_readerr() upon success.
693+
694+ The ambiguities were clarified in libfabric v1.1.0 (i.e., API
695+ v1.1); the usnic provider returned 1 from fi_cq_readerr() upon
696+ success.
697+
698+ So query to see what version of the libfabric API we are
699+ running with, and adapt accordingly. */
700+ libfabric_api = fi_version ();
701+ if (1 == FI_MAJOR (libfabric_api ) &&
702+ 0 == FI_MINOR (libfabric_api )) {
703+ // Old fi_cq_readerr() behavior: success=sizeof(...), try again=0
704+ mca_btl_usnic_component .cq_readerr_success_value =
705+ sizeof (struct fi_cq_err_entry );
706+ mca_btl_usnic_component .cq_readerr_try_again_value = 0 ;
707+ } else {
708+ // New fi_cq_readerr() behavior: success=1, try again=-FI_EAGAIN
709+ mca_btl_usnic_component .cq_readerr_success_value = 1 ;
710+ mca_btl_usnic_component .cq_readerr_try_again_value = - FI_EAGAIN ;
711+ }
712+
667713 /* libnl initialization */
668714 opal_proc_t * me = opal_proc_local_get ();
669715 opal_process_name_t * name = & (me -> proc_name );
@@ -1087,34 +1133,28 @@ static int usnic_handle_completion(
10871133 seg = (opal_btl_usnic_segment_t * )completion -> op_context ;
10881134 rseg = (opal_btl_usnic_recv_segment_t * )seg ;
10891135
1136+ /* Make the completion be Valgrind-defined */
1137+ opal_memchecker_base_mem_defined (seg , sizeof (* seg ));
1138+
10901139 /* Handle work completions */
10911140 switch (seg -> us_type ) {
10921141
10931142 /**** Send ACK completions ****/
10941143 case OPAL_BTL_USNIC_SEG_ACK :
10951144 opal_btl_usnic_ack_complete (module ,
10961145 (opal_btl_usnic_ack_segment_t * )seg );
1097- { opal_btl_usnic_send_segment_t * sseg = (opal_btl_usnic_send_segment_t * )seg ;
1098- ++ module -> mod_channels [sseg -> ss_channel ].credits ;
1099- }
11001146 break ;
11011147
11021148 /**** Send of frag segment completion ****/
11031149 case OPAL_BTL_USNIC_SEG_FRAG :
11041150 opal_btl_usnic_frag_send_complete (module ,
11051151 (opal_btl_usnic_frag_segment_t * )seg );
1106- { opal_btl_usnic_send_segment_t * sseg = (opal_btl_usnic_send_segment_t * )seg ;
1107- ++ module -> mod_channels [sseg -> ss_channel ].credits ;
1108- }
11091152 break ;
11101153
11111154 /**** Send of chunk segment completion ****/
11121155 case OPAL_BTL_USNIC_SEG_CHUNK :
11131156 opal_btl_usnic_chunk_send_complete (module ,
11141157 (opal_btl_usnic_chunk_segment_t * )seg );
1115- { opal_btl_usnic_send_segment_t * sseg = (opal_btl_usnic_send_segment_t * )seg ;
1116- ++ module -> mod_channels [sseg -> ss_channel ].credits ;
1117- }
11181158 break ;
11191159
11201160 /**** Receive completions ****/
@@ -1145,17 +1185,27 @@ usnic_handle_cq_error(opal_btl_usnic_module_t* module,
11451185 }
11461186
11471187 rc = fi_cq_readerr (channel -> cq , & err_entry , 0 );
1148- if (rc != sizeof (err_entry )) {
1149- BTL_ERROR (("%s: cq_readerr ret = %d" ,
1150- module -> fabric_info -> fabric_attr -> name , rc ));
1188+ if (rc == mca_btl_usnic_component .cq_readerr_try_again_value ) {
1189+ return ;
1190+ } else if (rc != mca_btl_usnic_component .cq_readerr_success_value ) {
1191+ BTL_ERROR (("%s: cq_readerr ret = %d (expected %d)" ,
1192+ module -> fabric_info -> fabric_attr -> name , rc ,
1193+ (int ) mca_btl_usnic_component .cq_readerr_success_value ));
11511194 channel -> chan_error = true;
1152- } else if (err_entry .prov_errno == 1 ) {
1195+ }
1196+
1197+ /* Silently count CRC errors. Truncation errors are usually a
1198+ different symptom of a CRC error. */
1199+ else if (FI_ECRC == err_entry .prov_errno ||
1200+ FI_ETRUNC == err_entry .prov_errno ) {
11531201#if MSGDEBUG1
11541202 static int once = 0 ;
11551203 if (once ++ == 0 ) {
1156- BTL_ERROR (("%s: Channel %d, CRC error" ,
1157- module -> fabric_info -> fabric_attr -> name ,
1158- channel -> chan_index ));
1204+ BTL_ERROR (("%s: Channel %d, %s" ,
1205+ module -> fabric_info -> fabric_attr -> name ,
1206+ channel -> chan_index ,
1207+ FI_ECRC == err_entry .prov_errno ?
1208+ "CRC error" : "message truncation" ));
11591209 }
11601210#endif
11611211
@@ -1171,23 +1221,10 @@ usnic_handle_cq_error(opal_btl_usnic_module_t* module,
11711221 rseg -> rs_next = channel -> repost_recv_head ;
11721222 channel -> repost_recv_head = rseg ;
11731223 }
1174- } else if (FI_ETRUNC == err_entry .prov_errno ) {
1175- /* This error is usually a different symptom of a CRC error */
1176- #if MSGDEBUG1
1177- static int once = 0 ;
1178- if (once ++ == 0 ) {
1179- BTL_ERROR (("%s: Channel %d, message truncation" ,
1180- module -> fabric_info -> fabric_attr -> name ,
1181- channel -> chan_index ));
1182- }
1183- #endif
1184-
1185- /* silently count CRC errors */
1186- ++ module -> stats .num_crc_errors ;
11871224 } else {
11881225 BTL_ERROR (("%s: CQ[%d] prov_err = %d" ,
11891226 module -> fabric_info -> fabric_attr -> name , channel -> chan_index ,
1190- err_entry .prov_errno ));
1227+ err_entry .prov_errno ));
11911228 channel -> chan_error = true;
11921229 }
11931230}
0 commit comments