aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/core/ucma.c35
-rw-r--r--include/uapi/rdma/rdma_user_cm.h9
2 files changed, 43 insertions, 1 deletions
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index 18bdccc0c2ec..722f2ff0400f 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -750,6 +750,38 @@ static ssize_t ucma_query_addr(struct ucma_context *ctx,
750 return ret; 750 return ret;
751} 751}
752 752
753static ssize_t ucma_query_path(struct ucma_context *ctx,
754 void __user *response, int out_len)
755{
756 struct rdma_ucm_query_path_resp *resp;
757 int i, ret = 0;
758
759 if (out_len < sizeof(*resp))
760 return -ENOSPC;
761
762 resp = kzalloc(out_len, GFP_KERNEL);
763 if (!resp)
764 return -ENOMEM;
765
766 resp->num_paths = ctx->cm_id->route.num_paths;
767 for (i = 0, out_len -= sizeof(*resp);
768 i < resp->num_paths && out_len > sizeof(struct ib_path_rec_data);
769 i++, out_len -= sizeof(struct ib_path_rec_data)) {
770
771 resp->path_data[i].flags = IB_PATH_GMP | IB_PATH_PRIMARY |
772 IB_PATH_BIDIRECTIONAL;
773 ib_sa_pack_path(&ctx->cm_id->route.path_rec[i],
774 &resp->path_data[i].path_rec);
775 }
776
777 if (copy_to_user(response, resp,
778 sizeof(*resp) + (i * sizeof(struct ib_path_rec_data))))
779 ret = -EFAULT;
780
781 kfree(resp);
782 return ret;
783}
784
753static ssize_t ucma_query(struct ucma_file *file, 785static ssize_t ucma_query(struct ucma_file *file,
754 const char __user *inbuf, 786 const char __user *inbuf,
755 int in_len, int out_len) 787 int in_len, int out_len)
@@ -771,6 +803,9 @@ static ssize_t ucma_query(struct ucma_file *file,
771 case RDMA_USER_CM_QUERY_ADDR: 803 case RDMA_USER_CM_QUERY_ADDR:
772 ret = ucma_query_addr(ctx, response, out_len); 804 ret = ucma_query_addr(ctx, response, out_len);
773 break; 805 break;
806 case RDMA_USER_CM_QUERY_PATH:
807 ret = ucma_query_path(ctx, response, out_len);
808 break;
774 default: 809 default:
775 ret = -ENOSYS; 810 ret = -ENOSYS;
776 break; 811 break;
diff --git a/include/uapi/rdma/rdma_user_cm.h b/include/uapi/rdma/rdma_user_cm.h
index 3ea7e7a4d54b..07eb6cfa926c 100644
--- a/include/uapi/rdma/rdma_user_cm.h
+++ b/include/uapi/rdma/rdma_user_cm.h
@@ -115,7 +115,8 @@ struct rdma_ucm_resolve_route {
115}; 115};
116 116
117enum { 117enum {
118 RDMA_USER_CM_QUERY_ADDR 118 RDMA_USER_CM_QUERY_ADDR,
119 RDMA_USER_CM_QUERY_PATH
119}; 120};
120 121
121struct rdma_ucm_query { 122struct rdma_ucm_query {
@@ -145,6 +146,12 @@ struct rdma_ucm_query_addr_resp {
145 struct sockaddr_storage dst_addr; 146 struct sockaddr_storage dst_addr;
146}; 147};
147 148
149struct rdma_ucm_query_path_resp {
150 __u32 num_paths;
151 __u32 reserved;
152 struct ib_path_rec_data path_data[0];
153};
154
148struct rdma_ucm_conn_param { 155struct rdma_ucm_conn_param {
149 __u32 qp_num; 156 __u32 qp_num;
150 __u32 qkey; 157 __u32 qkey;