summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2025-10-28 04:05:01 +0300
committerJakub Kicinski <kuba@kernel.org>2025-10-28 04:05:02 +0300
commitc5a644d254d887a5ebc7544e0c2c41abd11b96a9 (patch)
tree5c53bd212f6a30160c8871238a8d094f121b9ab6 /include
parent8b2ee2df6a324b6071de26bd708835f2f5ef85eb (diff)
parent71068e2e1b6bd78f5599e5bc89e125a75149884b (diff)
downloadlinux-c5a644d254d887a5ebc7544e0c2c41abd11b96a9.tar.xz
Merge branch 'sctp-avoid-redundant-initialisation-in-sctp_accept-and-sctp_do_peeloff'
Kuniyuki Iwashima says: ==================== sctp: Avoid redundant initialisation in sctp_accept() and sctp_do_peeloff(). When sctp_accept() and sctp_do_peeloff() allocates a new socket, somehow sk_alloc() is used, and the new socket goes through full initialisation, but most of the fields are overwritten later. 1) sctp_accept() |- sctp_v[46]_create_accept_sk() | |- sk_alloc() | |- sock_init_data() | |- sctp_copy_sock() | `- newsk->sk_prot->init() / sctp_init_sock() | `- sctp_sock_migrate() `- sctp_copy_descendant(newsk, oldsk) sock_init_data() initialises struct sock, but many fields are overwritten by sctp_copy_sock(), which inherits fields of struct sock and inet_sock from the parent socket. sctp_init_sock() fully initialises struct sctp_sock, but later sctp_copy_descendant() inherits most fields from the parent's struct sctp_sock by memcpy(). 2) sctp_do_peeloff() |- sock_create() | | | ... | |- sk_alloc() | |- sock_init_data() | ... | `- newsk->sk_prot->init() / sctp_init_sock() | |- sctp_copy_sock() `- sctp_sock_migrate() `- sctp_copy_descendant(newsk, oldsk) sock_create() creates a brand new socket, but sctp_copy_sock() and sctp_sock_migrate() overwrite most of the fields. So, sk_alloc(), sock_init_data(), sctp_copy_sock(), and sctp_copy_descendant() can be replaced with a single function like sk_clone_lock(). This series does the conversion and removes TODO comment added by commit 4a997d49d92ad ("tcp: Save lock_sock() for memcg in inet_csk_accept()."). Tested accept() and SCTP_SOCKOPT_PEELOFF and both work properly. socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP) = 3 bind(3, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("127.0.0.1")}, 16) = 0 listen(3, -1) = 0 getsockname(3, {sa_family=AF_INET, sin_port=htons(49460), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0 socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP) = 4 connect(4, {sa_family=AF_INET, sin_port=htons(49460), sin_addr=inet_addr("127.0.0.1")}, 16) = 0 accept(3, NULL, NULL) = 5 ... socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP) = 3 bind(3, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("127.0.0.1")}, 16) = 0 listen(3, -1) = 0 getsockname(3, {sa_family=AF_INET, sin_port=htons(48240), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0 socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP) = 4 connect(4, {sa_family=AF_INET, sin_port=htons(48240), sin_addr=inet_addr("127.0.0.1")}, 16) = 0 getsockopt(3, SOL_SCTP, SCTP_SOCKOPT_PEELOFF, "*\0\0\0\5\0\0\0", [8]) = 5 v1: https://lore.kernel.org/20251021214422.1941691-1-kuniyu@google.com ==================== Link: https://patch.msgid.link/20251023231751.4168390-1-kuniyu@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'include')
-rw-r--r--include/net/inet_sock.h8
-rw-r--r--include/net/sctp/sctp.h3
-rw-r--r--include/net/sctp/structs.h3
-rw-r--r--include/net/sock.h7
4 files changed, 7 insertions, 14 deletions
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
index b6ec08072533..ac1c75975908 100644
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -355,14 +355,6 @@ static inline struct sock *skb_to_full_sk(const struct sk_buff *skb)
#define inet_sk(ptr) container_of_const(ptr, struct inet_sock, sk)
-static inline void __inet_sk_copy_descendant(struct sock *sk_to,
- const struct sock *sk_from,
- const int ancestor_size)
-{
- memcpy(inet_sk(sk_to) + 1, inet_sk(sk_from) + 1,
- sk_from->sk_prot->obj_size - ancestor_size);
-}
-
int inet_sk_rebuild_header(struct sock *sk);
/**
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index e96d1bd087f6..bb4b80c12541 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -94,8 +94,7 @@ void sctp_data_ready(struct sock *sk);
__poll_t sctp_poll(struct file *file, struct socket *sock,
poll_table *wait);
void sctp_sock_rfree(struct sk_buff *skb);
-void sctp_copy_sock(struct sock *newsk, struct sock *sk,
- struct sctp_association *asoc);
+
extern struct percpu_counter sctp_sockets_allocated;
int sctp_asconf_mgmt(struct sctp_sock *, struct sctp_sockaddr_entry *);
struct sk_buff *sctp_skb_recv_datagram(struct sock *, int, int *);
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 2ae390219efd..3dd304e411d0 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -497,9 +497,6 @@ struct sctp_pf {
int (*bind_verify) (struct sctp_sock *, union sctp_addr *);
int (*send_verify) (struct sctp_sock *, union sctp_addr *);
int (*supported_addrs)(const struct sctp_sock *, __be16 *);
- struct sock *(*create_accept_sk) (struct sock *sk,
- struct sctp_association *asoc,
- bool kern);
int (*addr_to_user)(struct sctp_sock *sk, union sctp_addr *addr);
void (*to_sk_saddr)(union sctp_addr *, struct sock *sk);
void (*to_sk_daddr)(union sctp_addr *, struct sock *sk);
diff --git a/include/net/sock.h b/include/net/sock.h
index 01ce231603db..c7e58b8e8a90 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1822,7 +1822,12 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
void sk_free(struct sock *sk);
void sk_net_refcnt_upgrade(struct sock *sk);
void sk_destruct(struct sock *sk);
-struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority);
+struct sock *sk_clone(const struct sock *sk, const gfp_t priority, bool lock);
+
+static inline struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
+{
+ return sk_clone(sk, priority, true);
+}
struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force,
gfp_t priority);