@@ -2453,20 +2453,16 @@ acmp_get_ep(struct acmp_port *port, struct acm_endpoint *endpoint)
static uint16_t acmp_get_pkey_index(struct acm_endpoint *endpoint)
{
struct acmp_port *port;
- int ret;
- __be16 pkey;
- uint16_t i;
+ int i;
port = acmp_get_port(endpoint);
if (!port)
return 0;
-
- for (i = 0, ret = 0; !ret; i++) {
- ret = ibv_query_pkey(port->dev->verbs, port->port_num, i, &pkey);
- if (!ret && endpoint->pkey == be16toh(pkey))
- return i;
- }
- return 0;
+ i = ibv_get_pkey_index(port->dev->verbs, port->port_num,
+ htobe16(endpoint->pkey));
+ if (i < 0)
+ return 0;
+ return i;
}
static void acmp_close_endpoint(void *ep_context)
@@ -33,6 +33,7 @@ rdma_man_pages(
ibv_get_device_guid.3.md
ibv_get_device_list.3
ibv_get_device_name.3.md
+ ibv_get_pkey_index.3.md
ibv_get_srq_num.3.md
ibv_inc_rkey.3.md
ibv_modify_qp.3
new file mode 100644
@@ -0,0 +1,48 @@
+---
+date: 2018-07-16
+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_GET_PKEY_INDEX
+---
+
+# NAME
+
+ibv_get_pkey_index - obtain the index in the P_Key table of a P_Key
+
+# SYNOPSIS
+
+```c
+#include <infiniband/verbs.h>
+
+int ibv_get_pkey_index(struct ibv_context *context,
+ uint8_t port_num,
+ __be16 pkey);
+```
+
+# DESCRIPTION
+
+Every InfiniBand HCA maintains a P_Key table for each of its ports that is
+indexed by an integer and with a P_Key in each element. Certain InfiniBand
+data structures that work with P_Keys expect a P_Key index, e.g. **struct
+ibv_qp_attr** and **struct ib_mad_addr**. Hence the function
+**ibv_get_pkey_index()** that accepts a P_Key in network byte order and that
+returns an index in the P_Key table as result.
+
+# RETURN VALUE
+
+**ibv_get_pkey_index()** returns the P_Key index on success, and -1 on error.
+
+# SEE ALSO
+
+**ibv_open_device**(3),
+**ibv_query_device**(3),
+**ibv_query_gid**(3),
+**ibv_query_pkey**(3),
+**ibv_query_port**(3)
+
+# AUTHOR
+
+Bart Van Assche <bvanassche@acm.org>
@@ -200,6 +200,22 @@ LATEST_SYMVER_FUNC(ibv_query_pkey, 1_1, "IBVERBS_1.1",
return 0;
}
+LATEST_SYMVER_FUNC(ibv_get_pkey_index, 1_1, "IBVERBS_1.1",
+ int,
+ struct ibv_context *context, uint8_t port_num, __be16 pkey)
+{
+ __be16 pkey_i;
+ int i, ret;
+
+ for (i = 0; ; i++) {
+ ret = ibv_query_pkey(context, port_num, i, &pkey_i);
+ if (ret < 0)
+ return ret;
+ if (pkey == pkey_i)
+ return i;
+ }
+}
+
LATEST_SYMVER_FUNC(ibv_alloc_pd, 1_1, "IBVERBS_1.1",
struct ibv_pd *,
struct ibv_context *context)
@@ -1969,6 +1969,12 @@ int ibv_query_gid(struct ibv_context *context, uint8_t port_num,
int ibv_query_pkey(struct ibv_context *context, uint8_t port_num,
int index, __be16 *pkey);
+/**
+ * ibv_get_pkey_index - Translate a P_Key into a P_Key index
+ */
+int ibv_get_pkey_index(struct ibv_context *context, uint8_t port_num,
+ __be16 pkey);
+
/**
* ibv_alloc_pd - Allocate a protection domain
*/
@@ -1092,33 +1092,17 @@ static int ucma_modify_qp_err(struct rdma_cm_id *id)
return rdma_seterrno(ibv_modify_qp(id->qp, &qp_attr, IBV_QP_STATE));
}
-static int ucma_find_pkey(struct cma_device *cma_dev, uint8_t port_num,
- __be16 pkey, uint16_t *pkey_index)
-{
- int ret, i;
- __be16 chk_pkey;
-
- for (i = 0, ret = 0; !ret; i++) {
- ret = ibv_query_pkey(cma_dev->verbs, port_num, i, &chk_pkey);
- if (!ret && pkey == chk_pkey) {
- *pkey_index = (uint16_t) i;
- return 0;
- }
- }
- return ERR(EINVAL);
-}
-
static int ucma_init_conn_qp3(struct cma_id_private *id_priv, struct ibv_qp *qp)
{
struct ibv_qp_attr qp_attr;
int ret;
- ret = ucma_find_pkey(id_priv->cma_dev, id_priv->id.port_num,
- id_priv->id.route.addr.addr.ibaddr.pkey,
- &qp_attr.pkey_index);
- if (ret)
- return ret;
+ ret = ibv_get_pkey_index(id_priv->cma_dev->verbs, id_priv->id.port_num,
+ id_priv->id.route.addr.addr.ibaddr.pkey);
+ if (ret < 0)
+ return ERR(EINVAL);
+ qp_attr.pkey_index = ret;
qp_attr.port_num = id_priv->id.port_num;
qp_attr.qp_state = IBV_QPS_INIT;
qp_attr.qp_access_flags = 0;
@@ -1149,12 +1133,12 @@ static int ucma_init_ud_qp3(struct cma_id_private *id_priv, struct ibv_qp *qp)
struct ibv_qp_attr qp_attr;
int ret;
- ret = ucma_find_pkey(id_priv->cma_dev, id_priv->id.port_num,
- id_priv->id.route.addr.addr.ibaddr.pkey,
- &qp_attr.pkey_index);
- if (ret)
- return ret;
+ ret = ibv_get_pkey_index(id_priv->cma_dev->verbs, id_priv->id.port_num,
+ id_priv->id.route.addr.addr.ibaddr.pkey);
+ if (ret < 0)
+ return ERR(EINVAL);
+ qp_attr.pkey_index = ret;
qp_attr.port_num = id_priv->id.port_num;
qp_attr.qp_state = IBV_QPS_INIT;
qp_attr.qkey = RDMA_UDP_QKEY;
This patch does not change any functionality. Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com> --- ibacm/prov/acmp/src/acmp.c | 16 ++++----- libibverbs/man/CMakeLists.txt | 1 + libibverbs/man/ibv_get_pkey_index.3.md | 48 ++++++++++++++++++++++++++ libibverbs/verbs.c | 16 +++++++++ libibverbs/verbs.h | 6 ++++ librdmacm/cma.c | 36 ++++++------------- 6 files changed, 87 insertions(+), 36 deletions(-) create mode 100644 libibverbs/man/ibv_get_pkey_index.3.md