diff options
author | David Howells <dhowells@redhat.com> | 2018-10-04 04:42:29 -0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2018-10-04 04:42:29 -0400 |
commit | 2070a3e44962212d6ef02c5def821b1b9744e496 (patch) | |
tree | b2149de8243cccfe5858284d739813aa6f390f2c | |
parent | 5a790b7375414cffb0f7e8ab0f175d2e02a0af0e (diff) |
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>
-rw-r--r-- | Documentation/networking/rxrpc.txt | 11 | ||||
-rw-r--r-- | include/net/af_rxrpc.h | 3 | ||||
-rw-r--r-- | net/rxrpc/recvmsg.c | 43 |
3 files changed, 57 insertions, 0 deletions
diff --git a/Documentation/networking/rxrpc.txt b/Documentation/networking/rxrpc.txt index b5407163d53b..67879992b4c2 100644 --- a/Documentation/networking/rxrpc.txt +++ b/Documentation/networking/rxrpc.txt | |||
@@ -1069,6 +1069,17 @@ The kernel interface functions are as follows: | |||
1069 | 1069 | ||
1070 | This function may transmit a PING ACK. | 1070 | This function may transmit a PING ACK. |
1071 | 1071 | ||
1072 | (*) Get reply timestamp. | ||
1073 | |||
1074 | bool rxrpc_kernel_get_reply_time(struct socket *sock, | ||
1075 | struct rxrpc_call *call, | ||
1076 | ktime_t *_ts) | ||
1077 | |||
1078 | This allows the timestamp on the first DATA packet of the reply of a | ||
1079 | client call to be queried, provided that it is still in the Rx ring. If | ||
1080 | successful, the timestamp will be stored into *_ts and true will be | ||
1081 | returned; false will be returned otherwise. | ||
1082 | |||
1072 | 1083 | ||
1073 | ======================= | 1084 | ======================= |
1074 | CONFIGURABLE PARAMETERS | 1085 | CONFIGURABLE PARAMETERS |
diff --git a/include/net/af_rxrpc.h b/include/net/af_rxrpc.h index f53edb3754bc..c4c912554dee 100644 --- a/include/net/af_rxrpc.h +++ b/include/net/af_rxrpc.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #define _NET_RXRPC_H | 13 | #define _NET_RXRPC_H |
14 | 14 | ||
15 | #include <linux/rxrpc.h> | 15 | #include <linux/rxrpc.h> |
16 | #include <linux/ktime.h> | ||
16 | 17 | ||
17 | struct key; | 18 | struct key; |
18 | struct sock; | 19 | struct sock; |
@@ -77,5 +78,7 @@ int rxrpc_kernel_retry_call(struct socket *, struct rxrpc_call *, | |||
77 | int rxrpc_kernel_check_call(struct socket *, struct rxrpc_call *, | 78 | int rxrpc_kernel_check_call(struct socket *, struct rxrpc_call *, |
78 | enum rxrpc_call_completion *, u32 *); | 79 | enum rxrpc_call_completion *, u32 *); |
79 | u32 rxrpc_kernel_check_life(struct socket *, struct rxrpc_call *); | 80 | u32 rxrpc_kernel_check_life(struct socket *, struct rxrpc_call *); |
81 | bool rxrpc_kernel_get_reply_time(struct socket *, struct rxrpc_call *, | ||
82 | ktime_t *); | ||
80 | 83 | ||
81 | #endif /* _NET_RXRPC_H */ | 84 | #endif /* _NET_RXRPC_H */ |
diff --git a/net/rxrpc/recvmsg.c b/net/rxrpc/recvmsg.c index 816b19a78809..eaf19ebaa964 100644 --- a/net/rxrpc/recvmsg.c +++ b/net/rxrpc/recvmsg.c | |||
@@ -715,3 +715,46 @@ call_complete: | |||
715 | goto out; | 715 | goto out; |
716 | } | 716 | } |
717 | EXPORT_SYMBOL(rxrpc_kernel_recv_data); | 717 | EXPORT_SYMBOL(rxrpc_kernel_recv_data); |
718 | |||
719 | /** | ||
720 | * rxrpc_kernel_get_reply_time - Get timestamp on first reply packet | ||
721 | * @sock: The socket that the call exists on | ||
722 | * @call: The call to query | ||
723 | * @_ts: Where to put the timestamp | ||
724 | * | ||
725 | * Retrieve the timestamp from the first DATA packet of the reply if it is | ||
726 | * in the ring. Returns true if successful, false if not. | ||
727 | */ | ||
728 | bool rxrpc_kernel_get_reply_time(struct socket *sock, struct rxrpc_call *call, | ||
729 | ktime_t *_ts) | ||
730 | { | ||
731 | struct sk_buff *skb; | ||
732 | rxrpc_seq_t hard_ack, top, seq; | ||
733 | bool success = false; | ||
734 | |||
735 | mutex_lock(&call->user_mutex); | ||
736 | |||
737 | if (READ_ONCE(call->state) != RXRPC_CALL_CLIENT_RECV_REPLY) | ||
738 | goto out; | ||
739 | |||
740 | hard_ack = call->rx_hard_ack; | ||
741 | if (hard_ack != 0) | ||
742 | goto out; | ||
743 | |||
744 | seq = hard_ack + 1; | ||
745 | top = smp_load_acquire(&call->rx_top); | ||
746 | if (after(seq, top)) | ||
747 | goto out; | ||
748 | |||
749 | skb = call->rxtx_buffer[seq & RXRPC_RXTX_BUFF_MASK]; | ||
750 | if (!skb) | ||
751 | goto out; | ||
752 | |||
753 | *_ts = skb_get_ktime(skb); | ||
754 | success = true; | ||
755 | |||
756 | out: | ||
757 | mutex_unlock(&call->user_mutex); | ||
758 | return success; | ||
759 | } | ||
760 | EXPORT_SYMBOL(rxrpc_kernel_get_reply_time); | ||