Skip to content

Commit

Permalink
rxrpc: Add a tracepoint to track rxrpc_peer refcounting
Browse files Browse the repository at this point in the history
Add a tracepoint to track reference counting on the rxrpc_peer struct.

Signed-off-by: David Howells <[email protected]>
  • Loading branch information
dhowells committed Mar 30, 2018
1 parent 31f5f9a commit 1159d4b
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 22 deletions.
42 changes: 42 additions & 0 deletions include/trace/events/rxrpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ enum rxrpc_local_trace {
rxrpc_local_queued,
};

enum rxrpc_peer_trace {
rxrpc_peer_got,
rxrpc_peer_new,
rxrpc_peer_processing,
rxrpc_peer_put,
rxrpc_peer_queued_error,
};

enum rxrpc_conn_trace {
rxrpc_conn_got,
rxrpc_conn_new_client,
Expand Down Expand Up @@ -230,6 +238,13 @@ enum rxrpc_congest_change {
EM(rxrpc_local_put, "PUT") \
E_(rxrpc_local_queued, "QUE")

#define rxrpc_peer_traces \
EM(rxrpc_peer_got, "GOT") \
EM(rxrpc_peer_new, "NEW") \
EM(rxrpc_peer_processing, "PRO") \
EM(rxrpc_peer_put, "PUT") \
E_(rxrpc_peer_queued_error, "QER")

#define rxrpc_conn_traces \
EM(rxrpc_conn_got, "GOT") \
EM(rxrpc_conn_new_client, "NWc") \
Expand Down Expand Up @@ -482,6 +497,33 @@ TRACE_EVENT(rxrpc_local,
__entry->where)
);

TRACE_EVENT(rxrpc_peer,
TP_PROTO(struct rxrpc_peer *peer, enum rxrpc_peer_trace op,
int usage, const void *where),

TP_ARGS(peer, op, usage, where),

TP_STRUCT__entry(
__field(unsigned int, peer )
__field(int, op )
__field(int, usage )
__field(const void *, where )
),

TP_fast_assign(
__entry->peer = peer->debug_id;
__entry->op = op;
__entry->usage = usage;
__entry->where = where;
),

TP_printk("P=%08x %s u=%d sp=%pSR",
__entry->peer,
__print_symbolic(__entry->op, rxrpc_peer_traces),
__entry->usage,
__entry->where)
);

TRACE_EVENT(rxrpc_conn,
TP_PROTO(struct rxrpc_connection *conn, enum rxrpc_conn_trace op,
int usage, const void *where),
Expand Down
23 changes: 4 additions & 19 deletions net/rxrpc/ar-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -1041,25 +1041,10 @@ struct rxrpc_peer *rxrpc_lookup_peer(struct rxrpc_local *,
struct rxrpc_peer *rxrpc_alloc_peer(struct rxrpc_local *, gfp_t);
struct rxrpc_peer *rxrpc_lookup_incoming_peer(struct rxrpc_local *,
struct rxrpc_peer *);

static inline struct rxrpc_peer *rxrpc_get_peer(struct rxrpc_peer *peer)
{
atomic_inc(&peer->usage);
return peer;
}

static inline
struct rxrpc_peer *rxrpc_get_peer_maybe(struct rxrpc_peer *peer)
{
return atomic_inc_not_zero(&peer->usage) ? peer : NULL;
}

extern void __rxrpc_put_peer(struct rxrpc_peer *peer);
static inline void rxrpc_put_peer(struct rxrpc_peer *peer)
{
if (peer && atomic_dec_and_test(&peer->usage))
__rxrpc_put_peer(peer);
}
struct rxrpc_peer *rxrpc_get_peer(struct rxrpc_peer *);
struct rxrpc_peer *rxrpc_get_peer_maybe(struct rxrpc_peer *);
void rxrpc_put_peer(struct rxrpc_peer *);
void __rxrpc_queue_peer_error(struct rxrpc_peer *);

/*
* proc.c
Expand Down
2 changes: 1 addition & 1 deletion net/rxrpc/peer_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ void rxrpc_error_report(struct sock *sk)
rxrpc_free_skb(skb, rxrpc_skb_rx_freed);

/* The ref we obtained is passed off to the work item */
rxrpc_queue_work(&peer->error_distributor);
__rxrpc_queue_peer_error(peer);
_leave("");
}

Expand Down
65 changes: 63 additions & 2 deletions net/rxrpc/peer_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -386,9 +386,54 @@ struct rxrpc_peer *rxrpc_lookup_peer(struct rxrpc_local *local,
}

/*
* Discard a ref on a remote peer record.
* Get a ref on a peer record.
*/
void __rxrpc_put_peer(struct rxrpc_peer *peer)
struct rxrpc_peer *rxrpc_get_peer(struct rxrpc_peer *peer)
{
const void *here = __builtin_return_address(0);
int n;

n = atomic_inc_return(&peer->usage);
trace_rxrpc_peer(peer, rxrpc_peer_got, n, here);
return peer;
}

/*
* Get a ref on a peer record unless its usage has already reached 0.
*/
struct rxrpc_peer *rxrpc_get_peer_maybe(struct rxrpc_peer *peer)
{
const void *here = __builtin_return_address(0);

if (peer) {
int n = __atomic_add_unless(&peer->usage, 1, 0);
if (n > 0)
trace_rxrpc_peer(peer, rxrpc_peer_got, n + 1, here);
else
peer = NULL;
}
return peer;
}

/*
* Queue a peer record. This passes the caller's ref to the workqueue.
*/
void __rxrpc_queue_peer_error(struct rxrpc_peer *peer)
{
const void *here = __builtin_return_address(0);
int n;

n = atomic_read(&peer->usage);
if (rxrpc_queue_work(&peer->error_distributor))
trace_rxrpc_peer(peer, rxrpc_peer_queued_error, n, here);
else
rxrpc_put_peer(peer);
}

/*
* Discard a peer record.
*/
static void __rxrpc_put_peer(struct rxrpc_peer *peer)
{
struct rxrpc_net *rxnet = peer->local->rxnet;

Expand All @@ -402,6 +447,22 @@ void __rxrpc_put_peer(struct rxrpc_peer *peer)
kfree_rcu(peer, rcu);
}

/*
* Drop a ref on a peer record.
*/
void rxrpc_put_peer(struct rxrpc_peer *peer)
{
const void *here = __builtin_return_address(0);
int n;

if (peer) {
n = atomic_dec_return(&peer->usage);
trace_rxrpc_peer(peer, rxrpc_peer_put, n, here);
if (n == 0)
__rxrpc_put_peer(peer);
}
}

/**
* rxrpc_kernel_get_peer - Get the peer address of a call
* @sock: The socket on which the call is in progress.
Expand Down

0 comments on commit 1159d4b

Please sign in to comment.