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

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

rxrpc: Add per-peer RTT tracker



Add a function to track the average RTT for a peer.  Sources of RTT data
will be added in subsequent patches.

The RTT data will be useful in the future for determining resend timeouts
and for handling the slow-start part of the Rx protocol.

Also add a pair of tracepoints, one to log transmissions to elicit a
response for RTT purposes and one to log responses that contribute RTT
data.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
parent f07373ea
Loading
Loading
Loading
Loading
+61 −0
Original line number Diff line number Diff line
@@ -353,6 +353,67 @@ TRACE_EVENT(rxrpc_recvmsg,
		      __entry->ret)
	    );

TRACE_EVENT(rxrpc_rtt_tx,
	    TP_PROTO(struct rxrpc_call *call, enum rxrpc_rtt_tx_trace why,
		     rxrpc_serial_t send_serial),

	    TP_ARGS(call, why, send_serial),

	    TP_STRUCT__entry(
		    __field(struct rxrpc_call *,	call		)
		    __field(enum rxrpc_rtt_tx_trace,	why		)
		    __field(rxrpc_serial_t,		send_serial	)
			     ),

	    TP_fast_assign(
		    __entry->call = call;
		    __entry->why = why;
		    __entry->send_serial = send_serial;
			   ),

	    TP_printk("c=%p %s sr=%08x",
		      __entry->call,
		      rxrpc_rtt_tx_traces[__entry->why],
		      __entry->send_serial)
	    );

TRACE_EVENT(rxrpc_rtt_rx,
	    TP_PROTO(struct rxrpc_call *call, enum rxrpc_rtt_rx_trace why,
		     rxrpc_serial_t send_serial, rxrpc_serial_t resp_serial,
		     s64 rtt, u8 nr, s64 avg),

	    TP_ARGS(call, why, send_serial, resp_serial, rtt, nr, avg),

	    TP_STRUCT__entry(
		    __field(struct rxrpc_call *,	call		)
		    __field(enum rxrpc_rtt_rx_trace,	why		)
		    __field(u8,				nr		)
		    __field(rxrpc_serial_t,		send_serial	)
		    __field(rxrpc_serial_t,		resp_serial	)
		    __field(s64,			rtt		)
		    __field(u64,			avg		)
			     ),

	    TP_fast_assign(
		    __entry->call = call;
		    __entry->why = why;
		    __entry->send_serial = send_serial;
		    __entry->resp_serial = resp_serial;
		    __entry->rtt = rtt;
		    __entry->nr = nr;
		    __entry->avg = avg;
			   ),

	    TP_printk("c=%p %s sr=%08x rr=%08x rtt=%lld nr=%u avg=%lld",
		      __entry->call,
		      rxrpc_rtt_rx_traces[__entry->why],
		      __entry->send_serial,
		      __entry->resp_serial,
		      __entry->rtt,
		      __entry->nr,
		      __entry->avg)
	    );

#endif /* _TRACE_RXRPC_H */

/* This part must be outside protection */
+21 −4
Original line number Diff line number Diff line
@@ -258,10 +258,11 @@ struct rxrpc_peer {

	/* calculated RTT cache */
#define RXRPC_RTT_CACHE_SIZE 32
	suseconds_t		rtt;		/* current RTT estimate (in uS) */
	unsigned int		rtt_point;	/* next entry at which to insert */
	unsigned int		rtt_usage;	/* amount of cache actually used */
	suseconds_t		rtt_cache[RXRPC_RTT_CACHE_SIZE]; /* calculated RTT cache */
	u64			rtt;		/* Current RTT estimate (in nS) */
	u64			rtt_sum;	/* Sum of cache contents */
	u64			rtt_cache[RXRPC_RTT_CACHE_SIZE]; /* Determined RTT cache */
	u8			rtt_cursor;	/* next entry at which to insert */
	u8			rtt_usage;	/* amount of cache actually used */
};

/*
@@ -657,6 +658,20 @@ enum rxrpc_recvmsg_trace {

extern const char rxrpc_recvmsg_traces[rxrpc_recvmsg__nr_trace][5];

enum rxrpc_rtt_tx_trace {
	rxrpc_rtt_tx_ping,
	rxrpc_rtt_tx__nr_trace
};

extern const char rxrpc_rtt_tx_traces[rxrpc_rtt_tx__nr_trace][5];

enum rxrpc_rtt_rx_trace {
	rxrpc_rtt_rx_ping_response,
	rxrpc_rtt_rx__nr_trace
};

extern const char rxrpc_rtt_rx_traces[rxrpc_rtt_rx__nr_trace][5];

extern const char *const rxrpc_pkts[];
extern const char *rxrpc_acks(u8 reason);

@@ -955,6 +970,8 @@ void rxrpc_reject_packets(struct rxrpc_local *);
 */
void rxrpc_error_report(struct sock *);
void rxrpc_peer_error_distributor(struct work_struct *);
void rxrpc_peer_add_rtt(struct rxrpc_call *, enum rxrpc_rtt_rx_trace,
			rxrpc_serial_t, rxrpc_serial_t, ktime_t, ktime_t);

/*
 * peer_object.c
+8 −0
Original line number Diff line number Diff line
@@ -182,3 +182,11 @@ const char rxrpc_recvmsg_traces[rxrpc_recvmsg__nr_trace][5] = {
	[rxrpc_recvmsg_to_be_accepted]	= "TBAC",
	[rxrpc_recvmsg_return]		= "RETN",
};

const char rxrpc_rtt_tx_traces[rxrpc_rtt_tx__nr_trace][5] = {
	[rxrpc_rtt_tx_ping]		= "PING",
};

const char rxrpc_rtt_rx_traces[rxrpc_rtt_rx__nr_trace][5] = {
	[rxrpc_rtt_rx_ping_response]	= "PONG",
};
+41 −0
Original line number Diff line number Diff line
@@ -305,3 +305,44 @@ void rxrpc_peer_error_distributor(struct work_struct *work)
	rxrpc_put_peer(peer);
	_leave("");
}

/*
 * Add RTT information to cache.  This is called in softirq mode and has
 * exclusive access to the peer RTT data.
 */
void rxrpc_peer_add_rtt(struct rxrpc_call *call, enum rxrpc_rtt_rx_trace why,
			rxrpc_serial_t send_serial, rxrpc_serial_t resp_serial,
			ktime_t send_time, ktime_t resp_time)
{
	struct rxrpc_peer *peer = call->peer;
	s64 rtt;
	u64 sum = peer->rtt_sum, avg;
	u8 cursor = peer->rtt_cursor, usage = peer->rtt_usage;

	rtt = ktime_to_ns(ktime_sub(resp_time, send_time));
	if (rtt < 0)
		return;

	/* Replace the oldest datum in the RTT buffer */
	sum -= peer->rtt_cache[cursor];
	sum += rtt;
	peer->rtt_cache[cursor] = rtt;
	peer->rtt_cursor = (cursor + 1) & (RXRPC_RTT_CACHE_SIZE - 1);
	peer->rtt_sum = sum;
	if (usage < RXRPC_RTT_CACHE_SIZE) {
		usage++;
		peer->rtt_usage = usage;
	}

	/* Now recalculate the average */
	if (usage == RXRPC_RTT_CACHE_SIZE) {
		avg = sum / RXRPC_RTT_CACHE_SIZE;
	} else {
		avg = sum;
		do_div(avg, usage);
	}

	peer->rtt = avg;
	trace_rxrpc_rtt_rx(call, why, send_serial, resp_serial, rtt,
			   usage, avg);
}