rxrpc: Trace rxrpc_bundle refcount
authorDavid Howells <dhowells@redhat.com>
Wed, 2 Nov 2022 21:54:46 +0000 (21:54 +0000)
committerDavid Howells <dhowells@redhat.com>
Thu, 1 Dec 2022 13:36:39 +0000 (13:36 +0000)
Add a tracepoint for the rxrpc_bundle refcounting.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org

include/trace/events/rxrpc.h
net/rxrpc/ar-internal.h
net/rxrpc/conn_client.c
net/rxrpc/conn_object.c
net/rxrpc/conn_service.c

index 3f6de42..6f5be7a 100644 (file)
        EM(rxrpc_peer_put_input_error,          "PUT inpt-err") \
        E_(rxrpc_peer_put_keepalive,            "PUT keepaliv")
 
+#define rxrpc_bundle_traces \
+       EM(rxrpc_bundle_free,                   "FREE        ") \
+       EM(rxrpc_bundle_get_client_call,        "GET clt-call") \
+       EM(rxrpc_bundle_get_client_conn,        "GET clt-conn") \
+       EM(rxrpc_bundle_get_service_conn,       "GET svc-conn") \
+       EM(rxrpc_bundle_put_conn,               "PUT conn    ") \
+       EM(rxrpc_bundle_put_discard,            "PUT discard ") \
+       E_(rxrpc_bundle_new,                    "NEW         ")
+
 #define rxrpc_conn_traces \
        EM(rxrpc_conn_free,                     "FREE        ") \
        EM(rxrpc_conn_get_activate_call,        "GET act-call") \
 #define EM(a, b) a,
 #define E_(a, b) a
 
+enum rxrpc_bundle_trace                { rxrpc_bundle_traces } __mode(byte);
 enum rxrpc_call_trace          { rxrpc_call_traces } __mode(byte);
 enum rxrpc_client_trace                { rxrpc_client_traces } __mode(byte);
 enum rxrpc_congest_change      { rxrpc_congest_changes } __mode(byte);
@@ -390,6 +400,7 @@ enum rxrpc_txqueue_trace    { rxrpc_txqueue_traces } __mode(byte);
 #define EM(a, b) TRACE_DEFINE_ENUM(a);
 #define E_(a, b) TRACE_DEFINE_ENUM(a);
 
+rxrpc_bundle_traces;
 rxrpc_call_traces;
 rxrpc_client_traces;
 rxrpc_congest_changes;
@@ -467,6 +478,29 @@ TRACE_EVENT(rxrpc_peer,
                      __entry->ref)
            );
 
+TRACE_EVENT(rxrpc_bundle,
+           TP_PROTO(unsigned int bundle_debug_id, int ref, enum rxrpc_bundle_trace why),
+
+           TP_ARGS(bundle_debug_id, ref, why),
+
+           TP_STRUCT__entry(
+                   __field(unsigned int,       bundle          )
+                   __field(int,                ref             )
+                   __field(int,                why             )
+                            ),
+
+           TP_fast_assign(
+                   __entry->bundle = bundle_debug_id;
+                   __entry->ref = ref;
+                   __entry->why = why;
+                          ),
+
+           TP_printk("CB=%08x %s r=%d",
+                     __entry->bundle,
+                     __print_symbolic(__entry->why, rxrpc_bundle_traces),
+                     __entry->ref)
+           );
+
 TRACE_EVENT(rxrpc_conn,
            TP_PROTO(unsigned int conn_debug_id, int ref, enum rxrpc_conn_trace why),
 
index 82eb09b..c588c0e 100644 (file)
@@ -875,8 +875,8 @@ extern unsigned long rxrpc_conn_idle_client_fast_expiry;
 extern struct idr rxrpc_client_conn_ids;
 
 void rxrpc_destroy_client_conn_ids(void);
-struct rxrpc_bundle *rxrpc_get_bundle(struct rxrpc_bundle *);
-void rxrpc_put_bundle(struct rxrpc_bundle *);
+struct rxrpc_bundle *rxrpc_get_bundle(struct rxrpc_bundle *, enum rxrpc_bundle_trace);
+void rxrpc_put_bundle(struct rxrpc_bundle *, enum rxrpc_bundle_trace);
 int rxrpc_connect_call(struct rxrpc_sock *, struct rxrpc_call *,
                       struct rxrpc_conn_parameters *, struct sockaddr_rxrpc *,
                       gfp_t);
index 4352e77..34ff6fa 100644 (file)
@@ -133,31 +133,36 @@ static struct rxrpc_bundle *rxrpc_alloc_bundle(struct rxrpc_conn_parameters *cp,
                atomic_set(&bundle->active, 1);
                spin_lock_init(&bundle->channel_lock);
                INIT_LIST_HEAD(&bundle->waiting_calls);
+               trace_rxrpc_bundle(bundle->debug_id, 1, rxrpc_bundle_new);
        }
        return bundle;
 }
 
-struct rxrpc_bundle *rxrpc_get_bundle(struct rxrpc_bundle *bundle)
+struct rxrpc_bundle *rxrpc_get_bundle(struct rxrpc_bundle *bundle,
+                                     enum rxrpc_bundle_trace why)
 {
-       refcount_inc(&bundle->ref);
+       int r;
+
+       __refcount_inc(&bundle->ref, &r);
+       trace_rxrpc_bundle(bundle->debug_id, r + 1, why);
        return bundle;
 }
 
 static void rxrpc_free_bundle(struct rxrpc_bundle *bundle)
 {
+       trace_rxrpc_bundle(bundle->debug_id, 1, rxrpc_bundle_free);
        rxrpc_put_peer(bundle->peer, rxrpc_peer_put_bundle);
        kfree(bundle);
 }
 
-void rxrpc_put_bundle(struct rxrpc_bundle *bundle)
+void rxrpc_put_bundle(struct rxrpc_bundle *bundle, enum rxrpc_bundle_trace why)
 {
-       unsigned int d = bundle->debug_id;
+       unsigned int id = bundle->debug_id;
        bool dead;
        int r;
 
        dead = __refcount_dec_and_test(&bundle->ref, &r);
-
-       _debug("PUT B=%x %d", d, r - 1);
+       trace_rxrpc_bundle(id, r - 1, why);
        if (dead)
                rxrpc_free_bundle(bundle);
 }
@@ -206,7 +211,7 @@ rxrpc_alloc_client_connection(struct rxrpc_bundle *bundle, gfp_t gfp)
        list_add_tail(&conn->proc_link, &rxnet->conn_proc_list);
        write_unlock(&rxnet->conn_lock);
 
-       rxrpc_get_bundle(bundle);
+       rxrpc_get_bundle(bundle, rxrpc_bundle_get_client_conn);
        rxrpc_get_peer(conn->peer, rxrpc_peer_get_client_conn);
        rxrpc_get_local(conn->local, rxrpc_local_get_client_conn);
        key_get(conn->key);
@@ -342,7 +347,7 @@ static struct rxrpc_bundle *rxrpc_look_up_bundle(struct rxrpc_conn_parameters *c
        candidate->debug_id = atomic_inc_return(&rxrpc_bundle_id);
        rb_link_node(&candidate->local_node, parent, pp);
        rb_insert_color(&candidate->local_node, &local->client_bundles);
-       rxrpc_get_bundle(candidate);
+       rxrpc_get_bundle(candidate, rxrpc_bundle_get_client_call);
        spin_unlock(&local->client_bundles_lock);
        _leave(" = %u [new]", candidate->debug_id);
        return candidate;
@@ -350,7 +355,7 @@ static struct rxrpc_bundle *rxrpc_look_up_bundle(struct rxrpc_conn_parameters *c
 found_bundle_free:
        rxrpc_free_bundle(candidate);
 found_bundle:
-       rxrpc_get_bundle(bundle);
+       rxrpc_get_bundle(bundle, rxrpc_bundle_get_client_call);
        atomic_inc(&bundle->active);
        spin_unlock(&local->client_bundles_lock);
        _leave(" = %u [found]", bundle->debug_id);
@@ -740,7 +745,7 @@ granted_channel:
 
 out_put_bundle:
        rxrpc_deactivate_bundle(bundle);
-       rxrpc_put_bundle(bundle);
+       rxrpc_put_bundle(bundle, rxrpc_bundle_get_client_call);
 out:
        _leave(" = %d", ret);
        return ret;
@@ -958,7 +963,7 @@ static void rxrpc_deactivate_bundle(struct rxrpc_bundle *bundle)
 
                spin_unlock(&local->client_bundles_lock);
                if (need_put)
-                       rxrpc_put_bundle(bundle);
+                       rxrpc_put_bundle(bundle, rxrpc_bundle_put_discard);
        }
 }
 
index bbace8d..f7c271a 100644 (file)
@@ -363,7 +363,7 @@ static void rxrpc_destroy_connection(struct rcu_head *rcu)
 
        conn->security->clear(conn);
        key_put(conn->key);
-       rxrpc_put_bundle(conn->bundle);
+       rxrpc_put_bundle(conn->bundle, rxrpc_bundle_put_conn);
        rxrpc_put_peer(conn->peer, rxrpc_peer_put_conn);
 
        if (atomic_dec_and_test(&conn->local->rxnet->nr_conns))
index bf08721..2c44d67 100644 (file)
@@ -133,7 +133,8 @@ struct rxrpc_connection *rxrpc_prealloc_service_connection(struct rxrpc_net *rxn
                 */
                conn->state = RXRPC_CONN_SERVICE_PREALLOC;
                refcount_set(&conn->ref, 2);
-               conn->bundle = rxrpc_get_bundle(&rxrpc_service_dummy_bundle);
+               conn->bundle = rxrpc_get_bundle(&rxrpc_service_dummy_bundle,
+                                               rxrpc_bundle_get_service_conn);
 
                atomic_inc(&rxnet->nr_conns);
                write_lock(&rxnet->conn_lock);