]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
rds: tcp: Take explicit refcounts on struct net
authorSowmini Varadhan <sowmini.varadhan@oracle.com>
Fri, 16 Jun 2017 19:08:29 +0000 (12:08 -0700)
committerChuck Anderson <chuck.anderson@oracle.com>
Sun, 18 Jun 2017 19:49:27 +0000 (12:49 -0700)
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.

Orabug: 26289770

(Cherry-pick of upstream 8edc3affc0770886c7bfb3436b0fdd09bce13167)

Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
net/rds/connection.c
net/rds/rds.h
net/rds/tcp.c

index 6cd8b0e7ce7970e109fcf53f60e141b3dc74acc3..35714ce80680bc76b7f7d69b984adb24a0ec850b 100644 (file)
@@ -522,6 +522,7 @@ void rds_conn_destroy(struct rds_connection *conn, int shutdown)
         */
        rds_cong_remove_conn(conn);
 
+       put_net(conn->c_net);
        kmem_cache_free(rds_conn_slab, conn);
 
        spin_lock_irqsave(&rds_conn_lock, flags);
index 511f1f583d0821ec562c8136716d79ab933e55eb..c0678c72671927ff7890a5d3f4e738f0e91333a2 100644 (file)
@@ -318,7 +318,7 @@ struct rds_connection {
        /* Protocol version */
        unsigned int            c_proposed_version;
        unsigned int            c_version;
-       possible_net_t          c_net;
+       struct net              *c_net;
 
        /* Qos support */
        u8                      c_tos;
@@ -337,13 +337,13 @@ struct rds_connection {
 static inline
 struct net *rds_conn_net(struct rds_connection *conn)
 {
-       return read_pnet(&conn->c_net);
+       return conn->c_net;
 }
 
 static inline
 void rds_conn_net_set(struct rds_connection *conn, struct net *net)
 {
-       write_pnet(&conn->c_net, net);
+       conn->c_net = get_net(net);
 }
 
 #define RDS_FLAG_CONG_BITMAP           0x01
index ced67c57821ae9fbfc7d90ef8b3efd79c38e6e81..db4d5ad590d6a09f4e3a04b10d11c3be47a8c202 100644 (file)
@@ -527,7 +527,7 @@ static void rds_tcp_kill_sock(struct net *net)
        flush_work(&rtn->rds_tcp_accept_w);
        spin_lock_irq(&rds_tcp_conn_lock);
        list_for_each_entry_safe(tc, _tc, &rds_tcp_conn_list, t_tcp_node) {
-               struct net *c_net = read_pnet(&tc->t_cpath->cp_conn->c_net);
+               struct net *c_net = tc->t_cpath->cp_conn->c_net;
 
                if (net != c_net || !tc->t_sock)
                        continue;
@@ -582,7 +582,7 @@ static void rds_tcp_sysctl_reset(struct net *net)
 
        spin_lock_irq(&rds_tcp_conn_lock);
        list_for_each_entry_safe(tc, _tc, &rds_tcp_conn_list, t_tcp_node) {
-               struct net *c_net = read_pnet(&tc->t_cpath->cp_conn->c_net);
+               struct net *c_net = tc->t_cpath->cp_conn->c_net;
 
                if (net != c_net || !tc->t_sock)
                        continue;