diff options
| author | Jakub Kicinski <kuba@kernel.org> | 2025-10-28 04:05:01 +0300 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2025-10-28 04:05:02 +0300 |
| commit | c5a644d254d887a5ebc7544e0c2c41abd11b96a9 (patch) | |
| tree | 5c53bd212f6a30160c8871238a8d094f121b9ab6 /include | |
| parent | 8b2ee2df6a324b6071de26bd708835f2f5ef85eb (diff) | |
| parent | 71068e2e1b6bd78f5599e5bc89e125a75149884b (diff) | |
| download | linux-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.h | 8 | ||||
| -rw-r--r-- | include/net/sctp/sctp.h | 3 | ||||
| -rw-r--r-- | include/net/sctp/structs.h | 3 | ||||
| -rw-r--r-- | include/net/sock.h | 7 |
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); |
