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

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

rxrpc: Use a tracepoint for skb accounting debugging



Use a tracepoint to log various skb accounting points to help in debugging
refcounting errors.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
parent 01a90a45
Loading
Loading
Loading
Loading
+56 −0
Original line number Diff line number Diff line
/* AF_RXRPC tracepoints
 *
 * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public Licence
 * as published by the Free Software Foundation; either version
 * 2 of the Licence, or (at your option) any later version.
 */
#undef TRACE_SYSTEM
#define TRACE_SYSTEM rxrpc

#if !defined(_TRACE_RXRPC_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_RXRPC_H

#include <linux/tracepoint.h>

TRACE_EVENT(rxrpc_skb,
	    TP_PROTO(struct sk_buff *skb, int op, int usage, int mod_count,
		     const void *where),

	    TP_ARGS(skb, op, usage, mod_count, where),

	    TP_STRUCT__entry(
		    __field(struct sk_buff *,		skb		)
		    __field(int,			op		)
		    __field(int,			usage		)
		    __field(int,			mod_count	)
		    __field(const void *,		where		)
			     ),

	    TP_fast_assign(
		    __entry->skb = skb;
		    __entry->op = op;
		    __entry->usage = usage;
		    __entry->mod_count = mod_count;
		    __entry->where = where;
			   ),

	    TP_printk("s=%p %s u=%d m=%d p=%pSR",
		      __entry->skb,
		      (__entry->op == 0 ? "NEW" :
		       __entry->op == 1 ? "SEE" :
		       __entry->op == 2 ? "GET" :
		       __entry->op == 3 ? "FRE" :
		       "PUR"),
		      __entry->usage,
		      __entry->mod_count,
		      __entry->where)
	    );

#endif /* _TRACE_RXRPC_H */

/* This part must be outside protection */
#include <trace/define_trace.h>
+1 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <net/net_namespace.h>
#include <net/sock.h>
#include <net/af_rxrpc.h>
#define CREATE_TRACE_POINTS
#include "ar-internal.h"

MODULE_DESCRIPTION("RxRPC network protocol");
+7 −38
Original line number Diff line number Diff line
@@ -479,6 +479,8 @@ static inline void rxrpc_abort_call(struct rxrpc_call *call, u32 abort_code)
	write_unlock_bh(&call->state_lock);
}

#include <trace/events/rxrpc.h>

/*
 * af_rxrpc.c
 */
@@ -752,6 +754,11 @@ int rxrpc_init_server_conn_security(struct rxrpc_connection *);
 * skbuff.c
 */
void rxrpc_packet_destructor(struct sk_buff *);
void rxrpc_new_skb(struct sk_buff *);
void rxrpc_see_skb(struct sk_buff *);
void rxrpc_get_skb(struct sk_buff *);
void rxrpc_free_skb(struct sk_buff *);
void rxrpc_purge_queue(struct sk_buff_head *);

/*
 * sysctl.c
@@ -899,44 +906,6 @@ do { \

#endif /* __KDEBUGALL */

/*
 * socket buffer accounting / leak finding
 */
static inline void __rxrpc_new_skb(struct sk_buff *skb, const char *fn)
{
	//_net("new skb %p %s [%d]", skb, fn, atomic_read(&rxrpc_n_skbs));
	//atomic_inc(&rxrpc_n_skbs);
}

#define rxrpc_new_skb(skb) __rxrpc_new_skb((skb), __func__)

static inline void __rxrpc_kill_skb(struct sk_buff *skb, const char *fn)
{
	//_net("kill skb %p %s [%d]", skb, fn, atomic_read(&rxrpc_n_skbs));
	//atomic_dec(&rxrpc_n_skbs);
}

#define rxrpc_kill_skb(skb) __rxrpc_kill_skb((skb), __func__)

static inline void __rxrpc_free_skb(struct sk_buff *skb, const char *fn)
{
	if (skb) {
		CHECK_SLAB_OKAY(&skb->users);
		//_net("free skb %p %s [%d]",
		//     skb, fn, atomic_read(&rxrpc_n_skbs));
		//atomic_dec(&rxrpc_n_skbs);
		kfree_skb(skb);
	}
}

#define rxrpc_free_skb(skb) __rxrpc_free_skb((skb), __func__)

static inline void rxrpc_purge_queue(struct sk_buff_head *list)
{
	struct sk_buff *skb;
	while ((skb = skb_dequeue((list))) != NULL)
		rxrpc_free_skb(skb);
}

#define rxrpc_get_call(CALL)				\
do {							\
+1 −0
Original line number Diff line number Diff line
@@ -203,6 +203,7 @@ void rxrpc_accept_incoming_calls(struct rxrpc_local *local)

	_net("incoming call skb %p", skb);

	rxrpc_see_skb(skb);
	sp = rxrpc_skb(skb);

	/* Set up a response packet header in case we need it */
+3 −0
Original line number Diff line number Diff line
@@ -407,6 +407,7 @@ static int rxrpc_drain_rx_oos_queue(struct rxrpc_call *call)

	skb = skb_dequeue(&call->rx_oos_queue);
	if (skb) {
		rxrpc_see_skb(skb);
		sp = rxrpc_skb(skb);

		_debug("drain OOS packet %d [%d]",
@@ -427,6 +428,7 @@ static int rxrpc_drain_rx_oos_queue(struct rxrpc_call *call)

			/* find out what the next packet is */
			skb = skb_peek(&call->rx_oos_queue);
			rxrpc_see_skb(skb);
			if (skb)
				call->rx_first_oos = rxrpc_skb(skb)->hdr.seq;
			else
@@ -576,6 +578,7 @@ static int rxrpc_process_rx_queue(struct rxrpc_call *call,
	if (!skb)
		return -EAGAIN;

	rxrpc_see_skb(skb);
	_net("deferred skb %p", skb);

	sp = rxrpc_skb(skb);
Loading