Skip to content

Commit

Permalink
verbs: Introduce ibv_import_device() verb
Browse files Browse the repository at this point in the history
Introduce ibv_import_device(), it enable a process to get an ibv_context
that is associated with a given command FD that it owns.

A process is creating a device and then uses some of the Linux systems
calls to dup its 'cmd_fd' member and lets other process to obtain owning
on.

Once other process obtains the 'cmd_fd' it can call ibv_import_device()
which returns an ibv_contxet on the original RDMA device.

A detailed man page as part of this patch describes the expected usage
and flow.

Signed-off-by: Yishai Hadas <yishaih@mellanox.com>
  • Loading branch information
yishaih committed Jul 9, 2020
1 parent 317d889 commit 36133ef
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 0 deletions.
1 change: 1 addition & 0 deletions debian/libibverbs1.symbols
Expand Up @@ -67,6 +67,7 @@ libibverbs.so.1 libibverbs1 #MINVER#
ibv_get_device_name@IBVERBS_1.1 1.1.6
ibv_get_pkey_index@IBVERBS_1.5 20
ibv_get_sysfs_path@IBVERBS_1.0 1.1.6
ibv_import_device@IBVERBS_1.10 31
ibv_init_ah_from_wc@IBVERBS_1.1 1.1.6
ibv_modify_qp@IBVERBS_1.0 1.1.6
ibv_modify_qp@IBVERBS_1.1 1.1.6
Expand Down
62 changes: 62 additions & 0 deletions libibverbs/device.c
Expand Up @@ -382,6 +382,68 @@ LATEST_SYMVER_FUNC(ibv_open_device, 1_1, "IBVERBS_1.1",
return verbs_open_device(device, NULL);
}

struct ibv_context *ibv_import_device(int cmd_fd)
{
struct verbs_device *verbs_device = NULL;
struct verbs_context *context_ex;
struct ibv_device **dev_list;
struct ibv_context *ctx = NULL;
struct stat st;
int ret;
int i;

if (fstat(cmd_fd, &st) || !S_ISCHR(st.st_mode)) {
errno = EINVAL;
return NULL;
}

dev_list = ibv_get_device_list(NULL);
if (!dev_list) {
errno = ENODEV;
return NULL;
}

for (i = 0; dev_list[i]; ++i) {
if (verbs_get_device(dev_list[i])->sysfs->sysfs_cdev ==
st.st_rdev) {
verbs_device = verbs_get_device(dev_list[i]);
break;
}
}

if (!verbs_device) {
errno = ENODEV;
goto out;
}

if (!verbs_device->ops->import_context) {
errno = EOPNOTSUPP;
goto out;
}

/* In case the underlay cdev number was assigned in the meantime to
* other device as of some disassociate flow, the next call on the
* FD will end up with EIO (i.e. query_context command) and we should
* be safe from using the wrong device.
*/
context_ex = verbs_device->ops->import_context(&verbs_device->device, cmd_fd);
if (!context_ex)
goto out;

set_lib_ops(context_ex);

context_ex->priv->imported = true;
ctx = &context_ex->context;
ret = ibv_cmd_alloc_async_fd(ctx);
if (ret) {
ibv_close_device(ctx);
ctx = NULL;
}
out:
ibv_free_device_list(dev_list);
return ctx;
}

void verbs_uninit_context(struct verbs_context *context_ex)
{
free(context_ex->priv);
Expand Down
2 changes: 2 additions & 0 deletions libibverbs/driver.h
Expand Up @@ -216,6 +216,8 @@ struct verbs_device_ops {
struct verbs_context *(*alloc_context)(struct ibv_device *device,
int cmd_fd,
void *private_data);
struct verbs_context *(*import_context)(struct ibv_device *device,
int cmd_fd);

struct verbs_device *(*alloc_device)(struct verbs_sysfs_dev *sysfs_dev);
void (*uninit_device)(struct verbs_device *device);
Expand Down
1 change: 1 addition & 0 deletions libibverbs/libibverbs.map.in
Expand Up @@ -133,6 +133,7 @@ IBVERBS_1.9 {

IBVERBS_1.10 {
global:
ibv_import_device;
ibv_query_ece;
ibv_set_ece;
} IBVERBS_1.9;
Expand Down
1 change: 1 addition & 0 deletions libibverbs/man/CMakeLists.txt
Expand Up @@ -37,6 +37,7 @@ rdma_man_pages(
ibv_get_device_name.3.md
ibv_get_pkey_index.3.md
ibv_get_srq_num.3.md
ibv_import_device.3.md
ibv_inc_rkey.3.md
ibv_modify_qp.3
ibv_modify_qp_rate_limit.3
Expand Down
48 changes: 48 additions & 0 deletions libibverbs/man/ibv_import_device.3.md
@@ -0,0 +1,48 @@
---
date: 2020-5-3
footer: libibverbs
header: "Libibverbs Programmer's Manual"
layout: page
license: 'Licensed under the OpenIB.org BSD license (FreeBSD Variant) - See COPYING.md'
section: 3
title: ibv_import_device
---

# NAME

ibv_import_device - import a device from a given comamnd FD

# SYNOPSIS

```c
#include <infiniband/verbs.h>

struct ibv_context *ibv_import_device(int cmd_fd);

```
# DESCRIPTION
**ibv_import_device()** returns an *ibv_context* pointer that is associated with the given
*cmd_fd*.
The *cmd_fd* is obtained from the ibv_context cmd_fd member, which must be dup'd (eg by dup(), SCM_RIGHTS, etc)
before being passed to ibv_import_device().
Once the *ibv_context* usage has been ended *ibv_close_device()* should be called.
This call may cleanup whatever is needed/opposite of the import including closing the command FD.
# RETURN VALUE
**ibv_import_device()** returns a pointer to the allocated RDMA context, or NULL if the request fails.
# SEE ALSO
**ibv_open_device**(3),
**ibv_close_device**(3),
# AUTHOR
Yishai Hadas <yishaih@mellanox.com>
5 changes: 5 additions & 0 deletions libibverbs/verbs.h
Expand Up @@ -2241,6 +2241,11 @@ struct ibv_context *ibv_open_device(struct ibv_device *device);
*/
int ibv_close_device(struct ibv_context *context);

/**
* ibv_import_device - Import device
*/
struct ibv_context *ibv_import_device(int cmd_fd);

/**
* ibv_get_async_event - Get next async event
* @event: Pointer to use to return async event
Expand Down

0 comments on commit 36133ef

Please sign in to comment.