Introduce an environment variable (i.e. RDMAV_ALLOW_DISASSOC_DESTROY) to control the returned code from destroy commands. Once it's set any destroy command that will get an EIO from the kernel is related as a success. In that case the underlying kernel resources for this object had to be already destroyed via the disassociate mechanism and the user space driver and application can safely clean their resources as well. This comes to prevent a memory leak in the user space area. Signed-off-by: Yishai Hadas <yishaih@xxxxxxxxxxxx> --- libibverbs/cmd.c | 2 ++ libibverbs/cmd_write.h | 17 +++++++++++++++++ libibverbs/init.c | 4 ++++ libibverbs/man/ibv_open_device.3 | 8 ++++++++ 4 files changed, 31 insertions(+) diff --git a/libibverbs/cmd.c b/libibverbs/cmd.c index 5bad9a3..89f8778 100644 --- a/libibverbs/cmd.c +++ b/libibverbs/cmd.c @@ -45,6 +45,8 @@ #include "ibverbs.h" #include <ccan/minmax.h> +bool verbs_allow_disassociate_destroy; + int ibv_cmd_get_context(struct verbs_context *context_ex, struct ibv_get_context *cmd, size_t cmd_size, struct ib_uverbs_get_context_resp *resp, size_t resp_size) diff --git a/libibverbs/cmd_write.h b/libibverbs/cmd_write.h index ac59525..6ee4f30 100644 --- a/libibverbs/cmd_write.h +++ b/libibverbs/cmd_write.h @@ -291,4 +291,21 @@ _execute_write_only(struct ibv_context *context, struct ibv_command_buffer *cmd, #endif +extern bool verbs_allow_disassociate_destroy; + +/* + * Return true if 'ret' indicates that a destroy operation has failed + * and the function should exit. If the kernel destroy failure is being + * ignored then this will set ret to 0, so the calling function appears to succeed. + */ +static inline bool verbs_is_destroy_err(int *ret) +{ + if (*ret == EIO && verbs_allow_disassociate_destroy) { + *ret = 0; + return true; + } + + return *ret != 0; +} + #endif diff --git a/libibverbs/init.c b/libibverbs/init.c index c3451e6..853515d 100644 --- a/libibverbs/init.c +++ b/libibverbs/init.c @@ -50,6 +50,7 @@ #include <util/util.h> #include "ibverbs.h" +#include <infiniband/cmd_write.h> int abi_ver; @@ -705,6 +706,9 @@ int ibverbs_init(void) fprintf(stderr, PFX "Warning: fork()-safety requested " "but init failed\n"); + if (getenv("RDMAV_ALLOW_DISASSOC_DESTROY")) + verbs_allow_disassociate_destroy = true; + sysfs_path = ibv_get_sysfs_path(); if (!sysfs_path) return -ENOSYS; diff --git a/libibverbs/man/ibv_open_device.3 b/libibverbs/man/ibv_open_device.3 index cae2c4d..3a12d2d 100644 --- a/libibverbs/man/ibv_open_device.3 +++ b/libibverbs/man/ibv_open_device.3 @@ -33,6 +33,14 @@ does not release all the resources allocated using context .I context\fR. To avoid resource leaks, the user should release all associated resources before closing a context. + +Setting the environment variable **RDMAV_ALLOW_DISASSOC_DESTROY** tells the +library to relate an EIO from destroy commands as a success as the kernel +resources were already released. This comes to prevent memory leakage in the +user space area upon device disassociation. Applications using this flag cannot +call ibv_get_cq_event or ibv_get_async_event concurrently with any call to an +object destruction function. + .SH "SEE ALSO" .BR ibv_get_device_list (3), .BR ibv_query_device (3), -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html