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

Commit 71f3ca40 authored by David Howells's avatar David Howells
Browse files

rxrpc: Improve skb tracing



Improve sk_buff tracing within AF_RXRPC by the following means:

 (1) Use an enum to note the event type rather than plain integers and use
     an array of event names rather than a big multi ?: list.

 (2) Distinguish Rx from Tx packets and account them separately.  This
     requires the call phase to be tracked so that we know what we might
     find in rxtx_buffer[].

 (3) Add a parameter to rxrpc_{new,see,get,free}_skb() to indicate the
     event type.

 (4) A pair of 'rotate' events are added to indicate packets that are about
     to be rotated out of the Rx and Tx windows.

 (5) A pair of 'lost' events are added, along with rxrpc_lose_skb() for
     packet loss injection recording.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
 
parent ba39f3a0
Loading
Loading
Loading
Loading
+4 −8
Original line number Diff line number Diff line
@@ -107,14 +107,14 @@ TRACE_EVENT(rxrpc_call,
	    );

TRACE_EVENT(rxrpc_skb,
	    TP_PROTO(struct sk_buff *skb, int op, int usage, int mod_count,
		     const void *where),
	    TP_PROTO(struct sk_buff *skb, enum rxrpc_skb_trace 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(enum rxrpc_skb_trace,	op		)
		    __field(int,			usage		)
		    __field(int,			mod_count	)
		    __field(const void *,		where		)
@@ -130,11 +130,7 @@ TRACE_EVENT(rxrpc_skb,

	    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"),
		      rxrpc_skb_traces[__entry->op],
		      __entry->usage,
		      __entry->mod_count,
		      __entry->where)
+3 −2
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@ u32 rxrpc_epoch;
atomic_t rxrpc_debug_id;

/* count of skbs currently in use */
atomic_t rxrpc_n_skbs;
atomic_t rxrpc_n_tx_skbs, rxrpc_n_rx_skbs;

struct workqueue_struct *rxrpc_workqueue;

@@ -867,7 +867,8 @@ static void __exit af_rxrpc_exit(void)
	proto_unregister(&rxrpc_proto);
	rxrpc_destroy_all_calls();
	rxrpc_destroy_all_connections();
	ASSERTCMP(atomic_read(&rxrpc_n_skbs), ==, 0);
	ASSERTCMP(atomic_read(&rxrpc_n_tx_skbs), ==, 0);
	ASSERTCMP(atomic_read(&rxrpc_n_rx_skbs), ==, 0);
	rxrpc_destroy_all_locals();

	remove_proc_entry("rxrpc_conns", init_net.proc_net);
+28 −5
Original line number Diff line number Diff line
@@ -520,6 +520,7 @@ struct rxrpc_call {
	rxrpc_seq_t		rx_expect_next;	/* Expected next packet sequence number */
	u8			rx_winsize;	/* Size of Rx window */
	u8			tx_winsize;	/* Maximum size of Tx window */
	bool			tx_phase;	/* T if transmission phase, F if receive phase */
	u8			nr_jumbo_bad;	/* Number of jumbo dups/exceeds-windows */

	/* receive-phase ACK management */
@@ -534,6 +535,27 @@ struct rxrpc_call {
	rxrpc_serial_t		acks_latest;	/* serial number of latest ACK received */
};

enum rxrpc_skb_trace {
	rxrpc_skb_rx_cleaned,
	rxrpc_skb_rx_freed,
	rxrpc_skb_rx_got,
	rxrpc_skb_rx_lost,
	rxrpc_skb_rx_received,
	rxrpc_skb_rx_rotated,
	rxrpc_skb_rx_purged,
	rxrpc_skb_rx_seen,
	rxrpc_skb_tx_cleaned,
	rxrpc_skb_tx_freed,
	rxrpc_skb_tx_got,
	rxrpc_skb_tx_lost,
	rxrpc_skb_tx_new,
	rxrpc_skb_tx_rotated,
	rxrpc_skb_tx_seen,
	rxrpc_skb__nr_trace
};

extern const char rxrpc_skb_traces[rxrpc_skb__nr_trace][7];

enum rxrpc_conn_trace {
	rxrpc_conn_new_client,
	rxrpc_conn_new_service,
@@ -642,7 +664,7 @@ extern const char *rxrpc_acks(u8 reason);
/*
 * af_rxrpc.c
 */
extern atomic_t rxrpc_n_skbs;
extern atomic_t rxrpc_n_tx_skbs, rxrpc_n_rx_skbs;
extern u32 rxrpc_epoch;
extern atomic_t rxrpc_debug_id;
extern struct workqueue_struct *rxrpc_workqueue;
@@ -1000,10 +1022,11 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *, struct msghdr *, size_t);
 */
void rxrpc_kernel_data_consumed(struct rxrpc_call *, struct sk_buff *);
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_new_skb(struct sk_buff *, enum rxrpc_skb_trace);
void rxrpc_see_skb(struct sk_buff *, enum rxrpc_skb_trace);
void rxrpc_get_skb(struct sk_buff *, enum rxrpc_skb_trace);
void rxrpc_free_skb(struct sk_buff *, enum rxrpc_skb_trace);
void rxrpc_lose_skb(struct sk_buff *, enum rxrpc_skb_trace);
void rxrpc_purge_queue(struct sk_buff_head *);

/*
+4 −4
Original line number Diff line number Diff line
@@ -170,7 +170,7 @@ static void rxrpc_resend(struct rxrpc_call *call)
			continue;

		skb = call->rxtx_buffer[ix];
		rxrpc_see_skb(skb);
		rxrpc_see_skb(skb, rxrpc_skb_tx_seen);
		sp = rxrpc_skb(skb);

		if (annotation == RXRPC_TX_ANNO_UNACK) {
@@ -199,7 +199,7 @@ static void rxrpc_resend(struct rxrpc_call *call)
			continue;

		skb = call->rxtx_buffer[ix];
		rxrpc_get_skb(skb);
		rxrpc_get_skb(skb, rxrpc_skb_tx_got);
		spin_unlock_bh(&call->lock);
		sp = rxrpc_skb(skb);

@@ -211,7 +211,7 @@ static void rxrpc_resend(struct rxrpc_call *call)

		if (rxrpc_send_data_packet(call->conn, skb) < 0) {
			call->resend_at = now + 2;
			rxrpc_free_skb(skb);
			rxrpc_free_skb(skb, rxrpc_skb_tx_freed);
			return;
		}

@@ -219,7 +219,7 @@ static void rxrpc_resend(struct rxrpc_call *call)
			rxrpc_expose_client_call(call);
		sp->resend_at = now + rxrpc_resend_timeout;

		rxrpc_free_skb(skb);
		rxrpc_free_skb(skb, rxrpc_skb_tx_freed);
		spin_lock_bh(&call->lock);

		/* We need to clear the retransmit state, but there are two
+8 −3
Original line number Diff line number Diff line
@@ -182,6 +182,7 @@ static struct rxrpc_call *rxrpc_alloc_client_call(struct sockaddr_rxrpc *srx,
		return ERR_PTR(-ENOMEM);
	call->state = RXRPC_CALL_CLIENT_AWAIT_CONN;
	call->service_id = srx->srx_service;
	call->tx_phase = true;

	_leave(" = %p", call);
	return call;
@@ -458,7 +459,9 @@ void rxrpc_release_call(struct rxrpc_sock *rx, struct rxrpc_call *call)
		rxrpc_disconnect_call(call);

	for (i = 0; i < RXRPC_RXTX_BUFF_SIZE; i++) {
		rxrpc_free_skb(call->rxtx_buffer[i]);
		rxrpc_free_skb(call->rxtx_buffer[i],
			       (call->tx_phase ? rxrpc_skb_tx_cleaned :
				rxrpc_skb_rx_cleaned));
		call->rxtx_buffer[i] = NULL;
	}

@@ -552,9 +555,11 @@ void rxrpc_cleanup_call(struct rxrpc_call *call)

	/* Clean up the Rx/Tx buffer */
	for (i = 0; i < RXRPC_RXTX_BUFF_SIZE; i++)
		rxrpc_free_skb(call->rxtx_buffer[i]);
		rxrpc_free_skb(call->rxtx_buffer[i],
			       (call->tx_phase ? rxrpc_skb_tx_cleaned :
				rxrpc_skb_rx_cleaned));

	rxrpc_free_skb(call->tx_pending);
	rxrpc_free_skb(call->tx_pending, rxrpc_skb_tx_cleaned);

	call_rcu(&call->rcu, rxrpc_rcu_destroy_call);
}
Loading