Skip to content

Commit 01d2f7e

Browse files
Ursula Braundavem330
authored andcommitted
net/smc: sockopts TCP_NODELAY and TCP_CORK
Setting sockopt TCP_NODELAY or resetting sockopt TCP_CORK triggers data transfer. For a corked SMC socket RDMA writes are deferred, if there is still sufficient send buffer space available. Signed-off-by: Ursula Braun <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent ee9dfbe commit 01d2f7e

File tree

2 files changed

+40
-4
lines changed

2 files changed

+40
-4
lines changed

net/smc/af_smc.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1291,7 +1291,7 @@ static int smc_setsockopt(struct socket *sock, int level, int optname,
12911291
{
12921292
struct sock *sk = sock->sk;
12931293
struct smc_sock *smc;
1294-
int rc;
1294+
int val, rc;
12951295

12961296
smc = smc_sk(sk);
12971297

@@ -1307,6 +1307,10 @@ static int smc_setsockopt(struct socket *sock, int level, int optname,
13071307
if (rc)
13081308
return rc;
13091309

1310+
if (optlen < sizeof(int))
1311+
return rc;
1312+
get_user(val, (int __user *)optval);
1313+
13101314
lock_sock(sk);
13111315
switch (optname) {
13121316
case TCP_ULP:
@@ -1322,6 +1326,20 @@ static int smc_setsockopt(struct socket *sock, int level, int optname,
13221326
rc = -EINVAL;
13231327
}
13241328
break;
1329+
case TCP_NODELAY:
1330+
if (sk->sk_state != SMC_INIT && sk->sk_state != SMC_LISTEN) {
1331+
if (val)
1332+
mod_delayed_work(system_wq, &smc->conn.tx_work,
1333+
0);
1334+
}
1335+
break;
1336+
case TCP_CORK:
1337+
if (sk->sk_state != SMC_INIT && sk->sk_state != SMC_LISTEN) {
1338+
if (!val)
1339+
mod_delayed_work(system_wq, &smc->conn.tx_work,
1340+
0);
1341+
}
1342+
break;
13251343
default:
13261344
break;
13271345
}

net/smc/smc_tx.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,15 @@
1919
#include <linux/sched/signal.h>
2020

2121
#include <net/sock.h>
22+
#include <net/tcp.h>
2223

2324
#include "smc.h"
2425
#include "smc_wr.h"
2526
#include "smc_cdc.h"
2627
#include "smc_tx.h"
2728

2829
#define SMC_TX_WORK_DELAY HZ
30+
#define SMC_TX_CORK_DELAY (HZ >> 2) /* 250 ms */
2931

3032
/***************************** sndbuf producer *******************************/
3133

@@ -115,6 +117,13 @@ static int smc_tx_wait_memory(struct smc_sock *smc, int flags)
115117
return rc;
116118
}
117119

120+
static bool smc_tx_is_corked(struct smc_sock *smc)
121+
{
122+
struct tcp_sock *tp = tcp_sk(smc->clcsock->sk);
123+
124+
return (tp->nonagle & TCP_NAGLE_CORK) ? true : false;
125+
}
126+
118127
/* sndbuf producer: main API called by socket layer.
119128
* called under sock lock.
120129
*/
@@ -209,7 +218,16 @@ int smc_tx_sendmsg(struct smc_sock *smc, struct msghdr *msg, size_t len)
209218
/* since we just produced more new data into sndbuf,
210219
* trigger sndbuf consumer: RDMA write into peer RMBE and CDC
211220
*/
212-
smc_tx_sndbuf_nonempty(conn);
221+
if ((msg->msg_flags & MSG_MORE || smc_tx_is_corked(smc)) &&
222+
(atomic_read(&conn->sndbuf_space) >
223+
(conn->sndbuf_size >> 1)))
224+
/* for a corked socket defer the RDMA writes if there
225+
* is still sufficient sndbuf_space available
226+
*/
227+
schedule_delayed_work(&conn->tx_work,
228+
SMC_TX_CORK_DELAY);
229+
else
230+
smc_tx_sndbuf_nonempty(conn);
213231
} /* while (msg_data_left(msg)) */
214232

215233
return send_done;
@@ -409,8 +427,8 @@ int smc_tx_sndbuf_nonempty(struct smc_connection *conn)
409427
}
410428
rc = 0;
411429
if (conn->alert_token_local) /* connection healthy */
412-
schedule_delayed_work(&conn->tx_work,
413-
SMC_TX_WORK_DELAY);
430+
mod_delayed_work(system_wq, &conn->tx_work,
431+
SMC_TX_WORK_DELAY);
414432
}
415433
goto out_unlock;
416434
}

0 commit comments

Comments
 (0)