mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	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: David Howells <dhowells@redhat.com>
This commit is contained in:
		
							parent
							
								
									f07373ead4
								
							
						
					
					
						commit
						cf1a6474f8
					
				
					 4 changed files with 131 additions and 4 deletions
				
			
		| 
						 | 
				
			
			@ -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 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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",
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue