Skip to content

Commit bd4ad57

Browse files
Ursula Braundavem330
Ursula Braun
authored andcommitted
smc: initialize IB transport incl. PD, MR, QP, CQ, event, WR
Prepare the link for RDMA transport: Create a queue pair (QP) and move it into the state Ready-To-Receive (RTR). Signed-off-by: Ursula Braun <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent f38ba17 commit bd4ad57

File tree

8 files changed

+374
-9
lines changed

8 files changed

+374
-9
lines changed

net/smc/af_smc.c

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -339,9 +339,20 @@ static int smc_connect_rdma(struct smc_sock *smc)
339339

340340
if (local_contact == SMC_FIRST_CONTACT)
341341
smc_link_save_peer_info(link, &aclc);
342-
/* tbd in follow-on patch: more steps to setup RDMA communcication,
343-
* create rmbs, map rmbs, rtoken_handling, modify_qp
344-
*/
342+
343+
rc = smc_rmb_rtoken_handling(&smc->conn, &aclc);
344+
if (rc) {
345+
reason_code = SMC_CLC_DECL_INTERR;
346+
goto decline_rdma_unlock;
347+
}
348+
349+
if (local_contact == SMC_FIRST_CONTACT) {
350+
rc = smc_ib_ready_link(link);
351+
if (rc) {
352+
reason_code = SMC_CLC_DECL_INTERR;
353+
goto decline_rdma_unlock;
354+
}
355+
}
345356

346357
rc = smc_clc_send_confirm(smc);
347358
if (rc)
@@ -638,9 +649,20 @@ static void smc_listen_work(struct work_struct *work)
638649
if (local_contact == SMC_FIRST_CONTACT)
639650
smc_link_save_peer_info(link, &cclc);
640651

641-
/* tbd in follow-on patch: more steps to setup RDMA communcication,
642-
* rtoken_handling, modify_qp
643-
*/
652+
rc = smc_rmb_rtoken_handling(&new_smc->conn, &cclc);
653+
if (rc) {
654+
reason_code = SMC_CLC_DECL_INTERR;
655+
goto decline_rdma;
656+
}
657+
658+
/* tbd in follow-on patch: modify_qp, llc_confirm */
659+
if (local_contact == SMC_FIRST_CONTACT) {
660+
rc = smc_ib_ready_link(link);
661+
if (rc) {
662+
reason_code = SMC_CLC_DECL_INTERR;
663+
goto decline_rdma;
664+
}
665+
}
644666

645667
out_connected:
646668
sk_refcnt_debug_inc(newsmcsk);

net/smc/smc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ struct smc_connection {
4343
atomic_t peer_rmbe_space;/* remaining free bytes in peer
4444
* rmbe
4545
*/
46+
int rtoken_idx; /* idx to peer RMB rkey/addr */
4647

4748
struct smc_buf_desc *sndbuf_desc; /* send buffer descriptor */
4849
int sndbuf_size; /* sndbuf size <== sock wmem */

net/smc/smc_clc.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,13 +201,15 @@ int smc_clc_send_confirm(struct smc_sock *smc)
201201
SMC_GID_SIZE);
202202
memcpy(&cclc.lcl.mac, &link->smcibdev->mac[link->ibport - 1],
203203
sizeof(link->smcibdev->mac));
204-
205-
/* tbd in follow-on patch: fill in rmb-related values */
206-
207204
hton24(cclc.qpn, link->roce_qp->qp_num);
205+
cclc.rmb_rkey =
206+
htonl(conn->rmb_desc->mr_rx[SMC_SINGLE_LINK]->rkey);
208207
cclc.conn_idx = 1; /* for now: 1 RMB = 1 RMBE */
209208
cclc.rmbe_alert_token = htonl(conn->alert_token_local);
210209
cclc.qp_mtu = min(link->path_mtu, link->peer_mtu);
210+
cclc.rmbe_size = conn->rmbe_size_short;
211+
cclc.rmb_dma_addr =
212+
cpu_to_be64((u64)conn->rmb_desc->dma_addr[SMC_SINGLE_LINK]);
211213
hton24(cclc.psn, link->psn_initial);
212214

213215
memcpy(cclc.trl.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
@@ -253,6 +255,8 @@ int smc_clc_send_accept(struct smc_sock *new_smc, int srv_first_contact)
253255
memcpy(&aclc.lcl.mac, link->smcibdev->mac[link->ibport - 1],
254256
sizeof(link->smcibdev->mac[link->ibport - 1]));
255257
hton24(aclc.qpn, link->roce_qp->qp_num);
258+
aclc.rmb_rkey =
259+
htonl(conn->rmb_desc->mr_rx[SMC_SINGLE_LINK]->rkey);
256260
aclc.conn_idx = 1; /* as long as 1 RMB = 1 RMBE */
257261
aclc.rmbe_alert_token = htonl(conn->alert_token_local);
258262
aclc.qp_mtu = link->path_mtu;

net/smc/smc_core.c

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,12 +160,23 @@ static int smc_lgr_create(struct smc_sock *smc, __be32 peer_in_addr,
160160
lnk->smcibdev = smcibdev;
161161
lnk->ibport = ibport;
162162
lnk->path_mtu = smcibdev->pattr[ibport - 1].active_mtu;
163+
if (!smcibdev->initialized)
164+
smc_ib_setup_per_ibdev(smcibdev);
163165
get_random_bytes(rndvec, sizeof(rndvec));
164166
lnk->psn_initial = rndvec[0] + (rndvec[1] << 8) + (rndvec[2] << 16);
165167
rc = smc_wr_alloc_link_mem(lnk);
166168
if (rc)
167169
goto free_lgr;
168170
init_waitqueue_head(&lnk->wr_tx_wait);
171+
rc = smc_ib_create_protection_domain(lnk);
172+
if (rc)
173+
goto free_link_mem;
174+
rc = smc_ib_create_queue_pair(lnk);
175+
if (rc)
176+
goto dealloc_pd;
177+
rc = smc_wr_create_link(lnk);
178+
if (rc)
179+
goto destroy_qp;
169180

170181
smc->conn.lgr = lgr;
171182
rwlock_init(&lgr->conns_lock);
@@ -174,6 +185,12 @@ static int smc_lgr_create(struct smc_sock *smc, __be32 peer_in_addr,
174185
spin_unlock_bh(&smc_lgr_list.lock);
175186
return 0;
176187

188+
destroy_qp:
189+
smc_ib_destroy_queue_pair(lnk);
190+
dealloc_pd:
191+
smc_ib_dealloc_protection_domain(lnk);
192+
free_link_mem:
193+
smc_wr_free_link_mem(lnk);
177194
free_lgr:
178195
kfree(lgr);
179196
out:
@@ -211,7 +228,10 @@ void smc_conn_free(struct smc_connection *conn)
211228
static void smc_link_clear(struct smc_link *lnk)
212229
{
213230
lnk->peer_qpn = 0;
231+
smc_ib_modify_qp_reset(lnk);
214232
smc_wr_free_link(lnk);
233+
smc_ib_destroy_queue_pair(lnk);
234+
smc_ib_dealloc_protection_domain(lnk);
215235
smc_wr_free_link_mem(lnk);
216236
}
217237

@@ -223,6 +243,10 @@ static void smc_lgr_free_sndbufs(struct smc_link_group *lgr)
223243
for (i = 0; i < SMC_RMBE_SIZES; i++) {
224244
list_for_each_entry_safe(sndbuf_desc, bf_desc, &lgr->sndbufs[i],
225245
list) {
246+
list_del(&sndbuf_desc->list);
247+
smc_ib_buf_unmap(lgr->lnk[SMC_SINGLE_LINK].smcibdev,
248+
smc_uncompress_bufsize(i),
249+
sndbuf_desc, DMA_TO_DEVICE);
226250
kfree(sndbuf_desc->cpu_addr);
227251
kfree(sndbuf_desc);
228252
}
@@ -232,11 +256,16 @@ static void smc_lgr_free_sndbufs(struct smc_link_group *lgr)
232256
static void smc_lgr_free_rmbs(struct smc_link_group *lgr)
233257
{
234258
struct smc_buf_desc *rmb_desc, *bf_desc;
259+
struct smc_link *lnk = &lgr->lnk[SMC_SINGLE_LINK];
235260
int i;
236261

237262
for (i = 0; i < SMC_RMBE_SIZES; i++) {
238263
list_for_each_entry_safe(rmb_desc, bf_desc, &lgr->rmbs[i],
239264
list) {
265+
list_del(&rmb_desc->list);
266+
smc_ib_buf_unmap(lnk->smcibdev,
267+
smc_uncompress_bufsize(i),
268+
rmb_desc, DMA_FROM_DEVICE);
240269
kfree(rmb_desc->cpu_addr);
241270
kfree(rmb_desc);
242271
}
@@ -550,6 +579,18 @@ int smc_rmb_create(struct smc_sock *smc)
550579
kfree(rmb_desc);
551580
continue; /* if mapping failed, try smaller one */
552581
}
582+
rc = smc_ib_get_memory_region(lgr->lnk[SMC_SINGLE_LINK].roce_pd,
583+
IB_ACCESS_REMOTE_WRITE |
584+
IB_ACCESS_LOCAL_WRITE,
585+
&rmb_desc->mr_rx[SMC_SINGLE_LINK]);
586+
if (rc) {
587+
smc_ib_buf_unmap(lgr->lnk[SMC_SINGLE_LINK].smcibdev,
588+
tmp_bufsize, rmb_desc,
589+
DMA_FROM_DEVICE);
590+
kfree(rmb_desc->cpu_addr);
591+
kfree(rmb_desc);
592+
continue;
593+
}
553594
rmb_desc->used = 1;
554595
write_lock_bh(&lgr->rmbs_lock);
555596
list_add(&rmb_desc->list,
@@ -567,3 +608,38 @@ int smc_rmb_create(struct smc_sock *smc)
567608
return -ENOMEM;
568609
}
569610
}
611+
612+
static inline int smc_rmb_reserve_rtoken_idx(struct smc_link_group *lgr)
613+
{
614+
int i;
615+
616+
for_each_clear_bit(i, lgr->rtokens_used_mask, SMC_RMBS_PER_LGR_MAX) {
617+
if (!test_and_set_bit(i, lgr->rtokens_used_mask))
618+
return i;
619+
}
620+
return -ENOSPC;
621+
}
622+
623+
/* save rkey and dma_addr received from peer during clc handshake */
624+
int smc_rmb_rtoken_handling(struct smc_connection *conn,
625+
struct smc_clc_msg_accept_confirm *clc)
626+
{
627+
u64 dma_addr = be64_to_cpu(clc->rmb_dma_addr);
628+
struct smc_link_group *lgr = conn->lgr;
629+
u32 rkey = ntohl(clc->rmb_rkey);
630+
int i;
631+
632+
for (i = 0; i < SMC_RMBS_PER_LGR_MAX; i++) {
633+
if ((lgr->rtokens[i][SMC_SINGLE_LINK].rkey == rkey) &&
634+
test_bit(i, lgr->rtokens_used_mask)) {
635+
conn->rtoken_idx = i;
636+
return 0;
637+
}
638+
}
639+
conn->rtoken_idx = smc_rmb_reserve_rtoken_idx(lgr);
640+
if (conn->rtoken_idx < 0)
641+
return conn->rtoken_idx;
642+
lgr->rtokens[conn->rtoken_idx][SMC_SINGLE_LINK].rkey = rkey;
643+
lgr->rtokens[conn->rtoken_idx][SMC_SINGLE_LINK].dma_addr = dma_addr;
644+
return 0;
645+
}

net/smc/smc_core.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,18 @@ struct smc_buf_desc {
9090
u64 dma_addr[SMC_LINKS_PER_LGR_MAX];
9191
/* mapped address of buffer */
9292
void *cpu_addr; /* virtual address of buffer */
93+
struct ib_mr *mr_rx[SMC_LINKS_PER_LGR_MAX];
94+
/* for rmb only:
95+
* rkey provided to peer
96+
*/
9397
u32 used; /* currently used / unused */
9498
};
9599

100+
struct smc_rtoken { /* address/key of remote RMB */
101+
u64 dma_addr;
102+
u32 rkey;
103+
};
104+
96105
struct smc_link_group {
97106
struct list_head list;
98107
enum smc_lgr_role role; /* client or server */
@@ -109,6 +118,13 @@ struct smc_link_group {
109118
rwlock_t sndbufs_lock; /* protects tx buffers */
110119
struct list_head rmbs[SMC_RMBE_SIZES]; /* rx buffers */
111120
rwlock_t rmbs_lock; /* protects rx buffers */
121+
struct smc_rtoken rtokens[SMC_RMBS_PER_LGR_MAX]
122+
[SMC_LINKS_PER_LGR_MAX];
123+
/* remote addr/key pairs */
124+
unsigned long rtokens_used_mask[BITS_TO_LONGS(
125+
SMC_RMBS_PER_LGR_MAX)];
126+
/* used rtoken elements */
127+
112128
struct delayed_work free_work; /* delayed freeing of an lgr */
113129
bool sync_err; /* lgr no longer fits to peer */
114130
};
@@ -153,5 +169,7 @@ void smc_lgr_free(struct smc_link_group *lgr);
153169
void smc_lgr_terminate(struct smc_link_group *lgr);
154170
int smc_sndbuf_create(struct smc_sock *smc);
155171
int smc_rmb_create(struct smc_sock *smc);
172+
int smc_rmb_rtoken_handling(struct smc_connection *conn,
173+
struct smc_clc_msg_accept_confirm *clc);
156174

157175
#endif

0 commit comments

Comments
 (0)