Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IB/BASE: Fixes #8595 #8603

Merged
merged 1 commit into from
Oct 19, 2022
Merged

IB/BASE: Fixes #8595 #8603

merged 1 commit into from
Oct 19, 2022

Conversation

shamisp
Copy link
Contributor

@shamisp shamisp commented Oct 6, 2022

What

The code prevents MD to create PD if the underlying transport is not supported by UCX.

Why ?

Fixes #8595

How ?

If the verbs transport layer is not ethernet, roce, or IB - skip the device

@shamisp shamisp requested review from dmitrygx and yosefe October 6, 2022 22:05
uint8_t port_num;
uint8_t usable_port_cnt = 0;

if (uct_ib_device_is_iwarp(dev)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO we should modify

if (uct_ib_device_is_iwarp(dev)) {
/* TODO: enable it when support is ready */
ucs_debug("iWarp device %s is not supported", uct_ib_device_name(dev));
return UCS_ERR_UNSUPPORTED;
}
if (!uct_ib_device_is_port_ib(dev, port_num) && (flags & UCT_IB_DEVICE_FLAG_LINK_IB)) {
ucs_debug("%s:%d is not IB link layer", uct_ib_device_name(dev),
port_num);
return UCS_ERR_UNSUPPORTED;
}

  1. move uct_ib_device_is_iwarp() from uct_ib_device_port_check to
    if (!uct_ib_device_is_accessible(device_list[i])) {
  2. check that port is RoCE or IB in
    if (!uct_ib_device_is_port_ib(dev, port_num) && (flags & UCT_IB_DEVICE_FLAG_LINK_IB)) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that the solution does not look super clean. The logic between MD creating and the rest of the code is not unified. I was really puzzled when I went through the code.

Copy link
Contributor Author

@shamisp shamisp Oct 15, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yosefe I implemented what you have suggested and it does not look good.
1 - Will work but ...
2 - It is not going to work because uct_ib_device_port_check that you referenced is invoked after MD creation, which too late.

Just addressing #1 is possible but then you only execute the iwarp part of the check in uct_ib_device_is_accessible and the second half (not roce or IB) in uct_ib_device_init which makes code much more complex to understand. Essentially the logical check "not verbs compliant device that has verbs" gets spread over different places. IMHO current implementation is more reasonable.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we are checking the port type after creating the md because in case some ports are supported and some are not, it makes more sense to disable only the unsupported ports and not the entire device.
if the device does not have any supported ports we would eventually close the md anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yosefe I understand why you are checking port by port and the patch is doing the same in much earlier stage so we don't create MD for "non-verbs" devices.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yosefe I understand why you are checking port by port and the patch is doing the same in much earlier stage so we don't create MD for "non-verbs" devices.

@shamisp what is the reason we must avoid creating such MD?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yosefe Because the TL does not work on transport layers other than IBV_TRANSPORT_IB, which cover both ROCE and IB.
We know that IBV_TRANSPORT_USNIC, IBV_TRANSPORT_USNIC_UDP, and IBV_TRANSPORT_UNSPECIFIED. So, why to enable and then cause failures and leaks when on such systems only TCP has to be used in default mode.

Copy link
Contributor Author

@shamisp shamisp Oct 17, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yosefe , what to do thing about the patch bellow (please ignore my ifdef 0 debug section). On AWS machine with EFA I have all tests passing.

@@ -1280,6 +1280,32 @@ static uct_md_ops_t UCS_V_UNUSED uct_ib_md_global_odp_ops = {
     .detect_memory_type = ucs_empty_function_return_unsupported,
 };
 
+#if 0
+static const char *uct_ib_device_transport_to_name(struct ibv_device *device)
+{
+    switch (device->transport_type) {
+        case IBV_TRANSPORT_IB:
+            return "InfiniBand";
+        case IBV_TRANSPORT_IWARP:
+            return "iWARP";
+        case IBV_TRANSPORT_USNIC:
+            return "usNIC";
+        case IBV_TRANSPORT_USNIC_UDP:
+            return "usNIC UDP";
+        case IBV_TRANSPORT_UNSPECIFIED:
+            return "Unspecified";
+        default:
+            return "Unknown";
+    }
+}
+#endif
+
+static int uct_ib_device_is_supported(struct ibv_device *device)
+{
+    /* TODO: enable additional transport types when ready */
+    return device->transport_type == IBV_TRANSPORT_IB;
+}
+
 int uct_ib_device_is_accessible(struct ibv_device *device)
 {
     /* Enough place to hold the full path */
@@ -1298,7 +1324,7 @@ int uct_ib_device_is_accessible(struct ibv_device *device)
         return 0;
     }
 
-    return 1;
+    return uct_ib_device_is_supported(device);
 }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@yosefe
Copy link
Contributor

yosefe commented Oct 15, 2022

@shamisp does #8466 fix the issue?

@shamisp
Copy link
Contributor Author

shamisp commented Oct 15, 2022

I will take a look but IMHO what I proposed here is cleaner - we should not create these MD all together.

@shamisp
Copy link
Contributor Author

shamisp commented Oct 15, 2022

@yosefe #8466 fixes ucx_perftest run but with my patch I see less failures in gtest
with this patch:

[----------] Global test environment tear-down
[==========] 11097 tests from 500 test suites ran. (1752337 ms total)
[  PASSED  ] 11067 tests.
[  FAILED  ] 30 tests, listed below:
[  FAILED  ] test_uct_ib_sl_utils.query_ooo_sl_mask, where TypeParam =  and GetParam() = 
[  FAILED  ] ib/test_md.rkey_ptr/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.alloc/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.mem_type_detect_mds/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.mem_query/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.sys_device/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.reg/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.reg_perf/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.reg_advise/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.alloc_advise/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.reg_multi_thread/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.sockaddr_accessibility/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.invalidate/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.reg_bad_arg/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.dereg_bad_arg/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.exported_mkey/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md_fork.fork/0, where GetParam() = rdmap0s6
[  FAILED  ] alloc_methods/test_mem.md_alloc/0, where GetParam() = 0
[  FAILED  ] alloc_methods/test_mem.md_alloc/1, where GetParam() = 2
[  FAILED  ] alloc_methods/test_mem.md_alloc/2, where GetParam() = 3
[  FAILED  ] alloc_methods/test_mem.md_alloc/3, where GetParam() = 4
[  FAILED  ] alloc_methods/test_mem.md_fixed/0, where GetParam() = 0
[  FAILED  ] alloc_methods/test_mem.md_fixed/1, where GetParam() = 2
[  FAILED  ] alloc_methods/test_mem.md_fixed/2, where GetParam() = 3
[  FAILED  ] alloc_methods/test_mem.md_fixed/3, where GetParam() = 4
[  FAILED  ] ib/test_ib_md.ib_md_umr_rcache/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_ib_md.ib_md_umr_direct/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_ib_md.ib_md_umr_ksm/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_ib_md.relaxed_order/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_ib_md.aligned/0, where GetParam() = rdmap0s6

with #8466 only

[----------] Global test environment tear-down
[==========] 11097 tests from 500 test suites ran. (1728054 ms total)
[  PASSED  ] 11065 tests.
[  FAILED  ] 32 tests, listed below:
[  FAILED  ] test_uct_ib_sl_utils.query_ooo_sl_mask, where TypeParam =  and GetParam() = 
[  FAILED  ] ib/test_md.rkey_ptr/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.alloc/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.mem_type_detect_mds/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.mem_query/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.sys_device/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.reg/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.reg_perf/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.reg_advise/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.alloc_advise/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.reg_multi_thread/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.sockaddr_accessibility/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.invalidate/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.reg_bad_arg/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.dereg_bad_arg/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.exported_mkey/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md_fork.fork/0, where GetParam() = rdmap0s6
[  FAILED  ] alloc_methods/test_mem.md_alloc/0, where GetParam() = 0
[  FAILED  ] alloc_methods/test_mem.md_alloc/1, where GetParam() = 2
[  FAILED  ] alloc_methods/test_mem.md_alloc/2, where GetParam() = 3
[  FAILED  ] alloc_methods/test_mem.md_alloc/3, where GetParam() = 4
[  FAILED  ] alloc_methods/test_mem.md_fixed/0, where GetParam() = 0
[  FAILED  ] alloc_methods/test_mem.md_fixed/1, where GetParam() = 2
[  FAILED  ] alloc_methods/test_mem.md_fixed/2, where GetParam() = 3
[  FAILED  ] alloc_methods/test_mem.md_fixed/3, where GetParam() = 4
[  FAILED  ] cma/test_uct_perf.envelope/0, where GetParam() = cma/memory
[  FAILED  ] cma/test_uct_loopback.envelope/0, where GetParam() = cma/memory
[  FAILED  ] ib/test_ib_md.ib_md_umr_rcache/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_ib_md.ib_md_umr_direct/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_ib_md.ib_md_umr_ksm/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_ib_md.relaxed_order/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_ib_md.aligned/0, where GetParam() = rdmap0s6

@dmitrygx
Copy link
Member

I see the difference:

[  FAILED  ] cma/test_uct_perf.envelope/0, where GetParam() = cma/memory
[  FAILED  ] cma/test_uct_loopback.envelope/0, where GetParam() = cma/memory

these failures couldn't be related to #8466

@shamisp
Copy link
Contributor Author

shamisp commented Oct 17, 2022

@dmitrygx I applied this patch on top of your patch and I don't see these two errors.
Probably some other leaks that is not covered by your original patch:

[  PASSED  ] 11067 tests.
[  FAILED  ] 30 tests, listed below:
[  FAILED  ] test_uct_ib_sl_utils.query_ooo_sl_mask, where TypeParam =  and GetParam() = 
[  FAILED  ] ib/test_md.rkey_ptr/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.alloc/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.mem_type_detect_mds/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.mem_query/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.sys_device/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.reg/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.reg_perf/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.reg_advise/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.alloc_advise/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.reg_multi_thread/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.sockaddr_accessibility/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.invalidate/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.reg_bad_arg/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.dereg_bad_arg/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md.exported_mkey/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_md_fork.fork/0, where GetParam() = rdmap0s6
[  FAILED  ] alloc_methods/test_mem.md_alloc/0, where GetParam() = 0
[  FAILED  ] alloc_methods/test_mem.md_alloc/1, where GetParam() = 2
[  FAILED  ] alloc_methods/test_mem.md_alloc/2, where GetParam() = 3
[  FAILED  ] alloc_methods/test_mem.md_alloc/3, where GetParam() = 4
[  FAILED  ] alloc_methods/test_mem.md_fixed/0, where GetParam() = 0
[  FAILED  ] alloc_methods/test_mem.md_fixed/1, where GetParam() = 2
[  FAILED  ] alloc_methods/test_mem.md_fixed/2, where GetParam() = 3
[  FAILED  ] alloc_methods/test_mem.md_fixed/3, where GetParam() = 4
[  FAILED  ] ib/test_ib_md.ib_md_umr_rcache/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_ib_md.ib_md_umr_direct/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_ib_md.ib_md_umr_ksm/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_ib_md.relaxed_order/0, where GetParam() = rdmap0s6
[  FAILED  ] ib/test_ib_md.aligned/0, where GetParam() = rdmap0s6

static const char *uct_ib_device_transport_to_name(struct ibv_device *device)
{
switch (device->transport_type) {
case IBV_TRANSPORT_IB:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code style - no indent here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kk

@@ -1230,6 +1230,36 @@ static uct_md_ops_t UCS_V_UNUSED uct_ib_md_global_odp_ops = {
.detect_memory_type = ucs_empty_function_return_unsupported,
};

static const char *uct_ib_device_transport_to_name(struct ibv_device *device)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uct_ib_device_transport_type_name

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kk

/* TODO: enable additional transport types when ready */
int ret = device->transport_type == IBV_TRANSPORT_IB;
if (!ret) {
ucs_debug("Device %s of type %s is not supported",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

small case (Device->device)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kk

}
}

static int uct_ib_device_is_supported(struct ibv_device *device)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this function is small and used once, IMO we can move its code to uct_ib_device_is_accessible

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO stand alone static functions look cleaner and makes code easier to read.

@shamisp
Copy link
Contributor Author

shamisp commented Oct 18, 2022

@yosefe It seems there are pre-2014 rdma-core builds that don't have post 2014 defines.

/__w/1/s/contrib/../src/uct/ib/base/ib_md.c: In function 'uct_ib_device_transport_to_name':
/__w/1/s/contrib/../src/uct/ib/base/ib_md.c:1294:14: error: 'IBV_TRANSPORT_USNIC' undeclared (first use in this function)
         case IBV_TRANSPORT_USNIC:
              ^
/__w/1/s/contrib/../src/uct/ib/base/ib_md.c:1294:14: note: each undeclared identifier is reported only once for each function it appears in
/__w/1/s/contrib/../src/uct/ib/base/ib_md.c:1296:14: error: 'IBV_TRANSPORT_USNIC_UDP' undeclared (first use in this function)
         case IBV_TRANSPORT_USNIC_UDP:
              ^
/__w/1/s/contrib/../src/uct/ib/base/ib_md.c:1298:14: error: 'IBV_TRANSPORT_UNSPECIFIED' undeclared (first use in this function)
         case IBV_TRANSPORT_UNSPECIFIED:
              ^

To workaround this, instead of introducing bunch of m4 config scripts I'm thinking to go with numerical values. These are not expected to change. What do you thing ?

@yosefe
Copy link
Contributor

yosefe commented Oct 18, 2022

@shamisp I don't think it's a clean solution, IMO adding these to AC_CHECK_DECLS and using #if is better.
OR we can drop the verbose naming in this PR and just print the numerical value

@shamisp
Copy link
Contributor Author

shamisp commented Oct 18, 2022

@shamisp I don't think it's a clean solution, IMO adding these to AC_CHECK_DECLS and using #if is better.
OR we can drop the verbose naming in this PR and just print the numerical value

IMO, numerical values are in debug messages are not super useful to debug. I went with numerical cases as for now. AC_CHECK_DECLS is possible but IMHO just too many ifdef for a simple print message.

yosefe
yosefe previously approved these changes Oct 18, 2022
Copy link
Contributor

@yosefe yosefe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pls squash

The code move RDMA transport check to MD level and prevents
MD creation if the underlying NIC is not supported.
@shamisp
Copy link
Contributor Author

shamisp commented Oct 19, 2022

pls squash

done

@yosefe yosefe merged commit f848eea into openucx:master Oct 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

uct_ib_async_event_handler failure prevents from running on AWS machine with TCP transport
3 participants