Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

rxrpc: Replace call->acks_first_seq with tracking of the hard ACK point

Replace the call->acks_first_seq variable (which holds ack.firstPacket from
the latest ACK packet and indicates the sequence number of the first ack
slot in the SACK table) with call->acks_hard_ack which will hold the
highest sequence hard ACK'd. This is 1 less than call->acks_first_seq, but
it fits in the same schema as the other tracking variables which hold the
sequence of a packet, not one past it.

This will fix the rxrpc_congest tracepoint's calculation of SACK window
size which shows one fewer than it should - and will occasionally go to -1.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
Link: https://patch.msgid.link/20241204074710.990092-21-dhowells@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

David Howells and committed by
Jakub Kicinski
203457e1 692c4caa

+59 -67
+32 -36
include/trace/events/rxrpc.h
··· 893 893 __field(unsigned int, call) 894 894 __field(enum rxrpc_txqueue_trace, why) 895 895 __field(rxrpc_seq_t, tx_bottom) 896 - __field(rxrpc_seq_t, acks_first_seq) 896 + __field(rxrpc_seq_t, acks_hard_ack) 897 897 __field(rxrpc_seq_t, tx_top) 898 898 __field(rxrpc_seq_t, send_top) 899 899 __field(int, tx_winsize) ··· 903 903 __entry->call = call->debug_id; 904 904 __entry->why = why; 905 905 __entry->tx_bottom = call->tx_bottom; 906 - __entry->acks_first_seq = call->acks_first_seq; 906 + __entry->acks_hard_ack = call->acks_hard_ack; 907 907 __entry->tx_top = call->tx_top; 908 908 __entry->send_top = call->send_top; 909 909 __entry->tx_winsize = call->tx_winsize; 910 910 ), 911 911 912 - TP_printk("c=%08x %s f=%08x h=%08x n=%u/%u/%u/%u", 912 + TP_printk("c=%08x %s b=%08x h=%08x n=%u/%u/%u/%u", 913 913 __entry->call, 914 914 __print_symbolic(__entry->why, rxrpc_txqueue_traces), 915 915 __entry->tx_bottom, 916 - __entry->acks_first_seq, 917 - __entry->acks_first_seq - __entry->tx_bottom, 918 - __entry->tx_top - __entry->acks_first_seq, 916 + __entry->acks_hard_ack, 917 + __entry->acks_hard_ack - __entry->tx_bottom, 918 + __entry->tx_top - __entry->acks_hard_ack, 919 919 __entry->send_top - __entry->tx_top, 920 920 __entry->tx_winsize) 921 921 ); ··· 1015 1015 ); 1016 1016 1017 1017 TRACE_EVENT(rxrpc_rx_ack, 1018 - TP_PROTO(struct rxrpc_call *call, 1019 - rxrpc_serial_t serial, rxrpc_serial_t ack_serial, 1020 - rxrpc_seq_t first, rxrpc_seq_t prev, u8 reason, u8 n_acks), 1018 + TP_PROTO(struct rxrpc_call *call, struct rxrpc_skb_priv *sp), 1021 1019 1022 - TP_ARGS(call, serial, ack_serial, first, prev, reason, n_acks), 1020 + TP_ARGS(call, sp), 1023 1021 1024 1022 TP_STRUCT__entry( 1025 1023 __field(unsigned int, call) ··· 1030 1032 ), 1031 1033 1032 1034 TP_fast_assign( 1033 - __entry->call = call->debug_id; 1034 - __entry->serial = serial; 1035 - __entry->ack_serial = ack_serial; 1036 - __entry->first = first; 1037 - __entry->prev = prev; 1038 - __entry->reason = reason; 1039 - __entry->n_acks = n_acks; 1035 + __entry->call = call->debug_id; 1036 + __entry->serial = sp->hdr.serial; 1037 + __entry->ack_serial = sp->ack.acked_serial; 1038 + __entry->first = sp->ack.first_ack; 1039 + __entry->prev = sp->ack.prev_ack; 1040 + __entry->reason = sp->ack.reason; 1041 + __entry->n_acks = sp->ack.nr_acks; 1040 1042 ), 1041 1043 1042 1044 TP_printk("c=%08x %08x %s r=%08x f=%08x p=%08x n=%u", ··· 1705 1707 TP_fast_assign( 1706 1708 __entry->call = call->debug_id; 1707 1709 __entry->change = change; 1708 - __entry->hard_ack = call->acks_first_seq; 1710 + __entry->hard_ack = call->acks_hard_ack; 1709 1711 __entry->top = call->tx_top; 1710 1712 __entry->lowest_nak = call->acks_lowest_nak; 1711 1713 __entry->ack_serial = ack_serial; ··· 1752 1754 __entry->mode = call->cong_mode; 1753 1755 __entry->cwnd = call->cong_cwnd; 1754 1756 __entry->extra = call->cong_extra; 1755 - __entry->hard_ack = call->acks_first_seq; 1757 + __entry->hard_ack = call->acks_hard_ack; 1756 1758 __entry->prepared = call->send_top - call->tx_bottom; 1757 1759 __entry->since_last_tx = ktime_sub(now, call->tx_last_sent); 1758 1760 __entry->has_data = call->tx_bottom != call->tx_top; ··· 1853 1855 TP_fast_assign( 1854 1856 struct rxrpc_skb_priv *sp = ack ? rxrpc_skb(ack) : NULL; 1855 1857 __entry->call = call->debug_id; 1856 - __entry->seq = call->acks_first_seq; 1858 + __entry->seq = call->acks_hard_ack; 1857 1859 __entry->transmitted = call->tx_transmitted; 1858 1860 __entry->ack_serial = sp ? sp->hdr.serial : 0; 1859 1861 ), ··· 1942 1944 __entry->call_id = call->call_id; 1943 1945 __entry->call_serial = call->rx_serial; 1944 1946 __entry->conn_serial = call->conn->hi_serial; 1945 - __entry->tx_seq = call->acks_first_seq; 1947 + __entry->tx_seq = call->acks_hard_ack; 1946 1948 __entry->rx_seq = call->rx_highest_seq; 1947 1949 ), 1948 1950 ··· 1974 1976 ); 1975 1977 1976 1978 TRACE_EVENT(rxrpc_rx_discard_ack, 1977 - TP_PROTO(unsigned int debug_id, rxrpc_serial_t serial, 1978 - rxrpc_seq_t first_soft_ack, rxrpc_seq_t call_ackr_first, 1979 - rxrpc_seq_t prev_pkt, rxrpc_seq_t call_ackr_prev), 1979 + TP_PROTO(struct rxrpc_call *call, rxrpc_serial_t serial, 1980 + rxrpc_seq_t hard_ack, rxrpc_seq_t prev_pkt), 1980 1981 1981 - TP_ARGS(debug_id, serial, first_soft_ack, call_ackr_first, 1982 - prev_pkt, call_ackr_prev), 1982 + TP_ARGS(call, serial, hard_ack, prev_pkt), 1983 1983 1984 1984 TP_STRUCT__entry( 1985 1985 __field(unsigned int, debug_id) 1986 1986 __field(rxrpc_serial_t, serial) 1987 - __field(rxrpc_seq_t, first_soft_ack) 1988 - __field(rxrpc_seq_t, call_ackr_first) 1987 + __field(rxrpc_seq_t, hard_ack) 1989 1988 __field(rxrpc_seq_t, prev_pkt) 1990 - __field(rxrpc_seq_t, call_ackr_prev) 1989 + __field(rxrpc_seq_t, acks_hard_ack) 1990 + __field(rxrpc_seq_t, acks_prev_seq) 1991 1991 ), 1992 1992 1993 1993 TP_fast_assign( 1994 - __entry->debug_id = debug_id; 1994 + __entry->debug_id = call->debug_id; 1995 1995 __entry->serial = serial; 1996 - __entry->first_soft_ack = first_soft_ack; 1997 - __entry->call_ackr_first = call_ackr_first; 1996 + __entry->hard_ack = hard_ack; 1998 1997 __entry->prev_pkt = prev_pkt; 1999 - __entry->call_ackr_prev = call_ackr_prev; 1998 + __entry->acks_hard_ack = call->acks_hard_ack; 1999 + __entry->acks_prev_seq = call->acks_prev_seq; 2000 2000 ), 2001 2001 2002 2002 TP_printk("c=%08x r=%08x %08x<%08x %08x<%08x", 2003 2003 __entry->debug_id, 2004 2004 __entry->serial, 2005 - __entry->first_soft_ack, 2006 - __entry->call_ackr_first, 2005 + __entry->hard_ack, 2006 + __entry->acks_hard_ack, 2007 2007 __entry->prev_pkt, 2008 - __entry->call_ackr_prev) 2008 + __entry->acks_prev_seq) 2009 2009 ); 2010 2010 2011 2011 TRACE_EVENT(rxrpc_req_ack,
+1 -1
net/rxrpc/ar-internal.h
··· 757 757 758 758 /* Transmission-phase ACK management (ACKs we've received). */ 759 759 ktime_t acks_latest_ts; /* Timestamp of latest ACK received */ 760 - rxrpc_seq_t acks_first_seq; /* first sequence number received */ 760 + rxrpc_seq_t acks_hard_ack; /* Highest sequence hard acked */ 761 761 rxrpc_seq_t acks_prev_seq; /* Highest previousPacket received */ 762 762 rxrpc_seq_t acks_lowest_nak; /* Lowest NACK in the buffer (or ==tx_hard_ack) */ 763 763 rxrpc_serial_t acks_highest_serial; /* Highest serial number ACK'd */
+26 -30
net/rxrpc/input.c
··· 782 782 */ 783 783 static rxrpc_seq_t rxrpc_input_check_prev_ack(struct rxrpc_call *call, 784 784 struct rxrpc_ack_summary *summary, 785 - rxrpc_seq_t seq) 785 + rxrpc_seq_t hard_ack) 786 786 { 787 787 struct sk_buff *skb = call->cong_last_nack; 788 788 struct rxrpc_skb_priv *sp = rxrpc_skb(skb); 789 789 unsigned int i, new_acks = 0, retained_nacks = 0; 790 - rxrpc_seq_t old_seq = sp->ack.first_ack; 790 + rxrpc_seq_t seq = hard_ack + 1, old_seq = sp->ack.first_ack; 791 791 u8 *acks = skb->data + sizeof(struct rxrpc_wire_header) + sizeof(struct rxrpc_ackpacket); 792 792 793 793 if (after_eq(seq, old_seq + sp->ack.nr_acks)) { ··· 810 810 summary->nr_retained_nacks = retained_nacks; 811 811 } 812 812 813 - return old_seq + sp->ack.nr_acks; 813 + return old_seq + sp->ack.nr_acks - 1; 814 814 } 815 815 816 816 /* ··· 825 825 static void rxrpc_input_soft_acks(struct rxrpc_call *call, 826 826 struct rxrpc_ack_summary *summary, 827 827 struct sk_buff *skb, 828 - rxrpc_seq_t seq, 829 828 rxrpc_seq_t since) 830 829 { 831 830 struct rxrpc_skb_priv *sp = rxrpc_skb(skb); 832 831 unsigned int i, old_nacks = 0; 833 - rxrpc_seq_t lowest_nak = seq + sp->ack.nr_acks; 832 + rxrpc_seq_t lowest_nak = call->acks_hard_ack + sp->ack.nr_acks + 1; 833 + rxrpc_seq_t seq = call->acks_hard_ack; 834 834 u8 *acks = skb->data + sizeof(struct rxrpc_wire_header) + sizeof(struct rxrpc_ackpacket); 835 835 836 836 for (i = 0; i < sp->ack.nr_acks; i++) { 837 + seq++; 837 838 if (acks[i] == RXRPC_ACK_TYPE_ACK) { 838 839 summary->nr_acks++; 839 - if (after_eq(seq, since)) 840 + if (after(seq, since)) 840 841 summary->nr_new_acks++; 841 842 } else { 842 843 summary->saw_nacks = true; 843 - if (before(seq, since)) { 844 + if (before_eq(seq, since)) { 844 845 /* Overlap with previous ACK */ 845 846 old_nacks++; 846 847 } else { ··· 852 851 if (before(seq, lowest_nak)) 853 852 lowest_nak = seq; 854 853 } 855 - seq++; 856 854 } 857 855 858 856 if (lowest_nak != call->acks_lowest_nak) { ··· 874 874 * with respect to the ack state conveyed by preceding ACKs. 875 875 */ 876 876 static bool rxrpc_is_ack_valid(struct rxrpc_call *call, 877 - rxrpc_seq_t first_pkt, rxrpc_seq_t prev_pkt) 877 + rxrpc_seq_t hard_ack, rxrpc_seq_t prev_pkt) 878 878 { 879 - rxrpc_seq_t base = READ_ONCE(call->acks_first_seq); 879 + rxrpc_seq_t base = READ_ONCE(call->acks_hard_ack); 880 880 881 - if (after(first_pkt, base)) 881 + if (after(hard_ack, base)) 882 882 return true; /* The window advanced */ 883 883 884 - if (before(first_pkt, base)) 884 + if (before(hard_ack, base)) 885 885 return false; /* firstPacket regressed */ 886 886 887 887 if (after_eq(prev_pkt, call->acks_prev_seq)) 888 888 return true; /* previousPacket hasn't regressed. */ 889 889 890 890 /* Some rx implementations put a serial number in previousPacket. */ 891 - if (after_eq(prev_pkt, base + call->tx_winsize)) 891 + if (after(prev_pkt, base + call->tx_winsize)) 892 892 return false; 893 893 return true; 894 894 } ··· 906 906 static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb) 907 907 { 908 908 struct rxrpc_ack_summary summary = { 0 }; 909 - struct rxrpc_skb_priv *sp = rxrpc_skb(skb); 910 909 struct rxrpc_acktrailer trailer; 910 + struct rxrpc_skb_priv *sp = rxrpc_skb(skb); 911 911 rxrpc_serial_t ack_serial, acked_serial; 912 912 rxrpc_seq_t first_soft_ack, hard_ack, prev_pkt, since; 913 913 int nr_acks, offset, ioffset; ··· 925 925 summary.ack_reason = (sp->ack.reason < RXRPC_ACK__INVALID ? 926 926 sp->ack.reason : RXRPC_ACK__INVALID); 927 927 928 - trace_rxrpc_rx_ack(call, ack_serial, acked_serial, 929 - first_soft_ack, prev_pkt, 930 - summary.ack_reason, nr_acks); 928 + trace_rxrpc_rx_ack(call, sp); 931 929 rxrpc_inc_stat(call->rxnet, stat_rx_acks[summary.ack_reason]); 932 930 933 931 if (acked_serial != 0) { ··· 950 952 * lost the call because it switched to a different peer. 951 953 */ 952 954 if (unlikely(summary.ack_reason == RXRPC_ACK_EXCEEDS_WINDOW) && 953 - first_soft_ack == 1 && 955 + hard_ack == 0 && 954 956 prev_pkt == 0 && 955 957 rxrpc_is_client_call(call)) { 956 958 rxrpc_set_call_completion(call, RXRPC_CALL_REMOTELY_ABORTED, ··· 963 965 * if we still have it buffered to the beginning. 964 966 */ 965 967 if (unlikely(summary.ack_reason == RXRPC_ACK_OUT_OF_SEQUENCE) && 966 - first_soft_ack == 1 && 968 + hard_ack == 0 && 967 969 prev_pkt == 0 && 968 970 call->tx_bottom == 0 && 969 971 rxrpc_is_client_call(call)) { ··· 973 975 } 974 976 975 977 /* Discard any out-of-order or duplicate ACKs (outside lock). */ 976 - if (!rxrpc_is_ack_valid(call, first_soft_ack, prev_pkt)) { 977 - trace_rxrpc_rx_discard_ack(call->debug_id, ack_serial, 978 - first_soft_ack, call->acks_first_seq, 979 - prev_pkt, call->acks_prev_seq); 978 + if (!rxrpc_is_ack_valid(call, hard_ack, prev_pkt)) { 979 + trace_rxrpc_rx_discard_ack(call, ack_serial, hard_ack, prev_pkt); 980 980 goto send_response; 981 981 } 982 982 ··· 988 992 skb_condense(skb); 989 993 990 994 if (call->cong_last_nack) { 991 - since = rxrpc_input_check_prev_ack(call, &summary, first_soft_ack); 995 + since = rxrpc_input_check_prev_ack(call, &summary, hard_ack); 992 996 rxrpc_free_skb(call->cong_last_nack, rxrpc_skb_put_last_nack); 993 997 call->cong_last_nack = NULL; 994 998 } else { 995 - summary.nr_new_acks = first_soft_ack - call->acks_first_seq; 996 - call->acks_lowest_nak = first_soft_ack + nr_acks; 997 - since = first_soft_ack; 999 + summary.nr_new_acks = hard_ack - call->acks_hard_ack; 1000 + call->acks_lowest_nak = hard_ack + nr_acks; 1001 + since = hard_ack; 998 1002 } 999 1003 1000 1004 call->acks_latest_ts = skb->tstamp; 1001 - call->acks_first_seq = first_soft_ack; 1005 + call->acks_hard_ack = hard_ack; 1002 1006 call->acks_prev_seq = prev_pkt; 1003 1007 1004 1008 switch (summary.ack_reason) { ··· 1014 1018 if (trailer.maxMTU) 1015 1019 rxrpc_input_ack_trailer(call, skb, &trailer); 1016 1020 1017 - if (first_soft_ack == 0) 1021 + if (hard_ack + 1 == 0) 1018 1022 return rxrpc_proto_abort(call, 0, rxrpc_eproto_ackr_zero); 1019 1023 1020 1024 /* Ignore ACKs unless we are or have just been transmitting. */ ··· 1044 1048 if (nr_acks > 0) { 1045 1049 if (offset > (int)skb->len - nr_acks) 1046 1050 return rxrpc_proto_abort(call, 0, rxrpc_eproto_ackr_short_sack); 1047 - rxrpc_input_soft_acks(call, &summary, skb, first_soft_ack, since); 1051 + rxrpc_input_soft_acks(call, &summary, skb, since); 1048 1052 rxrpc_get_skb(skb, rxrpc_skb_get_last_nack); 1049 1053 call->cong_last_nack = skb; 1050 1054 }