Skip to content

Commit b8d1994

Browse files
Wen Gudavem330
authored andcommitted
net/smc: Allow virtually contiguous sndbufs or RMBs for SMC-R
On long-running enterprise production servers, high-order contiguous memory pages are usually very rare and in most cases we can only get fragmented pages. When replacing TCP with SMC-R in such production scenarios, attempting to allocate high-order physically contiguous sndbufs and RMBs may result in frequent memory compaction, which will cause unexpected hung issue and further stability risks. So this patch is aimed to allow SMC-R link group to use virtually contiguous sndbufs and RMBs to avoid potential issues mentioned above. Whether to use physically or virtually contiguous buffers can be set by sysctl smcr_buf_type. Note that using virtually contiguous buffers will bring an acceptable performance regression, which can be mainly divided into two parts: 1) regression in data path, which is brought by additional address translation of sndbuf by RNIC in Tx. But in general, translating address through MTT is fast. Taking 256KB sndbuf and RMB as an example, the comparisons in qperf latency and bandwidth test with physically and virtually contiguous buffers are as follows: - client: smc_run taskset -c <cpu> qperf <server> -oo msg_size:1:64K:*2\ -t 5 -vu tcp_{bw|lat} - server: smc_run taskset -c <cpu> qperf [latency] msgsize tcp smcr smcr-use-virt-buf 1 11.17 us 7.56 us 7.51 us (-0.67%) 2 10.65 us 7.74 us 7.56 us (-2.31%) 4 11.11 us 7.52 us 7.59 us ( 0.84%) 8 10.83 us 7.55 us 7.51 us (-0.48%) 16 11.21 us 7.46 us 7.51 us ( 0.71%) 32 10.65 us 7.53 us 7.58 us ( 0.61%) 64 10.95 us 7.74 us 7.80 us ( 0.76%) 128 11.14 us 7.83 us 7.87 us ( 0.47%) 256 10.97 us 7.94 us 7.92 us (-0.28%) 512 11.23 us 7.94 us 8.20 us ( 3.25%) 1024 11.60 us 8.12 us 8.20 us ( 0.96%) 2048 14.04 us 8.30 us 8.51 us ( 2.49%) 4096 16.88 us 9.13 us 9.07 us (-0.64%) 8192 22.50 us 10.56 us 11.22 us ( 6.26%) 16384 28.99 us 12.88 us 13.83 us ( 7.37%) 32768 40.13 us 16.76 us 16.95 us ( 1.16%) 65536 68.70 us 24.68 us 24.85 us ( 0.68%) [bandwidth] msgsize tcp smcr smcr-use-virt-buf 1 1.65 MB/s 1.59 MB/s 1.53 MB/s (-3.88%) 2 3.32 MB/s 3.17 MB/s 3.08 MB/s (-2.67%) 4 6.66 MB/s 6.33 MB/s 6.09 MB/s (-3.85%) 8 13.67 MB/s 13.45 MB/s 11.97 MB/s (-10.99%) 16 25.36 MB/s 27.15 MB/s 24.16 MB/s (-11.01%) 32 48.22 MB/s 54.24 MB/s 49.41 MB/s (-8.89%) 64 106.79 MB/s 107.32 MB/s 99.05 MB/s (-7.71%) 128 210.21 MB/s 202.46 MB/s 201.02 MB/s (-0.71%) 256 400.81 MB/s 416.81 MB/s 393.52 MB/s (-5.59%) 512 746.49 MB/s 834.12 MB/s 809.99 MB/s (-2.89%) 1024 1292.33 MB/s 1641.96 MB/s 1571.82 MB/s (-4.27%) 2048 2007.64 MB/s 2760.44 MB/s 2717.68 MB/s (-1.55%) 4096 2665.17 MB/s 4157.44 MB/s 4070.76 MB/s (-2.09%) 8192 3159.72 MB/s 4361.57 MB/s 4270.65 MB/s (-2.08%) 16384 4186.70 MB/s 4574.13 MB/s 4501.17 MB/s (-1.60%) 32768 4093.21 MB/s 4487.42 MB/s 4322.43 MB/s (-3.68%) 65536 4057.14 MB/s 4735.61 MB/s 4555.17 MB/s (-3.81%) 2) regression in buffer initialization and destruction path, which is brought by additional MR operations of sndbufs. But thanks to link group buffer reuse mechanism, the impact of this kind of regression decreases as times of buffer reuse increases. Taking 256KB sndbuf and RMB as an example, latency of some key SMC-R buffer-related function obtained by bpftrace are as follows: Function Phys-bufs Virt-bufs smcr_new_buf_create() 67154 ns 79164 ns smc_ib_buf_map_sg() 525 ns 928 ns smc_ib_get_memory_region() 162294 ns 161191 ns smc_wr_reg_send() 9957 ns 9635 ns smc_ib_put_memory_region() 203548 ns 198374 ns smc_ib_buf_unmap_sg() 508 ns 1158 ns ------------ Test environment notes: 1. Above tests run on 2 VMs within the same Host. 2. The NIC is ConnectX-4Lx, using SRIOV and passing through 2 VFs to the each VM respectively. 3. VMs' vCPUs are binded to different physical CPUs, and the binded physical CPUs are isolated by `isolcpus=xxx` cmdline. 4. NICs' queue number are set to 1. Signed-off-by: Wen Gu <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent b984f37 commit b8d1994

File tree

9 files changed

+328
-118
lines changed

9 files changed

+328
-118
lines changed

net/smc/af_smc.c

Lines changed: 58 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,29 @@ static void smc_copy_sock_settings_to_smc(struct smc_sock *smc)
487487
smc_copy_sock_settings(&smc->sk, smc->clcsock->sk, SK_FLAGS_CLC_TO_SMC);
488488
}
489489

490+
/* register the new vzalloced sndbuf on all links */
491+
static int smcr_lgr_reg_sndbufs(struct smc_link *link,
492+
struct smc_buf_desc *snd_desc)
493+
{
494+
struct smc_link_group *lgr = link->lgr;
495+
int i, rc = 0;
496+
497+
if (!snd_desc->is_vm)
498+
return -EINVAL;
499+
500+
/* protect against parallel smcr_link_reg_buf() */
501+
mutex_lock(&lgr->llc_conf_mutex);
502+
for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) {
503+
if (!smc_link_active(&lgr->lnk[i]))
504+
continue;
505+
rc = smcr_link_reg_buf(&lgr->lnk[i], snd_desc);
506+
if (rc)
507+
break;
508+
}
509+
mutex_unlock(&lgr->llc_conf_mutex);
510+
return rc;
511+
}
512+
490513
/* register the new rmb on all links */
491514
static int smcr_lgr_reg_rmbs(struct smc_link *link,
492515
struct smc_buf_desc *rmb_desc)
@@ -498,13 +521,13 @@ static int smcr_lgr_reg_rmbs(struct smc_link *link,
498521
if (rc)
499522
return rc;
500523
/* protect against parallel smc_llc_cli_rkey_exchange() and
501-
* parallel smcr_link_reg_rmb()
524+
* parallel smcr_link_reg_buf()
502525
*/
503526
mutex_lock(&lgr->llc_conf_mutex);
504527
for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) {
505528
if (!smc_link_active(&lgr->lnk[i]))
506529
continue;
507-
rc = smcr_link_reg_rmb(&lgr->lnk[i], rmb_desc);
530+
rc = smcr_link_reg_buf(&lgr->lnk[i], rmb_desc);
508531
if (rc)
509532
goto out;
510533
}
@@ -550,8 +573,15 @@ static int smcr_clnt_conf_first_link(struct smc_sock *smc)
550573

551574
smc_wr_remember_qp_attr(link);
552575

553-
if (smcr_link_reg_rmb(link, smc->conn.rmb_desc))
554-
return SMC_CLC_DECL_ERR_REGRMB;
576+
/* reg the sndbuf if it was vzalloced */
577+
if (smc->conn.sndbuf_desc->is_vm) {
578+
if (smcr_link_reg_buf(link, smc->conn.sndbuf_desc))
579+
return SMC_CLC_DECL_ERR_REGBUF;
580+
}
581+
582+
/* reg the rmb */
583+
if (smcr_link_reg_buf(link, smc->conn.rmb_desc))
584+
return SMC_CLC_DECL_ERR_REGBUF;
555585

556586
/* confirm_rkey is implicit on 1st contact */
557587
smc->conn.rmb_desc->is_conf_rkey = true;
@@ -1221,8 +1251,15 @@ static int smc_connect_rdma(struct smc_sock *smc,
12211251
goto connect_abort;
12221252
}
12231253
} else {
1254+
/* reg sendbufs if they were vzalloced */
1255+
if (smc->conn.sndbuf_desc->is_vm) {
1256+
if (smcr_lgr_reg_sndbufs(link, smc->conn.sndbuf_desc)) {
1257+
reason_code = SMC_CLC_DECL_ERR_REGBUF;
1258+
goto connect_abort;
1259+
}
1260+
}
12241261
if (smcr_lgr_reg_rmbs(link, smc->conn.rmb_desc)) {
1225-
reason_code = SMC_CLC_DECL_ERR_REGRMB;
1262+
reason_code = SMC_CLC_DECL_ERR_REGBUF;
12261263
goto connect_abort;
12271264
}
12281265
}
@@ -1749,8 +1786,15 @@ static int smcr_serv_conf_first_link(struct smc_sock *smc)
17491786
struct smc_llc_qentry *qentry;
17501787
int rc;
17511788

1752-
if (smcr_link_reg_rmb(link, smc->conn.rmb_desc))
1753-
return SMC_CLC_DECL_ERR_REGRMB;
1789+
/* reg the sndbuf if it was vzalloced*/
1790+
if (smc->conn.sndbuf_desc->is_vm) {
1791+
if (smcr_link_reg_buf(link, smc->conn.sndbuf_desc))
1792+
return SMC_CLC_DECL_ERR_REGBUF;
1793+
}
1794+
1795+
/* reg the rmb */
1796+
if (smcr_link_reg_buf(link, smc->conn.rmb_desc))
1797+
return SMC_CLC_DECL_ERR_REGBUF;
17541798

17551799
/* send CONFIRM LINK request to client over the RoCE fabric */
17561800
rc = smc_llc_send_confirm_link(link, SMC_LLC_REQ);
@@ -2109,8 +2153,14 @@ static int smc_listen_rdma_reg(struct smc_sock *new_smc, bool local_first)
21092153
struct smc_connection *conn = &new_smc->conn;
21102154

21112155
if (!local_first) {
2156+
/* reg sendbufs if they were vzalloced */
2157+
if (conn->sndbuf_desc->is_vm) {
2158+
if (smcr_lgr_reg_sndbufs(conn->lnk,
2159+
conn->sndbuf_desc))
2160+
return SMC_CLC_DECL_ERR_REGBUF;
2161+
}
21122162
if (smcr_lgr_reg_rmbs(conn->lnk, conn->rmb_desc))
2113-
return SMC_CLC_DECL_ERR_REGRMB;
2163+
return SMC_CLC_DECL_ERR_REGBUF;
21142164
}
21152165

21162166
return 0;

net/smc/smc_clc.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,7 +1034,7 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc,
10341034
ETH_ALEN);
10351035
hton24(clc->r0.qpn, link->roce_qp->qp_num);
10361036
clc->r0.rmb_rkey =
1037-
htonl(conn->rmb_desc->mr_rx[link->link_idx]->rkey);
1037+
htonl(conn->rmb_desc->mr[link->link_idx]->rkey);
10381038
clc->r0.rmbe_idx = 1; /* for now: 1 RMB = 1 RMBE */
10391039
clc->r0.rmbe_alert_token = htonl(conn->alert_token_local);
10401040
switch (clc->hdr.type) {
@@ -1046,8 +1046,10 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc,
10461046
break;
10471047
}
10481048
clc->r0.rmbe_size = conn->rmbe_size_short;
1049-
clc->r0.rmb_dma_addr = cpu_to_be64((u64)sg_dma_address
1050-
(conn->rmb_desc->sgt[link->link_idx].sgl));
1049+
clc->r0.rmb_dma_addr = conn->rmb_desc->is_vm ?
1050+
cpu_to_be64((uintptr_t)conn->rmb_desc->cpu_addr) :
1051+
cpu_to_be64((u64)sg_dma_address
1052+
(conn->rmb_desc->sgt[link->link_idx].sgl));
10511053
hton24(clc->r0.psn, link->psn_initial);
10521054
if (version == SMC_V1) {
10531055
clc->hdr.length = htons(SMCR_CLC_ACCEPT_CONFIRM_LEN);

net/smc/smc_clc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
#define SMC_CLC_DECL_INTERR 0x09990000 /* internal error */
6363
#define SMC_CLC_DECL_ERR_RTOK 0x09990001 /* rtoken handling failed */
6464
#define SMC_CLC_DECL_ERR_RDYLNK 0x09990002 /* ib ready link failed */
65-
#define SMC_CLC_DECL_ERR_REGRMB 0x09990003 /* reg rmb failed */
65+
#define SMC_CLC_DECL_ERR_REGBUF 0x09990003 /* reg rdma bufs failed */
6666

6767
#define SMC_FIRST_CONTACT_MASK 0b10 /* first contact bit within typev2 */
6868

0 commit comments

Comments
 (0)