aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/trace.c
diff options
context:
space:
mode:
authorTuong Lien <tuong.t.lien@dektech.com.au>2018-12-18 21:17:56 -0500
committerDavid S. Miller <davem@davemloft.net>2018-12-19 14:49:24 -0500
commitb4b9771bcbbd5839b0f77aba55e2f85989ed6779 (patch)
tree4ff4e950e174540191a45b5b2cbfc5ef649f6baa /net/tipc/trace.c
parent4a54877ee767fe70a6966352c788fc5f405aa3c6 (diff)
tipc: enable tracepoints in tipc
As for the sake of debugging/tracing, the commit enables tracepoints in TIPC along with some general trace_events as shown below. It also defines some 'tipc_*_dump()' functions that allow to dump TIPC object data whenever needed, that is, for general debug purposes, ie. not just for the trace_events. The following trace_events are now available: - trace_tipc_skb_dump(): allows to trace and dump TIPC msg & skb data, e.g. message type, user, droppable, skb truesize, cloned skb, etc. - trace_tipc_list_dump(): allows to trace and dump any TIPC buffers or queues, e.g. TIPC link transmq, socket receive queue, etc. - trace_tipc_sk_dump(): allows to trace and dump TIPC socket data, e.g. sk state, sk type, connection type, rmem_alloc, socket queues, etc. - trace_tipc_link_dump(): allows to trace and dump TIPC link data, e.g. link state, silent_intv_cnt, gap, bc_gap, link queues, etc. - trace_tipc_node_dump(): allows to trace and dump TIPC node data, e.g. node state, active links, capabilities, link entries, etc. How to use: Put the trace functions at any places where we want to dump TIPC data or events. Note: a) The dump functions will generate raw data only, that is, to offload the trace event's processing, it can require a tool or script to parse the data but this should be simple. b) The trace_tipc_*_dump() should be reserved for a failure cases only (e.g. the retransmission failure case) or where we do not expect to happen too often, then we can consider enabling these events by default since they will almost not take any effects under normal conditions, but once the rare condition or failure occurs, we get the dumped data fully for post-analysis. For other trace purposes, we can reuse these trace classes as template but different events. c) A trace_event is only effective when we enable it. To enable the TIPC trace_events, echo 1 to 'enable' files in the events/tipc/ directory in the 'debugfs' file system. Normally, they are located at: /sys/kernel/debug/tracing/events/tipc/ For example: To enable the tipc_link_dump event: echo 1 > /sys/kernel/debug/tracing/events/tipc/tipc_link_dump/enable To enable all the TIPC trace_events: echo 1 > /sys/kernel/debug/tracing/events/tipc/enable To collect the trace data: cat trace or cat trace_pipe > /trace.out & To disable all the TIPC trace_events: echo 0 > /sys/kernel/debug/tracing/events/tipc/enable To clear the trace buffer: echo > trace d) Like the other trace_events, the feature like 'filter' or 'trigger' is also usable for the tipc trace_events. For more details, have a look at: Documentation/trace/ftrace.txt MAINTAINERS | add two new files 'trace.h' & 'trace.c' in tipc Acked-by: Ying Xue <ying.xue@windriver.com> Tested-by: Ying Xue <ying.xue@windriver.com> Acked-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: Tuong Lien <tuong.t.lien@dektech.com.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/trace.c')
-rw-r--r--net/tipc/trace.c200
1 files changed, 200 insertions, 0 deletions
diff --git a/net/tipc/trace.c b/net/tipc/trace.c
new file mode 100644
index 000000000000..846196f0e810
--- /dev/null
+++ b/net/tipc/trace.c
@@ -0,0 +1,200 @@
1/*
2 * net/tipc/trace.c: TIPC tracepoints code
3 *
4 * Copyright (c) 2018, Ericsson AB
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the names of the copyright holders nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * Alternatively, this software may be distributed under the terms of the
20 * GNU General Public License ("GPL") version 2 as published by the Free
21 * Software Foundation.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "ASIS"
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 */
35
36#define CREATE_TRACE_POINTS
37#include "trace.h"
38
39/**
40 * tipc_skb_dump - dump TIPC skb data
41 * @skb: skb to be dumped
42 * @more: dump more?
43 * - false: dump only tipc msg data
44 * - true: dump kernel-related skb data and tipc cb[] array as well
45 * @buf: returned buffer of dump data in format
46 */
47int tipc_skb_dump(struct sk_buff *skb, bool more, char *buf)
48{
49 int i = 0;
50 size_t sz = (more) ? SKB_LMAX : SKB_LMIN;
51 struct tipc_msg *hdr;
52 struct tipc_skb_cb *skbcb;
53
54 if (!skb) {
55 i += scnprintf(buf, sz, "msg: (null)\n");
56 return i;
57 }
58
59 hdr = buf_msg(skb);
60 skbcb = TIPC_SKB_CB(skb);
61
62 /* tipc msg data section */
63 i += scnprintf(buf, sz, "msg: %u", msg_user(hdr));
64 i += scnprintf(buf + i, sz - i, " %u", msg_type(hdr));
65 i += scnprintf(buf + i, sz - i, " %u", msg_hdr_sz(hdr));
66 i += scnprintf(buf + i, sz - i, " %u", msg_data_sz(hdr));
67 i += scnprintf(buf + i, sz - i, " %x", msg_orignode(hdr));
68 i += scnprintf(buf + i, sz - i, " %x", msg_destnode(hdr));
69 i += scnprintf(buf + i, sz - i, " %u", msg_seqno(hdr));
70 i += scnprintf(buf + i, sz - i, " %u", msg_ack(hdr));
71 i += scnprintf(buf + i, sz - i, " %u", msg_bcast_ack(hdr));
72 switch (msg_user(hdr)) {
73 case LINK_PROTOCOL:
74 i += scnprintf(buf + i, sz - i, " %c", msg_net_plane(hdr));
75 i += scnprintf(buf + i, sz - i, " %u", msg_probe(hdr));
76 i += scnprintf(buf + i, sz - i, " %u", msg_peer_stopping(hdr));
77 i += scnprintf(buf + i, sz - i, " %u", msg_session(hdr));
78 i += scnprintf(buf + i, sz - i, " %u", msg_next_sent(hdr));
79 i += scnprintf(buf + i, sz - i, " %u", msg_seq_gap(hdr));
80 i += scnprintf(buf + i, sz - i, " %u", msg_bc_snd_nxt(hdr));
81 i += scnprintf(buf + i, sz - i, " %u", msg_bc_gap(hdr));
82 break;
83 case TIPC_LOW_IMPORTANCE:
84 case TIPC_MEDIUM_IMPORTANCE:
85 case TIPC_HIGH_IMPORTANCE:
86 case TIPC_CRITICAL_IMPORTANCE:
87 case CONN_MANAGER:
88 case SOCK_WAKEUP:
89 i += scnprintf(buf + i, sz - i, " | %u", msg_origport(hdr));
90 i += scnprintf(buf + i, sz - i, " %u", msg_destport(hdr));
91 switch (msg_type(hdr)) {
92 case TIPC_NAMED_MSG:
93 i += scnprintf(buf + i, sz - i, " %u",
94 msg_nametype(hdr));
95 i += scnprintf(buf + i, sz - i, " %u",
96 msg_nameinst(hdr));
97 break;
98 case TIPC_MCAST_MSG:
99 i += scnprintf(buf + i, sz - i, " %u",
100 msg_nametype(hdr));
101 i += scnprintf(buf + i, sz - i, " %u",
102 msg_namelower(hdr));
103 i += scnprintf(buf + i, sz - i, " %u",
104 msg_nameupper(hdr));
105 break;
106 default:
107 break;
108 };
109 i += scnprintf(buf + i, sz - i, " | %u",
110 msg_src_droppable(hdr));
111 i += scnprintf(buf + i, sz - i, " %u",
112 msg_dest_droppable(hdr));
113 i += scnprintf(buf + i, sz - i, " %u", msg_errcode(hdr));
114 i += scnprintf(buf + i, sz - i, " %u", msg_reroute_cnt(hdr));
115 break;
116 default:
117 /* need more? */
118 break;
119 };
120
121 i += scnprintf(buf + i, sz - i, "\n");
122 if (!more)
123 return i;
124
125 /* kernel-related skb data section */
126 i += scnprintf(buf + i, sz - i, "skb: %s",
127 (skb->dev) ? skb->dev->name : "n/a");
128 i += scnprintf(buf + i, sz - i, " %u", skb->len);
129 i += scnprintf(buf + i, sz - i, " %u", skb->data_len);
130 i += scnprintf(buf + i, sz - i, " %u", skb->hdr_len);
131 i += scnprintf(buf + i, sz - i, " %u", skb->truesize);
132 i += scnprintf(buf + i, sz - i, " %u", skb_cloned(skb));
133 i += scnprintf(buf + i, sz - i, " %p", skb->sk);
134 i += scnprintf(buf + i, sz - i, " %u", skb_shinfo(skb)->nr_frags);
135 i += scnprintf(buf + i, sz - i, " %llx",
136 ktime_to_ms(skb_get_ktime(skb)));
137 i += scnprintf(buf + i, sz - i, " %llx\n",
138 ktime_to_ms(skb_hwtstamps(skb)->hwtstamp));
139
140 /* tipc skb cb[] data section */
141 i += scnprintf(buf + i, sz - i, "cb[]: %u", skbcb->bytes_read);
142 i += scnprintf(buf + i, sz - i, " %u", skbcb->orig_member);
143 i += scnprintf(buf + i, sz - i, " %u",
144 jiffies_to_msecs(skbcb->nxt_retr));
145 i += scnprintf(buf + i, sz - i, " %u", skbcb->validated);
146 i += scnprintf(buf + i, sz - i, " %u", skbcb->chain_imp);
147 i += scnprintf(buf + i, sz - i, " %u\n", skbcb->ackers);
148
149 return i;
150}
151
152/**
153 * tipc_list_dump - dump TIPC skb list/queue
154 * @list: list of skbs to be dumped
155 * @more: dump more?
156 * - false: dump only the head & tail skbs
157 * - true: dump the first & last 5 skbs
158 * @buf: returned buffer of dump data in format
159 */
160int tipc_list_dump(struct sk_buff_head *list, bool more, char *buf)
161{
162 int i = 0;
163 size_t sz = (more) ? LIST_LMAX : LIST_LMIN;
164 u32 count, len;
165 struct sk_buff *hskb, *tskb, *skb, *tmp;
166
167 if (!list) {
168 i += scnprintf(buf, sz, "(null)\n");
169 return i;
170 }
171
172 len = skb_queue_len(list);
173 i += scnprintf(buf, sz, "len = %d\n", len);
174
175 if (!len)
176 return i;
177
178 if (!more) {
179 hskb = skb_peek(list);
180 i += scnprintf(buf + i, sz - i, " head ");
181 i += tipc_skb_dump(hskb, false, buf + i);
182 if (len > 1) {
183 tskb = skb_peek_tail(list);
184 i += scnprintf(buf + i, sz - i, " tail ");
185 i += tipc_skb_dump(tskb, false, buf + i);
186 }
187 } else {
188 count = 0;
189 skb_queue_walk_safe(list, skb, tmp) {
190 count++;
191 if (count == 6)
192 i += scnprintf(buf + i, sz - i, " .\n .\n");
193 if (count > 5 && count <= len - 5)
194 continue;
195 i += scnprintf(buf + i, sz - i, " #%d ", count);
196 i += tipc_skb_dump(skb, false, buf + i);
197 }
198 }
199 return i;
200}