aboutsummaryrefslogtreecommitdiffstats
path: root/net/rds/ib_cm.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/rds/ib_cm.c')
-rw-r--r--net/rds/ib_cm.c62
1 files changed, 42 insertions, 20 deletions
diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c
index f8e40e1a6038..c2d372f13dbb 100644
--- a/net/rds/ib_cm.c
+++ b/net/rds/ib_cm.c
@@ -98,21 +98,34 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even
98 struct ib_qp_attr qp_attr; 98 struct ib_qp_attr qp_attr;
99 int err; 99 int err;
100 100
101 if (event->param.conn.private_data_len) { 101 if (event->param.conn.private_data_len >= sizeof(*dp)) {
102 dp = event->param.conn.private_data; 102 dp = event->param.conn.private_data;
103 103
104 rds_ib_set_protocol(conn, 104 /* make sure it isn't empty data */
105 if (dp->dp_protocol_major) {
106 rds_ib_set_protocol(conn,
105 RDS_PROTOCOL(dp->dp_protocol_major, 107 RDS_PROTOCOL(dp->dp_protocol_major,
106 dp->dp_protocol_minor)); 108 dp->dp_protocol_minor));
107 rds_ib_set_flow_control(conn, be32_to_cpu(dp->dp_credit)); 109 rds_ib_set_flow_control(conn, be32_to_cpu(dp->dp_credit));
110 }
108 } 111 }
109 112
110 printk(KERN_NOTICE "RDS/IB: connected to %pI4 version %u.%u%s\n", 113 printk(KERN_NOTICE "RDS/IB: connected to %pI4 version %u.%u%s\n",
111 &conn->c_laddr, 114 &conn->c_faddr,
112 RDS_PROTOCOL_MAJOR(conn->c_version), 115 RDS_PROTOCOL_MAJOR(conn->c_version),
113 RDS_PROTOCOL_MINOR(conn->c_version), 116 RDS_PROTOCOL_MINOR(conn->c_version),
114 ic->i_flowctl ? ", flow control" : ""); 117 ic->i_flowctl ? ", flow control" : "");
115 118
119 /*
120 * Init rings and fill recv. this needs to wait until protocol negotiation
121 * is complete, since ring layout is different from 3.0 to 3.1.
122 */
123 rds_ib_send_init_ring(ic);
124 rds_ib_recv_init_ring(ic);
125 /* Post receive buffers - as a side effect, this will update
126 * the posted credit count. */
127 rds_ib_recv_refill(conn, GFP_KERNEL, GFP_HIGHUSER, 1);
128
116 /* Tune RNR behavior */ 129 /* Tune RNR behavior */
117 rds_ib_tune_rnr(ic, &qp_attr); 130 rds_ib_tune_rnr(ic, &qp_attr);
118 131
@@ -145,7 +158,7 @@ static void rds_ib_cm_fill_conn_param(struct rds_connection *conn,
145 /* XXX tune these? */ 158 /* XXX tune these? */
146 conn_param->responder_resources = 1; 159 conn_param->responder_resources = 1;
147 conn_param->initiator_depth = 1; 160 conn_param->initiator_depth = 1;
148 conn_param->retry_count = 7; 161 conn_param->retry_count = min_t(unsigned int, rds_ib_retry_count, 7);
149 conn_param->rnr_retry_count = 7; 162 conn_param->rnr_retry_count = 7;
150 163
151 if (dp) { 164 if (dp) {
@@ -190,9 +203,9 @@ static void rds_ib_qp_event_handler(struct ib_event *event, void *data)
190 rdma_notify(ic->i_cm_id, IB_EVENT_COMM_EST); 203 rdma_notify(ic->i_cm_id, IB_EVENT_COMM_EST);
191 break; 204 break;
192 default: 205 default:
193 printk(KERN_WARNING "RDS/ib: unhandled QP event %u " 206 rds_ib_conn_error(conn, "RDS/IB: Fatal QP Event %u "
194 "on connection to %pI4\n", event->event, 207 "- connection %pI4->%pI4, reconnecting\n",
195 &conn->c_faddr); 208 event->event, &conn->c_laddr, &conn->c_faddr);
196 break; 209 break;
197 } 210 }
198} 211}
@@ -321,7 +334,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn)
321 rdsdebug("send allocation failed\n"); 334 rdsdebug("send allocation failed\n");
322 goto out; 335 goto out;
323 } 336 }
324 rds_ib_send_init_ring(ic); 337 memset(ic->i_sends, 0, ic->i_send_ring.w_nr * sizeof(struct rds_ib_send_work));
325 338
326 ic->i_recvs = vmalloc(ic->i_recv_ring.w_nr * sizeof(struct rds_ib_recv_work)); 339 ic->i_recvs = vmalloc(ic->i_recv_ring.w_nr * sizeof(struct rds_ib_recv_work));
327 if (ic->i_recvs == NULL) { 340 if (ic->i_recvs == NULL) {
@@ -329,14 +342,10 @@ static int rds_ib_setup_qp(struct rds_connection *conn)
329 rdsdebug("recv allocation failed\n"); 342 rdsdebug("recv allocation failed\n");
330 goto out; 343 goto out;
331 } 344 }
345 memset(ic->i_recvs, 0, ic->i_recv_ring.w_nr * sizeof(struct rds_ib_recv_work));
332 346
333 rds_ib_recv_init_ring(ic);
334 rds_ib_recv_init_ack(ic); 347 rds_ib_recv_init_ack(ic);
335 348
336 /* Post receive buffers - as a side effect, this will update
337 * the posted credit count. */
338 rds_ib_recv_refill(conn, GFP_KERNEL, GFP_HIGHUSER, 1);
339
340 rdsdebug("conn %p pd %p mr %p cq %p %p\n", conn, ic->i_pd, ic->i_mr, 349 rdsdebug("conn %p pd %p mr %p cq %p %p\n", conn, ic->i_pd, ic->i_mr,
341 ic->i_send_cq, ic->i_recv_cq); 350 ic->i_send_cq, ic->i_recv_cq);
342 351
@@ -344,19 +353,32 @@ out:
344 return ret; 353 return ret;
345} 354}
346 355
347static u32 rds_ib_protocol_compatible(const struct rds_ib_connect_private *dp) 356static u32 rds_ib_protocol_compatible(struct rdma_cm_event *event)
348{ 357{
358 const struct rds_ib_connect_private *dp = event->param.conn.private_data;
349 u16 common; 359 u16 common;
350 u32 version = 0; 360 u32 version = 0;
351 361
352 /* rdma_cm private data is odd - when there is any private data in the 362 /*
363 * rdma_cm private data is odd - when there is any private data in the
353 * request, we will be given a pretty large buffer without telling us the 364 * request, we will be given a pretty large buffer without telling us the
354 * original size. The only way to tell the difference is by looking at 365 * original size. The only way to tell the difference is by looking at
355 * the contents, which are initialized to zero. 366 * the contents, which are initialized to zero.
356 * If the protocol version fields aren't set, this is a connection attempt 367 * If the protocol version fields aren't set, this is a connection attempt
357 * from an older version. This could could be 3.0 or 2.0 - we can't tell. 368 * from an older version. This could could be 3.0 or 2.0 - we can't tell.
358 * We really should have changed this for OFED 1.3 :-( */ 369 * We really should have changed this for OFED 1.3 :-(
359 if (dp->dp_protocol_major == 0) 370 */
371
372 /* Be paranoid. RDS always has privdata */
373 if (!event->param.conn.private_data_len) {
374 printk(KERN_NOTICE "RDS incoming connection has no private data, "
375 "rejecting\n");
376 return 0;
377 }
378
379 /* Even if len is crap *now* I still want to check it. -ASG */
380 if (event->param.conn.private_data_len < sizeof (*dp)
381 || dp->dp_protocol_major == 0)
360 return RDS_PROTOCOL_3_0; 382 return RDS_PROTOCOL_3_0;
361 383
362 common = be16_to_cpu(dp->dp_protocol_minor_mask) & RDS_IB_SUPPORTED_PROTOCOLS; 384 common = be16_to_cpu(dp->dp_protocol_minor_mask) & RDS_IB_SUPPORTED_PROTOCOLS;
@@ -388,7 +410,7 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id,
388 int err, destroy = 1; 410 int err, destroy = 1;
389 411
390 /* Check whether the remote protocol version matches ours. */ 412 /* Check whether the remote protocol version matches ours. */
391 version = rds_ib_protocol_compatible(dp); 413 version = rds_ib_protocol_compatible(event);
392 if (!version) 414 if (!version)
393 goto out; 415 goto out;
394 416