aboutsummaryrefslogtreecommitdiffstats
path: root/net/smc/smc_tx.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/smc/smc_tx.c')
-rw-r--r--net/smc/smc_tx.c64
1 files changed, 31 insertions, 33 deletions
diff --git a/net/smc/smc_tx.c b/net/smc/smc_tx.c
index d8366ed51757..f93f3580c100 100644
--- a/net/smc/smc_tx.c
+++ b/net/smc/smc_tx.c
@@ -165,12 +165,11 @@ int smc_tx_sendmsg(struct smc_sock *smc, struct msghdr *msg, size_t len)
165 conn->local_tx_ctrl.prod_flags.urg_data_pending = 1; 165 conn->local_tx_ctrl.prod_flags.urg_data_pending = 1;
166 166
167 if (!atomic_read(&conn->sndbuf_space) || conn->urg_tx_pend) { 167 if (!atomic_read(&conn->sndbuf_space) || conn->urg_tx_pend) {
168 if (send_done)
169 return send_done;
168 rc = smc_tx_wait(smc, msg->msg_flags); 170 rc = smc_tx_wait(smc, msg->msg_flags);
169 if (rc) { 171 if (rc)
170 if (send_done)
171 return send_done;
172 goto out_err; 172 goto out_err;
173 }
174 continue; 173 continue;
175 } 174 }
176 175
@@ -267,27 +266,23 @@ int smcd_tx_ism_write(struct smc_connection *conn, void *data, size_t len,
267 266
268/* sndbuf consumer: actual data transfer of one target chunk with RDMA write */ 267/* sndbuf consumer: actual data transfer of one target chunk with RDMA write */
269static int smc_tx_rdma_write(struct smc_connection *conn, int peer_rmbe_offset, 268static int smc_tx_rdma_write(struct smc_connection *conn, int peer_rmbe_offset,
270 int num_sges, struct ib_sge sges[]) 269 int num_sges, struct ib_rdma_wr *rdma_wr)
271{ 270{
272 struct smc_link_group *lgr = conn->lgr; 271 struct smc_link_group *lgr = conn->lgr;
273 struct ib_rdma_wr rdma_wr;
274 struct smc_link *link; 272 struct smc_link *link;
275 int rc; 273 int rc;
276 274
277 memset(&rdma_wr, 0, sizeof(rdma_wr));
278 link = &lgr->lnk[SMC_SINGLE_LINK]; 275 link = &lgr->lnk[SMC_SINGLE_LINK];
279 rdma_wr.wr.wr_id = smc_wr_tx_get_next_wr_id(link); 276 rdma_wr->wr.wr_id = smc_wr_tx_get_next_wr_id(link);
280 rdma_wr.wr.sg_list = sges; 277 rdma_wr->wr.num_sge = num_sges;
281 rdma_wr.wr.num_sge = num_sges; 278 rdma_wr->remote_addr =
282 rdma_wr.wr.opcode = IB_WR_RDMA_WRITE;
283 rdma_wr.remote_addr =
284 lgr->rtokens[conn->rtoken_idx][SMC_SINGLE_LINK].dma_addr + 279 lgr->rtokens[conn->rtoken_idx][SMC_SINGLE_LINK].dma_addr +
285 /* RMBE within RMB */ 280 /* RMBE within RMB */
286 conn->tx_off + 281 conn->tx_off +
287 /* offset within RMBE */ 282 /* offset within RMBE */
288 peer_rmbe_offset; 283 peer_rmbe_offset;
289 rdma_wr.rkey = lgr->rtokens[conn->rtoken_idx][SMC_SINGLE_LINK].rkey; 284 rdma_wr->rkey = lgr->rtokens[conn->rtoken_idx][SMC_SINGLE_LINK].rkey;
290 rc = ib_post_send(link->roce_qp, &rdma_wr.wr, NULL); 285 rc = ib_post_send(link->roce_qp, &rdma_wr->wr, NULL);
291 if (rc) { 286 if (rc) {
292 conn->local_tx_ctrl.conn_state_flags.peer_conn_abort = 1; 287 conn->local_tx_ctrl.conn_state_flags.peer_conn_abort = 1;
293 smc_lgr_terminate(lgr); 288 smc_lgr_terminate(lgr);
@@ -314,24 +309,25 @@ static inline void smc_tx_advance_cursors(struct smc_connection *conn,
314/* SMC-R helper for smc_tx_rdma_writes() */ 309/* SMC-R helper for smc_tx_rdma_writes() */
315static int smcr_tx_rdma_writes(struct smc_connection *conn, size_t len, 310static int smcr_tx_rdma_writes(struct smc_connection *conn, size_t len,
316 size_t src_off, size_t src_len, 311 size_t src_off, size_t src_len,
317 size_t dst_off, size_t dst_len) 312 size_t dst_off, size_t dst_len,
313 struct smc_rdma_wr *wr_rdma_buf)
318{ 314{
319 dma_addr_t dma_addr = 315 dma_addr_t dma_addr =
320 sg_dma_address(conn->sndbuf_desc->sgt[SMC_SINGLE_LINK].sgl); 316 sg_dma_address(conn->sndbuf_desc->sgt[SMC_SINGLE_LINK].sgl);
321 struct smc_link *link = &conn->lgr->lnk[SMC_SINGLE_LINK];
322 int src_len_sum = src_len, dst_len_sum = dst_len; 317 int src_len_sum = src_len, dst_len_sum = dst_len;
323 struct ib_sge sges[SMC_IB_MAX_SEND_SGE];
324 int sent_count = src_off; 318 int sent_count = src_off;
325 int srcchunk, dstchunk; 319 int srcchunk, dstchunk;
326 int num_sges; 320 int num_sges;
327 int rc; 321 int rc;
328 322
329 for (dstchunk = 0; dstchunk < 2; dstchunk++) { 323 for (dstchunk = 0; dstchunk < 2; dstchunk++) {
324 struct ib_sge *sge =
325 wr_rdma_buf->wr_tx_rdma[dstchunk].wr.sg_list;
326
330 num_sges = 0; 327 num_sges = 0;
331 for (srcchunk = 0; srcchunk < 2; srcchunk++) { 328 for (srcchunk = 0; srcchunk < 2; srcchunk++) {
332 sges[srcchunk].addr = dma_addr + src_off; 329 sge[srcchunk].addr = dma_addr + src_off;
333 sges[srcchunk].length = src_len; 330 sge[srcchunk].length = src_len;
334 sges[srcchunk].lkey = link->roce_pd->local_dma_lkey;
335 num_sges++; 331 num_sges++;
336 332
337 src_off += src_len; 333 src_off += src_len;
@@ -344,7 +340,8 @@ static int smcr_tx_rdma_writes(struct smc_connection *conn, size_t len,
344 src_len = dst_len - src_len; /* remainder */ 340 src_len = dst_len - src_len; /* remainder */
345 src_len_sum += src_len; 341 src_len_sum += src_len;
346 } 342 }
347 rc = smc_tx_rdma_write(conn, dst_off, num_sges, sges); 343 rc = smc_tx_rdma_write(conn, dst_off, num_sges,
344 &wr_rdma_buf->wr_tx_rdma[dstchunk]);
348 if (rc) 345 if (rc)
349 return rc; 346 return rc;
350 if (dst_len_sum == len) 347 if (dst_len_sum == len)
@@ -403,7 +400,8 @@ static int smcd_tx_rdma_writes(struct smc_connection *conn, size_t len,
403/* sndbuf consumer: prepare all necessary (src&dst) chunks of data transmit; 400/* sndbuf consumer: prepare all necessary (src&dst) chunks of data transmit;
404 * usable snd_wnd as max transmit 401 * usable snd_wnd as max transmit
405 */ 402 */
406static int smc_tx_rdma_writes(struct smc_connection *conn) 403static int smc_tx_rdma_writes(struct smc_connection *conn,
404 struct smc_rdma_wr *wr_rdma_buf)
407{ 405{
408 size_t len, src_len, dst_off, dst_len; /* current chunk values */ 406 size_t len, src_len, dst_off, dst_len; /* current chunk values */
409 union smc_host_cursor sent, prep, prod, cons; 407 union smc_host_cursor sent, prep, prod, cons;
@@ -464,7 +462,7 @@ static int smc_tx_rdma_writes(struct smc_connection *conn)
464 dst_off, dst_len); 462 dst_off, dst_len);
465 else 463 else
466 rc = smcr_tx_rdma_writes(conn, len, sent.count, src_len, 464 rc = smcr_tx_rdma_writes(conn, len, sent.count, src_len,
467 dst_off, dst_len); 465 dst_off, dst_len, wr_rdma_buf);
468 if (rc) 466 if (rc)
469 return rc; 467 return rc;
470 468
@@ -485,31 +483,30 @@ static int smc_tx_rdma_writes(struct smc_connection *conn)
485static int smcr_tx_sndbuf_nonempty(struct smc_connection *conn) 483static int smcr_tx_sndbuf_nonempty(struct smc_connection *conn)
486{ 484{
487 struct smc_cdc_producer_flags *pflags; 485 struct smc_cdc_producer_flags *pflags;
486 struct smc_rdma_wr *wr_rdma_buf;
488 struct smc_cdc_tx_pend *pend; 487 struct smc_cdc_tx_pend *pend;
489 struct smc_wr_buf *wr_buf; 488 struct smc_wr_buf *wr_buf;
490 int rc; 489 int rc;
491 490
492 spin_lock_bh(&conn->send_lock); 491 rc = smc_cdc_get_free_slot(conn, &wr_buf, &wr_rdma_buf, &pend);
493 rc = smc_cdc_get_free_slot(conn, &wr_buf, &pend);
494 if (rc < 0) { 492 if (rc < 0) {
495 if (rc == -EBUSY) { 493 if (rc == -EBUSY) {
496 struct smc_sock *smc = 494 struct smc_sock *smc =
497 container_of(conn, struct smc_sock, conn); 495 container_of(conn, struct smc_sock, conn);
498 496
499 if (smc->sk.sk_err == ECONNABORTED) { 497 if (smc->sk.sk_err == ECONNABORTED)
500 rc = sock_error(&smc->sk); 498 return sock_error(&smc->sk);
501 goto out_unlock;
502 }
503 rc = 0; 499 rc = 0;
504 if (conn->alert_token_local) /* connection healthy */ 500 if (conn->alert_token_local) /* connection healthy */
505 mod_delayed_work(system_wq, &conn->tx_work, 501 mod_delayed_work(system_wq, &conn->tx_work,
506 SMC_TX_WORK_DELAY); 502 SMC_TX_WORK_DELAY);
507 } 503 }
508 goto out_unlock; 504 return rc;
509 } 505 }
510 506
507 spin_lock_bh(&conn->send_lock);
511 if (!conn->local_tx_ctrl.prod_flags.urg_data_present) { 508 if (!conn->local_tx_ctrl.prod_flags.urg_data_present) {
512 rc = smc_tx_rdma_writes(conn); 509 rc = smc_tx_rdma_writes(conn, wr_rdma_buf);
513 if (rc) { 510 if (rc) {
514 smc_wr_tx_put_slot(&conn->lgr->lnk[SMC_SINGLE_LINK], 511 smc_wr_tx_put_slot(&conn->lgr->lnk[SMC_SINGLE_LINK],
515 (struct smc_wr_tx_pend_priv *)pend); 512 (struct smc_wr_tx_pend_priv *)pend);
@@ -536,7 +533,7 @@ static int smcd_tx_sndbuf_nonempty(struct smc_connection *conn)
536 533
537 spin_lock_bh(&conn->send_lock); 534 spin_lock_bh(&conn->send_lock);
538 if (!pflags->urg_data_present) 535 if (!pflags->urg_data_present)
539 rc = smc_tx_rdma_writes(conn); 536 rc = smc_tx_rdma_writes(conn, NULL);
540 if (!rc) 537 if (!rc)
541 rc = smcd_cdc_msg_send(conn); 538 rc = smcd_cdc_msg_send(conn);
542 539
@@ -598,7 +595,8 @@ void smc_tx_consumer_update(struct smc_connection *conn, bool force)
598 if (to_confirm > conn->rmbe_update_limit) { 595 if (to_confirm > conn->rmbe_update_limit) {
599 smc_curs_copy(&prod, &conn->local_rx_ctrl.prod, conn); 596 smc_curs_copy(&prod, &conn->local_rx_ctrl.prod, conn);
600 sender_free = conn->rmb_desc->len - 597 sender_free = conn->rmb_desc->len -
601 smc_curs_diff(conn->rmb_desc->len, &prod, &cfed); 598 smc_curs_diff_large(conn->rmb_desc->len,
599 &cfed, &prod);
602 } 600 }
603 601
604 if (conn->local_rx_ctrl.prod_flags.cons_curs_upd_req || 602 if (conn->local_rx_ctrl.prod_flags.cons_curs_upd_req ||