aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSean Hefty <sean.hefty@intel.com>2013-05-29 13:09:25 -0400
committerRoland Dreier <roland@purestorage.com>2013-06-21 02:35:39 -0400
commitee7aed4528fb3c44a36abd79eb23fd5401a5b697 (patch)
tree16e084d5abbf42b117b8a4b4cb24dcb6d5bd281e /drivers
parent94d0c939416480066d4e4d69e0d3c217bc083cea (diff)
RDMA/ucma: Support querying for AF_IB addresses
The sockaddr structure for AF_IB is larger than sockaddr_in6. The rdma cm user space ABI uses the latter to exchange address information between user space and the kernel. To support querying for larger addresses, define a new query command that exchanges data using sockaddr_storage, rather than sockaddr_in6. Unlike the existing query_route command, the new command only returns address information. Route (i.e. path record) data is separated. Signed-off-by: Sean Hefty <sean.hefty@intel.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/infiniband/core/ucma.c76
1 files changed, 74 insertions, 2 deletions
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index e813774bf7a7..18bdccc0c2ec 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -47,6 +47,7 @@
47#include <rdma/ib_marshall.h> 47#include <rdma/ib_marshall.h>
48#include <rdma/rdma_cm.h> 48#include <rdma/rdma_cm.h>
49#include <rdma/rdma_cm_ib.h> 49#include <rdma/rdma_cm_ib.h>
50#include <rdma/ib_addr.h>
50 51
51MODULE_AUTHOR("Sean Hefty"); 52MODULE_AUTHOR("Sean Hefty");
52MODULE_DESCRIPTION("RDMA Userspace Connection Manager Access"); 53MODULE_DESCRIPTION("RDMA Userspace Connection Manager Access");
@@ -649,7 +650,7 @@ static ssize_t ucma_query_route(struct ucma_file *file,
649 const char __user *inbuf, 650 const char __user *inbuf,
650 int in_len, int out_len) 651 int in_len, int out_len)
651{ 652{
652 struct rdma_ucm_query_route cmd; 653 struct rdma_ucm_query cmd;
653 struct rdma_ucm_query_route_resp resp; 654 struct rdma_ucm_query_route_resp resp;
654 struct ucma_context *ctx; 655 struct ucma_context *ctx;
655 struct sockaddr *addr; 656 struct sockaddr *addr;
@@ -709,6 +710,76 @@ out:
709 return ret; 710 return ret;
710} 711}
711 712
713static void ucma_query_device_addr(struct rdma_cm_id *cm_id,
714 struct rdma_ucm_query_addr_resp *resp)
715{
716 if (!cm_id->device)
717 return;
718
719 resp->node_guid = (__force __u64) cm_id->device->node_guid;
720 resp->port_num = cm_id->port_num;
721 resp->pkey = (__force __u16) cpu_to_be16(
722 ib_addr_get_pkey(&cm_id->route.addr.dev_addr));
723}
724
725static ssize_t ucma_query_addr(struct ucma_context *ctx,
726 void __user *response, int out_len)
727{
728 struct rdma_ucm_query_addr_resp resp;
729 struct sockaddr *addr;
730 int ret = 0;
731
732 if (out_len < sizeof(resp))
733 return -ENOSPC;
734
735 memset(&resp, 0, sizeof resp);
736
737 addr = (struct sockaddr *) &ctx->cm_id->route.addr.src_addr;
738 resp.src_size = rdma_addr_size(addr);
739 memcpy(&resp.src_addr, addr, resp.src_size);
740
741 addr = (struct sockaddr *) &ctx->cm_id->route.addr.dst_addr;
742 resp.dst_size = rdma_addr_size(addr);
743 memcpy(&resp.dst_addr, addr, resp.dst_size);
744
745 ucma_query_device_addr(ctx->cm_id, &resp);
746
747 if (copy_to_user(response, &resp, sizeof(resp)))
748 ret = -EFAULT;
749
750 return ret;
751}
752
753static ssize_t ucma_query(struct ucma_file *file,
754 const char __user *inbuf,
755 int in_len, int out_len)
756{
757 struct rdma_ucm_query cmd;
758 struct ucma_context *ctx;
759 void __user *response;
760 int ret;
761
762 if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
763 return -EFAULT;
764
765 response = (void __user *)(unsigned long) cmd.response;
766 ctx = ucma_get_ctx(file, cmd.id);
767 if (IS_ERR(ctx))
768 return PTR_ERR(ctx);
769
770 switch (cmd.option) {
771 case RDMA_USER_CM_QUERY_ADDR:
772 ret = ucma_query_addr(ctx, response, out_len);
773 break;
774 default:
775 ret = -ENOSYS;
776 break;
777 }
778
779 ucma_put_ctx(ctx);
780 return ret;
781}
782
712static void ucma_copy_conn_param(struct rdma_cm_id *id, 783static void ucma_copy_conn_param(struct rdma_cm_id *id,
713 struct rdma_conn_param *dst, 784 struct rdma_conn_param *dst,
714 struct rdma_ucm_conn_param *src) 785 struct rdma_ucm_conn_param *src)
@@ -1241,7 +1312,8 @@ static ssize_t (*ucma_cmd_table[])(struct ucma_file *file,
1241 [RDMA_USER_CM_CMD_NOTIFY] = ucma_notify, 1312 [RDMA_USER_CM_CMD_NOTIFY] = ucma_notify,
1242 [RDMA_USER_CM_CMD_JOIN_MCAST] = ucma_join_multicast, 1313 [RDMA_USER_CM_CMD_JOIN_MCAST] = ucma_join_multicast,
1243 [RDMA_USER_CM_CMD_LEAVE_MCAST] = ucma_leave_multicast, 1314 [RDMA_USER_CM_CMD_LEAVE_MCAST] = ucma_leave_multicast,
1244 [RDMA_USER_CM_CMD_MIGRATE_ID] = ucma_migrate_id 1315 [RDMA_USER_CM_CMD_MIGRATE_ID] = ucma_migrate_id,
1316 [RDMA_USER_CM_CMD_QUERY] = ucma_query
1245}; 1317};
1246 1318
1247static ssize_t ucma_write(struct file *filp, const char __user *buf, 1319static ssize_t ucma_write(struct file *filp, const char __user *buf,