hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I76JHC
--------------------------------
If the receiver application reads data slower than the sender, the sender may occur sending failures due to a full sndbufs, and the receiver may not process the rmb timely which results in the sender unable to send data immediately. Increasing the buffer size appropriately can help reduce the probability of the above problems and increase throughput. Therefore, tune the maximum size to 256M of virtually contiguous sndbufs or RMBs for SMC-R.
Signed-off-by: Litao Jiao jiaolitao@sangfor.com.cn --- Documentation/networking/smc-sysctl.rst | 6 +++-- net/smc/smc_core.c | 32 +++++++++++++++++-------- 2 files changed, 26 insertions(+), 12 deletions(-)
diff --git a/Documentation/networking/smc-sysctl.rst b/Documentation/networking/smc-sysctl.rst index e38c92ab46f3..5983b951077e 100644 --- a/Documentation/networking/smc-sysctl.rst +++ b/Documentation/networking/smc-sysctl.rst @@ -25,7 +25,8 @@ wmem - INTEGER The default value inherits from net.ipv4.tcp_wmem[1].
The minimum value is 16KiB and there is no hard limit for max value, but - only allowed 512KiB for SMC-R and 1MiB for SMC-D. + only allowed 512KiB for SMC-R using physically contiguous buffers, 256MiB + for SMC-R using other buf type and 1MiB for SMC-D.
Default: 16K
@@ -34,6 +35,7 @@ rmem - INTEGER The default value inherits from net.ipv4.tcp_rmem[1].
The minimum value is 16KiB and there is no hard limit for max value, but - only allowed 512KiB for SMC-R and 1MiB for SMC-D. + only allowed 512KiB for SMC-R using physically contiguous buffers, 256MiB + for SMC-R using other buf type and 1MiB for SMC-D.
Default: 128K diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c index f3f296e206aa..8ac07d2b4e9a 100644 --- a/net/smc/smc_core.c +++ b/net/smc/smc_core.c @@ -1386,29 +1386,41 @@ int smc_conn_create(struct smc_sock *smc, struct smc_init_info *ini) return rc; }
-#define SMCD_DMBE_SIZES 6 /* 0 -> 16KB, 1 -> 32KB, .. 6 -> 1MB */ -#define SMCR_RMBE_SIZES 5 /* 0 -> 16KB, 1 -> 32KB, .. 5 -> 512KB */ +#define SMCD_DMBE_SIZES 6 /* 0 -> 16KB, 1 -> 32KB, .. 6 -> 1MB */ +#define SMCR_RMBE_SIZES 14 /* 0 -> 16KB, 1 -> 32KB, .. 14 -> 256MB */
/* convert the RMB size into the compressed notation (minimum 16K, see * SMCD/R_DMBE_SIZES. * In contrast to plain ilog2, this rounds towards the next power of 2, * so the socket application gets at least its desired sndbuf / rcvbuf size. */ -static u8 smc_compress_bufsize(int size, bool is_smcd, bool is_rmb) +static u8 smc_compress_bufsize(struct smc_link_group *lgr, int size, bool is_smcd, bool is_rmb) { const unsigned int max_scat = SG_MAX_SINGLE_ALLOC * PAGE_SIZE; - u8 compressed; + u8 compressed, max_phy_compressed;
if (size <= SMC_BUF_MIN_SIZE) return 0;
size = (size - 1) >> 14; /* convert to 16K multiple */ compressed = min_t(u8, ilog2(size) + 1, - is_smcd ? SMCD_DMBE_SIZES : SMCR_RMBE_SIZES); - - if (!is_smcd && is_rmb) - /* RMBs are backed by & limited to max size of scatterlists */ - compressed = min_t(u8, compressed, ilog2(max_scat >> 14)); + is_smcd ? SMCD_DMBE_SIZES : SMCR_RMBE_SIZES); + + if (!is_smcd && is_rmb && (lgr->buf_type != SMCR_VIRT_CONT_BUFS)) { + max_phy_compressed = ilog2(max_scat >> 14); + switch (lgr->buf_type) { + case SMCR_MIXED_BUFS: + if (compressed > max_phy_compressed) + break; + fallthrough; // try phys continguous buf + case SMCR_PHYS_CONT_BUFS: + /* RMBs are backed by & limited to max size of scatterlists */ + compressed = min_t(u8, compressed, max_phy_compressed); + break; + default: + break; + } + }
return compressed; } @@ -1752,7 +1764,7 @@ static int __smc_buf_create(struct smc_sock *smc, bool is_smcd, bool is_rmb) /* use socket send buffer size (w/o overhead) as start value */ sk_buf_size = smc->sk.sk_sndbuf;
- for (bufsize_short = smc_compress_bufsize(sk_buf_size, is_smcd, is_rmb); + for (bufsize_short = smc_compress_bufsize(lgr, sk_buf_size, is_smcd, is_rmb); bufsize_short >= 0; bufsize_short--) { if (is_rmb) { lock = &lgr->rmbs_lock;