aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core/ucma.c
diff options
context:
space:
mode:
authorSean Hefty <sean.hefty@intel.com>2013-05-29 13:09:27 -0400
committerRoland Dreier <roland@purestorage.com>2013-06-21 02:35:40 -0400
commitac53b264b2f39e89781e3b855008123dfdb44aea (patch)
treec72f7ee7aed7071da300d1f5cb52b0767b949ef5 /drivers/infiniband/core/ucma.c
parent2e08b5879e9244fa893fe09f5b887f72f4e6c29b (diff)
RDMA/ucma: Support querying when IB paths are not reversible
The current query_route call can return up to two path records. The assumption being that one is the primary path, with optional support for an alternate path. In both cases, the paths are assumed to be reversible and are used to send CM MADs. With the ability to manually set IB path data, the rdma cm can eventually be capable of using up to 6 paths per connection: forward primary, reverse primary, forward alternate, reverse alternate, reversible primary path for CM MADs reversible alternate path for CM MADs. (It is unclear at this time if IB routing will complicate this) In order to handle more flexible routing topologies, add a new command to report any number of paths. Signed-off-by: Sean Hefty <sean.hefty@intel.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband/core/ucma.c')
-rw-r--r--drivers/infiniband/core/ucma.c35
1 files changed, 35 insertions, 0 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;