Skip to content

Commit a3fe3d0

Browse files
Ursula Braundavem330
authored andcommitted
net/smc: introduce sg-logic for RMBs
The follow-on patch makes use of ib_map_mr_sg() when introducing separate memory regions for RMBs. This function is based on scatterlists; thus this patch introduces scatterlists for RMBs. Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent c45abf3 commit a3fe3d0

File tree

5 files changed

+76
-26
lines changed

5 files changed

+76
-26
lines changed

net/smc/smc_clc.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -204,13 +204,13 @@ int smc_clc_send_confirm(struct smc_sock *smc)
204204
memcpy(&cclc.lcl.mac, &link->smcibdev->mac[link->ibport - 1], ETH_ALEN);
205205
hton24(cclc.qpn, link->roce_qp->qp_num);
206206
cclc.rmb_rkey =
207-
htonl(conn->rmb_desc->rkey[SMC_SINGLE_LINK]);
207+
htonl(link->roce_pd->unsafe_global_rkey);
208208
cclc.conn_idx = 1; /* for now: 1 RMB = 1 RMBE */
209209
cclc.rmbe_alert_token = htonl(conn->alert_token_local);
210210
cclc.qp_mtu = min(link->path_mtu, link->peer_mtu);
211211
cclc.rmbe_size = conn->rmbe_size_short;
212-
cclc.rmb_dma_addr =
213-
cpu_to_be64((u64)conn->rmb_desc->dma_addr[SMC_SINGLE_LINK]);
212+
cclc.rmb_dma_addr = cpu_to_be64(
213+
(u64)sg_dma_address(conn->rmb_desc->sgt[SMC_SINGLE_LINK].sgl));
214214
hton24(cclc.psn, link->psn_initial);
215215

216216
memcpy(cclc.trl.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
@@ -256,13 +256,13 @@ int smc_clc_send_accept(struct smc_sock *new_smc, int srv_first_contact)
256256
memcpy(&aclc.lcl.mac, link->smcibdev->mac[link->ibport - 1], ETH_ALEN);
257257
hton24(aclc.qpn, link->roce_qp->qp_num);
258258
aclc.rmb_rkey =
259-
htonl(conn->rmb_desc->rkey[SMC_SINGLE_LINK]);
259+
htonl(link->roce_pd->unsafe_global_rkey);
260260
aclc.conn_idx = 1; /* as long as 1 RMB = 1 RMBE */
261261
aclc.rmbe_alert_token = htonl(conn->alert_token_local);
262262
aclc.qp_mtu = link->path_mtu;
263263
aclc.rmbe_size = conn->rmbe_size_short,
264-
aclc.rmb_dma_addr =
265-
cpu_to_be64((u64)conn->rmb_desc->dma_addr[SMC_SINGLE_LINK]);
264+
aclc.rmb_dma_addr = cpu_to_be64(
265+
(u64)sg_dma_address(conn->rmb_desc->sgt[SMC_SINGLE_LINK].sgl));
266266
hton24(aclc.psn, link->psn_initial);
267267
memcpy(aclc.trl.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
268268

net/smc/smc_core.c

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -266,17 +266,16 @@ static void smc_lgr_free_sndbufs(struct smc_link_group *lgr)
266266

267267
static void smc_lgr_free_rmbs(struct smc_link_group *lgr)
268268
{
269-
struct smc_buf_desc *rmb_desc, *bf_desc;
270269
struct smc_link *lnk = &lgr->lnk[SMC_SINGLE_LINK];
270+
struct smc_buf_desc *rmb_desc, *bf_desc;
271271
int i;
272272

273273
for (i = 0; i < SMC_RMBE_SIZES; i++) {
274274
list_for_each_entry_safe(rmb_desc, bf_desc, &lgr->rmbs[i],
275275
list) {
276276
list_del(&rmb_desc->list);
277-
smc_ib_buf_unmap(lnk->smcibdev,
278-
smc_uncompress_bufsize(i),
279-
rmb_desc, DMA_FROM_DEVICE);
277+
smc_ib_buf_unmap_sg(lnk->smcibdev, rmb_desc,
278+
DMA_FROM_DEVICE);
280279
kfree(rmb_desc->cpu_addr);
281280
kfree(rmb_desc);
282281
}
@@ -580,38 +579,54 @@ int smc_rmb_create(struct smc_sock *smc)
580579
for (bufsize_short = smc_compress_bufsize(smc->sk.sk_rcvbuf / 2);
581580
bufsize_short >= 0; bufsize_short--) {
582581
bufsize = smc_uncompress_bufsize(bufsize_short);
582+
if ((1 << get_order(bufsize)) > SG_MAX_SINGLE_ALLOC)
583+
continue;
584+
583585
/* check for reusable rmb_slot in the link group */
584586
rmb_desc = smc_rmb_get_slot(lgr, bufsize_short);
585587
if (rmb_desc) {
586588
memset(rmb_desc->cpu_addr, 0, bufsize);
587589
break; /* found reusable slot */
588590
}
591+
589592
/* try to alloc a new RMB */
590593
rmb_desc = kzalloc(sizeof(*rmb_desc), GFP_KERNEL);
591594
if (!rmb_desc)
592595
break; /* give up with -ENOMEM */
593-
rmb_desc->cpu_addr = kzalloc(bufsize,
594-
GFP_KERNEL | __GFP_NOWARN |
595-
__GFP_NOMEMALLOC |
596-
__GFP_NORETRY);
596+
rmb_desc->cpu_addr =
597+
(void *)__get_free_pages(GFP_KERNEL | __GFP_NOWARN |
598+
__GFP_NOMEMALLOC |
599+
__GFP_NORETRY | __GFP_ZERO,
600+
get_order(bufsize));
597601
if (!rmb_desc->cpu_addr) {
598602
kfree(rmb_desc);
599603
rmb_desc = NULL;
600-
/* if RMB allocation has failed,
601-
* try a smaller one
602-
*/
603604
continue;
604605
}
605-
rc = smc_ib_buf_map(lgr->lnk[SMC_SINGLE_LINK].smcibdev,
606-
bufsize, rmb_desc, DMA_FROM_DEVICE);
606+
rmb_desc->order = get_order(bufsize);
607+
608+
rc = sg_alloc_table(&rmb_desc->sgt[SMC_SINGLE_LINK], 1,
609+
GFP_KERNEL);
607610
if (rc) {
608-
kfree(rmb_desc->cpu_addr);
611+
free_pages((unsigned long)rmb_desc->cpu_addr,
612+
rmb_desc->order);
613+
kfree(rmb_desc);
614+
rmb_desc = NULL;
615+
continue;
616+
}
617+
sg_set_buf(rmb_desc->sgt[SMC_SINGLE_LINK].sgl,
618+
rmb_desc->cpu_addr, bufsize);
619+
620+
rc = smc_ib_buf_map_sg(lgr->lnk[SMC_SINGLE_LINK].smcibdev,
621+
rmb_desc, DMA_FROM_DEVICE);
622+
if (rc != 1) {
623+
sg_free_table(&rmb_desc->sgt[SMC_SINGLE_LINK]);
624+
free_pages((unsigned long)rmb_desc->cpu_addr,
625+
rmb_desc->order);
609626
kfree(rmb_desc);
610627
rmb_desc = NULL;
611628
continue; /* if mapping failed, try smaller one */
612629
}
613-
rmb_desc->rkey[SMC_SINGLE_LINK] =
614-
lgr->lnk[SMC_SINGLE_LINK].roce_pd->unsafe_global_rkey;
615630
rmb_desc->used = 1;
616631
write_lock_bh(&lgr->rmbs_lock);
617632
list_add(&rmb_desc->list, &lgr->rmbs[bufsize_short]);

net/smc/smc_core.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,8 @@ struct smc_buf_desc {
9393
u64 dma_addr[SMC_LINKS_PER_LGR_MAX];
9494
/* mapped address of buffer */
9595
void *cpu_addr; /* virtual address of buffer */
96-
u32 rkey[SMC_LINKS_PER_LGR_MAX];
97-
/* for rmb only:
98-
* rkey provided to peer
99-
*/
96+
struct sg_table sgt[SMC_LINKS_PER_LGR_MAX];/* virtual buffer */
97+
u32 order; /* allocation order */
10098
u32 used; /* currently used / unused */
10199
};
102100

net/smc/smc_ib.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,37 @@ void smc_ib_buf_unmap(struct smc_ib_device *smcibdev, int buf_size,
283283
buf_slot->dma_addr[SMC_SINGLE_LINK] = 0;
284284
}
285285

286+
/* Map a new TX or RX buffer SG-table to DMA */
287+
int smc_ib_buf_map_sg(struct smc_ib_device *smcibdev,
288+
struct smc_buf_desc *buf_slot,
289+
enum dma_data_direction data_direction)
290+
{
291+
int mapped_nents;
292+
293+
mapped_nents = ib_dma_map_sg(smcibdev->ibdev,
294+
buf_slot->sgt[SMC_SINGLE_LINK].sgl,
295+
buf_slot->sgt[SMC_SINGLE_LINK].orig_nents,
296+
data_direction);
297+
if (!mapped_nents)
298+
return -ENOMEM;
299+
300+
return mapped_nents;
301+
}
302+
303+
void smc_ib_buf_unmap_sg(struct smc_ib_device *smcibdev,
304+
struct smc_buf_desc *buf_slot,
305+
enum dma_data_direction data_direction)
306+
{
307+
if (!buf_slot->sgt[SMC_SINGLE_LINK].sgl->dma_address)
308+
return; /* already unmapped */
309+
310+
ib_dma_unmap_sg(smcibdev->ibdev,
311+
buf_slot->sgt[SMC_SINGLE_LINK].sgl,
312+
buf_slot->sgt[SMC_SINGLE_LINK].orig_nents,
313+
data_direction);
314+
buf_slot->sgt[SMC_SINGLE_LINK].sgl->dma_address = 0;
315+
}
316+
286317
static int smc_ib_fill_gid_and_mac(struct smc_ib_device *smcibdev, u8 ibport)
287318
{
288319
struct net_device *ndev;

net/smc/smc_ib.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@ int smc_ib_buf_map(struct smc_ib_device *smcibdev, int buf_size,
5757
void smc_ib_buf_unmap(struct smc_ib_device *smcibdev, int bufsize,
5858
struct smc_buf_desc *buf_slot,
5959
enum dma_data_direction data_direction);
60+
int smc_ib_buf_map_sg(struct smc_ib_device *smcibdev,
61+
struct smc_buf_desc *buf_slot,
62+
enum dma_data_direction data_direction);
63+
void smc_ib_buf_unmap_sg(struct smc_ib_device *smcibdev,
64+
struct smc_buf_desc *buf_slot,
65+
enum dma_data_direction data_direction);
6066
void smc_ib_dealloc_protection_domain(struct smc_link *lnk);
6167
int smc_ib_create_protection_domain(struct smc_link *lnk);
6268
void smc_ib_destroy_queue_pair(struct smc_link *lnk);

0 commit comments

Comments
 (0)