mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	rxrpc: Allow the reply time to be obtained on a client call
Allow the timestamp on the sk_buff holding the first DATA packet of a reply to be queried. This can then be used as a base for the expiry time calculation on the callback promise duration indicated by an operation result. Signed-off-by: David Howells <dhowells@redhat.com>
This commit is contained in:
		
							parent
							
								
									5a790b7375
								
							
						
					
					
						commit
						2070a3e449
					
				
					 3 changed files with 57 additions and 0 deletions
				
			
		| 
						 | 
					@ -1069,6 +1069,17 @@ The kernel interface functions are as follows:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
     This function may transmit a PING ACK.
 | 
					     This function may transmit a PING ACK.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 (*) Get reply timestamp.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool rxrpc_kernel_get_reply_time(struct socket *sock,
 | 
				
			||||||
 | 
										 struct rxrpc_call *call,
 | 
				
			||||||
 | 
										 ktime_t *_ts)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     This allows the timestamp on the first DATA packet of the reply of a
 | 
				
			||||||
 | 
					     client call to be queried, provided that it is still in the Rx ring.  If
 | 
				
			||||||
 | 
					     successful, the timestamp will be stored into *_ts and true will be
 | 
				
			||||||
 | 
					     returned; false will be returned otherwise.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
=======================
 | 
					=======================
 | 
				
			||||||
CONFIGURABLE PARAMETERS
 | 
					CONFIGURABLE PARAMETERS
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,6 +13,7 @@
 | 
				
			||||||
#define _NET_RXRPC_H
 | 
					#define _NET_RXRPC_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <linux/rxrpc.h>
 | 
					#include <linux/rxrpc.h>
 | 
				
			||||||
 | 
					#include <linux/ktime.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct key;
 | 
					struct key;
 | 
				
			||||||
struct sock;
 | 
					struct sock;
 | 
				
			||||||
| 
						 | 
					@ -77,5 +78,7 @@ int rxrpc_kernel_retry_call(struct socket *, struct rxrpc_call *,
 | 
				
			||||||
int rxrpc_kernel_check_call(struct socket *, struct rxrpc_call *,
 | 
					int rxrpc_kernel_check_call(struct socket *, struct rxrpc_call *,
 | 
				
			||||||
			    enum rxrpc_call_completion *, u32 *);
 | 
								    enum rxrpc_call_completion *, u32 *);
 | 
				
			||||||
u32 rxrpc_kernel_check_life(struct socket *, struct rxrpc_call *);
 | 
					u32 rxrpc_kernel_check_life(struct socket *, struct rxrpc_call *);
 | 
				
			||||||
 | 
					bool rxrpc_kernel_get_reply_time(struct socket *, struct rxrpc_call *,
 | 
				
			||||||
 | 
									 ktime_t *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* _NET_RXRPC_H */
 | 
					#endif /* _NET_RXRPC_H */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -715,3 +715,46 @@ int rxrpc_kernel_recv_data(struct socket *sock, struct rxrpc_call *call,
 | 
				
			||||||
	goto out;
 | 
						goto out;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(rxrpc_kernel_recv_data);
 | 
					EXPORT_SYMBOL(rxrpc_kernel_recv_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * rxrpc_kernel_get_reply_time - Get timestamp on first reply packet
 | 
				
			||||||
 | 
					 * @sock: The socket that the call exists on
 | 
				
			||||||
 | 
					 * @call: The call to query
 | 
				
			||||||
 | 
					 * @_ts: Where to put the timestamp
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Retrieve the timestamp from the first DATA packet of the reply if it is
 | 
				
			||||||
 | 
					 * in the ring.  Returns true if successful, false if not.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool rxrpc_kernel_get_reply_time(struct socket *sock, struct rxrpc_call *call,
 | 
				
			||||||
 | 
									 ktime_t *_ts)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct sk_buff *skb;
 | 
				
			||||||
 | 
						rxrpc_seq_t hard_ack, top, seq;
 | 
				
			||||||
 | 
						bool success = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_lock(&call->user_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (READ_ONCE(call->state) != RXRPC_CALL_CLIENT_RECV_REPLY)
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hard_ack = call->rx_hard_ack;
 | 
				
			||||||
 | 
						if (hard_ack != 0)
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						seq = hard_ack + 1;
 | 
				
			||||||
 | 
						top = smp_load_acquire(&call->rx_top);
 | 
				
			||||||
 | 
						if (after(seq, top))
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						skb = call->rxtx_buffer[seq & RXRPC_RXTX_BUFF_MASK];
 | 
				
			||||||
 | 
						if (!skb)
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*_ts = skb_get_ktime(skb);
 | 
				
			||||||
 | 
						success = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						mutex_unlock(&call->user_mutex);
 | 
				
			||||||
 | 
						return success;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(rxrpc_kernel_get_reply_time);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue