Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eb9b9d22 authored by David Howells's avatar David Howells
Browse files

rxrpc: Check that the client conns cache is empty before module removal



Check that the client conns cache is empty before module removal and bug if
not, listing any offending connections that are still present.  Unfortunately,
if there are connections still around, then the transport socket is still
unexpectedly open and active, so we can't just unallocate the connections.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
parent bba304db
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -807,8 +807,7 @@ static void __exit af_rxrpc_exit(void)
	_debug("synchronise RCU");
	rcu_barrier();
	_debug("destroy locals");
	ASSERT(idr_is_empty(&rxrpc_client_conn_ids));
	idr_destroy(&rxrpc_client_conn_ids);
	rxrpc_destroy_client_conn_ids();
	rxrpc_destroy_all_locals();

	remove_proc_entry("rxrpc_conns", init_net.proc_net);
+1 −0
Original line number Diff line number Diff line
@@ -541,6 +541,7 @@ extern struct idr rxrpc_client_conn_ids;

int rxrpc_get_client_connection_id(struct rxrpc_connection *, gfp_t);
void rxrpc_put_client_connection_id(struct rxrpc_connection *);
void rxrpc_destroy_client_conn_ids(void);

/*
 * conn_event.c
+19 −0
Original line number Diff line number Diff line
@@ -92,3 +92,22 @@ void rxrpc_put_client_connection_id(struct rxrpc_connection *conn)
		spin_unlock(&rxrpc_conn_id_lock);
	}
}

/*
 * Destroy the client connection ID tree.
 */
void rxrpc_destroy_client_conn_ids(void)
{
	struct rxrpc_connection *conn;
	int id;

	if (!idr_is_empty(&rxrpc_client_conn_ids)) {
		idr_for_each_entry(&rxrpc_client_conn_ids, conn, id) {
			pr_err("AF_RXRPC: Leaked client conn %p {%d}\n",
			       conn, atomic_read(&conn->usage));
		}
		BUG();
	}

	idr_destroy(&rxrpc_client_conn_ids);
}