diff options
Diffstat (limited to 'net/rds/connection.c')
| -rw-r--r-- | net/rds/connection.c | 17 | 
1 files changed, 15 insertions, 2 deletions
diff --git a/net/rds/connection.c b/net/rds/connection.c index 14f041398ca1..da6da57e5f36 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -126,7 +126,10 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr,  	struct rds_transport *loop_trans;  	unsigned long flags;  	int ret; +	struct rds_transport *otrans = trans; +	if (!is_outgoing && otrans->t_type == RDS_TRANS_TCP) +		goto new_conn;  	rcu_read_lock();  	conn = rds_conn_lookup(head, laddr, faddr, trans);  	if (conn && conn->c_loopback && conn->c_trans != &rds_loop_transport && @@ -142,6 +145,7 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr,  	if (conn)  		goto out; +new_conn:  	conn = kmem_cache_zalloc(rds_conn_slab, gfp);  	if (!conn) {  		conn = ERR_PTR(-ENOMEM); @@ -230,13 +234,22 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr,  		/* Creating normal conn */  		struct rds_connection *found; -		found = rds_conn_lookup(head, laddr, faddr, trans); +		if (!is_outgoing && otrans->t_type == RDS_TRANS_TCP) +			found = NULL; +		else +			found = rds_conn_lookup(head, laddr, faddr, trans);  		if (found) {  			trans->conn_free(conn->c_transport_data);  			kmem_cache_free(rds_conn_slab, conn);  			conn = found;  		} else { -			hlist_add_head_rcu(&conn->c_hash_node, head); +			if ((is_outgoing && otrans->t_type == RDS_TRANS_TCP) || +			    (otrans->t_type != RDS_TRANS_TCP)) { +				/* Only the active side should be added to +				 * reconnect list for TCP. +				 */ +				hlist_add_head_rcu(&conn->c_hash_node, head); +			}  			rds_cong_add_conn(conn);  			rds_conn_count++;  		}  |