diff options
-rw-r--r-- | include/infiniband/driver.h | 7 | ||||
-rw-r--r-- | src/libibverbs.map | 1 | ||||
-rw-r--r-- | src/verbs.c | 65 |
3 files changed, 73 insertions, 0 deletions
diff --git a/include/infiniband/driver.h b/include/infiniband/driver.h index 72866a0..ea3dade 100644 --- a/include/infiniband/driver.h +++ b/include/infiniband/driver.h @@ -86,6 +86,11 @@ enum verbs_qp_mask { VERBS_QP_RESERVED = 1 << 1 }; +enum ibv_gid_type { + IBV_GID_TYPE_IB_ROCE_V1, + IBV_GID_TYPE_ROCE_V2, +}; + struct verbs_qp { struct ibv_qp qp; uint32_t comp_mask; @@ -281,4 +286,6 @@ static inline int verbs_get_srq_num(struct ibv_srq *srq, uint32_t *srq_num) return ENOSYS; } +int ibv_query_gid_type(struct ibv_context *context, uint8_t port_num, + unsigned int index, enum ibv_gid_type *type); #endif /* INFINIBAND_DRIVER_H */ diff --git a/src/libibverbs.map b/src/libibverbs.map index 6f66eac..46744e5 100644 --- a/src/libibverbs.map +++ b/src/libibverbs.map @@ -128,4 +128,5 @@ IBVERBS_1.3 { ibv_cmd_destroy_wq; ibv_cmd_create_rwq_ind_table; ibv_cmd_destroy_rwq_ind_table; + ibv_query_gid_type; } IBVERBS_1.1; diff --git a/src/verbs.c b/src/verbs.c index 68888c3..08f03e3 100644 --- a/src/verbs.c +++ b/src/verbs.c @@ -41,6 +41,7 @@ #include <stdlib.h> #include <errno.h> #include <string.h> +#include <dirent.h> #include "ibverbs.h" #ifndef NRESOLVE_NEIGH @@ -585,6 +586,70 @@ struct ibv_ah *__ibv_create_ah(struct ibv_pd *pd, struct ibv_ah_attr *attr) } default_symver(__ibv_create_ah, ibv_create_ah); +/* GID types as appear in sysfs, no change is expected as of ABI + * compatibility. + */ +#define V1_TYPE "IB/RoCE v1" +#define V2_TYPE "RoCE v2" +int ibv_query_gid_type(struct ibv_context *context, uint8_t port_num, + unsigned int index, enum ibv_gid_type *type) +{ + char name[32]; + char buff[11]; + + snprintf(name, sizeof(name), "ports/%d/gid_attrs/types/%d", port_num, + index); + + /* Reset errno so that we can rely on its value upon any error flow in + * ibv_read_sysfs_file. + */ + errno = 0; + if (ibv_read_sysfs_file(context->device->ibdev_path, name, buff, + sizeof(buff)) <= 0) { + char *dir_path; + DIR *dir; + + if (errno == EINVAL) { + /* In IB, this file doesn't exist and the kernel sets + * errno to -EINVAL. + */ + *type = IBV_GID_TYPE_IB_ROCE_V1; + return 0; + } + if (asprintf(&dir_path, "%s/%s/%d/%s/", + context->device->ibdev_path, "ports", port_num, + "gid_attrs") < 0) + return -1; + dir = opendir(dir_path); + free(dir_path); + if (!dir) { + if (errno == ENOENT) + /* Assuming that if gid_attrs doesn't exist, + * we have an old kernel and all GIDs are + * IB/RoCE v1 + */ + *type = IBV_GID_TYPE_IB_ROCE_V1; + else + return -1; + } else { + closedir(dir); + errno = EFAULT; + return -1; + } + } else { + if (!strcmp(buff, V1_TYPE)) { + *type = IBV_GID_TYPE_IB_ROCE_V1; + } else if (!strcmp(buff, V2_TYPE)) { + *type = IBV_GID_TYPE_ROCE_V2; + } else { + errno = ENOTSUP; + return -1; + } + } + + return 0; +} + static int ibv_find_gid_index(struct ibv_context *context, uint8_t port_num, union ibv_gid *gid) { |