aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
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
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')
-rw-r--r--net/tipc/Makefile4
-rw-r--r--net/tipc/bearer.c7
-rw-r--r--net/tipc/bearer.h2
-rw-r--r--net/tipc/link.c120
-rw-r--r--net/tipc/link.h1
-rw-r--r--net/tipc/node.c63
-rw-r--r--net/tipc/node.h1
-rw-r--r--net/tipc/socket.c90
-rw-r--r--net/tipc/socket.h2
-rw-r--r--net/tipc/trace.c200
-rw-r--r--net/tipc/trace.h231
11 files changed, 716 insertions, 5 deletions
diff --git a/net/tipc/Makefile b/net/tipc/Makefile
index aca168f2abb1..c86aba0282af 100644
--- a/net/tipc/Makefile
+++ b/net/tipc/Makefile
@@ -9,7 +9,9 @@ tipc-y += addr.o bcast.o bearer.o \
9 core.o link.o discover.o msg.o \ 9 core.o link.o discover.o msg.o \
10 name_distr.o subscr.o monitor.o name_table.o net.o \ 10 name_distr.o subscr.o monitor.o name_table.o net.o \
11 netlink.o netlink_compat.o node.o socket.o eth_media.o \ 11 netlink.o netlink_compat.o node.o socket.o eth_media.o \
12 topsrv.o socket.o group.o 12 topsrv.o socket.o group.o trace.o
13
14CFLAGS_trace.o += -I$(src)
13 15
14tipc-$(CONFIG_TIPC_MEDIA_UDP) += udp_media.o 16tipc-$(CONFIG_TIPC_MEDIA_UDP) += udp_media.o
15tipc-$(CONFIG_TIPC_MEDIA_IB) += ib_media.o 17tipc-$(CONFIG_TIPC_MEDIA_IB) += ib_media.o
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index e65c3a8551e4..e32294f37c29 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -99,7 +99,7 @@ static struct tipc_media *media_find_id(u8 type)
99/** 99/**
100 * tipc_media_addr_printf - record media address in print buffer 100 * tipc_media_addr_printf - record media address in print buffer
101 */ 101 */
102void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a) 102int tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a)
103{ 103{
104 char addr_str[MAX_ADDR_STR]; 104 char addr_str[MAX_ADDR_STR];
105 struct tipc_media *m; 105 struct tipc_media *m;
@@ -114,9 +114,10 @@ void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a)
114 114
115 ret = scnprintf(buf, len, "UNKNOWN(%u)", a->media_id); 115 ret = scnprintf(buf, len, "UNKNOWN(%u)", a->media_id);
116 for (i = 0; i < sizeof(a->value); i++) 116 for (i = 0; i < sizeof(a->value); i++)
117 ret += scnprintf(buf - ret, len + ret, 117 ret += scnprintf(buf + ret, len - ret,
118 "-%02x", a->value[i]); 118 "-%x", a->value[i]);
119 } 119 }
120 return ret;
120} 121}
121 122
122/** 123/**
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index 394290cbbb1d..7f4c569594a5 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -207,7 +207,7 @@ int __tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info);
207 207
208int tipc_media_set_priority(const char *name, u32 new_value); 208int tipc_media_set_priority(const char *name, u32 new_value);
209int tipc_media_set_window(const char *name, u32 new_value); 209int tipc_media_set_window(const char *name, u32 new_value);
210void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a); 210int tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a);
211int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b, 211int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b,
212 struct nlattr *attrs[]); 212 struct nlattr *attrs[]);
213void tipc_disable_l2_media(struct tipc_bearer *b); 213void tipc_disable_l2_media(struct tipc_bearer *b);
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 9e265eb89726..668dab529021 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -43,6 +43,7 @@
43#include "discover.h" 43#include "discover.h"
44#include "netlink.h" 44#include "netlink.h"
45#include "monitor.h" 45#include "monitor.h"
46#include "trace.h"
46 47
47#include <linux/pkt_sched.h> 48#include <linux/pkt_sched.h>
48 49
@@ -2222,3 +2223,122 @@ void tipc_link_set_abort_limit(struct tipc_link *l, u32 limit)
2222{ 2223{
2223 l->abort_limit = limit; 2224 l->abort_limit = limit;
2224} 2225}
2226
2227char *tipc_link_name_ext(struct tipc_link *l, char *buf)
2228{
2229 if (!l)
2230 scnprintf(buf, TIPC_MAX_LINK_NAME, "null");
2231 else if (link_is_bc_sndlink(l))
2232 scnprintf(buf, TIPC_MAX_LINK_NAME, "broadcast-sender");
2233 else if (link_is_bc_rcvlink(l))
2234 scnprintf(buf, TIPC_MAX_LINK_NAME,
2235 "broadcast-receiver, peer %x", l->addr);
2236 else
2237 memcpy(buf, l->name, TIPC_MAX_LINK_NAME);
2238
2239 return buf;
2240}
2241
2242/**
2243 * tipc_link_dump - dump TIPC link data
2244 * @l: tipc link to be dumped
2245 * @dqueues: bitmask to decide if any link queue to be dumped?
2246 * - TIPC_DUMP_NONE: don't dump link queues
2247 * - TIPC_DUMP_TRANSMQ: dump link transmq queue
2248 * - TIPC_DUMP_BACKLOGQ: dump link backlog queue
2249 * - TIPC_DUMP_DEFERDQ: dump link deferd queue
2250 * - TIPC_DUMP_INPUTQ: dump link input queue
2251 * - TIPC_DUMP_WAKEUP: dump link wakeup queue
2252 * - TIPC_DUMP_ALL: dump all the link queues above
2253 * @buf: returned buffer of dump data in format
2254 */
2255int tipc_link_dump(struct tipc_link *l, u16 dqueues, char *buf)
2256{
2257 int i = 0;
2258 size_t sz = (dqueues) ? LINK_LMAX : LINK_LMIN;
2259 struct sk_buff_head *list;
2260 struct sk_buff *hskb, *tskb;
2261 u32 len;
2262
2263 if (!l) {
2264 i += scnprintf(buf, sz, "link data: (null)\n");
2265 return i;
2266 }
2267
2268 i += scnprintf(buf, sz, "link data: %x", l->addr);
2269 i += scnprintf(buf + i, sz - i, " %x", l->state);
2270 i += scnprintf(buf + i, sz - i, " %u", l->in_session);
2271 i += scnprintf(buf + i, sz - i, " %u", l->session);
2272 i += scnprintf(buf + i, sz - i, " %u", l->peer_session);
2273 i += scnprintf(buf + i, sz - i, " %u", l->snd_nxt);
2274 i += scnprintf(buf + i, sz - i, " %u", l->rcv_nxt);
2275 i += scnprintf(buf + i, sz - i, " %u", l->snd_nxt_state);
2276 i += scnprintf(buf + i, sz - i, " %u", l->rcv_nxt_state);
2277 i += scnprintf(buf + i, sz - i, " %x", l->peer_caps);
2278 i += scnprintf(buf + i, sz - i, " %u", l->silent_intv_cnt);
2279 i += scnprintf(buf + i, sz - i, " %u", l->rst_cnt);
2280 i += scnprintf(buf + i, sz - i, " %u", l->prev_from);
2281 i += scnprintf(buf + i, sz - i, " %u", l->stale_cnt);
2282 i += scnprintf(buf + i, sz - i, " %u", l->acked);
2283
2284 list = &l->transmq;
2285 len = skb_queue_len(list);
2286 hskb = skb_peek(list);
2287 tskb = skb_peek_tail(list);
2288 i += scnprintf(buf + i, sz - i, " | %u %u %u", len,
2289 (hskb) ? msg_seqno(buf_msg(hskb)) : 0,
2290 (tskb) ? msg_seqno(buf_msg(tskb)) : 0);
2291
2292 list = &l->deferdq;
2293 len = skb_queue_len(list);
2294 hskb = skb_peek(list);
2295 tskb = skb_peek_tail(list);
2296 i += scnprintf(buf + i, sz - i, " | %u %u %u", len,
2297 (hskb) ? msg_seqno(buf_msg(hskb)) : 0,
2298 (tskb) ? msg_seqno(buf_msg(tskb)) : 0);
2299
2300 list = &l->backlogq;
2301 len = skb_queue_len(list);
2302 hskb = skb_peek(list);
2303 tskb = skb_peek_tail(list);
2304 i += scnprintf(buf + i, sz - i, " | %u %u %u", len,
2305 (hskb) ? msg_seqno(buf_msg(hskb)) : 0,
2306 (tskb) ? msg_seqno(buf_msg(tskb)) : 0);
2307
2308 list = l->inputq;
2309 len = skb_queue_len(list);
2310 hskb = skb_peek(list);
2311 tskb = skb_peek_tail(list);
2312 i += scnprintf(buf + i, sz - i, " | %u %u %u\n", len,
2313 (hskb) ? msg_seqno(buf_msg(hskb)) : 0,
2314 (tskb) ? msg_seqno(buf_msg(tskb)) : 0);
2315
2316 if (dqueues & TIPC_DUMP_TRANSMQ) {
2317 i += scnprintf(buf + i, sz - i, "transmq: ");
2318 i += tipc_list_dump(&l->transmq, false, buf + i);
2319 }
2320 if (dqueues & TIPC_DUMP_BACKLOGQ) {
2321 i += scnprintf(buf + i, sz - i,
2322 "backlogq: <%u %u %u %u %u>, ",
2323 l->backlog[TIPC_LOW_IMPORTANCE].len,
2324 l->backlog[TIPC_MEDIUM_IMPORTANCE].len,
2325 l->backlog[TIPC_HIGH_IMPORTANCE].len,
2326 l->backlog[TIPC_CRITICAL_IMPORTANCE].len,
2327 l->backlog[TIPC_SYSTEM_IMPORTANCE].len);
2328 i += tipc_list_dump(&l->backlogq, false, buf + i);
2329 }
2330 if (dqueues & TIPC_DUMP_DEFERDQ) {
2331 i += scnprintf(buf + i, sz - i, "deferdq: ");
2332 i += tipc_list_dump(&l->deferdq, false, buf + i);
2333 }
2334 if (dqueues & TIPC_DUMP_INPUTQ) {
2335 i += scnprintf(buf + i, sz - i, "inputq: ");
2336 i += tipc_list_dump(l->inputq, false, buf + i);
2337 }
2338 if (dqueues & TIPC_DUMP_WAKEUP) {
2339 i += scnprintf(buf + i, sz - i, "wakeup: ");
2340 i += tipc_list_dump(&l->wakeupq, false, buf + i);
2341 }
2342
2343 return i;
2344}
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 90488c538a4e..e8f692598e4d 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -109,6 +109,7 @@ u16 tipc_link_rcv_nxt(struct tipc_link *l);
109u16 tipc_link_acked(struct tipc_link *l); 109u16 tipc_link_acked(struct tipc_link *l);
110u32 tipc_link_id(struct tipc_link *l); 110u32 tipc_link_id(struct tipc_link *l);
111char *tipc_link_name(struct tipc_link *l); 111char *tipc_link_name(struct tipc_link *l);
112char *tipc_link_name_ext(struct tipc_link *l, char *buf);
112u32 tipc_link_state(struct tipc_link *l); 113u32 tipc_link_state(struct tipc_link *l);
113char tipc_link_plane(struct tipc_link *l); 114char tipc_link_plane(struct tipc_link *l);
114int tipc_link_prio(struct tipc_link *l); 115int tipc_link_prio(struct tipc_link *l);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 5980abb7839b..4fd6e2887818 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -43,6 +43,7 @@
43#include "monitor.h" 43#include "monitor.h"
44#include "discover.h" 44#include "discover.h"
45#include "netlink.h" 45#include "netlink.h"
46#include "trace.h"
46 47
47#define INVALID_NODE_SIG 0x10000 48#define INVALID_NODE_SIG 0x10000
48#define NODE_CLEANUP_AFTER 300000 49#define NODE_CLEANUP_AFTER 300000
@@ -2435,3 +2436,65 @@ int tipc_nl_node_dump_monitor_peer(struct sk_buff *skb,
2435 2436
2436 return skb->len; 2437 return skb->len;
2437} 2438}
2439
2440u32 tipc_node_get_addr(struct tipc_node *node)
2441{
2442 return (node) ? node->addr : 0;
2443}
2444
2445/**
2446 * tipc_node_dump - dump TIPC node data
2447 * @n: tipc node to be dumped
2448 * @more: dump more?
2449 * - false: dump only tipc node data
2450 * - true: dump node link data as well
2451 * @buf: returned buffer of dump data in format
2452 */
2453int tipc_node_dump(struct tipc_node *n, bool more, char *buf)
2454{
2455 int i = 0;
2456 size_t sz = (more) ? NODE_LMAX : NODE_LMIN;
2457
2458 if (!n) {
2459 i += scnprintf(buf, sz, "node data: (null)\n");
2460 return i;
2461 }
2462
2463 i += scnprintf(buf, sz, "node data: %x", n->addr);
2464 i += scnprintf(buf + i, sz - i, " %x", n->state);
2465 i += scnprintf(buf + i, sz - i, " %d", n->active_links[0]);
2466 i += scnprintf(buf + i, sz - i, " %d", n->active_links[1]);
2467 i += scnprintf(buf + i, sz - i, " %x", n->action_flags);
2468 i += scnprintf(buf + i, sz - i, " %u", n->failover_sent);
2469 i += scnprintf(buf + i, sz - i, " %u", n->sync_point);
2470 i += scnprintf(buf + i, sz - i, " %d", n->link_cnt);
2471 i += scnprintf(buf + i, sz - i, " %u", n->working_links);
2472 i += scnprintf(buf + i, sz - i, " %x", n->capabilities);
2473 i += scnprintf(buf + i, sz - i, " %lu\n", n->keepalive_intv);
2474
2475 if (!more)
2476 return i;
2477
2478 i += scnprintf(buf + i, sz - i, "link_entry[0]:\n");
2479 i += scnprintf(buf + i, sz - i, " mtu: %u\n", n->links[0].mtu);
2480 i += scnprintf(buf + i, sz - i, " media: ");
2481 i += tipc_media_addr_printf(buf + i, sz - i, &n->links[0].maddr);
2482 i += scnprintf(buf + i, sz - i, "\n");
2483 i += tipc_link_dump(n->links[0].link, TIPC_DUMP_NONE, buf + i);
2484 i += scnprintf(buf + i, sz - i, " inputq: ");
2485 i += tipc_list_dump(&n->links[0].inputq, false, buf + i);
2486
2487 i += scnprintf(buf + i, sz - i, "link_entry[1]:\n");
2488 i += scnprintf(buf + i, sz - i, " mtu: %u\n", n->links[1].mtu);
2489 i += scnprintf(buf + i, sz - i, " media: ");
2490 i += tipc_media_addr_printf(buf + i, sz - i, &n->links[1].maddr);
2491 i += scnprintf(buf + i, sz - i, "\n");
2492 i += tipc_link_dump(n->links[1].link, TIPC_DUMP_NONE, buf + i);
2493 i += scnprintf(buf + i, sz - i, " inputq: ");
2494 i += tipc_list_dump(&n->links[1].inputq, false, buf + i);
2495
2496 i += scnprintf(buf + i, sz - i, "bclink:\n ");
2497 i += tipc_link_dump(n->bc_entry.link, TIPC_DUMP_NONE, buf + i);
2498
2499 return i;
2500}
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 03f5efb62cfb..4f59a30e989a 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -65,6 +65,7 @@ enum {
65 65
66void tipc_node_stop(struct net *net); 66void tipc_node_stop(struct net *net);
67bool tipc_node_get_id(struct net *net, u32 addr, u8 *id); 67bool tipc_node_get_id(struct net *net, u32 addr, u8 *id);
68u32 tipc_node_get_addr(struct tipc_node *node);
68u32 tipc_node_try_addr(struct net *net, u8 *id, u32 addr); 69u32 tipc_node_try_addr(struct net *net, u8 *id, u32 addr);
69void tipc_node_check_dest(struct net *net, u32 onode, u8 *peer_id128, 70void tipc_node_check_dest(struct net *net, u32 onode, u8 *peer_id128,
70 struct tipc_bearer *bearer, 71 struct tipc_bearer *bearer,
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index b57b1be7252b..b6b2a94eb54e 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -46,6 +46,7 @@
46#include "bcast.h" 46#include "bcast.h"
47#include "netlink.h" 47#include "netlink.h"
48#include "group.h" 48#include "group.h"
49#include "trace.h"
49 50
50#define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */ 51#define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */
51#define CONN_PROBING_INTV msecs_to_jiffies(3600000) /* [ms] => 1 h */ 52#define CONN_PROBING_INTV msecs_to_jiffies(3600000) /* [ms] => 1 h */
@@ -3564,3 +3565,92 @@ int tipc_nl_publ_dump(struct sk_buff *skb, struct netlink_callback *cb)
3564 3565
3565 return skb->len; 3566 return skb->len;
3566} 3567}
3568
3569u32 tipc_sock_get_portid(struct sock *sk)
3570{
3571 return (sk) ? (tipc_sk(sk))->portid : 0;
3572}
3573
3574/**
3575 * tipc_sk_dump - dump TIPC socket
3576 * @sk: tipc sk to be dumped
3577 * @dqueues: bitmask to decide if any socket queue to be dumped?
3578 * - TIPC_DUMP_NONE: don't dump socket queues
3579 * - TIPC_DUMP_SK_SNDQ: dump socket send queue
3580 * - TIPC_DUMP_SK_RCVQ: dump socket rcv queue
3581 * - TIPC_DUMP_SK_BKLGQ: dump socket backlog queue
3582 * - TIPC_DUMP_ALL: dump all the socket queues above
3583 * @buf: returned buffer of dump data in format
3584 */
3585int tipc_sk_dump(struct sock *sk, u16 dqueues, char *buf)
3586{
3587 int i = 0;
3588 size_t sz = (dqueues) ? SK_LMAX : SK_LMIN;
3589 struct tipc_sock *tsk;
3590 struct publication *p;
3591 bool tsk_connected;
3592
3593 if (!sk) {
3594 i += scnprintf(buf, sz, "sk data: (null)\n");
3595 return i;
3596 }
3597
3598 tsk = tipc_sk(sk);
3599 tsk_connected = !tipc_sk_type_connectionless(sk);
3600
3601 i += scnprintf(buf, sz, "sk data: %u", sk->sk_type);
3602 i += scnprintf(buf + i, sz - i, " %d", sk->sk_state);
3603 i += scnprintf(buf + i, sz - i, " %x", tsk_own_node(tsk));
3604 i += scnprintf(buf + i, sz - i, " %u", tsk->portid);
3605 i += scnprintf(buf + i, sz - i, " | %u", tsk_connected);
3606 if (tsk_connected) {
3607 i += scnprintf(buf + i, sz - i, " %x", tsk_peer_node(tsk));
3608 i += scnprintf(buf + i, sz - i, " %u", tsk_peer_port(tsk));
3609 i += scnprintf(buf + i, sz - i, " %u", tsk->conn_type);
3610 i += scnprintf(buf + i, sz - i, " %u", tsk->conn_instance);
3611 }
3612 i += scnprintf(buf + i, sz - i, " | %u", tsk->published);
3613 if (tsk->published) {
3614 p = list_first_entry_or_null(&tsk->publications,
3615 struct publication, binding_sock);
3616 i += scnprintf(buf + i, sz - i, " %u", (p) ? p->type : 0);
3617 i += scnprintf(buf + i, sz - i, " %u", (p) ? p->lower : 0);
3618 i += scnprintf(buf + i, sz - i, " %u", (p) ? p->upper : 0);
3619 }
3620 i += scnprintf(buf + i, sz - i, " | %u", tsk->snd_win);
3621 i += scnprintf(buf + i, sz - i, " %u", tsk->rcv_win);
3622 i += scnprintf(buf + i, sz - i, " %u", tsk->max_pkt);
3623 i += scnprintf(buf + i, sz - i, " %x", tsk->peer_caps);
3624 i += scnprintf(buf + i, sz - i, " %u", tsk->cong_link_cnt);
3625 i += scnprintf(buf + i, sz - i, " %u", tsk->snt_unacked);
3626 i += scnprintf(buf + i, sz - i, " %u", tsk->rcv_unacked);
3627 i += scnprintf(buf + i, sz - i, " %u", atomic_read(&tsk->dupl_rcvcnt));
3628 i += scnprintf(buf + i, sz - i, " %u", sk->sk_shutdown);
3629 i += scnprintf(buf + i, sz - i, " | %d", sk_wmem_alloc_get(sk));
3630 i += scnprintf(buf + i, sz - i, " %d", sk->sk_sndbuf);
3631 i += scnprintf(buf + i, sz - i, " | %d", sk_rmem_alloc_get(sk));
3632 i += scnprintf(buf + i, sz - i, " %d", sk->sk_rcvbuf);
3633 i += scnprintf(buf + i, sz - i, " | %d\n", sk->sk_backlog.len);
3634
3635 if (dqueues & TIPC_DUMP_SK_SNDQ) {
3636 i += scnprintf(buf + i, sz - i, "sk_write_queue: ");
3637 i += tipc_list_dump(&sk->sk_write_queue, false, buf + i);
3638 }
3639
3640 if (dqueues & TIPC_DUMP_SK_RCVQ) {
3641 i += scnprintf(buf + i, sz - i, "sk_receive_queue: ");
3642 i += tipc_list_dump(&sk->sk_receive_queue, false, buf + i);
3643 }
3644
3645 if (dqueues & TIPC_DUMP_SK_BKLGQ) {
3646 i += scnprintf(buf + i, sz - i, "sk_backlog:\n head ");
3647 i += tipc_skb_dump(sk->sk_backlog.head, false, buf + i);
3648 if (sk->sk_backlog.tail != sk->sk_backlog.head) {
3649 i += scnprintf(buf + i, sz - i, " tail ");
3650 i += tipc_skb_dump(sk->sk_backlog.tail, false,
3651 buf + i);
3652 }
3653 }
3654
3655 return i;
3656}
diff --git a/net/tipc/socket.h b/net/tipc/socket.h
index 5e575f205afe..07e36545b696 100644
--- a/net/tipc/socket.h
+++ b/net/tipc/socket.h
@@ -71,4 +71,6 @@ int tipc_nl_sk_walk(struct sk_buff *skb, struct netlink_callback *cb,
71int tipc_dump_start(struct netlink_callback *cb); 71int tipc_dump_start(struct netlink_callback *cb);
72int __tipc_dump_start(struct netlink_callback *cb, struct net *net); 72int __tipc_dump_start(struct netlink_callback *cb, struct net *net);
73int tipc_dump_done(struct netlink_callback *cb); 73int tipc_dump_done(struct netlink_callback *cb);
74u32 tipc_sock_get_portid(struct sock *sk);
75
74#endif 76#endif
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}
diff --git a/net/tipc/trace.h b/net/tipc/trace.h
new file mode 100644
index 000000000000..4c74927df685
--- /dev/null
+++ b/net/tipc/trace.h
@@ -0,0 +1,231 @@
1/*
2 * net/tipc/trace.h: TIPC tracepoints
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#undef TRACE_SYSTEM
37#define TRACE_SYSTEM tipc
38
39#if !defined(_TIPC_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
40#define _TIPC_TRACE_H
41
42#include <linux/tracepoint.h>
43#include "core.h"
44#include "link.h"
45#include "socket.h"
46#include "node.h"
47
48#define SKB_LMIN (100)
49#define SKB_LMAX (SKB_LMIN * 2)
50#define LIST_LMIN (SKB_LMIN * 3)
51#define LIST_LMAX (SKB_LMIN * 11)
52#define SK_LMIN (SKB_LMIN * 2)
53#define SK_LMAX (SKB_LMIN * 11)
54#define LINK_LMIN (SKB_LMIN)
55#define LINK_LMAX (SKB_LMIN * 16)
56#define NODE_LMIN (SKB_LMIN)
57#define NODE_LMAX (SKB_LMIN * 11)
58
59#ifndef __TIPC_TRACE_ENUM
60#define __TIPC_TRACE_ENUM
61enum {
62 TIPC_DUMP_NONE = 0,
63
64 TIPC_DUMP_TRANSMQ = 1,
65 TIPC_DUMP_BACKLOGQ = (1 << 1),
66 TIPC_DUMP_DEFERDQ = (1 << 2),
67 TIPC_DUMP_INPUTQ = (1 << 3),
68 TIPC_DUMP_WAKEUP = (1 << 4),
69
70 TIPC_DUMP_SK_SNDQ = (1 << 8),
71 TIPC_DUMP_SK_RCVQ = (1 << 9),
72 TIPC_DUMP_SK_BKLGQ = (1 << 10),
73 TIPC_DUMP_ALL = 0xffffu
74};
75#endif
76
77int tipc_skb_dump(struct sk_buff *skb, bool more, char *buf);
78int tipc_list_dump(struct sk_buff_head *list, bool more, char *buf);
79int tipc_sk_dump(struct sock *sk, u16 dqueues, char *buf);
80int tipc_link_dump(struct tipc_link *l, u16 dqueues, char *buf);
81int tipc_node_dump(struct tipc_node *n, bool more, char *buf);
82
83DECLARE_EVENT_CLASS(tipc_skb_class,
84
85 TP_PROTO(struct sk_buff *skb, bool more, const char *header),
86
87 TP_ARGS(skb, more, header),
88
89 TP_STRUCT__entry(
90 __string(header, header)
91 __dynamic_array(char, buf, (more) ? SKB_LMAX : SKB_LMIN)
92 ),
93
94 TP_fast_assign(
95 __assign_str(header, header);
96 tipc_skb_dump(skb, more, __get_str(buf));
97 ),
98
99 TP_printk("%s\n%s", __get_str(header), __get_str(buf))
100)
101
102#define DEFINE_SKB_EVENT(name) \
103DEFINE_EVENT(tipc_skb_class, name, \
104 TP_PROTO(struct sk_buff *skb, bool more, const char *header), \
105 TP_ARGS(skb, more, header))
106DEFINE_SKB_EVENT(tipc_skb_dump);
107
108DECLARE_EVENT_CLASS(tipc_list_class,
109
110 TP_PROTO(struct sk_buff_head *list, bool more, const char *header),
111
112 TP_ARGS(list, more, header),
113
114 TP_STRUCT__entry(
115 __string(header, header)
116 __dynamic_array(char, buf, (more) ? LIST_LMAX : LIST_LMIN)
117 ),
118
119 TP_fast_assign(
120 __assign_str(header, header);
121 tipc_list_dump(list, more, __get_str(buf));
122 ),
123
124 TP_printk("%s\n%s", __get_str(header), __get_str(buf))
125);
126
127#define DEFINE_LIST_EVENT(name) \
128DEFINE_EVENT(tipc_list_class, name, \
129 TP_PROTO(struct sk_buff_head *list, bool more, const char *header), \
130 TP_ARGS(list, more, header))
131DEFINE_LIST_EVENT(tipc_list_dump);
132
133DECLARE_EVENT_CLASS(tipc_sk_class,
134
135 TP_PROTO(struct sock *sk, struct sk_buff *skb, u16 dqueues,
136 const char *header),
137
138 TP_ARGS(sk, skb, dqueues, header),
139
140 TP_STRUCT__entry(
141 __string(header, header)
142 __field(u32, portid)
143 __dynamic_array(char, buf, (dqueues) ? SK_LMAX : SK_LMIN)
144 __dynamic_array(char, skb_buf, (skb) ? SKB_LMIN : 1)
145 ),
146
147 TP_fast_assign(
148 __assign_str(header, header);
149 __entry->portid = tipc_sock_get_portid(sk);
150 tipc_sk_dump(sk, dqueues, __get_str(buf));
151 if (skb)
152 tipc_skb_dump(skb, false, __get_str(skb_buf));
153 else
154 *(__get_str(skb_buf)) = '\0';
155 ),
156
157 TP_printk("<%u> %s\n%s%s", __entry->portid, __get_str(header),
158 __get_str(skb_buf), __get_str(buf))
159);
160
161#define DEFINE_SK_EVENT(name) \
162DEFINE_EVENT(tipc_sk_class, name, \
163 TP_PROTO(struct sock *sk, struct sk_buff *skb, u16 dqueues, \
164 const char *header), \
165 TP_ARGS(sk, skb, dqueues, header))
166DEFINE_SK_EVENT(tipc_sk_dump);
167
168DECLARE_EVENT_CLASS(tipc_link_class,
169
170 TP_PROTO(struct tipc_link *l, u16 dqueues, const char *header),
171
172 TP_ARGS(l, dqueues, header),
173
174 TP_STRUCT__entry(
175 __string(header, header)
176 __array(char, name, TIPC_MAX_LINK_NAME)
177 __dynamic_array(char, buf, (dqueues) ? LINK_LMAX : LINK_LMIN)
178 ),
179
180 TP_fast_assign(
181 __assign_str(header, header);
182 tipc_link_name_ext(l, __entry->name);
183 tipc_link_dump(l, dqueues, __get_str(buf));
184 ),
185
186 TP_printk("<%s> %s\n%s", __entry->name, __get_str(header),
187 __get_str(buf))
188);
189
190#define DEFINE_LINK_EVENT(name) \
191DEFINE_EVENT(tipc_link_class, name, \
192 TP_PROTO(struct tipc_link *l, u16 dqueues, const char *header), \
193 TP_ARGS(l, dqueues, header))
194DEFINE_LINK_EVENT(tipc_link_dump);
195
196DECLARE_EVENT_CLASS(tipc_node_class,
197
198 TP_PROTO(struct tipc_node *n, bool more, const char *header),
199
200 TP_ARGS(n, more, header),
201
202 TP_STRUCT__entry(
203 __string(header, header)
204 __field(u32, addr)
205 __dynamic_array(char, buf, (more) ? NODE_LMAX : NODE_LMIN)
206 ),
207
208 TP_fast_assign(
209 __assign_str(header, header);
210 __entry->addr = tipc_node_get_addr(n);
211 tipc_node_dump(n, more, __get_str(buf));
212 ),
213
214 TP_printk("<%x> %s\n%s", __entry->addr, __get_str(header),
215 __get_str(buf))
216);
217
218#define DEFINE_NODE_EVENT(name) \
219DEFINE_EVENT(tipc_node_class, name, \
220 TP_PROTO(struct tipc_node *n, bool more, const char *header), \
221 TP_ARGS(n, more, header))
222DEFINE_NODE_EVENT(tipc_node_dump);
223
224#endif /* _TIPC_TRACE_H */
225
226/* This part must be outside protection */
227#undef TRACE_INCLUDE_PATH
228#define TRACE_INCLUDE_PATH .
229#undef TRACE_INCLUDE_FILE
230#define TRACE_INCLUDE_FILE trace
231#include <trace/define_trace.h>