Commit d0e35656 authored by D. Wythe's avatar D. Wythe Committed by David S. Miller

net/smc: refactoring initialization of smc sock

This patch aims to isolate the shared components of SMC socket
allocation by introducing smc_sk_init() for sock initialization
and __smc_create_clcsk() for the initialization of clcsock.

This is in preparation for the subsequent implementation of the
AF_INET version of SMC.
Signed-off-by: default avatarD. Wythe <alibuda@linux.alibaba.com>
Reviewed-by: default avatarTony Lu <tonylu@linux.alibaba.com>
Reviewed-by: default avatarWenjia Zhang <wenjia@linux.ibm.com>
Reviewed-by: default avatarDust Li <dust.li@linux.alibaba.com>
Tested-by: default avatarNiklas Schnelle <schnelle@linux.ibm.com>
Tested-by: default avatarWenjia Zhang <wenjia@linux.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f22b4b55
...@@ -361,25 +361,15 @@ static void smc_destruct(struct sock *sk) ...@@ -361,25 +361,15 @@ static void smc_destruct(struct sock *sk)
return; return;
} }
static struct sock *smc_sock_alloc(struct net *net, struct socket *sock, void smc_sk_init(struct net *net, struct sock *sk, int protocol)
int protocol)
{ {
struct smc_sock *smc; struct smc_sock *smc = smc_sk(sk);
struct proto *prot;
struct sock *sk;
prot = (protocol == SMCPROTO_SMC6) ? &smc_proto6 : &smc_proto;
sk = sk_alloc(net, PF_SMC, GFP_KERNEL, prot, 0);
if (!sk)
return NULL;
sock_init_data(sock, sk); /* sets sk_refcnt to 1 */
sk->sk_state = SMC_INIT; sk->sk_state = SMC_INIT;
sk->sk_destruct = smc_destruct; sk->sk_destruct = smc_destruct;
sk->sk_protocol = protocol; sk->sk_protocol = protocol;
WRITE_ONCE(sk->sk_sndbuf, 2 * READ_ONCE(net->smc.sysctl_wmem)); WRITE_ONCE(sk->sk_sndbuf, 2 * READ_ONCE(net->smc.sysctl_wmem));
WRITE_ONCE(sk->sk_rcvbuf, 2 * READ_ONCE(net->smc.sysctl_rmem)); WRITE_ONCE(sk->sk_rcvbuf, 2 * READ_ONCE(net->smc.sysctl_rmem));
smc = smc_sk(sk);
INIT_WORK(&smc->tcp_listen_work, smc_tcp_listen_work); INIT_WORK(&smc->tcp_listen_work, smc_tcp_listen_work);
INIT_WORK(&smc->connect_work, smc_connect_work); INIT_WORK(&smc->connect_work, smc_connect_work);
INIT_DELAYED_WORK(&smc->conn.tx_work, smc_tx_work); INIT_DELAYED_WORK(&smc->conn.tx_work, smc_tx_work);
...@@ -389,6 +379,24 @@ static struct sock *smc_sock_alloc(struct net *net, struct socket *sock, ...@@ -389,6 +379,24 @@ static struct sock *smc_sock_alloc(struct net *net, struct socket *sock,
sk->sk_prot->hash(sk); sk->sk_prot->hash(sk);
mutex_init(&smc->clcsock_release_lock); mutex_init(&smc->clcsock_release_lock);
smc_init_saved_callbacks(smc); smc_init_saved_callbacks(smc);
smc->limit_smc_hs = net->smc.limit_smc_hs;
smc->use_fallback = false; /* assume rdma capability first */
smc->fallback_rsn = 0;
}
static struct sock *smc_sock_alloc(struct net *net, struct socket *sock,
int protocol)
{
struct proto *prot;
struct sock *sk;
prot = (protocol == SMCPROTO_SMC6) ? &smc_proto6 : &smc_proto;
sk = sk_alloc(net, PF_SMC, GFP_KERNEL, prot, 0);
if (!sk)
return NULL;
sock_init_data(sock, sk); /* sets sk_refcnt to 1 */
smc_sk_init(net, sk, protocol);
return sk; return sk;
} }
...@@ -3303,6 +3311,31 @@ static const struct proto_ops smc_sock_ops = { ...@@ -3303,6 +3311,31 @@ static const struct proto_ops smc_sock_ops = {
.splice_read = smc_splice_read, .splice_read = smc_splice_read,
}; };
int smc_create_clcsk(struct net *net, struct sock *sk, int family)
{
struct smc_sock *smc = smc_sk(sk);
int rc;
rc = sock_create_kern(net, family, SOCK_STREAM, IPPROTO_TCP,
&smc->clcsock);
if (rc) {
sk_common_release(sk);
return rc;
}
/* smc_clcsock_release() does not wait smc->clcsock->sk's
* destruction; its sk_state might not be TCP_CLOSE after
* smc->sk is close()d, and TCP timers can be fired later,
* which need net ref.
*/
sk = smc->clcsock->sk;
__netns_tracker_free(net, &sk->ns_tracker, false);
sk->sk_net_refcnt = 1;
get_net_track(net, &sk->ns_tracker, GFP_KERNEL);
sock_inuse_add(net, 1);
return 0;
}
static int __smc_create(struct net *net, struct socket *sock, int protocol, static int __smc_create(struct net *net, struct socket *sock, int protocol,
int kern, struct socket *clcsock) int kern, struct socket *clcsock)
{ {
...@@ -3328,35 +3361,12 @@ static int __smc_create(struct net *net, struct socket *sock, int protocol, ...@@ -3328,35 +3361,12 @@ static int __smc_create(struct net *net, struct socket *sock, int protocol,
/* create internal TCP socket for CLC handshake and fallback */ /* create internal TCP socket for CLC handshake and fallback */
smc = smc_sk(sk); smc = smc_sk(sk);
smc->use_fallback = false; /* assume rdma capability first */
smc->fallback_rsn = 0;
/* default behavior from limit_smc_hs in every net namespace */
smc->limit_smc_hs = net->smc.limit_smc_hs;
rc = 0; rc = 0;
if (!clcsock) { if (clcsock)
rc = sock_create_kern(net, family, SOCK_STREAM, IPPROTO_TCP,
&smc->clcsock);
if (rc) {
sk_common_release(sk);
goto out;
}
/* smc_clcsock_release() does not wait smc->clcsock->sk's
* destruction; its sk_state might not be TCP_CLOSE after
* smc->sk is close()d, and TCP timers can be fired later,
* which need net ref.
*/
sk = smc->clcsock->sk;
__netns_tracker_free(net, &sk->ns_tracker, false);
sk->sk_net_refcnt = 1;
get_net_track(net, &sk->ns_tracker, GFP_KERNEL);
sock_inuse_add(net, 1);
} else {
smc->clcsock = clcsock; smc->clcsock = clcsock;
} else
rc = smc_create_clcsk(net, sk, family);
out: out:
return rc; return rc;
} }
......
...@@ -34,6 +34,11 @@ ...@@ -34,6 +34,11 @@
extern struct proto smc_proto; extern struct proto smc_proto;
extern struct proto smc_proto6; extern struct proto smc_proto6;
/* smc sock initialization */
void smc_sk_init(struct net *net, struct sock *sk, int protocol);
/* clcsock initialization */
int smc_create_clcsk(struct net *net, struct sock *sk, int family);
#ifdef ATOMIC64_INIT #ifdef ATOMIC64_INIT
#define KERNEL_HAS_ATOMIC64 #define KERNEL_HAS_ATOMIC64
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment