]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
RDMA/ucma: Support query resolved service records
authorMark Zhang <markzhang@nvidia.com>
Mon, 30 Jun 2025 10:52:34 +0000 (13:52 +0300)
committerLeon Romanovsky <leon@kernel.org>
Wed, 13 Aug 2025 10:16:07 +0000 (06:16 -0400)
Enable user-space to query resolved service records through a ucma
command when a RDMA_CM_EVENT_ADDRINFO_RESOLVED event is received.

Signed-off-by: Or Har-Toov <ohartoov@nvidia.com>
Signed-off-by: Mark Zhang <markzhang@nvidia.com>
Reviewed-by: Vlad Dumitrescu <vdumitrescu@nvidia.com>
Link: https://patch.msgid.link/1090ee7c00c3f8058c4f9e7557de983504a16715.1751279794.git.leonro@nvidia.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
drivers/infiniband/core/ucma.c
include/uapi/rdma/ib_user_sa.h
include/uapi/rdma/rdma_user_cm.h

index 1915f4e68308e90a58fb71971e82317bc5d448c8..3b9ca6d7a21b83c7cf1c72cf7d145f00e1cbcb44 100644 (file)
@@ -1021,6 +1021,43 @@ static ssize_t ucma_query_gid(struct ucma_context *ctx,
        return ret;
 }
 
+static ssize_t ucma_query_ib_service(struct ucma_context *ctx,
+                                    void __user *response, int out_len)
+{
+       struct rdma_ucm_query_ib_service_resp *resp;
+       int n, ret = 0;
+
+       if (out_len < sizeof(struct rdma_ucm_query_ib_service_resp))
+               return -ENOSPC;
+
+       if (!ctx->cm_id->route.service_recs)
+               return -ENODATA;
+
+       resp = kzalloc(out_len, GFP_KERNEL);
+       if (!resp)
+               return -ENOMEM;
+
+       resp->num_service_recs = ctx->cm_id->route.num_service_recs;
+
+       n = (out_len - sizeof(struct rdma_ucm_query_ib_service_resp)) /
+               sizeof(struct ib_user_service_rec);
+
+       if (!n)
+               goto out;
+
+       if (n > ctx->cm_id->route.num_service_recs)
+               n = ctx->cm_id->route.num_service_recs;
+
+       memcpy(resp->recs, ctx->cm_id->route.service_recs,
+              sizeof(*resp->recs) * n);
+       if (copy_to_user(response, resp, struct_size(resp, recs, n)))
+               ret = -EFAULT;
+
+out:
+       kfree(resp);
+       return ret;
+}
+
 static ssize_t ucma_query(struct ucma_file *file,
                          const char __user *inbuf,
                          int in_len, int out_len)
@@ -1049,6 +1086,9 @@ static ssize_t ucma_query(struct ucma_file *file,
        case RDMA_USER_CM_QUERY_GID:
                ret = ucma_query_gid(ctx, response, out_len);
                break;
+       case RDMA_USER_CM_QUERY_IB_SERVICE:
+               ret = ucma_query_ib_service(ctx, response, out_len);
+               break;
        default:
                ret = -ENOSYS;
                break;
index 435155d6e1c6a53a6f79e14dec3a8c276ddaed2f..acfa20816bc67b0ca131547bd97f44dd1a71ff60 100644 (file)
@@ -74,4 +74,18 @@ struct ib_user_path_rec {
        __u8    preference;
 };
 
+struct ib_user_service_rec {
+       __be64  id;
+       __u8    gid[16];
+       __be16  pkey;
+       __u8    reserved[2];
+       __be32  lease;
+       __u8    key[16];
+       __u8    name[64];
+       __u8    data_8[16];
+       __be16  data_16[8];
+       __be32  data_32[4];
+       __be64  data_64[2];
+};
+
 #endif /* IB_USER_SA_H */
index 8799623bcba0eccfc7f22302507db500b7136ce6..00501da0567e33319dd7b5d96fc51c0be7096117 100644 (file)
@@ -148,7 +148,8 @@ struct rdma_ucm_resolve_route {
 enum {
        RDMA_USER_CM_QUERY_ADDR,
        RDMA_USER_CM_QUERY_PATH,
-       RDMA_USER_CM_QUERY_GID
+       RDMA_USER_CM_QUERY_GID,
+       RDMA_USER_CM_QUERY_IB_SERVICE
 };
 
 struct rdma_ucm_query {
@@ -188,6 +189,11 @@ struct rdma_ucm_query_path_resp {
        struct ib_path_rec_data path_data[];
 };
 
+struct rdma_ucm_query_ib_service_resp {
+       __u32 num_service_recs;
+       struct ib_user_service_rec recs[];
+};
+
 struct rdma_ucm_conn_param {
        __u32 qp_num;
        __u32 qkey;