Skip to content

Commit 66d58af

Browse files
committed
rxrpc: Fix the putting of client connections
In rxrpc_put_one_client_conn(), if a connection has RXRPC_CONN_COUNTED set on it, then it's accounted for in rxrpc_nr_client_conns and may be on various lists - and this is cleaned up correctly. However, if the connection doesn't have RXRPC_CONN_COUNTED set on it, then the put routine returns rather than just skipping the extra bit of cleanup. Fix this by making the extra bit of clean up conditional instead and always killing off the connection. This manifests itself as connections with a zero usage count hanging around in /proc/net/rxrpc_conns because the connection allocated, but discarded, due to a race with another process that set up a parallel connection, which was then shared instead. Signed-off-by: David Howells <[email protected]>
1 parent 0360da6 commit 66d58af

File tree

1 file changed

+13
-15
lines changed

1 file changed

+13
-15
lines changed

net/rxrpc/conn_client.c

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,7 @@ void rxrpc_disconnect_client_call(struct rxrpc_call *call)
818818
static struct rxrpc_connection *
819819
rxrpc_put_one_client_conn(struct rxrpc_connection *conn)
820820
{
821-
struct rxrpc_connection *next;
821+
struct rxrpc_connection *next = NULL;
822822
struct rxrpc_local *local = conn->params.local;
823823
unsigned int nr_conns;
824824

@@ -834,24 +834,22 @@ rxrpc_put_one_client_conn(struct rxrpc_connection *conn)
834834

835835
ASSERTCMP(conn->cache_state, ==, RXRPC_CONN_CLIENT_INACTIVE);
836836

837-
if (!test_bit(RXRPC_CONN_COUNTED, &conn->flags))
838-
return NULL;
839-
840-
spin_lock(&rxrpc_client_conn_cache_lock);
841-
nr_conns = --rxrpc_nr_client_conns;
837+
if (test_bit(RXRPC_CONN_COUNTED, &conn->flags)) {
838+
spin_lock(&rxrpc_client_conn_cache_lock);
839+
nr_conns = --rxrpc_nr_client_conns;
840+
841+
if (nr_conns < rxrpc_max_client_connections &&
842+
!list_empty(&rxrpc_waiting_client_conns)) {
843+
next = list_entry(rxrpc_waiting_client_conns.next,
844+
struct rxrpc_connection, cache_link);
845+
rxrpc_get_connection(next);
846+
rxrpc_activate_conn(next);
847+
}
842848

843-
next = NULL;
844-
if (nr_conns < rxrpc_max_client_connections &&
845-
!list_empty(&rxrpc_waiting_client_conns)) {
846-
next = list_entry(rxrpc_waiting_client_conns.next,
847-
struct rxrpc_connection, cache_link);
848-
rxrpc_get_connection(next);
849-
rxrpc_activate_conn(next);
849+
spin_unlock(&rxrpc_client_conn_cache_lock);
850850
}
851851

852-
spin_unlock(&rxrpc_client_conn_cache_lock);
853852
rxrpc_kill_connection(conn);
854-
855853
if (next)
856854
rxrpc_activate_channels(next);
857855

0 commit comments

Comments
 (0)