[RFC PATCH 11/13] firewire: core: add tracepoints event for asynchronous inbound response

From: Takashi Sakamoto
Date: Thu Apr 18 2024 - 05:25:23 EST


In the transaction of IEEE 1394, the node to receive the asynchronous
request transfers response packet to the requester.

This commit adds an event for the incoming packet. Note that the code to
decode the packet header is moved, against the note about the sanity
check.

Signed-off-by: Takashi Sakamoto <o-takashi@xxxxxxxxxxxxx>
---
drivers/firewire/core-transaction.c | 54 +++++++++++++++--------------
drivers/firewire/trace.h | 48 +++++++++++++++++++++++++
2 files changed, 76 insertions(+), 26 deletions(-)

diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c
index 11a60094182a..977d8a36f969 100644
--- a/drivers/firewire/core-transaction.c
+++ b/drivers/firewire/core-transaction.c
@@ -1010,32 +1010,10 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
source = async_header_get_source(p->header);
rcode = async_header_get_rcode(p->header);

- spin_lock_irqsave(&card->lock, flags);
- list_for_each_entry(iter, &card->transaction_list, link) {
- if (iter->node_id == source && iter->tlabel == tlabel) {
- if (!try_cancel_split_timeout(iter)) {
- spin_unlock_irqrestore(&card->lock, flags);
- goto timed_out;
- }
- list_del_init(&iter->link);
- card->tlabel_mask &= ~(1ULL << iter->tlabel);
- t = iter;
- break;
- }
- }
- spin_unlock_irqrestore(&card->lock, flags);
-
- if (!t) {
- timed_out:
- fw_notice(card, "unsolicited response (source %x, tlabel %x)\n",
- source, tlabel);
- return;
- }
-
- /*
- * FIXME: sanity check packet, is length correct, does tcodes
- * and addresses match.
- */
+ // FIXME: sanity check packet, is length correct, does tcodes
+ // and addresses match to the transaction request queried later.
+ //
+ // For the tracepoints event, let us decode the header here against the concern.

switch (tcode) {
case TCODE_READ_QUADLET_RESPONSE:
@@ -1061,6 +1039,30 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
break;
}

+ spin_lock_irqsave(&card->lock, flags);
+ list_for_each_entry(iter, &card->transaction_list, link) {
+ if (iter->node_id == source && iter->tlabel == tlabel) {
+ if (!try_cancel_split_timeout(iter)) {
+ spin_unlock_irqrestore(&card->lock, flags);
+ goto timed_out;
+ }
+ list_del_init(&iter->link);
+ card->tlabel_mask &= ~(1ULL << iter->tlabel);
+ t = iter;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&card->lock, flags);
+
+ trace_async_response_inbound(card, t, p, data, data_length / 4);
+
+ if (!t) {
+ timed_out:
+ fw_notice(card, "unsolicited response (source %x, tlabel %x)\n",
+ source, tlabel);
+ return;
+ }
+
/*
* The response handler may be executed while the request handler
* is still pending. Cancel the request handler.
diff --git a/drivers/firewire/trace.h b/drivers/firewire/trace.h
index 0f7d176ba647..5187f5f2b140 100644
--- a/drivers/firewire/trace.h
+++ b/drivers/firewire/trace.h
@@ -88,6 +88,54 @@ TRACE_EVENT(async_request_outbound_complete,
)
)

+TRACE_EVENT(async_response_inbound,
+ TP_PROTO(const struct fw_card *card, const struct fw_transaction *transaction,
+ const struct fw_packet *packet, u32 *data, unsigned int data_count),
+ TP_ARGS(card, transaction, packet, data, data_count),
+ TP_STRUCT__entry(
+ __field(u64, transaction)
+ __field(u8, scode)
+ __field(u8, generation)
+ __field(u16, timestamp)
+ __field(u16, destination)
+ __field(u8, tlabel)
+ __field(u8, retry)
+ __field(u8, tcode)
+ __field(u8, priority)
+ __field(u16, source)
+ __field(u8, rcode)
+ __dynamic_array(u32, data, data_count)
+ ),
+ TP_fast_assign(
+ __entry->transaction = (u64)transaction;
+ __entry->scode = packet->speed;
+ __entry->timestamp = packet->timestamp;
+ __entry->destination = async_header_get_destination(packet->header);
+ __entry->tlabel = async_header_get_tlabel(packet->header);
+ __entry->retry = async_header_get_retry(packet->header);
+ __entry->tcode = async_header_get_tcode(packet->header);
+ __entry->priority = async_header_get_priority(packet->header);
+ __entry->source = async_header_get_source(packet->header);
+ __entry->rcode = async_header_get_rcode(packet->header);
+ memcpy(__get_dynamic_array(data), data, __get_dynamic_array_len(data));
+ ),
+ TP_printk(
+ "transaction=0x%llx scode=%u timestamp=0x%04x dst_id=0x%04x tlabel=%u retry=%u tcode=%u priority=%u src_id=0x%04x rcode=%u data=%s",
+ __entry->transaction,
+ __entry->scode,
+ __entry->timestamp,
+ __entry->destination,
+ __entry->tlabel,
+ __entry->retry,
+ __entry->tcode,
+ __entry->priority,
+ __entry->source,
+ __entry->rcode,
+ __print_array(__get_dynamic_array(data),
+ __get_dynamic_array_len(data) / sizeof(u32), sizeof(u32))
+ )
+)
+
#endif // _FIREWIRE_TRACE_EVENT_H

#define TRACE_INCLUDE_PATH .
--
2.43.0