Skip to content

Commit 8edc3af

Browse files
sowminivdavem330
authored andcommitted
rds: tcp: Take explicit refcounts on struct net
It is incorrect for the rds_connection to piggyback on the sock_net() refcount for the netns because this gives rise to a chicken-and-egg problem during rds_conn_destroy. Instead explicitly take a ref on the net, and hold the netns down till the connection tear-down is complete. Reported-by: Dmitry Vyukov <[email protected]> Signed-off-by: Sowmini Varadhan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent fa4c7fb commit 8edc3af

File tree

3 files changed

+6
-5
lines changed

3 files changed

+6
-5
lines changed

net/rds/connection.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@ void rds_conn_destroy(struct rds_connection *conn)
429429
*/
430430
rds_cong_remove_conn(conn);
431431

432+
put_net(conn->c_net);
432433
kmem_cache_free(rds_conn_slab, conn);
433434

434435
spin_lock_irqsave(&rds_conn_lock, flags);

net/rds/rds.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ struct rds_connection {
147147

148148
/* Protocol version */
149149
unsigned int c_version;
150-
possible_net_t c_net;
150+
struct net *c_net;
151151

152152
struct list_head c_map_item;
153153
unsigned long c_map_queued;
@@ -162,13 +162,13 @@ struct rds_connection {
162162
static inline
163163
struct net *rds_conn_net(struct rds_connection *conn)
164164
{
165-
return read_pnet(&conn->c_net);
165+
return conn->c_net;
166166
}
167167

168168
static inline
169169
void rds_conn_net_set(struct rds_connection *conn, struct net *net)
170170
{
171-
write_pnet(&conn->c_net, net);
171+
conn->c_net = get_net(net);
172172
}
173173

174174
#define RDS_FLAG_CONG_BITMAP 0x01

net/rds/tcp.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ static void rds_tcp_kill_sock(struct net *net)
529529
flush_work(&rtn->rds_tcp_accept_w);
530530
spin_lock_irq(&rds_tcp_conn_lock);
531531
list_for_each_entry_safe(tc, _tc, &rds_tcp_conn_list, t_tcp_node) {
532-
struct net *c_net = read_pnet(&tc->t_cpath->cp_conn->c_net);
532+
struct net *c_net = tc->t_cpath->cp_conn->c_net;
533533

534534
if (net != c_net || !tc->t_sock)
535535
continue;
@@ -584,7 +584,7 @@ static void rds_tcp_sysctl_reset(struct net *net)
584584

585585
spin_lock_irq(&rds_tcp_conn_lock);
586586
list_for_each_entry_safe(tc, _tc, &rds_tcp_conn_list, t_tcp_node) {
587-
struct net *c_net = read_pnet(&tc->t_cpath->cp_conn->c_net);
587+
struct net *c_net = tc->t_cpath->cp_conn->c_net;
588588

589589
if (net != c_net || !tc->t_sock)
590590
continue;

0 commit comments

Comments
 (0)