Skip to content

Commit

Permalink
net/smc: refactoring initialization of smc sock
Browse files Browse the repository at this point in the history
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: D. Wythe <alibuda@linux.alibaba.com>
Reviewed-by: Tony Lu <tonylu@linux.alibaba.com>
Reviewed-by: Wenjia Zhang <wenjia@linux.ibm.com>
Reviewed-by: Dust Li <dust.li@linux.alibaba.com>
Tested-by: Niklas Schnelle <schnelle@linux.ibm.com>
Tested-by: Wenjia Zhang <wenjia@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
D. Wythe authored and David S. Miller committed Jun 17, 2024
1 parent f22b4b5 commit d0e3565
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 38 deletions.
86 changes: 48 additions & 38 deletions net/smc/af_smc.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,25 +361,15 @@ static void smc_destruct(struct sock *sk)
return;
}

static struct sock *smc_sock_alloc(struct net *net, struct socket *sock,
int protocol)
void smc_sk_init(struct net *net, struct sock *sk, int protocol)
{
struct smc_sock *smc;
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;
struct smc_sock *smc = smc_sk(sk);

sock_init_data(sock, sk); /* sets sk_refcnt to 1 */
sk->sk_state = SMC_INIT;
sk->sk_destruct = smc_destruct;
sk->sk_protocol = protocol;
WRITE_ONCE(sk->sk_sndbuf, 2 * READ_ONCE(net->smc.sysctl_wmem));
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->connect_work, smc_connect_work);
INIT_DELAYED_WORK(&smc->conn.tx_work, smc_tx_work);
Expand All @@ -389,6 +379,24 @@ static struct sock *smc_sock_alloc(struct net *net, struct socket *sock,
sk->sk_prot->hash(sk);
mutex_init(&smc->clcsock_release_lock);
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;
}
Expand Down Expand Up @@ -3303,6 +3311,31 @@ static const struct proto_ops smc_sock_ops = {
.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,
int kern, struct socket *clcsock)
{
Expand All @@ -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 */
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;
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 {
if (clcsock)
smc->clcsock = clcsock;
}

else
rc = smc_create_clcsk(net, sk, family);
out:
return rc;
}
Expand Down
5 changes: 5 additions & 0 deletions net/smc/smc.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
extern struct proto smc_proto;
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
#define KERNEL_HAS_ATOMIC64
#endif
Expand Down

0 comments on commit d0e3565

Please sign in to comment.