-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
send and receive LLC messages CONFIRM_LINK (via IB message send and CQE) Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
- Loading branch information
Ursula Braun
authored and
David S. Miller
committed
Jan 9, 2017
1 parent
bd4ad57
commit 9bf9abe
Showing
7 changed files
with
330 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
obj-$(CONFIG_SMC) += smc.o | ||
smc-y := af_smc.o smc_pnet.o smc_ib.o smc_clc.o smc_core.o smc_wr.o | ||
smc-y := af_smc.o smc_pnet.o smc_ib.o smc_clc.o smc_core.o smc_wr.o smc_llc.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
/* | ||
* Shared Memory Communications over RDMA (SMC-R) and RoCE | ||
* | ||
* Link Layer Control (LLC) | ||
* | ||
* For now, we only support the necessary "confirm link" functionality | ||
* which happens for the first RoCE link after successful CLC handshake. | ||
* | ||
* Copyright IBM Corp. 2016 | ||
* | ||
* Author(s): Klaus Wacker <Klaus.Wacker@de.ibm.com> | ||
* Ursula Braun <ubraun@linux.vnet.ibm.com> | ||
*/ | ||
|
||
#include <net/tcp.h> | ||
#include <rdma/ib_verbs.h> | ||
|
||
#include "smc.h" | ||
#include "smc_core.h" | ||
#include "smc_clc.h" | ||
#include "smc_llc.h" | ||
|
||
/********************************** send *************************************/ | ||
|
||
struct smc_llc_tx_pend { | ||
}; | ||
|
||
/* handler for send/transmission completion of an LLC msg */ | ||
static void smc_llc_tx_handler(struct smc_wr_tx_pend_priv *pend, | ||
struct smc_link *link, | ||
enum ib_wc_status wc_status) | ||
{ | ||
/* future work: handle wc_status error for recovery and failover */ | ||
} | ||
|
||
/** | ||
* smc_llc_add_pending_send() - add LLC control message to pending WQE transmits | ||
* @link: Pointer to SMC link used for sending LLC control message. | ||
* @wr_buf: Out variable returning pointer to work request payload buffer. | ||
* @pend: Out variable returning pointer to private pending WR tracking. | ||
* It's the context the transmit complete handler will get. | ||
* | ||
* Reserves and pre-fills an entry for a pending work request send/tx. | ||
* Used by mid-level smc_llc_send_msg() to prepare for later actual send/tx. | ||
* Can sleep due to smc_get_ctrl_buf (if not in softirq context). | ||
* | ||
* Return: 0 on success, otherwise an error value. | ||
*/ | ||
static int smc_llc_add_pending_send(struct smc_link *link, | ||
struct smc_wr_buf **wr_buf, | ||
struct smc_wr_tx_pend_priv **pend) | ||
{ | ||
int rc; | ||
|
||
rc = smc_wr_tx_get_free_slot(link, smc_llc_tx_handler, wr_buf, pend); | ||
if (rc < 0) | ||
return rc; | ||
BUILD_BUG_ON_MSG( | ||
sizeof(union smc_llc_msg) > SMC_WR_BUF_SIZE, | ||
"must increase SMC_WR_BUF_SIZE to at least sizeof(struct smc_llc_msg)"); | ||
BUILD_BUG_ON_MSG( | ||
sizeof(union smc_llc_msg) != SMC_WR_TX_SIZE, | ||
"must adapt SMC_WR_TX_SIZE to sizeof(struct smc_llc_msg); if not all smc_wr upper layer protocols use the same message size any more, must start to set link->wr_tx_sges[i].length on each individual smc_wr_tx_send()"); | ||
BUILD_BUG_ON_MSG( | ||
sizeof(struct smc_llc_tx_pend) > SMC_WR_TX_PEND_PRIV_SIZE, | ||
"must increase SMC_WR_TX_PEND_PRIV_SIZE to at least sizeof(struct smc_llc_tx_pend)"); | ||
return 0; | ||
} | ||
|
||
/* high-level API to send LLC confirm link */ | ||
int smc_llc_send_confirm_link(struct smc_link *link, u8 mac[], | ||
union ib_gid *gid, | ||
enum smc_llc_reqresp reqresp) | ||
{ | ||
struct smc_link_group *lgr = container_of(link, struct smc_link_group, | ||
lnk[SMC_SINGLE_LINK]); | ||
struct smc_llc_msg_confirm_link *confllc; | ||
struct smc_wr_tx_pend_priv *pend; | ||
struct smc_wr_buf *wr_buf; | ||
int rc; | ||
|
||
rc = smc_llc_add_pending_send(link, &wr_buf, &pend); | ||
if (rc) | ||
return rc; | ||
confllc = (struct smc_llc_msg_confirm_link *)wr_buf; | ||
memset(confllc, 0, sizeof(*confllc)); | ||
confllc->hd.common.type = SMC_LLC_CONFIRM_LINK; | ||
confllc->hd.length = sizeof(struct smc_llc_msg_confirm_link); | ||
if (reqresp == SMC_LLC_RESP) | ||
confllc->hd.flags |= SMC_LLC_FLAG_RESP; | ||
memcpy(confllc->sender_mac, mac, ETH_ALEN); | ||
memcpy(confllc->sender_gid, gid, SMC_GID_SIZE); | ||
hton24(confllc->sender_qp_num, link->roce_qp->qp_num); | ||
/* confllc->link_num = SMC_SINGLE_LINK; already done by memset above */ | ||
memcpy(confllc->link_uid, lgr->id, SMC_LGR_ID_SIZE); | ||
confllc->max_links = SMC_LINKS_PER_LGR_MAX; | ||
/* send llc message */ | ||
rc = smc_wr_tx_send(link, pend); | ||
return rc; | ||
} | ||
|
||
/********************************* receive ***********************************/ | ||
|
||
static void smc_llc_rx_confirm_link(struct smc_link *link, | ||
struct smc_llc_msg_confirm_link *llc) | ||
{ | ||
struct smc_link_group *lgr; | ||
|
||
lgr = container_of(link, struct smc_link_group, lnk[SMC_SINGLE_LINK]); | ||
if (llc->hd.flags & SMC_LLC_FLAG_RESP) { | ||
if (lgr->role == SMC_SERV) | ||
complete(&link->llc_confirm_resp); | ||
} else { | ||
if (lgr->role == SMC_CLNT) { | ||
link->link_id = llc->link_num; | ||
complete(&link->llc_confirm); | ||
} | ||
} | ||
} | ||
|
||
static void smc_llc_rx_handler(struct ib_wc *wc, void *buf) | ||
{ | ||
struct smc_link *link = (struct smc_link *)wc->qp->qp_context; | ||
union smc_llc_msg *llc = buf; | ||
|
||
if (wc->byte_len < sizeof(*llc)) | ||
return; /* short message */ | ||
if (llc->raw.hdr.length != sizeof(*llc)) | ||
return; /* invalid message */ | ||
if (llc->raw.hdr.common.type == SMC_LLC_CONFIRM_LINK) | ||
smc_llc_rx_confirm_link(link, &llc->confirm_link); | ||
} | ||
|
||
/***************************** init, exit, misc ******************************/ | ||
|
||
static struct smc_wr_rx_handler smc_llc_rx_handlers[] = { | ||
{ | ||
.handler = smc_llc_rx_handler, | ||
.type = SMC_LLC_CONFIRM_LINK | ||
}, | ||
{ | ||
.handler = NULL, | ||
} | ||
}; | ||
|
||
int __init smc_llc_init(void) | ||
{ | ||
struct smc_wr_rx_handler *handler; | ||
int rc = 0; | ||
|
||
for (handler = smc_llc_rx_handlers; handler->handler; handler++) { | ||
INIT_HLIST_NODE(&handler->list); | ||
rc = smc_wr_rx_register_handler(handler); | ||
if (rc) | ||
break; | ||
} | ||
return rc; | ||
} |
Oops, something went wrong.