@@ -392,38 +392,54 @@ static inline int ipv6_addr_v4mapped(const struct in6_addr *a) {
392392 ((a->s6_addr32 [1 ] | (a->s6_addr32 [2 ] ^ htonl (0x0000ffff ))) == 0UL ));
393393}
394394
395+
396+ static std::string readGidNdev (const std::string &device_name, uint8_t port, int gid_index) {
397+ std::string sysfs_path = " /sys/class/infiniband/" + device_name +
398+ " /ports/" + std::to_string (port) +
399+ " /gid_attrs/ndevs/" + std::to_string (gid_index);
400+ std::ifstream file (sysfs_path);
401+ if (!file.is_open ()) {
402+ return " " ;
403+ }
404+
405+ std::string ndev;
406+ std::getline (file, ndev);
407+ file.close ();
408+ return ndev;
409+ }
410+
395411int RdmaContext::getBestGidIndex (const std::string &device_name,
396412 struct ibv_context *context,
397413 ibv_port_attr &port_attr, uint8_t port) {
398- int best_gid_index = 0 ;
399- int best_priority = -1 ;
414+ int gid_index = 0 , i;
400415 struct ibv_gid_entry gid_entry;
416+ bool fallback_found = false ;
401417
402- for (int i = 0 ; i < port_attr.gid_tbl_len ; i++) {
418+ for (i = 0 ; i < port_attr.gid_tbl_len ; i++) {
403419 if (ibv_query_gid_ex (context, port, i, &gid_entry, 0 )) {
404420 PLOG (ERROR) << " Failed to query GID " << i << " on " << device_name
405421 << " /" << port;
406422 continue ; // if gid is invalid ibv_query_gid_ex() will return !0
407423 }
408- int priority = -1 ;
409- bool is_ipv4_mapped = ipv6_addr_v4mapped ((struct in6_addr *)gid_entry.gid .raw );
410-
411- if (is_ipv4_mapped && gid_entry.gid_type == IBV_GID_TYPE_ROCE_V2) {
412- priority = 3 ; // 最高优先级
413- } else if (is_ipv4_mapped) {
414- priority = 2 ;
415- } else if (gid_entry.gid_type == IBV_GID_TYPE_IB) {
416- priority = 1 ;
417- } else if (gid_entry.gid_type == IBV_GID_TYPE_ROCE_V2) {
418- priority = 0 ;
419- }
420424
421- if (priority > best_priority) {
422- best_priority = priority;
423- best_gid_index = i;
425+ if ((ipv6_addr_v4mapped ((struct in6_addr *)gid_entry.gid .raw ) &&
426+ gid_entry.gid_type == IBV_GID_TYPE_ROCE_V2) ||
427+ gid_entry.gid_type == IBV_GID_TYPE_IB) {
428+ // Check if this GID has an associated network device
429+ std::string ndev = readGidNdev (device_name, port, i);
430+ if (!ndev.empty ()) {
431+ // Found a GID with network device, this is the best choice
432+ gid_index = i;
433+ break ;
434+ }
435+ // No network device, keep the first one as fallback candidate
436+ if (!fallback_found) {
437+ gid_index = i;
438+ fallback_found = true ;
439+ }
424440 }
425441 }
426- return best_gid_index ;
442+ return gid_index ;
427443}
428444
429445int RdmaContext::openRdmaDevice (const std::string &device_name, uint8_t port,
0 commit comments