ib_low.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #include "stdafx.h"
  2. #include "ib_low.h"
  3. namespace NNetliba {
  4. static bool EnableROCEFlag = false;
  5. void EnableROCE(bool f) {
  6. EnableROCEFlag = f;
  7. }
  8. #if defined(_linux_)
  9. static TMutex IBPortMutex;
  10. static TIntrusivePtr<TIBPort> IBPort;
  11. static bool IBWasInitialized;
  12. TIntrusivePtr<TIBPort> GetIBDevice() {
  13. TGuard<TMutex> gg(IBPortMutex);
  14. if (IBWasInitialized) {
  15. return IBPort;
  16. }
  17. IBWasInitialized = true;
  18. try {
  19. int rv = ibv_fork_init();
  20. if (rv != 0) {
  21. //printf("ibv_fork_init() failed");
  22. return nullptr;
  23. }
  24. } catch (...) {
  25. //we can not load ib interface, so no ib
  26. return nullptr;
  27. }
  28. TIntrusivePtr<TIBContext> ctx;
  29. TIntrusivePtr<TIBPort> resPort;
  30. int numDevices;
  31. ibv_device** deviceList = ibv_get_device_list(&numDevices);
  32. //for (int i = 0; i < numDevices; ++i) {
  33. // ibv_device *dev = deviceList[i];
  34. // printf("Dev %d\n", i);
  35. // printf("name:%s\ndev_name:%s\ndev_path:%s\nibdev_path:%s\n",
  36. // dev->name,
  37. // dev->dev_name,
  38. // dev->dev_path,
  39. // dev->ibdev_path);
  40. // printf("get_device_name(): %s\n", ibv_get_device_name(dev));
  41. // ui64 devGuid = ibv_get_device_guid(dev);
  42. // printf("ibv_get_device_guid: %" PRIx64 "\n", devGuid);
  43. // printf("node type: %s\n", ibv_node_type_str(dev->node_type));
  44. // printf("\n");
  45. //}
  46. if (numDevices == 1) {
  47. ctx = new TIBContext(deviceList[0]);
  48. TIBContext::TLock ibContext(ctx);
  49. ibv_device_attr devAttrs;
  50. CHECK_Z(ibv_query_device(ibContext.GetContext(), &devAttrs));
  51. for (int port = 1; port <= devAttrs.phys_port_cnt; ++port) {
  52. ibv_port_attr portAttrs;
  53. CHECK_Z(ibv_query_port(ibContext.GetContext(), port, &portAttrs));
  54. //ibv_gid myAddress; // ipv6 address of this port;
  55. //CHECK_Z(ibv_query_gid(ibContext.GetContext(), port, 0, &myAddress));
  56. //{
  57. // ibv_gid p = myAddress;
  58. // for (int k = 0; k < 4; ++k) {
  59. // DoSwap(p.raw[k], p.raw[7 - k]);
  60. // DoSwap(p.raw[8 + k], p.raw[15 - k]);
  61. // }
  62. // printf("Port %d, address %" PRIx64 ":%" PRIx64 "\n",
  63. // port,
  64. // p.global.subnet_prefix,
  65. // p.global.interface_id);
  66. //}
  67. // skip ROCE if flag is not set
  68. if (portAttrs.lid == 0 && EnableROCEFlag == false) {
  69. continue;
  70. }
  71. // bind to first active port
  72. if (portAttrs.state == IBV_PORT_ACTIVE) {
  73. resPort = new TIBPort(ctx, port);
  74. break;
  75. }
  76. }
  77. } else {
  78. //printf("%d IB devices found, fail\n", numDevices);
  79. ctx = nullptr;
  80. }
  81. ibv_free_device_list(deviceList);
  82. IBPort = resPort;
  83. return IBPort;
  84. }
  85. void MakeAH(ibv_ah_attr* res, TPtrArg<TIBPort> port, const TUdpAddress& remoteAddr, const TUdpAddress& localAddr, int serviceLevel) {
  86. ibv_gid localGid, remoteGid;
  87. localGid.global.subnet_prefix = localAddr.Network;
  88. localGid.global.interface_id = localAddr.Interface;
  89. remoteGid.global.subnet_prefix = remoteAddr.Network;
  90. remoteGid.global.interface_id = remoteAddr.Interface;
  91. Zero(*res);
  92. res->is_global = 1;
  93. res->port_num = port->GetPort();
  94. res->sl = serviceLevel;
  95. res->grh.dgid = remoteGid;
  96. //res->grh.flow_label = 0;
  97. res->grh.sgid_index = port->GetGIDIndex(localGid);
  98. res->grh.hop_limit = 7;
  99. //res->grh.traffic_class = 0;
  100. }
  101. #endif
  102. }