aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2016-09-23 08:50:40 -0400
committerDavid Howells <dhowells@redhat.com>2016-09-23 10:49:19 -0400
commit9c7ad434441da6b5d4ac878cac368fbdaec99b56 (patch)
treea86f83d437f8772c0865df213f27265bc826ed60
parent89b475abdb107a74f57497b65becaf837a0e5b6b (diff)
rxrpc: Add tracepoint for ACK proposal
Add a tracepoint to log proposed ACKs, including whether the proposal is used to update a pending ACK or is discarded in favour of an easlier, higher priority ACK. Whilst we're at it, get rid of the rxrpc_acks() function and access the name array directly. We do, however, need to validate the ACK reason number given to trace_rxrpc_rx_ack() to make sure we don't overrun the array. Signed-off-by: David Howells <dhowells@redhat.com>
-rw-r--r--include/rxrpc/packet.h1
-rw-r--r--include/trace/events/rxrpc.h42
-rw-r--r--net/rxrpc/ar-internal.h25
-rw-r--r--net/rxrpc/call_event.c21
-rw-r--r--net/rxrpc/input.c19
-rw-r--r--net/rxrpc/misc.c30
-rw-r--r--net/rxrpc/output.c3
-rw-r--r--net/rxrpc/recvmsg.c3
8 files changed, 114 insertions, 30 deletions
diff --git a/include/rxrpc/packet.h b/include/rxrpc/packet.h
index fd6eb3a60a8c..703a64b4681a 100644
--- a/include/rxrpc/packet.h
+++ b/include/rxrpc/packet.h
@@ -123,6 +123,7 @@ struct rxrpc_ackpacket {
123#define RXRPC_ACK_PING_RESPONSE 7 /* response to RXRPC_ACK_PING */ 123#define RXRPC_ACK_PING_RESPONSE 7 /* response to RXRPC_ACK_PING */
124#define RXRPC_ACK_DELAY 8 /* nothing happened since received packet */ 124#define RXRPC_ACK_DELAY 8 /* nothing happened since received packet */
125#define RXRPC_ACK_IDLE 9 /* ACK due to fully received ACK window */ 125#define RXRPC_ACK_IDLE 9 /* ACK due to fully received ACK window */
126#define RXRPC_ACK__INVALID 10 /* Representation of invalid ACK reason */
126 127
127 uint8_t nAcks; /* number of ACKs */ 128 uint8_t nAcks; /* number of ACKs */
128#define RXRPC_MAXACKS 255 129#define RXRPC_MAXACKS 255
diff --git a/include/trace/events/rxrpc.h b/include/trace/events/rxrpc.h
index 9413b17ba04b..d67a8c6b085a 100644
--- a/include/trace/events/rxrpc.h
+++ b/include/trace/events/rxrpc.h
@@ -251,7 +251,7 @@ TRACE_EVENT(rxrpc_rx_ack,
251 251
252 TP_printk("c=%p %s f=%08x n=%u", 252 TP_printk("c=%p %s f=%08x n=%u",
253 __entry->call, 253 __entry->call,
254 rxrpc_acks(__entry->reason), 254 rxrpc_ack_names[__entry->reason],
255 __entry->first, 255 __entry->first,
256 __entry->n_acks) 256 __entry->n_acks)
257 ); 257 );
@@ -314,7 +314,7 @@ TRACE_EVENT(rxrpc_tx_ack,
314 TP_printk(" c=%p ACK %08x %s f=%08x r=%08x n=%u", 314 TP_printk(" c=%p ACK %08x %s f=%08x r=%08x n=%u",
315 __entry->call, 315 __entry->call,
316 __entry->serial, 316 __entry->serial,
317 rxrpc_acks(__entry->reason), 317 rxrpc_ack_names[__entry->reason],
318 __entry->ack_first, 318 __entry->ack_first,
319 __entry->ack_serial, 319 __entry->ack_serial,
320 __entry->n_acks) 320 __entry->n_acks)
@@ -505,6 +505,44 @@ TRACE_EVENT(rxrpc_rx_lose,
505 __entry->hdr.type <= 15 ? rxrpc_pkts[__entry->hdr.type] : "?UNK") 505 __entry->hdr.type <= 15 ? rxrpc_pkts[__entry->hdr.type] : "?UNK")
506 ); 506 );
507 507
508TRACE_EVENT(rxrpc_propose_ack,
509 TP_PROTO(struct rxrpc_call *call, enum rxrpc_propose_ack_trace why,
510 u8 ack_reason, rxrpc_serial_t serial, bool immediate,
511 bool background, enum rxrpc_propose_ack_outcome outcome),
512
513 TP_ARGS(call, why, ack_reason, serial, immediate, background,
514 outcome),
515
516 TP_STRUCT__entry(
517 __field(struct rxrpc_call *, call )
518 __field(enum rxrpc_propose_ack_trace, why )
519 __field(rxrpc_serial_t, serial )
520 __field(u8, ack_reason )
521 __field(bool, immediate )
522 __field(bool, background )
523 __field(enum rxrpc_propose_ack_outcome, outcome )
524 ),
525
526 TP_fast_assign(
527 __entry->call = call;
528 __entry->why = why;
529 __entry->serial = serial;
530 __entry->ack_reason = ack_reason;
531 __entry->immediate = immediate;
532 __entry->background = background;
533 __entry->outcome = outcome;
534 ),
535
536 TP_printk("c=%p %s %s r=%08x i=%u b=%u%s",
537 __entry->call,
538 rxrpc_propose_ack_traces[__entry->why],
539 rxrpc_ack_names[__entry->ack_reason],
540 __entry->serial,
541 __entry->immediate,
542 __entry->background,
543 rxrpc_propose_ack_outcomes[__entry->outcome])
544 );
545
508#endif /* _TRACE_RXRPC_H */ 546#endif /* _TRACE_RXRPC_H */
509 547
510/* This part must be outside protection */ 548/* This part must be outside protection */
diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
index e564eca75985..042dbcc52654 100644
--- a/net/rxrpc/ar-internal.h
+++ b/net/rxrpc/ar-internal.h
@@ -689,8 +689,28 @@ enum rxrpc_timer_trace {
689 689
690extern const char rxrpc_timer_traces[rxrpc_timer__nr_trace][8]; 690extern const char rxrpc_timer_traces[rxrpc_timer__nr_trace][8];
691 691
692enum rxrpc_propose_ack_trace {
693 rxrpc_propose_ack_input_data,
694 rxrpc_propose_ack_ping_for_params,
695 rxrpc_propose_ack_respond_to_ack,
696 rxrpc_propose_ack_respond_to_ping,
697 rxrpc_propose_ack_retry_tx,
698 rxrpc_propose_ack_terminal_ack,
699 rxrpc_propose_ack__nr_trace
700};
701
702enum rxrpc_propose_ack_outcome {
703 rxrpc_propose_ack_use,
704 rxrpc_propose_ack_update,
705 rxrpc_propose_ack_subsume,
706 rxrpc_propose_ack__nr_outcomes
707};
708
709extern const char rxrpc_propose_ack_traces[rxrpc_propose_ack__nr_trace][8];
710extern const char *const rxrpc_propose_ack_outcomes[rxrpc_propose_ack__nr_outcomes];
711
692extern const char *const rxrpc_pkts[]; 712extern const char *const rxrpc_pkts[];
693extern const char *rxrpc_acks(u8 reason); 713extern const char const rxrpc_ack_names[RXRPC_ACK__INVALID + 1][4];
694 714
695#include <trace/events/rxrpc.h> 715#include <trace/events/rxrpc.h>
696 716
@@ -719,7 +739,8 @@ int rxrpc_reject_call(struct rxrpc_sock *);
719 * call_event.c 739 * call_event.c
720 */ 740 */
721void rxrpc_set_timer(struct rxrpc_call *, enum rxrpc_timer_trace); 741void rxrpc_set_timer(struct rxrpc_call *, enum rxrpc_timer_trace);
722void rxrpc_propose_ACK(struct rxrpc_call *, u8, u16, u32, bool, bool); 742void rxrpc_propose_ACK(struct rxrpc_call *, u8, u16, u32, bool, bool,
743 enum rxrpc_propose_ack_trace);
723void rxrpc_process_call(struct work_struct *); 744void rxrpc_process_call(struct work_struct *);
724 745
725/* 746/*
diff --git a/net/rxrpc/call_event.c b/net/rxrpc/call_event.c
index 90e970ba048a..fd5b11339ffb 100644
--- a/net/rxrpc/call_event.c
+++ b/net/rxrpc/call_event.c
@@ -58,14 +58,13 @@ out:
58 */ 58 */
59static void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason, 59static void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason,
60 u16 skew, u32 serial, bool immediate, 60 u16 skew, u32 serial, bool immediate,
61 bool background) 61 bool background,
62 enum rxrpc_propose_ack_trace why)
62{ 63{
64 enum rxrpc_propose_ack_outcome outcome = rxrpc_propose_ack_use;
63 unsigned long now, ack_at, expiry = rxrpc_soft_ack_delay; 65 unsigned long now, ack_at, expiry = rxrpc_soft_ack_delay;
64 s8 prior = rxrpc_ack_priority[ack_reason]; 66 s8 prior = rxrpc_ack_priority[ack_reason];
65 67
66 _enter("{%d},%s,%%%x,%u",
67 call->debug_id, rxrpc_acks(ack_reason), serial, immediate);
68
69 /* Update DELAY, IDLE, REQUESTED and PING_RESPONSE ACK serial 68 /* Update DELAY, IDLE, REQUESTED and PING_RESPONSE ACK serial
70 * numbers, but we don't alter the timeout. 69 * numbers, but we don't alter the timeout.
71 */ 70 */
@@ -74,15 +73,18 @@ static void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason,
74 call->ackr_reason, rxrpc_ack_priority[call->ackr_reason]); 73 call->ackr_reason, rxrpc_ack_priority[call->ackr_reason]);
75 if (ack_reason == call->ackr_reason) { 74 if (ack_reason == call->ackr_reason) {
76 if (RXRPC_ACK_UPDATEABLE & (1 << ack_reason)) { 75 if (RXRPC_ACK_UPDATEABLE & (1 << ack_reason)) {
76 outcome = rxrpc_propose_ack_update;
77 call->ackr_serial = serial; 77 call->ackr_serial = serial;
78 call->ackr_skew = skew; 78 call->ackr_skew = skew;
79 } 79 }
80 if (!immediate) 80 if (!immediate)
81 return; 81 goto trace;
82 } else if (prior > rxrpc_ack_priority[call->ackr_reason]) { 82 } else if (prior > rxrpc_ack_priority[call->ackr_reason]) {
83 call->ackr_reason = ack_reason; 83 call->ackr_reason = ack_reason;
84 call->ackr_serial = serial; 84 call->ackr_serial = serial;
85 call->ackr_skew = skew; 85 call->ackr_skew = skew;
86 } else {
87 outcome = rxrpc_propose_ack_subsume;
86 } 88 }
87 89
88 switch (ack_reason) { 90 switch (ack_reason) {
@@ -124,17 +126,22 @@ static void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason,
124 rxrpc_set_timer(call, rxrpc_timer_set_for_ack); 126 rxrpc_set_timer(call, rxrpc_timer_set_for_ack);
125 } 127 }
126 } 128 }
129
130trace:
131 trace_rxrpc_propose_ack(call, why, ack_reason, serial, immediate,
132 background, outcome);
127} 133}
128 134
129/* 135/*
130 * propose an ACK be sent, locking the call structure 136 * propose an ACK be sent, locking the call structure
131 */ 137 */
132void rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason, 138void rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason,
133 u16 skew, u32 serial, bool immediate, bool background) 139 u16 skew, u32 serial, bool immediate, bool background,
140 enum rxrpc_propose_ack_trace why)
134{ 141{
135 spin_lock_bh(&call->lock); 142 spin_lock_bh(&call->lock);
136 __rxrpc_propose_ACK(call, ack_reason, skew, serial, 143 __rxrpc_propose_ACK(call, ack_reason, skew, serial,
137 immediate, background); 144 immediate, background, why);
138 spin_unlock_bh(&call->lock); 145 spin_unlock_bh(&call->lock);
139} 146}
140 147
diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c
index 19b1e189f5dc..349698d87ad1 100644
--- a/net/rxrpc/input.c
+++ b/net/rxrpc/input.c
@@ -49,7 +49,8 @@ static void rxrpc_send_ping(struct rxrpc_call *call, struct sk_buff *skb,
49 if (call->peer->rtt_usage < 3 || 49 if (call->peer->rtt_usage < 3 ||
50 ktime_before(ktime_add_ms(call->peer->rtt_last_req, 1000), now)) 50 ktime_before(ktime_add_ms(call->peer->rtt_last_req, 1000), now))
51 rxrpc_propose_ACK(call, RXRPC_ACK_PING, skew, sp->hdr.serial, 51 rxrpc_propose_ACK(call, RXRPC_ACK_PING, skew, sp->hdr.serial,
52 true, true); 52 true, true,
53 rxrpc_propose_ack_ping_for_params);
53} 54}
54 55
55/* 56/*
@@ -382,7 +383,8 @@ skip:
382ack: 383ack:
383 if (ack) 384 if (ack)
384 rxrpc_propose_ACK(call, ack, skew, ack_serial, 385 rxrpc_propose_ACK(call, ack, skew, ack_serial,
385 immediate_ack, true); 386 immediate_ack, true,
387 rxrpc_propose_ack_input_data);
386 388
387 if (sp->hdr.seq == READ_ONCE(call->rx_hard_ack) + 1) 389 if (sp->hdr.seq == READ_ONCE(call->rx_hard_ack) + 1)
388 rxrpc_notify_socket(call); 390 rxrpc_notify_socket(call);
@@ -539,6 +541,7 @@ static void rxrpc_input_soft_acks(struct rxrpc_call *call, u8 *acks,
539static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb, 541static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb,
540 u16 skew) 542 u16 skew)
541{ 543{
544 u8 ack_reason;
542 struct rxrpc_skb_priv *sp = rxrpc_skb(skb); 545 struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
543 union { 546 union {
544 struct rxrpc_ackpacket ack; 547 struct rxrpc_ackpacket ack;
@@ -561,8 +564,10 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb,
561 first_soft_ack = ntohl(buf.ack.firstPacket); 564 first_soft_ack = ntohl(buf.ack.firstPacket);
562 hard_ack = first_soft_ack - 1; 565 hard_ack = first_soft_ack - 1;
563 nr_acks = buf.ack.nAcks; 566 nr_acks = buf.ack.nAcks;
567 ack_reason = (buf.ack.reason < RXRPC_ACK__INVALID ?
568 buf.ack.reason : RXRPC_ACK__INVALID);
564 569
565 trace_rxrpc_rx_ack(call, first_soft_ack, buf.ack.reason, nr_acks); 570 trace_rxrpc_rx_ack(call, first_soft_ack, ack_reason, nr_acks);
566 571
567 _proto("Rx ACK %%%u { m=%hu f=#%u p=#%u s=%%%u r=%s n=%u }", 572 _proto("Rx ACK %%%u { m=%hu f=#%u p=#%u s=%%%u r=%s n=%u }",
568 sp->hdr.serial, 573 sp->hdr.serial,
@@ -570,7 +575,7 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb,
570 first_soft_ack, 575 first_soft_ack,
571 ntohl(buf.ack.previousPacket), 576 ntohl(buf.ack.previousPacket),
572 acked_serial, 577 acked_serial,
573 rxrpc_acks(buf.ack.reason), 578 rxrpc_ack_names[ack_reason],
574 buf.ack.nAcks); 579 buf.ack.nAcks);
575 580
576 if (buf.ack.reason == RXRPC_ACK_PING_RESPONSE) 581 if (buf.ack.reason == RXRPC_ACK_PING_RESPONSE)
@@ -583,10 +588,12 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb,
583 if (buf.ack.reason == RXRPC_ACK_PING) { 588 if (buf.ack.reason == RXRPC_ACK_PING) {
584 _proto("Rx ACK %%%u PING Request", sp->hdr.serial); 589 _proto("Rx ACK %%%u PING Request", sp->hdr.serial);
585 rxrpc_propose_ACK(call, RXRPC_ACK_PING_RESPONSE, 590 rxrpc_propose_ACK(call, RXRPC_ACK_PING_RESPONSE,
586 skew, sp->hdr.serial, true, true); 591 skew, sp->hdr.serial, true, true,
592 rxrpc_propose_ack_respond_to_ping);
587 } else if (sp->hdr.flags & RXRPC_REQUEST_ACK) { 593 } else if (sp->hdr.flags & RXRPC_REQUEST_ACK) {
588 rxrpc_propose_ACK(call, RXRPC_ACK_REQUESTED, 594 rxrpc_propose_ACK(call, RXRPC_ACK_REQUESTED,
589 skew, sp->hdr.serial, true, true); 595 skew, sp->hdr.serial, true, true,
596 rxrpc_propose_ack_respond_to_ack);
590 } 597 }
591 598
592 offset = sp->offset + nr_acks + 3; 599 offset = sp->offset + nr_acks + 3;
diff --git a/net/rxrpc/misc.c b/net/rxrpc/misc.c
index fa9942fabdf2..1ca14835d87f 100644
--- a/net/rxrpc/misc.c
+++ b/net/rxrpc/misc.c
@@ -91,17 +91,10 @@ const s8 rxrpc_ack_priority[] = {
91 [RXRPC_ACK_PING] = 9, 91 [RXRPC_ACK_PING] = 9,
92}; 92};
93 93
94const char *rxrpc_acks(u8 reason) 94const char const rxrpc_ack_names[RXRPC_ACK__INVALID + 1][4] = {
95{ 95 "---", "REQ", "DUP", "OOS", "WIN", "MEM", "PNG", "PNR", "DLY",
96 static const char *const str[] = { 96 "IDL", "-?-"
97 "---", "REQ", "DUP", "OOS", "WIN", "MEM", "PNG", "PNR", "DLY", 97};
98 "IDL", "-?-"
99 };
100
101 if (reason >= ARRAY_SIZE(str))
102 reason = ARRAY_SIZE(str) - 1;
103 return str[reason];
104}
105 98
106const char rxrpc_skb_traces[rxrpc_skb__nr_trace][7] = { 99const char rxrpc_skb_traces[rxrpc_skb__nr_trace][7] = {
107 [rxrpc_skb_rx_cleaned] = "Rx CLN", 100 [rxrpc_skb_rx_cleaned] = "Rx CLN",
@@ -202,3 +195,18 @@ const char rxrpc_timer_traces[rxrpc_timer__nr_trace][8] = {
202 [rxrpc_timer_set_for_send] = "SetTx ", 195 [rxrpc_timer_set_for_send] = "SetTx ",
203 [rxrpc_timer_set_for_resend] = "SetRTx", 196 [rxrpc_timer_set_for_resend] = "SetRTx",
204}; 197};
198
199const char rxrpc_propose_ack_traces[rxrpc_propose_ack__nr_trace][8] = {
200 [rxrpc_propose_ack_input_data] = "DataIn ",
201 [rxrpc_propose_ack_ping_for_params] = "Params ",
202 [rxrpc_propose_ack_respond_to_ack] = "Rsp2Ack",
203 [rxrpc_propose_ack_respond_to_ping] = "Rsp2Png",
204 [rxrpc_propose_ack_retry_tx] = "RetryTx",
205 [rxrpc_propose_ack_terminal_ack] = "ClTerm ",
206};
207
208const char *const rxrpc_propose_ack_outcomes[rxrpc_propose_ack__nr_outcomes] = {
209 [rxrpc_propose_ack_use] = "",
210 [rxrpc_propose_ack_update] = " Update",
211 [rxrpc_propose_ack_subsume] = " Subsume",
212};
diff --git a/net/rxrpc/output.c b/net/rxrpc/output.c
index e47fbd1c836d..0c563e325c9d 100644
--- a/net/rxrpc/output.c
+++ b/net/rxrpc/output.c
@@ -210,7 +210,8 @@ int rxrpc_send_call_packet(struct rxrpc_call *call, u8 type)
210 rxrpc_propose_ACK(call, pkt->ack.reason, 210 rxrpc_propose_ACK(call, pkt->ack.reason,
211 ntohs(pkt->ack.maxSkew), 211 ntohs(pkt->ack.maxSkew),
212 ntohl(pkt->ack.serial), 212 ntohl(pkt->ack.serial),
213 true, true); 213 true, true,
214 rxrpc_propose_ack_retry_tx);
214 break; 215 break;
215 case RXRPC_PACKET_TYPE_ABORT: 216 case RXRPC_PACKET_TYPE_ABORT:
216 break; 217 break;
diff --git a/net/rxrpc/recvmsg.c b/net/rxrpc/recvmsg.c
index 99e4c0ae30f1..8c7f3de45bac 100644
--- a/net/rxrpc/recvmsg.c
+++ b/net/rxrpc/recvmsg.c
@@ -141,7 +141,8 @@ static void rxrpc_end_rx_phase(struct rxrpc_call *call)
141 ASSERTCMP(call->rx_hard_ack, ==, call->rx_top); 141 ASSERTCMP(call->rx_hard_ack, ==, call->rx_top);
142 142
143 if (call->state == RXRPC_CALL_CLIENT_RECV_REPLY) { 143 if (call->state == RXRPC_CALL_CLIENT_RECV_REPLY) {
144 rxrpc_propose_ACK(call, RXRPC_ACK_IDLE, 0, 0, true, false); 144 rxrpc_propose_ACK(call, RXRPC_ACK_IDLE, 0, 0, true, false,
145 rxrpc_propose_ack_terminal_ack);
145 rxrpc_send_call_packet(call, RXRPC_PACKET_TYPE_ACK); 146 rxrpc_send_call_packet(call, RXRPC_PACKET_TYPE_ACK);
146 } 147 }
147 148