diff --git a/net/rxrpc/conn_event.c b/net/rxrpc/conn_event.c index 611c790bc6d0..111f0844b0d6 100644 --- a/net/rxrpc/conn_event.c +++ b/net/rxrpc/conn_event.c @@ -274,4 +274,15 @@ static int rxrpc_process_event(struct rxrpc_connection *conn, - if (conn->state == RXRPC_CONN_ABORTED) + if (conn->state == RXRPC_CONN_ABORTED) { + /* A CHALLENGE packet queued for processing carries a ref on the + * connection (see rxrpc_post_challenge()). That ref has to be + * dropped here because the caller frees the skb as soon as we + * return. + */ + if (sp->hdr.type == RXRPC_PACKET_TYPE_CHALLENGE && + sp->chall.conn) { + rxrpc_put_connection(conn, rxrpc_conn_put_challenge_input); + sp->chall.conn = NULL; + } return -ECONNABORTED; + } diff --git a/net/rxrpc/conn_object.c b/net/rxrpc/conn_object.c index 0ece717db0f8..1295f3de3725 100644 --- a/net/rxrpc/conn_object.c +++ b/net/rxrpc/conn_object.c @@ -487,2 +487,18 @@ void rxrpc_destroy_all_connections(struct rxrpc_net *rxnet) + if (!list_empty(&rxnet->conn_proc_list)) { + struct rxrpc_connection *c; + + pr_err("AF_RXRPC: conn_proc_list not empty\n"); + write_lock(&rxnet->conn_lock); + list_for_each_entry(c, &rxnet->conn_proc_list, proc_link) + pr_err("AF_RXRPC: proc conn %x cid %x state %d ref %d act %d flags %lx cache_empty %d calls %px %px %px %px bundle %px\n", + c->debug_id, c->proto.cid, c->state, + refcount_read(&c->ref), c->act_chans, c->flags, + list_empty(&c->cache_link), + c->channels[0].call, c->channels[1].call, + c->channels[2].call, c->channels[3].call, + c->bundle); + write_unlock(&rxnet->conn_lock); + } + ASSERT(list_empty(&rxnet->conn_proc_list));