aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/core/cma.c142
-rw-r--r--include/rdma/rdma_cm.h31
2 files changed, 101 insertions, 72 deletions
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 914a5a4c7f1e..8187349fb25f 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -592,20 +592,6 @@ static inline int cma_user_data_offset(enum rdma_port_space ps)
592 } 592 }
593} 593}
594 594
595static int cma_notify_user(struct rdma_id_private *id_priv,
596 enum rdma_cm_event_type type, int status,
597 void *data, u8 data_len)
598{
599 struct rdma_cm_event event;
600
601 event.event = type;
602 event.status = status;
603 event.private_data = data;
604 event.private_data_len = data_len;
605
606 return id_priv->id.event_handler(&id_priv->id, &event);
607}
608
609static void cma_cancel_route(struct rdma_id_private *id_priv) 595static void cma_cancel_route(struct rdma_id_private *id_priv)
610{ 596{
611 switch (rdma_node_get_transport(id_priv->id.device->node_type)) { 597 switch (rdma_node_get_transport(id_priv->id.device->node_type)) {
@@ -790,47 +776,62 @@ reject:
790 return ret; 776 return ret;
791} 777}
792 778
779static void cma_set_rep_event_data(struct rdma_cm_event *event,
780 struct ib_cm_rep_event_param *rep_data,
781 void *private_data)
782{
783 event->param.conn.private_data = private_data;
784 event->param.conn.private_data_len = IB_CM_REP_PRIVATE_DATA_SIZE;
785 event->param.conn.responder_resources = rep_data->responder_resources;
786 event->param.conn.initiator_depth = rep_data->initiator_depth;
787 event->param.conn.flow_control = rep_data->flow_control;
788 event->param.conn.rnr_retry_count = rep_data->rnr_retry_count;
789 event->param.conn.srq = rep_data->srq;
790 event->param.conn.qp_num = rep_data->remote_qpn;
791}
792
793static int cma_ib_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) 793static int cma_ib_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
794{ 794{
795 struct rdma_id_private *id_priv = cm_id->context; 795 struct rdma_id_private *id_priv = cm_id->context;
796 enum rdma_cm_event_type event; 796 struct rdma_cm_event event;
797 u8 private_data_len = 0; 797 int ret = 0;
798 int ret = 0, status = 0;
799 798
800 atomic_inc(&id_priv->dev_remove); 799 atomic_inc(&id_priv->dev_remove);
801 if (!cma_comp(id_priv, CMA_CONNECT)) 800 if (!cma_comp(id_priv, CMA_CONNECT))
802 goto out; 801 goto out;
803 802
803 memset(&event, 0, sizeof event);
804 switch (ib_event->event) { 804 switch (ib_event->event) {
805 case IB_CM_REQ_ERROR: 805 case IB_CM_REQ_ERROR:
806 case IB_CM_REP_ERROR: 806 case IB_CM_REP_ERROR:
807 event = RDMA_CM_EVENT_UNREACHABLE; 807 event.event = RDMA_CM_EVENT_UNREACHABLE;
808 status = -ETIMEDOUT; 808 event.status = -ETIMEDOUT;
809 break; 809 break;
810 case IB_CM_REP_RECEIVED: 810 case IB_CM_REP_RECEIVED:
811 status = cma_verify_rep(id_priv, ib_event->private_data); 811 event.status = cma_verify_rep(id_priv, ib_event->private_data);
812 if (status) 812 if (event.status)
813 event = RDMA_CM_EVENT_CONNECT_ERROR; 813 event.event = RDMA_CM_EVENT_CONNECT_ERROR;
814 else if (id_priv->id.qp && id_priv->id.ps != RDMA_PS_SDP) { 814 else if (id_priv->id.qp && id_priv->id.ps != RDMA_PS_SDP) {
815 status = cma_rep_recv(id_priv); 815 event.status = cma_rep_recv(id_priv);
816 event = status ? RDMA_CM_EVENT_CONNECT_ERROR : 816 event.event = event.status ? RDMA_CM_EVENT_CONNECT_ERROR :
817 RDMA_CM_EVENT_ESTABLISHED; 817 RDMA_CM_EVENT_ESTABLISHED;
818 } else 818 } else
819 event = RDMA_CM_EVENT_CONNECT_RESPONSE; 819 event.event = RDMA_CM_EVENT_CONNECT_RESPONSE;
820 private_data_len = IB_CM_REP_PRIVATE_DATA_SIZE; 820 cma_set_rep_event_data(&event, &ib_event->param.rep_rcvd,
821 ib_event->private_data);
821 break; 822 break;
822 case IB_CM_RTU_RECEIVED: 823 case IB_CM_RTU_RECEIVED:
823 status = cma_rtu_recv(id_priv); 824 event.status = cma_rtu_recv(id_priv);
824 event = status ? RDMA_CM_EVENT_CONNECT_ERROR : 825 event.event = event.status ? RDMA_CM_EVENT_CONNECT_ERROR :
825 RDMA_CM_EVENT_ESTABLISHED; 826 RDMA_CM_EVENT_ESTABLISHED;
826 break; 827 break;
827 case IB_CM_DREQ_ERROR: 828 case IB_CM_DREQ_ERROR:
828 status = -ETIMEDOUT; /* fall through */ 829 event.status = -ETIMEDOUT; /* fall through */
829 case IB_CM_DREQ_RECEIVED: 830 case IB_CM_DREQ_RECEIVED:
830 case IB_CM_DREP_RECEIVED: 831 case IB_CM_DREP_RECEIVED:
831 if (!cma_comp_exch(id_priv, CMA_CONNECT, CMA_DISCONNECT)) 832 if (!cma_comp_exch(id_priv, CMA_CONNECT, CMA_DISCONNECT))
832 goto out; 833 goto out;
833 event = RDMA_CM_EVENT_DISCONNECTED; 834 event.event = RDMA_CM_EVENT_DISCONNECTED;
834 break; 835 break;
835 case IB_CM_TIMEWAIT_EXIT: 836 case IB_CM_TIMEWAIT_EXIT:
836 case IB_CM_MRA_RECEIVED: 837 case IB_CM_MRA_RECEIVED:
@@ -838,9 +839,10 @@ static int cma_ib_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
838 goto out; 839 goto out;
839 case IB_CM_REJ_RECEIVED: 840 case IB_CM_REJ_RECEIVED:
840 cma_modify_qp_err(&id_priv->id); 841 cma_modify_qp_err(&id_priv->id);
841 status = ib_event->param.rej_rcvd.reason; 842 event.status = ib_event->param.rej_rcvd.reason;
842 event = RDMA_CM_EVENT_REJECTED; 843 event.event = RDMA_CM_EVENT_REJECTED;
843 private_data_len = IB_CM_REJ_PRIVATE_DATA_SIZE; 844 event.param.conn.private_data = ib_event->private_data;
845 event.param.conn.private_data_len = IB_CM_REJ_PRIVATE_DATA_SIZE;
844 break; 846 break;
845 default: 847 default:
846 printk(KERN_ERR "RDMA CMA: unexpected IB CM event: %d", 848 printk(KERN_ERR "RDMA CMA: unexpected IB CM event: %d",
@@ -848,8 +850,7 @@ static int cma_ib_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
848 goto out; 850 goto out;
849 } 851 }
850 852
851 ret = cma_notify_user(id_priv, event, status, ib_event->private_data, 853 ret = id_priv->id.event_handler(&id_priv->id, &event);
852 private_data_len);
853 if (ret) { 854 if (ret) {
854 /* Destroy the CM ID by returning a non-zero value. */ 855 /* Destroy the CM ID by returning a non-zero value. */
855 id_priv->cm_id.ib = NULL; 856 id_priv->cm_id.ib = NULL;
@@ -911,9 +912,25 @@ err:
911 return NULL; 912 return NULL;
912} 913}
913 914
915static void cma_set_req_event_data(struct rdma_cm_event *event,
916 struct ib_cm_req_event_param *req_data,
917 void *private_data, int offset)
918{
919 event->param.conn.private_data = private_data + offset;
920 event->param.conn.private_data_len = IB_CM_REQ_PRIVATE_DATA_SIZE - offset;
921 event->param.conn.responder_resources = req_data->responder_resources;
922 event->param.conn.initiator_depth = req_data->initiator_depth;
923 event->param.conn.flow_control = req_data->flow_control;
924 event->param.conn.retry_count = req_data->retry_count;
925 event->param.conn.rnr_retry_count = req_data->rnr_retry_count;
926 event->param.conn.srq = req_data->srq;
927 event->param.conn.qp_num = req_data->remote_qpn;
928}
929
914static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) 930static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
915{ 931{
916 struct rdma_id_private *listen_id, *conn_id; 932 struct rdma_id_private *listen_id, *conn_id;
933 struct rdma_cm_event event;
917 int offset, ret; 934 int offset, ret;
918 935
919 listen_id = cm_id->context; 936 listen_id = cm_id->context;
@@ -941,9 +958,11 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
941 cm_id->cm_handler = cma_ib_handler; 958 cm_id->cm_handler = cma_ib_handler;
942 959
943 offset = cma_user_data_offset(listen_id->id.ps); 960 offset = cma_user_data_offset(listen_id->id.ps);
944 ret = cma_notify_user(conn_id, RDMA_CM_EVENT_CONNECT_REQUEST, 0, 961 memset(&event, 0, sizeof event);
945 ib_event->private_data + offset, 962 event.event = RDMA_CM_EVENT_CONNECT_REQUEST;
946 IB_CM_REQ_PRIVATE_DATA_SIZE - offset); 963 cma_set_req_event_data(&event, &ib_event->param.req_rcvd,
964 ib_event->private_data, offset);
965 ret = conn_id->id.event_handler(&conn_id->id, &event);
947 if (!ret) 966 if (!ret)
948 goto out; 967 goto out;
949 968
@@ -1019,15 +1038,16 @@ static void cma_set_compare_data(enum rdma_port_space ps, struct sockaddr *addr,
1019static int cma_iw_handler(struct iw_cm_id *iw_id, struct iw_cm_event *iw_event) 1038static int cma_iw_handler(struct iw_cm_id *iw_id, struct iw_cm_event *iw_event)
1020{ 1039{
1021 struct rdma_id_private *id_priv = iw_id->context; 1040 struct rdma_id_private *id_priv = iw_id->context;
1022 enum rdma_cm_event_type event = 0; 1041 struct rdma_cm_event event;
1023 struct sockaddr_in *sin; 1042 struct sockaddr_in *sin;
1024 int ret = 0; 1043 int ret = 0;
1025 1044
1045 memset(&event, 0, sizeof event);
1026 atomic_inc(&id_priv->dev_remove); 1046 atomic_inc(&id_priv->dev_remove);
1027 1047
1028 switch (iw_event->event) { 1048 switch (iw_event->event) {
1029 case IW_CM_EVENT_CLOSE: 1049 case IW_CM_EVENT_CLOSE:
1030 event = RDMA_CM_EVENT_DISCONNECTED; 1050 event.event = RDMA_CM_EVENT_DISCONNECTED;
1031 break; 1051 break;
1032 case IW_CM_EVENT_CONNECT_REPLY: 1052 case IW_CM_EVENT_CONNECT_REPLY:
1033 sin = (struct sockaddr_in *) &id_priv->id.route.addr.src_addr; 1053 sin = (struct sockaddr_in *) &id_priv->id.route.addr.src_addr;
@@ -1035,20 +1055,21 @@ static int cma_iw_handler(struct iw_cm_id *iw_id, struct iw_cm_event *iw_event)
1035 sin = (struct sockaddr_in *) &id_priv->id.route.addr.dst_addr; 1055 sin = (struct sockaddr_in *) &id_priv->id.route.addr.dst_addr;
1036 *sin = iw_event->remote_addr; 1056 *sin = iw_event->remote_addr;
1037 if (iw_event->status) 1057 if (iw_event->status)
1038 event = RDMA_CM_EVENT_REJECTED; 1058 event.event = RDMA_CM_EVENT_REJECTED;
1039 else 1059 else
1040 event = RDMA_CM_EVENT_ESTABLISHED; 1060 event.event = RDMA_CM_EVENT_ESTABLISHED;
1041 break; 1061 break;
1042 case IW_CM_EVENT_ESTABLISHED: 1062 case IW_CM_EVENT_ESTABLISHED:
1043 event = RDMA_CM_EVENT_ESTABLISHED; 1063 event.event = RDMA_CM_EVENT_ESTABLISHED;
1044 break; 1064 break;
1045 default: 1065 default:
1046 BUG_ON(1); 1066 BUG_ON(1);
1047 } 1067 }
1048 1068
1049 ret = cma_notify_user(id_priv, event, iw_event->status, 1069 event.status = iw_event->status;
1050 iw_event->private_data, 1070 event.param.conn.private_data = iw_event->private_data;
1051 iw_event->private_data_len); 1071 event.param.conn.private_data_len = iw_event->private_data_len;
1072 ret = id_priv->id.event_handler(&id_priv->id, &event);
1052 if (ret) { 1073 if (ret) {
1053 /* Destroy the CM ID by returning a non-zero value. */ 1074 /* Destroy the CM ID by returning a non-zero value. */
1054 id_priv->cm_id.iw = NULL; 1075 id_priv->cm_id.iw = NULL;
@@ -1069,6 +1090,7 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id,
1069 struct rdma_id_private *listen_id, *conn_id; 1090 struct rdma_id_private *listen_id, *conn_id;
1070 struct sockaddr_in *sin; 1091 struct sockaddr_in *sin;
1071 struct net_device *dev = NULL; 1092 struct net_device *dev = NULL;
1093 struct rdma_cm_event event;
1072 int ret; 1094 int ret;
1073 1095
1074 listen_id = cm_id->context; 1096 listen_id = cm_id->context;
@@ -1122,9 +1144,11 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id,
1122 sin = (struct sockaddr_in *) &new_cm_id->route.addr.dst_addr; 1144 sin = (struct sockaddr_in *) &new_cm_id->route.addr.dst_addr;
1123 *sin = iw_event->remote_addr; 1145 *sin = iw_event->remote_addr;
1124 1146
1125 ret = cma_notify_user(conn_id, RDMA_CM_EVENT_CONNECT_REQUEST, 0, 1147 memset(&event, 0, sizeof event);
1126 iw_event->private_data, 1148 event.event = RDMA_CM_EVENT_CONNECT_REQUEST;
1127 iw_event->private_data_len); 1149 event.param.conn.private_data = iw_event->private_data;
1150 event.param.conn.private_data_len = iw_event->private_data_len;
1151 ret = conn_id->id.event_handler(&conn_id->id, &event);
1128 if (ret) { 1152 if (ret) {
1129 /* User wants to destroy the CM ID */ 1153 /* User wants to destroy the CM ID */
1130 conn_id->cm_id.iw = NULL; 1154 conn_id->cm_id.iw = NULL;
@@ -1513,8 +1537,9 @@ static void addr_handler(int status, struct sockaddr *src_addr,
1513 struct rdma_dev_addr *dev_addr, void *context) 1537 struct rdma_dev_addr *dev_addr, void *context)
1514{ 1538{
1515 struct rdma_id_private *id_priv = context; 1539 struct rdma_id_private *id_priv = context;
1516 enum rdma_cm_event_type event; 1540 struct rdma_cm_event event;
1517 1541
1542 memset(&event, 0, sizeof event);
1518 atomic_inc(&id_priv->dev_remove); 1543 atomic_inc(&id_priv->dev_remove);
1519 1544
1520 /* 1545 /*
@@ -1534,14 +1559,15 @@ static void addr_handler(int status, struct sockaddr *src_addr,
1534 if (status) { 1559 if (status) {
1535 if (!cma_comp_exch(id_priv, CMA_ADDR_RESOLVED, CMA_ADDR_BOUND)) 1560 if (!cma_comp_exch(id_priv, CMA_ADDR_RESOLVED, CMA_ADDR_BOUND))
1536 goto out; 1561 goto out;
1537 event = RDMA_CM_EVENT_ADDR_ERROR; 1562 event.event = RDMA_CM_EVENT_ADDR_ERROR;
1563 event.status = status;
1538 } else { 1564 } else {
1539 memcpy(&id_priv->id.route.addr.src_addr, src_addr, 1565 memcpy(&id_priv->id.route.addr.src_addr, src_addr,
1540 ip_addr_size(src_addr)); 1566 ip_addr_size(src_addr));
1541 event = RDMA_CM_EVENT_ADDR_RESOLVED; 1567 event.event = RDMA_CM_EVENT_ADDR_RESOLVED;
1542 } 1568 }
1543 1569
1544 if (cma_notify_user(id_priv, event, status, NULL, 0)) { 1570 if (id_priv->id.event_handler(&id_priv->id, &event)) {
1545 cma_exch(id_priv, CMA_DESTROYING); 1571 cma_exch(id_priv, CMA_DESTROYING);
1546 cma_release_remove(id_priv); 1572 cma_release_remove(id_priv);
1547 cma_deref_id(id_priv); 1573 cma_deref_id(id_priv);
@@ -2132,6 +2158,7 @@ static void cma_add_one(struct ib_device *device)
2132 2158
2133static int cma_remove_id_dev(struct rdma_id_private *id_priv) 2159static int cma_remove_id_dev(struct rdma_id_private *id_priv)
2134{ 2160{
2161 struct rdma_cm_event event;
2135 enum cma_state state; 2162 enum cma_state state;
2136 2163
2137 /* Record that we want to remove the device */ 2164 /* Record that we want to remove the device */
@@ -2146,8 +2173,9 @@ static int cma_remove_id_dev(struct rdma_id_private *id_priv)
2146 if (!cma_comp(id_priv, CMA_DEVICE_REMOVAL)) 2173 if (!cma_comp(id_priv, CMA_DEVICE_REMOVAL))
2147 return 0; 2174 return 0;
2148 2175
2149 return cma_notify_user(id_priv, RDMA_CM_EVENT_DEVICE_REMOVAL, 2176 memset(&event, 0, sizeof event);
2150 0, NULL, 0); 2177 event.event = RDMA_CM_EVENT_DEVICE_REMOVAL;
2178 return id_priv->id.event_handler(&id_priv->id, &event);
2151} 2179}
2152 2180
2153static void cma_process_remove(struct cma_device *cma_dev) 2181static void cma_process_remove(struct cma_device *cma_dev)
diff --git a/include/rdma/rdma_cm.h b/include/rdma/rdma_cm.h
index 4c07f9699d06..aa6ce47537a2 100644
--- a/include/rdma/rdma_cm.h
+++ b/include/rdma/rdma_cm.h
@@ -77,11 +77,25 @@ struct rdma_route {
77 int num_paths; 77 int num_paths;
78}; 78};
79 79
80struct rdma_conn_param {
81 const void *private_data;
82 u8 private_data_len;
83 u8 responder_resources;
84 u8 initiator_depth;
85 u8 flow_control;
86 u8 retry_count; /* ignored when accepting */
87 u8 rnr_retry_count;
88 /* Fields below ignored if a QP is created on the rdma_cm_id. */
89 u8 srq;
90 u32 qp_num;
91};
92
80struct rdma_cm_event { 93struct rdma_cm_event {
81 enum rdma_cm_event_type event; 94 enum rdma_cm_event_type event;
82 int status; 95 int status;
83 void *private_data; 96 union {
84 u8 private_data_len; 97 struct rdma_conn_param conn;
98 } param;
85}; 99};
86 100
87struct rdma_cm_id; 101struct rdma_cm_id;
@@ -204,19 +218,6 @@ void rdma_destroy_qp(struct rdma_cm_id *id);
204int rdma_init_qp_attr(struct rdma_cm_id *id, struct ib_qp_attr *qp_attr, 218int rdma_init_qp_attr(struct rdma_cm_id *id, struct ib_qp_attr *qp_attr,
205 int *qp_attr_mask); 219 int *qp_attr_mask);
206 220
207struct rdma_conn_param {
208 const void *private_data;
209 u8 private_data_len;
210 u8 responder_resources;
211 u8 initiator_depth;
212 u8 flow_control;
213 u8 retry_count; /* ignored when accepting */
214 u8 rnr_retry_count;
215 /* Fields below ignored if a QP is created on the rdma_cm_id. */
216 u8 srq;
217 u32 qp_num;
218};
219
220/** 221/**
221 * rdma_connect - Initiate an active connection request. 222 * rdma_connect - Initiate an active connection request.
222 * 223 *