summaryrefslogtreecommitdiff
path: root/net/rds
diff options
context:
space:
mode:
authorSasha Levin <sashal@kernel.org>2026-03-12 07:35:07 -0400
committerSasha Levin <sashal@kernel.org>2026-03-12 07:35:07 -0400
commitee6bf57ad14c891455f6ea6f3e7b96d841b436b8 (patch)
treea71179a386eba8a95075de3c3ac665db2d02ba9b /net/rds
parent2c8fedbbbb8266b792c1bfec0dbcbed77d61fa8d (diff)
parent0d87da0c7e74868a63d2b856454122b5fb30d341 (diff)
Merge 6.19.7
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'net/rds')
-rw-r--r--net/rds/af_rds.c2
-rw-r--r--net/rds/bind.c2
-rw-r--r--net/rds/rds.h2
-rw-r--r--net/rds/tcp.c14
-rw-r--r--net/rds/tcp_connect.c4
-rw-r--r--net/rds/tcp_listen.c2
6 files changed, 16 insertions, 10 deletions
diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c
index 4a7217fbeab6..b396c673dfaf 100644
--- a/net/rds/af_rds.c
+++ b/net/rds/af_rds.c
@@ -533,7 +533,7 @@ out:
}
-static int rds_connect(struct socket *sock, struct sockaddr *uaddr,
+static int rds_connect(struct socket *sock, struct sockaddr_unsized *uaddr,
int addr_len, int flags)
{
struct sock *sk = sock->sk;
diff --git a/net/rds/bind.c b/net/rds/bind.c
index 97a29172a8ee..f800d920d969 100644
--- a/net/rds/bind.c
+++ b/net/rds/bind.c
@@ -160,7 +160,7 @@ void rds_remove_bound(struct rds_sock *rs)
rs->rs_bound_addr = in6addr_any;
}
-int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
+int rds_bind(struct socket *sock, struct sockaddr_unsized *uaddr, int addr_len)
{
struct sock *sk = sock->sk;
struct rds_sock *rs = rds_sk_to_rs(sk);
diff --git a/net/rds/rds.h b/net/rds/rds.h
index 5b1c072e2e7f..a029e5fcdea7 100644
--- a/net/rds/rds.h
+++ b/net/rds/rds.h
@@ -735,7 +735,7 @@ extern wait_queue_head_t rds_poll_waitq;
/* bind.c */
-int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len);
+int rds_bind(struct socket *sock, struct sockaddr_unsized *uaddr, int addr_len);
void rds_remove_bound(struct rds_sock *rs);
struct rds_sock *rds_find_bound(const struct in6_addr *addr, __be16 port,
__u32 scope_id);
diff --git a/net/rds/tcp.c b/net/rds/tcp.c
index 3cc2f303bf78..b66dfcc3efaa 100644
--- a/net/rds/tcp.c
+++ b/net/rds/tcp.c
@@ -495,18 +495,24 @@ bool rds_tcp_tune(struct socket *sock)
struct rds_tcp_net *rtn;
tcp_sock_set_nodelay(sock->sk);
- lock_sock(sk);
/* TCP timer functions might access net namespace even after
* a process which created this net namespace terminated.
*/
if (!sk->sk_net_refcnt) {
- if (!maybe_get_net(net)) {
- release_sock(sk);
+ if (!maybe_get_net(net))
return false;
- }
+ /*
+ * sk_net_refcnt_upgrade() must be called before lock_sock()
+ * because it does a GFP_KERNEL allocation, which can trigger
+ * fs_reclaim and create a circular lock dependency with the
+ * socket lock. The fields it modifies (sk_net_refcnt,
+ * ns_tracker) are not accessed by any concurrent code path
+ * at this point.
+ */
sk_net_refcnt_upgrade(sk);
put_net(net);
}
+ lock_sock(sk);
rtn = net_generic(net, rds_tcp_netid);
if (rtn->sndbuf_size > 0) {
sk->sk_sndbuf = rtn->sndbuf_size;
diff --git a/net/rds/tcp_connect.c b/net/rds/tcp_connect.c
index a0046e99d6df..92891b0d224d 100644
--- a/net/rds/tcp_connect.c
+++ b/net/rds/tcp_connect.c
@@ -145,7 +145,7 @@ int rds_tcp_conn_path_connect(struct rds_conn_path *cp)
addrlen = sizeof(sin);
}
- ret = kernel_bind(sock, addr, addrlen);
+ ret = kernel_bind(sock, (struct sockaddr_unsized *)addr, addrlen);
if (ret) {
rdsdebug("bind failed with %d at address %pI6c\n",
ret, &conn->c_laddr);
@@ -173,7 +173,7 @@ int rds_tcp_conn_path_connect(struct rds_conn_path *cp)
* own the socket
*/
rds_tcp_set_callbacks(sock, cp);
- ret = kernel_connect(sock, addr, addrlen, O_NONBLOCK);
+ ret = kernel_connect(sock, (struct sockaddr_unsized *)addr, addrlen, O_NONBLOCK);
rdsdebug("connect to address %pI6c returned %d\n", &conn->c_faddr, ret);
if (ret == -EINPROGRESS)
diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c
index 65c5425a02de..27b6107ddc28 100644
--- a/net/rds/tcp_listen.c
+++ b/net/rds/tcp_listen.c
@@ -285,7 +285,7 @@ struct socket *rds_tcp_listen_init(struct net *net, bool isv6)
addr_len = sizeof(*sin);
}
- ret = kernel_bind(sock, (struct sockaddr *)&ss, addr_len);
+ ret = kernel_bind(sock, (struct sockaddr_unsized *)&ss, addr_len);
if (ret < 0) {
rdsdebug("could not bind %s listener socket: %d\n",
isv6 ? "IPv6" : "IPv4", ret);