Skip to content

Commit 34f79c1

Browse files
quic-bjorandeandersson
authored andcommitted
rpmsg: glink: Introduce packet tracepoints
Introduce tracepoints to allow tracing the GLINK packets being exchanged with other subsystems. This is useful for debugging both interaction with remote processors and client driver issues, as well as tracking latency through the communication stack. Channel events are traced with both local and remote channel ids, as well as the textual representation when possible. The channel ids are useful when matching traces with traces from the firmware side logs, while the textual representation is necessary to identify channels when we're starting to trace an already running system. Signed-off-by: Bjorn Andersson <quic_bjorande@quicinc.com> Reviewed-by: Chris Lew <quic_clew@quicinc.com> Link: https://lore.kernel.org/r/20240805-glink-tracepoints-v1-3-a5f3293fb09e@quicinc.com Signed-off-by: Bjorn Andersson <andersson@kernel.org>
1 parent 91adb34 commit 34f79c1

File tree

3 files changed

+501
-2
lines changed

3 files changed

+501
-2
lines changed

drivers/rpmsg/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ obj-$(CONFIG_RPMSG_CHAR) += rpmsg_char.o
44
obj-$(CONFIG_RPMSG_CTRL) += rpmsg_ctrl.o
55
obj-$(CONFIG_RPMSG_NS) += rpmsg_ns.o
66
obj-$(CONFIG_RPMSG_MTK_SCP) += mtk_rpmsg.o
7+
CFLAGS_qcom_glink_native.o := -I$(src)
78
qcom_glink-objs := qcom_glink_native.o qcom_glink_ssr.o
89
obj-$(CONFIG_RPMSG_QCOM_GLINK) += qcom_glink.o
910
obj-$(CONFIG_RPMSG_QCOM_GLINK_RPM) += qcom_glink_rpm.o

drivers/rpmsg/qcom_glink_native.c

Lines changed: 94 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
#include "rpmsg_internal.h"
2424
#include "qcom_glink_native.h"
2525

26+
#define CREATE_TRACE_POINTS
27+
#include "qcom_glink_trace.h"
28+
2629
#define GLINK_NAME_SIZE 32
2730
#define GLINK_VERSION_1 1
2831

@@ -78,6 +81,7 @@ struct glink_core_rx_intent {
7881
/**
7982
* struct qcom_glink - driver context, relates to one remote subsystem
8083
* @dev: reference to the associated struct device
84+
* @label: identifier of the glink edge
8185
* @rx_pipe: pipe object for receive FIFO
8286
* @tx_pipe: pipe object for transmit FIFO
8387
* @rx_work: worker for handling received control messages
@@ -96,6 +100,8 @@ struct glink_core_rx_intent {
96100
struct qcom_glink {
97101
struct device *dev;
98102

103+
const char *label;
104+
99105
struct qcom_glink_pipe *rx_pipe;
100106
struct qcom_glink_pipe *tx_pipe;
101107

@@ -392,6 +398,8 @@ static int qcom_glink_send_version(struct qcom_glink *glink)
392398
msg.param1 = cpu_to_le16(GLINK_VERSION_1);
393399
msg.param2 = cpu_to_le32(glink->features);
394400

401+
trace_qcom_glink_cmd_version_tx(glink->label, GLINK_VERSION_1, glink->features);
402+
395403
return qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true);
396404
}
397405

@@ -403,6 +411,8 @@ static void qcom_glink_send_version_ack(struct qcom_glink *glink)
403411
msg.param1 = cpu_to_le16(GLINK_VERSION_1);
404412
msg.param2 = cpu_to_le32(glink->features);
405413

414+
trace_qcom_glink_cmd_version_ack_tx(glink->label, msg.param1, msg.param2);
415+
406416
qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true);
407417
}
408418

@@ -415,6 +425,9 @@ static void qcom_glink_send_open_ack(struct qcom_glink *glink,
415425
msg.param1 = cpu_to_le16(channel->rcid);
416426
msg.param2 = cpu_to_le32(0);
417427

428+
trace_qcom_glink_cmd_open_ack_tx(glink->label, channel->name,
429+
channel->lcid, channel->rcid);
430+
418431
qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true);
419432
}
420433

@@ -429,6 +442,11 @@ static void qcom_glink_handle_intent_req_ack(struct qcom_glink *glink,
429442
spin_lock_irqsave(&glink->idr_lock, flags);
430443
channel = idr_find(&glink->rcids, cid);
431444
spin_unlock_irqrestore(&glink->idr_lock, flags);
445+
446+
trace_qcom_glink_cmd_rx_intent_req_ack_rx(glink->label,
447+
channel ? channel->name : NULL,
448+
channel ? channel->lcid : 0,
449+
cid, granted);
432450
if (!channel) {
433451
dev_err(glink->dev, "unable to find channel\n");
434452
return;
@@ -483,6 +501,9 @@ static int qcom_glink_send_open_req(struct qcom_glink *glink,
483501
req.msg.param2 = cpu_to_le32(name_len);
484502
strcpy(req.name, channel->name);
485503

504+
trace_qcom_glink_cmd_open_tx(glink->label, channel->name,
505+
channel->lcid, channel->rcid);
506+
486507
ret = qcom_glink_tx(glink, &req, req_len, NULL, 0, true);
487508
if (ret)
488509
goto remove_idr;
@@ -507,6 +528,9 @@ static void qcom_glink_send_close_req(struct qcom_glink *glink,
507528
req.param1 = cpu_to_le16(channel->lcid);
508529
req.param2 = 0;
509530

531+
trace_qcom_glink_cmd_close_tx(glink->label, channel->name,
532+
channel->lcid, channel->rcid);
533+
510534
qcom_glink_tx(glink, &req, sizeof(req), NULL, 0, true);
511535
}
512536

@@ -519,6 +543,9 @@ static void qcom_glink_send_close_ack(struct qcom_glink *glink,
519543
req.param1 = cpu_to_le16(channel->rcid);
520544
req.param2 = 0;
521545

546+
trace_qcom_glink_cmd_close_ack_tx(glink->label, channel->name,
547+
channel->lcid, channel->rcid);
548+
522549
qcom_glink_tx(glink, &req, sizeof(req), NULL, 0, true);
523550
}
524551

@@ -550,6 +577,9 @@ static void qcom_glink_rx_done_work(struct work_struct *work)
550577
cmd.lcid = cid;
551578
cmd.liid = iid;
552579

580+
trace_qcom_glink_cmd_rx_done_tx(glink->label, channel->name,
581+
channel->lcid, channel->rcid, cmd.liid, reuse);
582+
553583
qcom_glink_tx(glink, &cmd, sizeof(cmd), NULL, 0, true);
554584
if (!reuse) {
555585
kfree(intent->data);
@@ -600,6 +630,8 @@ static void qcom_glink_receive_version(struct qcom_glink *glink,
600630
u32 version,
601631
u32 features)
602632
{
633+
trace_qcom_glink_cmd_version_rx(glink->label, version, features);
634+
603635
switch (version) {
604636
case 0:
605637
break;
@@ -627,6 +659,8 @@ static void qcom_glink_receive_version_ack(struct qcom_glink *glink,
627659
u32 version,
628660
u32 features)
629661
{
662+
trace_qcom_glink_cmd_version_ack_rx(glink->label, version, features);
663+
630664
switch (version) {
631665
case 0:
632666
/* Version negotiation failed */
@@ -658,6 +692,10 @@ static int qcom_glink_send_intent_req_ack(struct qcom_glink *glink,
658692
{
659693
struct glink_msg msg;
660694

695+
trace_qcom_glink_cmd_rx_intent_req_ack_tx(glink->label, channel->name,
696+
channel->lcid, channel->rcid,
697+
granted);
698+
661699
msg.cmd = cpu_to_le16(GLINK_CMD_RX_INTENT_REQ_ACK);
662700
msg.param1 = cpu_to_le16(channel->lcid);
663701
msg.param2 = cpu_to_le32(granted);
@@ -695,6 +733,10 @@ static int qcom_glink_advertise_intent(struct qcom_glink *glink,
695733
cmd.size = cpu_to_le32(intent->size);
696734
cmd.liid = cpu_to_le32(intent->id);
697735

736+
trace_qcom_glink_cmd_intent_tx(glink->label, channel->name,
737+
channel->lcid, channel->rcid,
738+
cmd.count, cmd.size, cmd.liid);
739+
698740
qcom_glink_tx(glink, &cmd, sizeof(cmd), NULL, 0, true);
699741

700742
return 0;
@@ -752,6 +794,9 @@ static void qcom_glink_handle_rx_done(struct qcom_glink *glink,
752794
spin_lock_irqsave(&glink->idr_lock, flags);
753795
channel = idr_find(&glink->rcids, cid);
754796
spin_unlock_irqrestore(&glink->idr_lock, flags);
797+
798+
trace_qcom_glink_cmd_rx_done_rx(glink->label, channel ? channel->name : NULL,
799+
channel ? channel->lcid : 0, cid, iid, reuse);
755800
if (!channel) {
756801
dev_err(glink->dev, "invalid channel id received\n");
757802
return;
@@ -801,6 +846,10 @@ static void qcom_glink_handle_intent_req(struct qcom_glink *glink,
801846
channel = idr_find(&glink->rcids, cid);
802847
spin_unlock_irqrestore(&glink->idr_lock, flags);
803848

849+
trace_qcom_glink_cmd_rx_intent_req_rx(glink->label,
850+
channel ? channel->name : NULL,
851+
channel ? channel->lcid : 0,
852+
cid, size);
804853
if (!channel) {
805854
pr_err("%s channel not found for cid %d\n", __func__, cid);
806855
return;
@@ -873,9 +922,15 @@ static int qcom_glink_rx_data(struct qcom_glink *glink, size_t avail)
873922
}
874923

875924
rcid = le16_to_cpu(hdr.msg.param1);
925+
liid = le32_to_cpu(hdr.msg.param2);
876926
spin_lock_irqsave(&glink->idr_lock, flags);
877927
channel = idr_find(&glink->rcids, rcid);
878928
spin_unlock_irqrestore(&glink->idr_lock, flags);
929+
930+
trace_qcom_glink_cmd_tx_data_rx(glink->label, channel ? channel->name : NULL,
931+
channel ? channel->lcid : 0, rcid,
932+
liid, chunk_size, left_size,
933+
hdr.msg.cmd == GLINK_CMD_TX_DATA_CONT);
879934
if (!channel) {
880935
dev_dbg(glink->dev, "Data on non-existing channel\n");
881936

@@ -906,8 +961,6 @@ static int qcom_glink_rx_data(struct qcom_glink *glink, size_t avail)
906961
intent = channel->buf;
907962
}
908963
} else {
909-
liid = le32_to_cpu(hdr.msg.param2);
910-
911964
spin_lock_irqsave(&channel->intent_lock, flags);
912965
intent = idr_find(&channel->liids, liid);
913966
spin_unlock_irqrestore(&channel->intent_lock, flags);
@@ -958,6 +1011,8 @@ static int qcom_glink_rx_data(struct qcom_glink *glink, size_t avail)
9581011

9591012
static void qcom_glink_rx_read_notif(struct qcom_glink *glink)
9601013
{
1014+
trace_qcom_glink_cmd_read_notif_rx(glink->label);
1015+
9611016
qcom_glink_rx_advance(glink, ALIGN(sizeof(struct glink_msg), 8));
9621017
qcom_glink_tx_kick(glink);
9631018
}
@@ -993,6 +1048,7 @@ static void qcom_glink_handle_intent(struct qcom_glink *glink,
9931048
channel = idr_find(&glink->rcids, cid);
9941049
spin_unlock_irqrestore(&glink->idr_lock, flags);
9951050
if (!channel) {
1051+
trace_qcom_glink_cmd_intent_rx(glink->label, NULL, 0, cid, count, 0, 0);
9961052
dev_err(glink->dev, "intents for non-existing channel\n");
9971053
qcom_glink_rx_advance(glink, ALIGN(msglen, 8));
9981054
return;
@@ -1004,6 +1060,11 @@ static void qcom_glink_handle_intent(struct qcom_glink *glink,
10041060

10051061
qcom_glink_rx_peek(glink, msg, 0, msglen);
10061062

1063+
trace_qcom_glink_cmd_intent_rx(glink->label, channel->name,
1064+
channel->lcid, cid, count,
1065+
count > 0 ? msg->intents[0].size : 0,
1066+
count > 0 ? msg->intents[0].iid : 0);
1067+
10071068
for (i = 0; i < count; ++i) {
10081069
intent = kzalloc(sizeof(*intent), GFP_ATOMIC);
10091070
if (!intent)
@@ -1037,6 +1098,9 @@ static int qcom_glink_rx_open_ack(struct qcom_glink *glink, unsigned int lcid)
10371098
spin_lock(&glink->idr_lock);
10381099
channel = idr_find(&glink->lcids, lcid);
10391100
spin_unlock(&glink->idr_lock);
1101+
1102+
trace_qcom_glink_cmd_open_ack_rx(glink->label, channel ? channel->name : NULL,
1103+
lcid, channel ? channel->rcid : 0);
10401104
if (!channel) {
10411105
dev_err(glink->dev, "Invalid open ack packet\n");
10421106
return -EINVAL;
@@ -1069,6 +1133,9 @@ static int qcom_glink_set_flow_control(struct rpmsg_endpoint *ept, bool pause, u
10691133
msg.param1 = cpu_to_le16(channel->lcid);
10701134
msg.param2 = cpu_to_le32(sigs);
10711135

1136+
trace_qcom_glink_cmd_signal_tx(glink->label, channel->name,
1137+
channel->lcid, channel->rcid, sigs);
1138+
10721139
return qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true);
10731140
}
10741141

@@ -1084,6 +1151,9 @@ static void qcom_glink_handle_signals(struct qcom_glink *glink,
10841151
spin_lock_irqsave(&glink->idr_lock, flags);
10851152
channel = idr_find(&glink->rcids, rcid);
10861153
spin_unlock_irqrestore(&glink->idr_lock, flags);
1154+
1155+
trace_qcom_glink_cmd_signal_rx(glink->label, channel ? channel->name : NULL,
1156+
channel ? channel->lcid : 0, rcid, sigs);
10871157
if (!channel) {
10881158
dev_err(glink->dev, "signal for non-existing channel\n");
10891159
return;
@@ -1357,6 +1427,10 @@ static int qcom_glink_request_intent(struct qcom_glink *glink,
13571427
cmd.cid = channel->lcid;
13581428
cmd.size = size;
13591429

1430+
trace_qcom_glink_cmd_rx_intent_req_tx(glink->label, channel->name,
1431+
channel->lcid, channel->rcid,
1432+
cmd.size);
1433+
13601434
ret = qcom_glink_tx(glink, &cmd, sizeof(cmd), NULL, 0, true);
13611435
if (ret)
13621436
goto unlock;
@@ -1437,6 +1511,12 @@ static int __qcom_glink_send(struct glink_channel *channel,
14371511
req.chunk_size = cpu_to_le32(chunk_size);
14381512
req.left_size = cpu_to_le32(len - offset - chunk_size);
14391513

1514+
trace_qcom_glink_cmd_tx_data_tx(glink->label, channel->name,
1515+
channel->lcid, channel->rcid,
1516+
iid, chunk_size,
1517+
len - offset - chunk_size,
1518+
offset > 0);
1519+
14401520
ret = qcom_glink_tx(glink, &req, sizeof(req), data + offset, chunk_size, wait);
14411521
if (ret) {
14421522
/* Mark intent available if we failed */
@@ -1552,6 +1632,8 @@ static int qcom_glink_rx_open(struct qcom_glink *glink, unsigned int rcid,
15521632
create_device = true;
15531633
}
15541634

1635+
trace_qcom_glink_cmd_open_rx(glink->label, name, channel->lcid, rcid);
1636+
15551637
spin_lock_irqsave(&glink->idr_lock, flags);
15561638
ret = idr_alloc(&glink->rcids, channel, rcid, rcid + 1, GFP_ATOMIC);
15571639
if (ret < 0) {
@@ -1613,6 +1695,9 @@ static void qcom_glink_rx_close(struct qcom_glink *glink, unsigned int rcid)
16131695
spin_lock_irqsave(&glink->idr_lock, flags);
16141696
channel = idr_find(&glink->rcids, rcid);
16151697
spin_unlock_irqrestore(&glink->idr_lock, flags);
1698+
1699+
trace_qcom_glink_cmd_close_rx(glink->label, channel ? channel->name : NULL,
1700+
channel ? channel->lcid : 0, rcid);
16161701
if (WARN(!channel, "close request on unknown channel\n"))
16171702
return;
16181703

@@ -1649,6 +1734,9 @@ static void qcom_glink_rx_close_ack(struct qcom_glink *glink, unsigned int lcid)
16491734

16501735
spin_lock_irqsave(&glink->idr_lock, flags);
16511736
channel = idr_find(&glink->lcids, lcid);
1737+
1738+
trace_qcom_glink_cmd_close_ack_rx(glink->label, channel ? channel->name : NULL,
1739+
lcid, channel ? channel->rcid : 0);
16521740
if (WARN(!channel, "close ack on unknown channel\n")) {
16531741
spin_unlock_irqrestore(&glink->idr_lock, flags);
16541742
return;
@@ -1823,6 +1911,10 @@ struct qcom_glink *qcom_glink_native_probe(struct device *dev,
18231911
idr_init(&glink->lcids);
18241912
idr_init(&glink->rcids);
18251913

1914+
ret = of_property_read_string(dev->of_node, "label", &glink->label);
1915+
if (ret < 0)
1916+
glink->label = dev->of_node->name;
1917+
18261918
glink->dev->groups = qcom_glink_groups;
18271919

18281920
ret = device_add_groups(dev, qcom_glink_groups);

0 commit comments

Comments
 (0)