rxrpc: trace: Don't use __builtin_return_address for rxrpc_local tracing
authorDavid Howells <dhowells@redhat.com>
Fri, 21 Oct 2022 12:00:34 +0000 (13:00 +0100)
committerDavid Howells <dhowells@redhat.com>
Thu, 1 Dec 2022 13:36:38 +0000 (13:36 +0000)
In rxrpc tracing, use enums to generate lists of points of interest rather
than __builtin_return_address() for the rxrpc_local tracepoint

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

13 files changed:
include/trace/events/rxrpc.h
net/rxrpc/af_rxrpc.c
net/rxrpc/ar-internal.h
net/rxrpc/call_accept.c
net/rxrpc/call_event.c
net/rxrpc/conn_client.c
net/rxrpc/conn_event.c
net/rxrpc/conn_object.c
net/rxrpc/input.c
net/rxrpc/local_object.c
net/rxrpc/output.c
net/rxrpc/peer_event.c
net/rxrpc/peer_object.c

index 2b77f9a..0155698 100644 (file)
        E_(rxrpc_skb_unshared_nomem,            "US0")
 
 #define rxrpc_local_traces \
-       EM(rxrpc_local_got,                     "GOT") \
-       EM(rxrpc_local_new,                     "NEW") \
-       EM(rxrpc_local_processing,              "PRO") \
-       EM(rxrpc_local_put,                     "PUT") \
-       EM(rxrpc_local_queued,                  "QUE") \
-       E_(rxrpc_local_tx_ack,                  "TAK")
+       EM(rxrpc_local_free,                    "FREE        ") \
+       EM(rxrpc_local_get_client_conn,         "GET conn-cln") \
+       EM(rxrpc_local_get_for_use,             "GET for-use ") \
+       EM(rxrpc_local_get_peer,                "GET peer    ") \
+       EM(rxrpc_local_get_prealloc_conn,       "GET conn-pre") \
+       EM(rxrpc_local_get_queue,               "GET queue   ") \
+       EM(rxrpc_local_new,                     "NEW         ") \
+       EM(rxrpc_local_processing,              "PROCESSING  ") \
+       EM(rxrpc_local_put_already_queued,      "PUT alreadyq") \
+       EM(rxrpc_local_put_bind,                "PUT bind    ") \
+       EM(rxrpc_local_put_for_use,             "PUT for-use ") \
+       EM(rxrpc_local_put_kill_conn,           "PUT conn-kil") \
+       EM(rxrpc_local_put_peer,                "PUT peer    ") \
+       EM(rxrpc_local_put_prealloc_conn,       "PUT conn-pre") \
+       EM(rxrpc_local_put_release_sock,        "PUT rel-sock") \
+       EM(rxrpc_local_put_queue,               "PUT queue   ") \
+       EM(rxrpc_local_queued,                  "QUEUED      ") \
+       EM(rxrpc_local_see_tx_ack,              "SEE tx-ack  ") \
+       EM(rxrpc_local_stop,                    "STOP        ") \
+       EM(rxrpc_local_stopped,                 "STOPPED     ") \
+       EM(rxrpc_local_unuse_bind,              "UNU bind    ") \
+       EM(rxrpc_local_unuse_conn_work,         "UNU conn-wrk") \
+       EM(rxrpc_local_unuse_peer_keepalive,    "UNU peer-kpa") \
+       EM(rxrpc_local_unuse_release_sock,      "UNU rel-sock") \
+       EM(rxrpc_local_unuse_work,              "UNU work    ") \
+       EM(rxrpc_local_use_conn_work,           "USE conn-wrk") \
+       EM(rxrpc_local_use_lookup,              "USE lookup  ") \
+       EM(rxrpc_local_use_peer_keepalive,      "USE peer-kpa") \
+       E_(rxrpc_local_use_work,                "USE work    ")
 
 #define rxrpc_peer_traces \
        EM(rxrpc_peer_got,                      "GOT") \
@@ -345,29 +368,29 @@ rxrpc_txqueue_traces;
 
 TRACE_EVENT(rxrpc_local,
            TP_PROTO(unsigned int local_debug_id, enum rxrpc_local_trace op,
-                    int usage, const void *where),
+                    int ref, int usage),
 
-           TP_ARGS(local_debug_id, op, usage, where),
+           TP_ARGS(local_debug_id, op, ref, usage),
 
            TP_STRUCT__entry(
                    __field(unsigned int,       local           )
                    __field(int,                op              )
+                   __field(int,                ref             )
                    __field(int,                usage           )
-                   __field(const void *,       where           )
                             ),
 
            TP_fast_assign(
                    __entry->local = local_debug_id;
                    __entry->op = op;
+                   __entry->ref = ref;
                    __entry->usage = usage;
-                   __entry->where = where;
                           ),
 
-           TP_printk("L=%08x %s u=%d sp=%pSR",
+           TP_printk("L=%08x %s r=%d u=%d",
                      __entry->local,
                      __print_symbolic(__entry->op, rxrpc_local_traces),
-                     __entry->usage,
-                     __entry->where)
+                     __entry->ref,
+                     __entry->usage)
            );
 
 TRACE_EVENT(rxrpc_peer,
index aacdd96..989ebca 100644 (file)
@@ -194,8 +194,8 @@ static int rxrpc_bind(struct socket *sock, struct sockaddr *saddr, int len)
 
 service_in_use:
        write_unlock(&local->services_lock);
-       rxrpc_unuse_local(local);
-       rxrpc_put_local(local);
+       rxrpc_unuse_local(local, rxrpc_local_unuse_bind);
+       rxrpc_put_local(local, rxrpc_local_put_bind);
        ret = -EADDRINUSE;
 error_unlock:
        release_sock(&rx->sk);
@@ -888,8 +888,8 @@ static int rxrpc_release_sock(struct sock *sk)
        flush_workqueue(rxrpc_workqueue);
        rxrpc_purge_queue(&sk->sk_receive_queue);
 
-       rxrpc_unuse_local(rx->local);
-       rxrpc_put_local(rx->local);
+       rxrpc_unuse_local(rx->local, rxrpc_local_unuse_release_sock);
+       rxrpc_put_local(rx->local, rxrpc_local_put_release_sock);
        rx->local = NULL;
        key_put(rx->key);
        rx->key = NULL;
index 7c48b01..dde9ce2 100644 (file)
@@ -979,22 +979,45 @@ extern void rxrpc_process_local_events(struct rxrpc_local *);
  * local_object.c
  */
 struct rxrpc_local *rxrpc_lookup_local(struct net *, const struct sockaddr_rxrpc *);
-struct rxrpc_local *rxrpc_get_local(struct rxrpc_local *);
-struct rxrpc_local *rxrpc_get_local_maybe(struct rxrpc_local *);
-void rxrpc_put_local(struct rxrpc_local *);
-struct rxrpc_local *rxrpc_use_local(struct rxrpc_local *);
-void rxrpc_unuse_local(struct rxrpc_local *);
+struct rxrpc_local *rxrpc_get_local(struct rxrpc_local *, enum rxrpc_local_trace);
+struct rxrpc_local *rxrpc_get_local_maybe(struct rxrpc_local *, enum rxrpc_local_trace);
+void rxrpc_put_local(struct rxrpc_local *, enum rxrpc_local_trace);
+struct rxrpc_local *rxrpc_use_local(struct rxrpc_local *, enum rxrpc_local_trace);
+void rxrpc_unuse_local(struct rxrpc_local *, enum rxrpc_local_trace);
 void rxrpc_queue_local(struct rxrpc_local *);
 void rxrpc_destroy_all_locals(struct rxrpc_net *);
 
-static inline bool __rxrpc_unuse_local(struct rxrpc_local *local)
+static inline bool __rxrpc_unuse_local(struct rxrpc_local *local,
+                                      enum rxrpc_local_trace why)
 {
-       return atomic_dec_return(&local->active_users) == 0;
+       unsigned int debug_id = local->debug_id;
+       int r, u;
+
+       r = refcount_read(&local->ref);
+       u = atomic_dec_return(&local->active_users);
+       trace_rxrpc_local(debug_id, why, r, u);
+       return u == 0;
+}
+
+static inline bool __rxrpc_use_local(struct rxrpc_local *local,
+                                    enum rxrpc_local_trace why)
+{
+       int r, u;
+
+       r = refcount_read(&local->ref);
+       u = atomic_fetch_add_unless(&local->active_users, 1, 0);
+       trace_rxrpc_local(local->debug_id, why, r, u);
+       return u != 0;
 }
 
-static inline bool __rxrpc_use_local(struct rxrpc_local *local)
+static inline void rxrpc_see_local(struct rxrpc_local *local,
+                                  enum rxrpc_local_trace why)
 {
-       return atomic_fetch_add_unless(&local->active_users, 1, 0) != 0;
+       int r, u;
+
+       r = refcount_read(&local->ref);
+       u = atomic_read(&local->active_users);
+       trace_rxrpc_local(local->debug_id, why, r, u);
 }
 
 /*
index 4888959..1b12d4e 100644 (file)
@@ -197,7 +197,7 @@ void rxrpc_discard_prealloc(struct rxrpc_sock *rx)
        tail = b->peer_backlog_tail;
        while (CIRC_CNT(head, tail, size) > 0) {
                struct rxrpc_peer *peer = b->peer_backlog[tail];
-               rxrpc_put_local(peer->local);
+               rxrpc_put_local(peer->local, rxrpc_local_put_prealloc_conn);
                kfree(peer);
                tail = (tail + 1) & (size - 1);
        }
@@ -305,7 +305,7 @@ static struct rxrpc_call *rxrpc_alloc_incoming_call(struct rxrpc_sock *rx,
                b->conn_backlog[conn_tail] = NULL;
                smp_store_release(&b->conn_backlog_tail,
                                  (conn_tail + 1) & (RXRPC_BACKLOG_MAX - 1));
-               conn->local = rxrpc_get_local(local);
+               conn->local = rxrpc_get_local(local, rxrpc_local_get_prealloc_conn);
                conn->peer = peer;
                rxrpc_see_connection(conn);
                rxrpc_new_incoming_connection(rx, conn, sec, skb);
index b17ed37..591af8e 100644 (file)
@@ -114,7 +114,7 @@ void rxrpc_send_ACK(struct rxrpc_call *call, u8 ack_reason,
        if (in_task()) {
                rxrpc_transmit_ack_packets(call->peer->local);
        } else {
-               rxrpc_get_local(local);
+               rxrpc_get_local(local, rxrpc_local_get_queue);
                rxrpc_queue_local(local);
        }
 }
index 71404b3..9a69b4c 100644 (file)
@@ -208,7 +208,7 @@ rxrpc_alloc_client_connection(struct rxrpc_bundle *bundle, gfp_t gfp)
 
        rxrpc_get_bundle(bundle);
        rxrpc_get_peer(conn->peer);
-       rxrpc_get_local(conn->local);
+       rxrpc_get_local(conn->local, rxrpc_local_get_client_conn);
        key_get(conn->key);
 
        trace_rxrpc_conn(conn->debug_id, rxrpc_conn_new_client,
index f890a30..225edaf 100644 (file)
@@ -474,9 +474,9 @@ void rxrpc_process_connection(struct work_struct *work)
 
        rxrpc_see_connection(conn);
 
-       if (__rxrpc_use_local(conn->local)) {
+       if (__rxrpc_use_local(conn->local, rxrpc_local_use_conn_work)) {
                rxrpc_do_process_connection(conn);
-               rxrpc_unuse_local(conn->local);
+               rxrpc_unuse_local(conn->local, rxrpc_local_unuse_conn_work);
        }
 
        rxrpc_put_connection(conn);
index ad6e5ee..725359a 100644 (file)
@@ -366,7 +366,7 @@ static void rxrpc_destroy_connection(struct rcu_head *rcu)
 
        if (atomic_dec_and_test(&conn->local->rxnet->nr_conns))
                wake_up_var(&conn->local->rxnet->nr_conns);
-       rxrpc_put_local(conn->local);
+       rxrpc_put_local(conn->local, rxrpc_local_put_kill_conn);
 
        kfree(conn);
        _leave("");
index 42c8257..cecfd20 100644 (file)
@@ -1133,7 +1133,7 @@ static void rxrpc_post_packet_to_local(struct rxrpc_local *local,
 {
        _enter("%p,%p", local, skb);
 
-       if (rxrpc_get_local_maybe(local)) {
+       if (rxrpc_get_local_maybe(local, rxrpc_local_get_queue)) {
                skb_queue_tail(&local->event_queue, skb);
                rxrpc_queue_local(local);
        } else {
@@ -1146,7 +1146,7 @@ static void rxrpc_post_packet_to_local(struct rxrpc_local *local,
  */
 static void rxrpc_reject_packet(struct rxrpc_local *local, struct sk_buff *skb)
 {
-       if (rxrpc_get_local_maybe(local)) {
+       if (rxrpc_get_local_maybe(local, rxrpc_local_get_queue)) {
                skb_queue_tail(&local->reject_queue, skb);
                rxrpc_queue_local(local);
        } else {
index 11080c3..1617ce6 100644 (file)
@@ -110,7 +110,7 @@ static struct rxrpc_local *rxrpc_alloc_local(struct rxrpc_net *rxnet,
                local->debug_id = atomic_inc_return(&rxrpc_debug_id);
                memcpy(&local->srx, srx, sizeof(*srx));
                local->srx.srx_service = 0;
-               trace_rxrpc_local(local->debug_id, rxrpc_local_new, 1, NULL);
+               trace_rxrpc_local(local->debug_id, rxrpc_local_new, 1, 1);
        }
 
        _leave(" = %p", local);
@@ -228,7 +228,7 @@ struct rxrpc_local *rxrpc_lookup_local(struct net *net,
                 * we're attempting to use a local address that the dying
                 * object is still using.
                 */
-               if (!rxrpc_use_local(local))
+               if (!rxrpc_use_local(local, rxrpc_local_use_lookup))
                        break;
 
                goto found;
@@ -272,32 +272,32 @@ addr_in_use:
 /*
  * Get a ref on a local endpoint.
  */
-struct rxrpc_local *rxrpc_get_local(struct rxrpc_local *local)
+struct rxrpc_local *rxrpc_get_local(struct rxrpc_local *local,
+                                   enum rxrpc_local_trace why)
 {
-       const void *here = __builtin_return_address(0);
-       int r;
+       int r, u;
 
+       u = atomic_read(&local->active_users);
        __refcount_inc(&local->ref, &r);
-       trace_rxrpc_local(local->debug_id, rxrpc_local_got, r + 1, here);
+       trace_rxrpc_local(local->debug_id, why, r + 1, u);
        return local;
 }
 
 /*
  * Get a ref on a local endpoint unless its usage has already reached 0.
  */
-struct rxrpc_local *rxrpc_get_local_maybe(struct rxrpc_local *local)
+struct rxrpc_local *rxrpc_get_local_maybe(struct rxrpc_local *local,
+                                         enum rxrpc_local_trace why)
 {
-       const void *here = __builtin_return_address(0);
-       int r;
+       int r, u;
 
-       if (local) {
-               if (__refcount_inc_not_zero(&local->ref, &r))
-                       trace_rxrpc_local(local->debug_id, rxrpc_local_got,
-                                         r + 1, here);
-               else
-                       local = NULL;
+       if (local && __refcount_inc_not_zero(&local->ref, &r)) {
+               u = atomic_read(&local->active_users);
+               trace_rxrpc_local(local->debug_id, why, r + 1, u);
+               return local;
        }
-       return local;
+
+       return NULL;
 }
 
 /*
@@ -305,31 +305,31 @@ struct rxrpc_local *rxrpc_get_local_maybe(struct rxrpc_local *local)
  */
 void rxrpc_queue_local(struct rxrpc_local *local)
 {
-       const void *here = __builtin_return_address(0);
        unsigned int debug_id = local->debug_id;
        int r = refcount_read(&local->ref);
+       int u = atomic_read(&local->active_users);
 
        if (rxrpc_queue_work(&local->processor))
-               trace_rxrpc_local(debug_id, rxrpc_local_queued, r + 1, here);
+               trace_rxrpc_local(debug_id, rxrpc_local_queued, r, u);
        else
-               rxrpc_put_local(local);
+               rxrpc_put_local(local, rxrpc_local_put_already_queued);
 }
 
 /*
  * Drop a ref on a local endpoint.
  */
-void rxrpc_put_local(struct rxrpc_local *local)
+void rxrpc_put_local(struct rxrpc_local *local, enum rxrpc_local_trace why)
 {
-       const void *here = __builtin_return_address(0);
        unsigned int debug_id;
        bool dead;
-       int r;
+       int r, u;
 
        if (local) {
                debug_id = local->debug_id;
 
+               u = atomic_read(&local->active_users);
                dead = __refcount_dec_and_test(&local->ref, &r);
-               trace_rxrpc_local(debug_id, rxrpc_local_put, r, here);
+               trace_rxrpc_local(debug_id, why, r, u);
 
                if (dead)
                        call_rcu(&local->rcu, rxrpc_local_rcu);
@@ -339,14 +339,15 @@ void rxrpc_put_local(struct rxrpc_local *local)
 /*
  * Start using a local endpoint.
  */
-struct rxrpc_local *rxrpc_use_local(struct rxrpc_local *local)
+struct rxrpc_local *rxrpc_use_local(struct rxrpc_local *local,
+                                   enum rxrpc_local_trace why)
 {
-       local = rxrpc_get_local_maybe(local);
+       local = rxrpc_get_local_maybe(local, rxrpc_local_get_for_use);
        if (!local)
                return NULL;
 
-       if (!__rxrpc_use_local(local)) {
-               rxrpc_put_local(local);
+       if (!__rxrpc_use_local(local, why)) {
+               rxrpc_put_local(local, rxrpc_local_put_for_use);
                return NULL;
        }
 
@@ -357,11 +358,18 @@ struct rxrpc_local *rxrpc_use_local(struct rxrpc_local *local)
  * Cease using a local endpoint.  Once the number of active users reaches 0, we
  * start the closure of the transport in the work processor.
  */
-void rxrpc_unuse_local(struct rxrpc_local *local)
+void rxrpc_unuse_local(struct rxrpc_local *local, enum rxrpc_local_trace why)
 {
+       unsigned int debug_id;
+       int r, u;
+
        if (local) {
-               if (__rxrpc_unuse_local(local)) {
-                       rxrpc_get_local(local);
+               debug_id = local->debug_id;
+               r = refcount_read(&local->ref);
+               u = atomic_dec_return(&local->active_users);
+               trace_rxrpc_local(debug_id, why, r, u);
+               if (u == 0) {
+                       rxrpc_get_local(local, rxrpc_local_get_queue);
                        rxrpc_queue_local(local);
                }
        }
@@ -418,12 +426,11 @@ static void rxrpc_local_processor(struct work_struct *work)
        if (local->dead)
                return;
 
-       trace_rxrpc_local(local->debug_id, rxrpc_local_processing,
-                         refcount_read(&local->ref), NULL);
+       rxrpc_see_local(local, rxrpc_local_processing);
 
        do {
                again = false;
-               if (!__rxrpc_use_local(local)) {
+               if (!__rxrpc_use_local(local, rxrpc_local_use_work)) {
                        rxrpc_local_destroyer(local);
                        break;
                }
@@ -443,10 +450,10 @@ static void rxrpc_local_processor(struct work_struct *work)
                        again = true;
                }
 
-               __rxrpc_unuse_local(local);
+               __rxrpc_unuse_local(local, rxrpc_local_unuse_work);
        } while (again);
 
-       rxrpc_put_local(local);
+       rxrpc_put_local(local, rxrpc_local_put_queue);
 }
 
 /*
@@ -460,6 +467,7 @@ static void rxrpc_local_rcu(struct rcu_head *rcu)
 
        ASSERT(!work_pending(&local->processor));
 
+       rxrpc_see_local(local, rxrpc_local_free);
        kfree(local);
        _leave("");
 }
index b5d8eac..2762b7a 100644 (file)
@@ -288,8 +288,7 @@ void rxrpc_transmit_ack_packets(struct rxrpc_local *local)
        LIST_HEAD(queue);
        int ret;
 
-       trace_rxrpc_local(local->debug_id, rxrpc_local_tx_ack,
-                         refcount_read(&local->ref), NULL);
+       rxrpc_see_local(local, rxrpc_local_see_tx_ack);
 
        if (list_empty(&local->ack_tx_queue))
                return;
index ad4d176..3f8d104 100644 (file)
@@ -266,7 +266,7 @@ static void rxrpc_peer_keepalive_dispatch(struct rxrpc_net *rxnet,
                if (!rxrpc_get_peer_maybe(peer))
                        continue;
 
-               if (__rxrpc_use_local(peer->local)) {
+               if (__rxrpc_use_local(peer->local, rxrpc_local_use_peer_keepalive)) {
                        spin_unlock_bh(&rxnet->peer_hash_lock);
 
                        keepalive_at = peer->last_tx_at + RXRPC_KEEPALIVE_TIME;
@@ -289,7 +289,7 @@ static void rxrpc_peer_keepalive_dispatch(struct rxrpc_net *rxnet,
                        spin_lock_bh(&rxnet->peer_hash_lock);
                        list_add_tail(&peer->keepalive_link,
                                      &rxnet->peer_keepalive[slot & mask]);
-                       rxrpc_unuse_local(peer->local);
+                       rxrpc_unuse_local(peer->local, rxrpc_local_unuse_peer_keepalive);
                }
                rxrpc_put_peer_locked(peer);
        }
index b3c3c1c..bcef897 100644 (file)
@@ -215,7 +215,7 @@ struct rxrpc_peer *rxrpc_alloc_peer(struct rxrpc_local *local, gfp_t gfp)
        peer = kzalloc(sizeof(struct rxrpc_peer), gfp);
        if (peer) {
                refcount_set(&peer->ref, 1);
-               peer->local = rxrpc_get_local(local);
+               peer->local = rxrpc_get_local(local, rxrpc_local_get_peer);
                INIT_HLIST_HEAD(&peer->error_targets);
                peer->service_conns = RB_ROOT;
                seqlock_init(&peer->service_conn_lock);
@@ -294,7 +294,7 @@ static struct rxrpc_peer *rxrpc_create_peer(struct rxrpc_sock *rx,
 
 static void rxrpc_free_peer(struct rxrpc_peer *peer)
 {
-       rxrpc_put_local(peer->local);
+       rxrpc_put_local(peer->local, rxrpc_local_put_peer);
        kfree_rcu(peer, rcu);
 }