Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net/smc: add infrastructure to send delete rkey messages

Add the infrastructure to send LLC messages of type DELETE RKEY to
unregister a shared memory region at the peer.

Signed-off-by: Karsten Graul <kgraul@linux.ibm.com>
Signed-off-by: Ursula Braun <ubraun@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Karsten Graul and committed by
David S. Miller
60e03c62 4600cfc3

+57 -1
+3
net/smc/smc_core.h
··· 109 109 int llc_testlink_time; /* testlink interval */ 110 110 struct completion llc_confirm_rkey; /* wait 4 rx of cnf rkey */ 111 111 int llc_confirm_rkey_rc; /* rc from cnf rkey msg */ 112 + struct completion llc_delete_rkey; /* wait 4 rx of del rkey */ 113 + int llc_delete_rkey_rc; /* rc from del rkey msg */ 114 + struct mutex llc_delete_rkey_mutex; /* serialize usage */ 112 115 }; 113 116 114 117 /* For now we just allow one parallel link per link group. The SMC protocol
+52 -1
net/smc/smc_llc.c
··· 238 238 return rc; 239 239 } 240 240 241 + /* send LLC delete rkey request */ 242 + static int smc_llc_send_delete_rkey(struct smc_link *link, 243 + struct smc_buf_desc *rmb_desc) 244 + { 245 + struct smc_llc_msg_delete_rkey *rkeyllc; 246 + struct smc_wr_tx_pend_priv *pend; 247 + struct smc_wr_buf *wr_buf; 248 + int rc; 249 + 250 + rc = smc_llc_add_pending_send(link, &wr_buf, &pend); 251 + if (rc) 252 + return rc; 253 + rkeyllc = (struct smc_llc_msg_delete_rkey *)wr_buf; 254 + memset(rkeyllc, 0, sizeof(*rkeyllc)); 255 + rkeyllc->hd.common.type = SMC_LLC_DELETE_RKEY; 256 + rkeyllc->hd.length = sizeof(struct smc_llc_msg_delete_rkey); 257 + rkeyllc->num_rkeys = 1; 258 + rkeyllc->rkey[0] = htonl(rmb_desc->mr_rx[SMC_SINGLE_LINK]->rkey); 259 + /* send llc message */ 260 + rc = smc_wr_tx_send(link, pend); 261 + return rc; 262 + } 263 + 241 264 /* prepare an add link message */ 242 265 static void smc_llc_prep_add_link(struct smc_llc_msg_add_link *addllc, 243 266 struct smc_link *link, u8 mac[], u8 gid[], ··· 532 509 int i, max; 533 510 534 511 if (llc->hd.flags & SMC_LLC_FLAG_RESP) { 535 - /* unused as long as we don't send this type of msg */ 512 + link->llc_delete_rkey_rc = llc->hd.flags & 513 + SMC_LLC_FLAG_RKEY_NEG; 514 + complete(&link->llc_delete_rkey); 536 515 } else { 537 516 max = min_t(u8, llc->num_rkeys, SMC_LLC_DEL_RKEY_MAX); 538 517 for (i = 0; i < max; i++) { ··· 635 610 init_completion(&link->llc_add); 636 611 init_completion(&link->llc_add_resp); 637 612 init_completion(&link->llc_confirm_rkey); 613 + init_completion(&link->llc_delete_rkey); 614 + mutex_init(&link->llc_delete_rkey_mutex); 638 615 init_completion(&link->llc_testlink_resp); 639 616 INIT_DELAYED_WORK(&link->llc_testlink_wrk, smc_llc_testlink_work); 640 617 return 0; ··· 677 650 { 678 651 int rc; 679 652 653 + /* protected by mutex smc_create_lgr_pending */ 680 654 reinit_completion(&link->llc_confirm_rkey); 681 655 rc = smc_llc_send_confirm_rkey(link, rmb_desc); 682 656 if (rc) ··· 688 660 if (rc <= 0 || link->llc_confirm_rkey_rc) 689 661 return -EFAULT; 690 662 return 0; 663 + } 664 + 665 + /* unregister an rtoken at the remote peer */ 666 + int smc_llc_do_delete_rkey(struct smc_link *link, 667 + struct smc_buf_desc *rmb_desc) 668 + { 669 + int rc; 670 + 671 + mutex_lock(&link->llc_delete_rkey_mutex); 672 + reinit_completion(&link->llc_delete_rkey); 673 + rc = smc_llc_send_delete_rkey(link, rmb_desc); 674 + if (rc) 675 + goto out; 676 + /* receive DELETE RKEY response from server over RoCE fabric */ 677 + rc = wait_for_completion_interruptible_timeout(&link->llc_delete_rkey, 678 + SMC_LLC_WAIT_TIME); 679 + if (rc <= 0 || link->llc_delete_rkey_rc) 680 + rc = -EFAULT; 681 + else 682 + rc = 0; 683 + out: 684 + mutex_unlock(&link->llc_delete_rkey_mutex); 685 + return rc; 691 686 } 692 687 693 688 /***************************** init, exit, misc ******************************/
+2
net/smc/smc_llc.h
··· 49 49 void smc_llc_link_clear(struct smc_link *link); 50 50 int smc_llc_do_confirm_rkey(struct smc_link *link, 51 51 struct smc_buf_desc *rmb_desc); 52 + int smc_llc_do_delete_rkey(struct smc_link *link, 53 + struct smc_buf_desc *rmb_desc); 52 54 int smc_llc_init(void) __init; 53 55 54 56 #endif /* SMC_LLC_H */