Skip to content

Commit cd6851f

Browse files
Ursula Braundavem330
Ursula Braun
authored andcommitted
smc: remote memory buffers (RMBs)
* allocate data RMB memory for sending and receiving * size depends on the maximum socket send and receive buffers * allocated RMBs are kept during life time of the owning link group * map the allocated RMBs to DMA Signed-off-by: Ursula Braun <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 0cfdd8f commit cd6851f

File tree

7 files changed

+342
-7
lines changed

7 files changed

+342
-7
lines changed

net/smc/af_smc.c

+26-3
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,8 @@ static void smc_conn_save_peer_info(struct smc_sock *smc,
249249
struct smc_clc_msg_accept_confirm *clc)
250250
{
251251
smc->conn.peer_conn_idx = clc->conn_idx;
252+
smc->conn.peer_rmbe_size = smc_uncompress_bufsize(clc->rmbe_size);
253+
atomic_set(&smc->conn.peer_rmbe_space, smc->conn.peer_rmbe_size);
252254
}
253255

254256
static void smc_link_save_peer_info(struct smc_link *link,
@@ -323,6 +325,18 @@ static int smc_connect_rdma(struct smc_sock *smc)
323325
link = &smc->conn.lgr->lnk[SMC_SINGLE_LINK];
324326

325327
smc_conn_save_peer_info(smc, &aclc);
328+
329+
rc = smc_sndbuf_create(smc);
330+
if (rc) {
331+
reason_code = SMC_CLC_DECL_MEM;
332+
goto decline_rdma_unlock;
333+
}
334+
rc = smc_rmb_create(smc);
335+
if (rc) {
336+
reason_code = SMC_CLC_DECL_MEM;
337+
goto decline_rdma_unlock;
338+
}
339+
326340
if (local_contact == SMC_FIRST_CONTACT)
327341
smc_link_save_peer_info(link, &aclc);
328342
/* tbd in follow-on patch: more steps to setup RDMA communcication,
@@ -598,9 +612,16 @@ static void smc_listen_work(struct work_struct *work)
598612
}
599613
link = &new_smc->conn.lgr->lnk[SMC_SINGLE_LINK];
600614

601-
/* tbd in follow-on patch: more steps to setup RDMA communcication,
602-
* create rmbs, map rmbs
603-
*/
615+
rc = smc_sndbuf_create(new_smc);
616+
if (rc) {
617+
reason_code = SMC_CLC_DECL_MEM;
618+
goto decline_rdma;
619+
}
620+
rc = smc_rmb_create(new_smc);
621+
if (rc) {
622+
reason_code = SMC_CLC_DECL_MEM;
623+
goto decline_rdma;
624+
}
604625

605626
rc = smc_clc_send_accept(new_smc, local_contact);
606627
if (rc)
@@ -1047,6 +1068,8 @@ static int smc_create(struct net *net, struct socket *sock, int protocol,
10471068
IPPROTO_TCP, &smc->clcsock);
10481069
if (rc)
10491070
sk_common_release(sk);
1071+
smc->sk.sk_sndbuf = max(smc->clcsock->sk->sk_sndbuf, SMC_BUF_MIN_SIZE);
1072+
smc->sk.sk_rcvbuf = max(smc->clcsock->sk->sk_rcvbuf, SMC_BUF_MIN_SIZE);
10501073

10511074
out:
10521075
return rc;

net/smc/smc.h

+45
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@ struct smc_connection {
3434
struct smc_link_group *lgr; /* link group of connection */
3535
u32 alert_token_local; /* unique conn. id */
3636
u8 peer_conn_idx; /* from tcp handshake */
37+
int peer_rmbe_size; /* size of peer rx buffer */
38+
atomic_t peer_rmbe_space;/* remaining free bytes in peer
39+
* rmbe
40+
*/
41+
42+
struct smc_buf_desc *sndbuf_desc; /* send buffer descriptor */
43+
int sndbuf_size; /* sndbuf size <== sock wmem */
44+
struct smc_buf_desc *rmb_desc; /* RMBE descriptor */
45+
int rmbe_size; /* RMBE size <== sock rmem */
46+
int rmbe_size_short;/* compressed notation */
3747
};
3848

3949
struct smc_sock { /* smc sock container */
@@ -76,6 +86,41 @@ static inline u32 ntoh24(u8 *net)
7686
return be32_to_cpu(t);
7787
}
7888

89+
#define SMC_BUF_MIN_SIZE 16384 /* minimum size of an RMB */
90+
91+
#define SMC_RMBE_SIZES 16 /* number of distinct sizes for an RMBE */
92+
/* theoretically, the RFC states that largest size would be 512K,
93+
* i.e. compressed 5 and thus 6 sizes (0..5), despite
94+
* struct smc_clc_msg_accept_confirm.rmbe_size being a 4 bit value (0..15)
95+
*/
96+
97+
/* convert the RMB size into the compressed notation - minimum 16K.
98+
* In contrast to plain ilog2, this rounds towards the next power of 2,
99+
* so the socket application gets at least its desired sndbuf / rcvbuf size.
100+
*/
101+
static inline u8 smc_compress_bufsize(int size)
102+
{
103+
u8 compressed;
104+
105+
if (size <= SMC_BUF_MIN_SIZE)
106+
return 0;
107+
108+
size = (size - 1) >> 14;
109+
compressed = ilog2(size) + 1;
110+
if (compressed >= SMC_RMBE_SIZES)
111+
compressed = SMC_RMBE_SIZES - 1;
112+
return compressed;
113+
}
114+
115+
/* convert the RMB size from compressed notation into integer */
116+
static inline int smc_uncompress_bufsize(u8 compressed)
117+
{
118+
u32 size;
119+
120+
size = 0x00000001 << (((int)compressed) + 14);
121+
return (int)size;
122+
}
123+
79124
#ifdef CONFIG_XFRM
80125
static inline bool using_ipsec(struct smc_sock *smc)
81126
{

net/smc/smc_clc.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -252,13 +252,13 @@ int smc_clc_send_accept(struct smc_sock *new_smc, int srv_first_contact)
252252
SMC_GID_SIZE);
253253
memcpy(&aclc.lcl.mac, link->smcibdev->mac[link->ibport - 1],
254254
sizeof(link->smcibdev->mac[link->ibport - 1]));
255-
256-
/* tbd in follow-on patch: fill in rmb-related values */
257-
258255
hton24(aclc.qpn, link->roce_qp->qp_num);
259256
aclc.conn_idx = 1; /* as long as 1 RMB = 1 RMBE */
260257
aclc.rmbe_alert_token = htonl(conn->alert_token_local);
261258
aclc.qp_mtu = link->path_mtu;
259+
aclc.rmbe_size = conn->rmbe_size_short,
260+
aclc.rmb_dma_addr =
261+
cpu_to_be64((u64)conn->rmb_desc->dma_addr[SMC_SINGLE_LINK]);
262262
hton24(aclc.psn, link->psn_initial);
263263
memcpy(aclc.trl.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
264264

0 commit comments

Comments
 (0)