From patchwork Wed Dec 19 02:17:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tuong Lien X-Patchwork-Id: 1015800 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=dektech.com.au Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=dektech.com.au header.i=@dektech.com.au header.b="JFQ+lgPl"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43KJlb02Nvz9s2P for ; Wed, 19 Dec 2018 13:30:35 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726981AbeLSCad (ORCPT ); Tue, 18 Dec 2018 21:30:33 -0500 Received: from f0-dek.dektech.com.au ([210.10.221.142]:39711 "EHLO mail.dektech.com.au" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726718AbeLSCab (ORCPT ); Tue, 18 Dec 2018 21:30:31 -0500 Received: from localhost (localhost [127.0.0.1]) by mail.dektech.com.au (Postfix) with ESMTP id 5770BF77A7; Wed, 19 Dec 2018 13:18:10 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=dektech.com.au; h=references:in-reply-to:x-mailer:message-id:date:date:subject :subject:from:from:received:received:received; s=mail_dkim; t= 1545185890; bh=NHelAOTjLb9POotNTH03Rts9bJYB8dF7542WyfabyiI=; b=J FQ+lgPlAYDGziqGZaqYM0KfU/2b1Arhocg1EU/g7+IfP/WfAMitm9rmBgyK7XbfC RtENpiJj2kXuwIFAxqhAwzha+jIziWgSiMbRLkh3C1TZWWIQWLMpyDpXMKsUhJP3 smGy46YR6jFXBu4yGpkmdipjuFOB2VOKDpaswJQNE8= X-Virus-Scanned: amavisd-new at dektech.com.au Received: from mail.dektech.com.au ([127.0.0.1]) by localhost (mail2.dektech.com.au [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id 99xPNEp8daZw; Wed, 19 Dec 2018 13:18:10 +1100 (AEDT) Received: from mail.dektech.com.au (localhost [127.0.0.1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.dektech.com.au (Postfix) with ESMTPS id 292ACF77A0; Wed, 19 Dec 2018 13:18:10 +1100 (AEDT) Received: from localhost.localdomain (unknown [14.161.14.188]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) by mail.dektech.com.au (Postfix) with ESMTPSA id 9B890F77A7; Wed, 19 Dec 2018 13:18:08 +1100 (AEDT) From: Tuong Lien To: davem@davemloft.net, jon.maloy@ericsson.com, netdev@vger.kernel.org Cc: tipc-discussion@lists.sourceforge.net Subject: [net-next 1/5] tipc: enable tracepoints in tipc Date: Wed, 19 Dec 2018 09:17:56 +0700 Message-Id: <20181219021800.21662-2-tuong.t.lien@dektech.com.au> X-Mailer: git-send-email 2.13.7 In-Reply-To: <20181219021800.21662-1-tuong.t.lien@dektech.com.au> References: <20181219021800.21662-1-tuong.t.lien@dektech.com.au> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org 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 Tested-by: Ying Xue Acked-by: Jon Maloy Signed-off-by: Tuong Lien --- net/tipc/Makefile | 4 +- net/tipc/bearer.c | 7 +- net/tipc/bearer.h | 2 +- net/tipc/link.c | 120 ++++++++++++++++++++++++++++ net/tipc/link.h | 1 + net/tipc/node.c | 63 +++++++++++++++ net/tipc/node.h | 1 + net/tipc/socket.c | 90 +++++++++++++++++++++ net/tipc/socket.h | 2 + net/tipc/trace.c | 200 ++++++++++++++++++++++++++++++++++++++++++++++ net/tipc/trace.h | 231 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 11 files changed, 716 insertions(+), 5 deletions(-) create mode 100644 net/tipc/trace.c create mode 100644 net/tipc/trace.h 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 \ core.o link.o discover.o msg.o \ name_distr.o subscr.o monitor.o name_table.o net.o \ netlink.o netlink_compat.o node.o socket.o eth_media.o \ - topsrv.o socket.o group.o + topsrv.o socket.o group.o trace.o + +CFLAGS_trace.o += -I$(src) tipc-$(CONFIG_TIPC_MEDIA_UDP) += udp_media.o tipc-$(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) /** * tipc_media_addr_printf - record media address in print buffer */ -void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a) +int tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a) { char addr_str[MAX_ADDR_STR]; struct tipc_media *m; @@ -114,9 +114,10 @@ void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a) ret = scnprintf(buf, len, "UNKNOWN(%u)", a->media_id); for (i = 0; i < sizeof(a->value); i++) - ret += scnprintf(buf - ret, len + ret, - "-%02x", a->value[i]); + ret += scnprintf(buf + ret, len - ret, + "-%x", a->value[i]); } + return ret; } /** 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); int tipc_media_set_priority(const char *name, u32 new_value); int tipc_media_set_window(const char *name, u32 new_value); -void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a); +int tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a); int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b, struct nlattr *attrs[]); void 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 @@ #include "discover.h" #include "netlink.h" #include "monitor.h" +#include "trace.h" #include @@ -2222,3 +2223,122 @@ void tipc_link_set_abort_limit(struct tipc_link *l, u32 limit) { l->abort_limit = limit; } + +char *tipc_link_name_ext(struct tipc_link *l, char *buf) +{ + if (!l) + scnprintf(buf, TIPC_MAX_LINK_NAME, "null"); + else if (link_is_bc_sndlink(l)) + scnprintf(buf, TIPC_MAX_LINK_NAME, "broadcast-sender"); + else if (link_is_bc_rcvlink(l)) + scnprintf(buf, TIPC_MAX_LINK_NAME, + "broadcast-receiver, peer %x", l->addr); + else + memcpy(buf, l->name, TIPC_MAX_LINK_NAME); + + return buf; +} + +/** + * tipc_link_dump - dump TIPC link data + * @l: tipc link to be dumped + * @dqueues: bitmask to decide if any link queue to be dumped? + * - TIPC_DUMP_NONE: don't dump link queues + * - TIPC_DUMP_TRANSMQ: dump link transmq queue + * - TIPC_DUMP_BACKLOGQ: dump link backlog queue + * - TIPC_DUMP_DEFERDQ: dump link deferd queue + * - TIPC_DUMP_INPUTQ: dump link input queue + * - TIPC_DUMP_WAKEUP: dump link wakeup queue + * - TIPC_DUMP_ALL: dump all the link queues above + * @buf: returned buffer of dump data in format + */ +int tipc_link_dump(struct tipc_link *l, u16 dqueues, char *buf) +{ + int i = 0; + size_t sz = (dqueues) ? LINK_LMAX : LINK_LMIN; + struct sk_buff_head *list; + struct sk_buff *hskb, *tskb; + u32 len; + + if (!l) { + i += scnprintf(buf, sz, "link data: (null)\n"); + return i; + } + + i += scnprintf(buf, sz, "link data: %x", l->addr); + i += scnprintf(buf + i, sz - i, " %x", l->state); + i += scnprintf(buf + i, sz - i, " %u", l->in_session); + i += scnprintf(buf + i, sz - i, " %u", l->session); + i += scnprintf(buf + i, sz - i, " %u", l->peer_session); + i += scnprintf(buf + i, sz - i, " %u", l->snd_nxt); + i += scnprintf(buf + i, sz - i, " %u", l->rcv_nxt); + i += scnprintf(buf + i, sz - i, " %u", l->snd_nxt_state); + i += scnprintf(buf + i, sz - i, " %u", l->rcv_nxt_state); + i += scnprintf(buf + i, sz - i, " %x", l->peer_caps); + i += scnprintf(buf + i, sz - i, " %u", l->silent_intv_cnt); + i += scnprintf(buf + i, sz - i, " %u", l->rst_cnt); + i += scnprintf(buf + i, sz - i, " %u", l->prev_from); + i += scnprintf(buf + i, sz - i, " %u", l->stale_cnt); + i += scnprintf(buf + i, sz - i, " %u", l->acked); + + list = &l->transmq; + len = skb_queue_len(list); + hskb = skb_peek(list); + tskb = skb_peek_tail(list); + i += scnprintf(buf + i, sz - i, " | %u %u %u", len, + (hskb) ? msg_seqno(buf_msg(hskb)) : 0, + (tskb) ? msg_seqno(buf_msg(tskb)) : 0); + + list = &l->deferdq; + len = skb_queue_len(list); + hskb = skb_peek(list); + tskb = skb_peek_tail(list); + i += scnprintf(buf + i, sz - i, " | %u %u %u", len, + (hskb) ? msg_seqno(buf_msg(hskb)) : 0, + (tskb) ? msg_seqno(buf_msg(tskb)) : 0); + + list = &l->backlogq; + len = skb_queue_len(list); + hskb = skb_peek(list); + tskb = skb_peek_tail(list); + i += scnprintf(buf + i, sz - i, " | %u %u %u", len, + (hskb) ? msg_seqno(buf_msg(hskb)) : 0, + (tskb) ? msg_seqno(buf_msg(tskb)) : 0); + + list = l->inputq; + len = skb_queue_len(list); + hskb = skb_peek(list); + tskb = skb_peek_tail(list); + i += scnprintf(buf + i, sz - i, " | %u %u %u\n", len, + (hskb) ? msg_seqno(buf_msg(hskb)) : 0, + (tskb) ? msg_seqno(buf_msg(tskb)) : 0); + + if (dqueues & TIPC_DUMP_TRANSMQ) { + i += scnprintf(buf + i, sz - i, "transmq: "); + i += tipc_list_dump(&l->transmq, false, buf + i); + } + if (dqueues & TIPC_DUMP_BACKLOGQ) { + i += scnprintf(buf + i, sz - i, + "backlogq: <%u %u %u %u %u>, ", + l->backlog[TIPC_LOW_IMPORTANCE].len, + l->backlog[TIPC_MEDIUM_IMPORTANCE].len, + l->backlog[TIPC_HIGH_IMPORTANCE].len, + l->backlog[TIPC_CRITICAL_IMPORTANCE].len, + l->backlog[TIPC_SYSTEM_IMPORTANCE].len); + i += tipc_list_dump(&l->backlogq, false, buf + i); + } + if (dqueues & TIPC_DUMP_DEFERDQ) { + i += scnprintf(buf + i, sz - i, "deferdq: "); + i += tipc_list_dump(&l->deferdq, false, buf + i); + } + if (dqueues & TIPC_DUMP_INPUTQ) { + i += scnprintf(buf + i, sz - i, "inputq: "); + i += tipc_list_dump(l->inputq, false, buf + i); + } + if (dqueues & TIPC_DUMP_WAKEUP) { + i += scnprintf(buf + i, sz - i, "wakeup: "); + i += tipc_list_dump(&l->wakeupq, false, buf + i); + } + + return i; +} 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); u16 tipc_link_acked(struct tipc_link *l); u32 tipc_link_id(struct tipc_link *l); char *tipc_link_name(struct tipc_link *l); +char *tipc_link_name_ext(struct tipc_link *l, char *buf); u32 tipc_link_state(struct tipc_link *l); char tipc_link_plane(struct tipc_link *l); int tipc_link_prio(struct tipc_link *l); diff --git a/net/tipc/node.c b/net/tipc/node.c index 2afc4f8c37a7..cb10b889ebf5 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -43,6 +43,7 @@ #include "monitor.h" #include "discover.h" #include "netlink.h" +#include "trace.h" #define INVALID_NODE_SIG 0x10000 #define NODE_CLEANUP_AFTER 300000 @@ -2422,3 +2423,65 @@ int tipc_nl_node_dump_monitor_peer(struct sk_buff *skb, return skb->len; } + +u32 tipc_node_get_addr(struct tipc_node *node) +{ + return (node) ? node->addr : 0; +} + +/** + * tipc_node_dump - dump TIPC node data + * @n: tipc node to be dumped + * @more: dump more? + * - false: dump only tipc node data + * - true: dump node link data as well + * @buf: returned buffer of dump data in format + */ +int tipc_node_dump(struct tipc_node *n, bool more, char *buf) +{ + int i = 0; + size_t sz = (more) ? NODE_LMAX : NODE_LMIN; + + if (!n) { + i += scnprintf(buf, sz, "node data: (null)\n"); + return i; + } + + i += scnprintf(buf, sz, "node data: %x", n->addr); + i += scnprintf(buf + i, sz - i, " %x", n->state); + i += scnprintf(buf + i, sz - i, " %d", n->active_links[0]); + i += scnprintf(buf + i, sz - i, " %d", n->active_links[1]); + i += scnprintf(buf + i, sz - i, " %x", n->action_flags); + i += scnprintf(buf + i, sz - i, " %u", n->failover_sent); + i += scnprintf(buf + i, sz - i, " %u", n->sync_point); + i += scnprintf(buf + i, sz - i, " %d", n->link_cnt); + i += scnprintf(buf + i, sz - i, " %u", n->working_links); + i += scnprintf(buf + i, sz - i, " %x", n->capabilities); + i += scnprintf(buf + i, sz - i, " %lu\n", n->keepalive_intv); + + if (!more) + return i; + + i += scnprintf(buf + i, sz - i, "link_entry[0]:\n"); + i += scnprintf(buf + i, sz - i, " mtu: %u\n", n->links[0].mtu); + i += scnprintf(buf + i, sz - i, " media: "); + i += tipc_media_addr_printf(buf + i, sz - i, &n->links[0].maddr); + i += scnprintf(buf + i, sz - i, "\n"); + i += tipc_link_dump(n->links[0].link, TIPC_DUMP_NONE, buf + i); + i += scnprintf(buf + i, sz - i, " inputq: "); + i += tipc_list_dump(&n->links[0].inputq, false, buf + i); + + i += scnprintf(buf + i, sz - i, "link_entry[1]:\n"); + i += scnprintf(buf + i, sz - i, " mtu: %u\n", n->links[1].mtu); + i += scnprintf(buf + i, sz - i, " media: "); + i += tipc_media_addr_printf(buf + i, sz - i, &n->links[1].maddr); + i += scnprintf(buf + i, sz - i, "\n"); + i += tipc_link_dump(n->links[1].link, TIPC_DUMP_NONE, buf + i); + i += scnprintf(buf + i, sz - i, " inputq: "); + i += tipc_list_dump(&n->links[1].inputq, false, buf + i); + + i += scnprintf(buf + i, sz - i, "bclink:\n "); + i += tipc_link_dump(n->bc_entry.link, TIPC_DUMP_NONE, buf + i); + + return i; +} 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 { void tipc_node_stop(struct net *net); bool tipc_node_get_id(struct net *net, u32 addr, u8 *id); +u32 tipc_node_get_addr(struct tipc_node *node); u32 tipc_node_try_addr(struct net *net, u8 *id, u32 addr); void tipc_node_check_dest(struct net *net, u32 onode, u8 *peer_id128, 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 @@ #include "bcast.h" #include "netlink.h" #include "group.h" +#include "trace.h" #define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */ #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) return skb->len; } + +u32 tipc_sock_get_portid(struct sock *sk) +{ + return (sk) ? (tipc_sk(sk))->portid : 0; +} + +/** + * tipc_sk_dump - dump TIPC socket + * @sk: tipc sk to be dumped + * @dqueues: bitmask to decide if any socket queue to be dumped? + * - TIPC_DUMP_NONE: don't dump socket queues + * - TIPC_DUMP_SK_SNDQ: dump socket send queue + * - TIPC_DUMP_SK_RCVQ: dump socket rcv queue + * - TIPC_DUMP_SK_BKLGQ: dump socket backlog queue + * - TIPC_DUMP_ALL: dump all the socket queues above + * @buf: returned buffer of dump data in format + */ +int tipc_sk_dump(struct sock *sk, u16 dqueues, char *buf) +{ + int i = 0; + size_t sz = (dqueues) ? SK_LMAX : SK_LMIN; + struct tipc_sock *tsk; + struct publication *p; + bool tsk_connected; + + if (!sk) { + i += scnprintf(buf, sz, "sk data: (null)\n"); + return i; + } + + tsk = tipc_sk(sk); + tsk_connected = !tipc_sk_type_connectionless(sk); + + i += scnprintf(buf, sz, "sk data: %u", sk->sk_type); + i += scnprintf(buf + i, sz - i, " %d", sk->sk_state); + i += scnprintf(buf + i, sz - i, " %x", tsk_own_node(tsk)); + i += scnprintf(buf + i, sz - i, " %u", tsk->portid); + i += scnprintf(buf + i, sz - i, " | %u", tsk_connected); + if (tsk_connected) { + i += scnprintf(buf + i, sz - i, " %x", tsk_peer_node(tsk)); + i += scnprintf(buf + i, sz - i, " %u", tsk_peer_port(tsk)); + i += scnprintf(buf + i, sz - i, " %u", tsk->conn_type); + i += scnprintf(buf + i, sz - i, " %u", tsk->conn_instance); + } + i += scnprintf(buf + i, sz - i, " | %u", tsk->published); + if (tsk->published) { + p = list_first_entry_or_null(&tsk->publications, + struct publication, binding_sock); + i += scnprintf(buf + i, sz - i, " %u", (p) ? p->type : 0); + i += scnprintf(buf + i, sz - i, " %u", (p) ? p->lower : 0); + i += scnprintf(buf + i, sz - i, " %u", (p) ? p->upper : 0); + } + i += scnprintf(buf + i, sz - i, " | %u", tsk->snd_win); + i += scnprintf(buf + i, sz - i, " %u", tsk->rcv_win); + i += scnprintf(buf + i, sz - i, " %u", tsk->max_pkt); + i += scnprintf(buf + i, sz - i, " %x", tsk->peer_caps); + i += scnprintf(buf + i, sz - i, " %u", tsk->cong_link_cnt); + i += scnprintf(buf + i, sz - i, " %u", tsk->snt_unacked); + i += scnprintf(buf + i, sz - i, " %u", tsk->rcv_unacked); + i += scnprintf(buf + i, sz - i, " %u", atomic_read(&tsk->dupl_rcvcnt)); + i += scnprintf(buf + i, sz - i, " %u", sk->sk_shutdown); + i += scnprintf(buf + i, sz - i, " | %d", sk_wmem_alloc_get(sk)); + i += scnprintf(buf + i, sz - i, " %d", sk->sk_sndbuf); + i += scnprintf(buf + i, sz - i, " | %d", sk_rmem_alloc_get(sk)); + i += scnprintf(buf + i, sz - i, " %d", sk->sk_rcvbuf); + i += scnprintf(buf + i, sz - i, " | %d\n", sk->sk_backlog.len); + + if (dqueues & TIPC_DUMP_SK_SNDQ) { + i += scnprintf(buf + i, sz - i, "sk_write_queue: "); + i += tipc_list_dump(&sk->sk_write_queue, false, buf + i); + } + + if (dqueues & TIPC_DUMP_SK_RCVQ) { + i += scnprintf(buf + i, sz - i, "sk_receive_queue: "); + i += tipc_list_dump(&sk->sk_receive_queue, false, buf + i); + } + + if (dqueues & TIPC_DUMP_SK_BKLGQ) { + i += scnprintf(buf + i, sz - i, "sk_backlog:\n head "); + i += tipc_skb_dump(sk->sk_backlog.head, false, buf + i); + if (sk->sk_backlog.tail != sk->sk_backlog.head) { + i += scnprintf(buf + i, sz - i, " tail "); + i += tipc_skb_dump(sk->sk_backlog.tail, false, + buf + i); + } + } + + return i; +} 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, int tipc_dump_start(struct netlink_callback *cb); int __tipc_dump_start(struct netlink_callback *cb, struct net *net); int tipc_dump_done(struct netlink_callback *cb); +u32 tipc_sock_get_portid(struct sock *sk); + #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 @@ +/* + * net/tipc/trace.c: TIPC tracepoints code + * + * Copyright (c) 2018, Ericsson AB + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the names of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "ASIS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#define CREATE_TRACE_POINTS +#include "trace.h" + +/** + * tipc_skb_dump - dump TIPC skb data + * @skb: skb to be dumped + * @more: dump more? + * - false: dump only tipc msg data + * - true: dump kernel-related skb data and tipc cb[] array as well + * @buf: returned buffer of dump data in format + */ +int tipc_skb_dump(struct sk_buff *skb, bool more, char *buf) +{ + int i = 0; + size_t sz = (more) ? SKB_LMAX : SKB_LMIN; + struct tipc_msg *hdr; + struct tipc_skb_cb *skbcb; + + if (!skb) { + i += scnprintf(buf, sz, "msg: (null)\n"); + return i; + } + + hdr = buf_msg(skb); + skbcb = TIPC_SKB_CB(skb); + + /* tipc msg data section */ + i += scnprintf(buf, sz, "msg: %u", msg_user(hdr)); + i += scnprintf(buf + i, sz - i, " %u", msg_type(hdr)); + i += scnprintf(buf + i, sz - i, " %u", msg_hdr_sz(hdr)); + i += scnprintf(buf + i, sz - i, " %u", msg_data_sz(hdr)); + i += scnprintf(buf + i, sz - i, " %x", msg_orignode(hdr)); + i += scnprintf(buf + i, sz - i, " %x", msg_destnode(hdr)); + i += scnprintf(buf + i, sz - i, " %u", msg_seqno(hdr)); + i += scnprintf(buf + i, sz - i, " %u", msg_ack(hdr)); + i += scnprintf(buf + i, sz - i, " %u", msg_bcast_ack(hdr)); + switch (msg_user(hdr)) { + case LINK_PROTOCOL: + i += scnprintf(buf + i, sz - i, " %c", msg_net_plane(hdr)); + i += scnprintf(buf + i, sz - i, " %u", msg_probe(hdr)); + i += scnprintf(buf + i, sz - i, " %u", msg_peer_stopping(hdr)); + i += scnprintf(buf + i, sz - i, " %u", msg_session(hdr)); + i += scnprintf(buf + i, sz - i, " %u", msg_next_sent(hdr)); + i += scnprintf(buf + i, sz - i, " %u", msg_seq_gap(hdr)); + i += scnprintf(buf + i, sz - i, " %u", msg_bc_snd_nxt(hdr)); + i += scnprintf(buf + i, sz - i, " %u", msg_bc_gap(hdr)); + break; + case TIPC_LOW_IMPORTANCE: + case TIPC_MEDIUM_IMPORTANCE: + case TIPC_HIGH_IMPORTANCE: + case TIPC_CRITICAL_IMPORTANCE: + case CONN_MANAGER: + case SOCK_WAKEUP: + i += scnprintf(buf + i, sz - i, " | %u", msg_origport(hdr)); + i += scnprintf(buf + i, sz - i, " %u", msg_destport(hdr)); + switch (msg_type(hdr)) { + case TIPC_NAMED_MSG: + i += scnprintf(buf + i, sz - i, " %u", + msg_nametype(hdr)); + i += scnprintf(buf + i, sz - i, " %u", + msg_nameinst(hdr)); + break; + case TIPC_MCAST_MSG: + i += scnprintf(buf + i, sz - i, " %u", + msg_nametype(hdr)); + i += scnprintf(buf + i, sz - i, " %u", + msg_namelower(hdr)); + i += scnprintf(buf + i, sz - i, " %u", + msg_nameupper(hdr)); + break; + default: + break; + }; + i += scnprintf(buf + i, sz - i, " | %u", + msg_src_droppable(hdr)); + i += scnprintf(buf + i, sz - i, " %u", + msg_dest_droppable(hdr)); + i += scnprintf(buf + i, sz - i, " %u", msg_errcode(hdr)); + i += scnprintf(buf + i, sz - i, " %u", msg_reroute_cnt(hdr)); + break; + default: + /* need more? */ + break; + }; + + i += scnprintf(buf + i, sz - i, "\n"); + if (!more) + return i; + + /* kernel-related skb data section */ + i += scnprintf(buf + i, sz - i, "skb: %s", + (skb->dev) ? skb->dev->name : "n/a"); + i += scnprintf(buf + i, sz - i, " %u", skb->len); + i += scnprintf(buf + i, sz - i, " %u", skb->data_len); + i += scnprintf(buf + i, sz - i, " %u", skb->hdr_len); + i += scnprintf(buf + i, sz - i, " %u", skb->truesize); + i += scnprintf(buf + i, sz - i, " %u", skb_cloned(skb)); + i += scnprintf(buf + i, sz - i, " %p", skb->sk); + i += scnprintf(buf + i, sz - i, " %u", skb_shinfo(skb)->nr_frags); + i += scnprintf(buf + i, sz - i, " %llx", + ktime_to_ms(skb_get_ktime(skb))); + i += scnprintf(buf + i, sz - i, " %llx\n", + ktime_to_ms(skb_hwtstamps(skb)->hwtstamp)); + + /* tipc skb cb[] data section */ + i += scnprintf(buf + i, sz - i, "cb[]: %u", skbcb->bytes_read); + i += scnprintf(buf + i, sz - i, " %u", skbcb->orig_member); + i += scnprintf(buf + i, sz - i, " %u", + jiffies_to_msecs(skbcb->nxt_retr)); + i += scnprintf(buf + i, sz - i, " %u", skbcb->validated); + i += scnprintf(buf + i, sz - i, " %u", skbcb->chain_imp); + i += scnprintf(buf + i, sz - i, " %u\n", skbcb->ackers); + + return i; +} + +/** + * tipc_list_dump - dump TIPC skb list/queue + * @list: list of skbs to be dumped + * @more: dump more? + * - false: dump only the head & tail skbs + * - true: dump the first & last 5 skbs + * @buf: returned buffer of dump data in format + */ +int tipc_list_dump(struct sk_buff_head *list, bool more, char *buf) +{ + int i = 0; + size_t sz = (more) ? LIST_LMAX : LIST_LMIN; + u32 count, len; + struct sk_buff *hskb, *tskb, *skb, *tmp; + + if (!list) { + i += scnprintf(buf, sz, "(null)\n"); + return i; + } + + len = skb_queue_len(list); + i += scnprintf(buf, sz, "len = %d\n", len); + + if (!len) + return i; + + if (!more) { + hskb = skb_peek(list); + i += scnprintf(buf + i, sz - i, " head "); + i += tipc_skb_dump(hskb, false, buf + i); + if (len > 1) { + tskb = skb_peek_tail(list); + i += scnprintf(buf + i, sz - i, " tail "); + i += tipc_skb_dump(tskb, false, buf + i); + } + } else { + count = 0; + skb_queue_walk_safe(list, skb, tmp) { + count++; + if (count == 6) + i += scnprintf(buf + i, sz - i, " .\n .\n"); + if (count > 5 && count <= len - 5) + continue; + i += scnprintf(buf + i, sz - i, " #%d ", count); + i += tipc_skb_dump(skb, false, buf + i); + } + } + return i; +} 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 @@ +/* + * net/tipc/trace.h: TIPC tracepoints + * + * Copyright (c) 2018, Ericsson AB + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the names of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "ASIS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM tipc + +#if !defined(_TIPC_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TIPC_TRACE_H + +#include +#include "core.h" +#include "link.h" +#include "socket.h" +#include "node.h" + +#define SKB_LMIN (100) +#define SKB_LMAX (SKB_LMIN * 2) +#define LIST_LMIN (SKB_LMIN * 3) +#define LIST_LMAX (SKB_LMIN * 11) +#define SK_LMIN (SKB_LMIN * 2) +#define SK_LMAX (SKB_LMIN * 11) +#define LINK_LMIN (SKB_LMIN) +#define LINK_LMAX (SKB_LMIN * 16) +#define NODE_LMIN (SKB_LMIN) +#define NODE_LMAX (SKB_LMIN * 11) + +#ifndef __TIPC_TRACE_ENUM +#define __TIPC_TRACE_ENUM +enum { + TIPC_DUMP_NONE = 0, + + TIPC_DUMP_TRANSMQ = 1, + TIPC_DUMP_BACKLOGQ = (1 << 1), + TIPC_DUMP_DEFERDQ = (1 << 2), + TIPC_DUMP_INPUTQ = (1 << 3), + TIPC_DUMP_WAKEUP = (1 << 4), + + TIPC_DUMP_SK_SNDQ = (1 << 8), + TIPC_DUMP_SK_RCVQ = (1 << 9), + TIPC_DUMP_SK_BKLGQ = (1 << 10), + TIPC_DUMP_ALL = 0xffffu +}; +#endif + +int tipc_skb_dump(struct sk_buff *skb, bool more, char *buf); +int tipc_list_dump(struct sk_buff_head *list, bool more, char *buf); +int tipc_sk_dump(struct sock *sk, u16 dqueues, char *buf); +int tipc_link_dump(struct tipc_link *l, u16 dqueues, char *buf); +int tipc_node_dump(struct tipc_node *n, bool more, char *buf); + +DECLARE_EVENT_CLASS(tipc_skb_class, + + TP_PROTO(struct sk_buff *skb, bool more, const char *header), + + TP_ARGS(skb, more, header), + + TP_STRUCT__entry( + __string(header, header) + __dynamic_array(char, buf, (more) ? SKB_LMAX : SKB_LMIN) + ), + + TP_fast_assign( + __assign_str(header, header); + tipc_skb_dump(skb, more, __get_str(buf)); + ), + + TP_printk("%s\n%s", __get_str(header), __get_str(buf)) +) + +#define DEFINE_SKB_EVENT(name) \ +DEFINE_EVENT(tipc_skb_class, name, \ + TP_PROTO(struct sk_buff *skb, bool more, const char *header), \ + TP_ARGS(skb, more, header)) +DEFINE_SKB_EVENT(tipc_skb_dump); + +DECLARE_EVENT_CLASS(tipc_list_class, + + TP_PROTO(struct sk_buff_head *list, bool more, const char *header), + + TP_ARGS(list, more, header), + + TP_STRUCT__entry( + __string(header, header) + __dynamic_array(char, buf, (more) ? LIST_LMAX : LIST_LMIN) + ), + + TP_fast_assign( + __assign_str(header, header); + tipc_list_dump(list, more, __get_str(buf)); + ), + + TP_printk("%s\n%s", __get_str(header), __get_str(buf)) +); + +#define DEFINE_LIST_EVENT(name) \ +DEFINE_EVENT(tipc_list_class, name, \ + TP_PROTO(struct sk_buff_head *list, bool more, const char *header), \ + TP_ARGS(list, more, header)) +DEFINE_LIST_EVENT(tipc_list_dump); + +DECLARE_EVENT_CLASS(tipc_sk_class, + + TP_PROTO(struct sock *sk, struct sk_buff *skb, u16 dqueues, + const char *header), + + TP_ARGS(sk, skb, dqueues, header), + + TP_STRUCT__entry( + __string(header, header) + __field(u32, portid) + __dynamic_array(char, buf, (dqueues) ? SK_LMAX : SK_LMIN) + __dynamic_array(char, skb_buf, (skb) ? SKB_LMIN : 1) + ), + + TP_fast_assign( + __assign_str(header, header); + __entry->portid = tipc_sock_get_portid(sk); + tipc_sk_dump(sk, dqueues, __get_str(buf)); + if (skb) + tipc_skb_dump(skb, false, __get_str(skb_buf)); + else + *(__get_str(skb_buf)) = '\0'; + ), + + TP_printk("<%u> %s\n%s%s", __entry->portid, __get_str(header), + __get_str(skb_buf), __get_str(buf)) +); + +#define DEFINE_SK_EVENT(name) \ +DEFINE_EVENT(tipc_sk_class, name, \ + TP_PROTO(struct sock *sk, struct sk_buff *skb, u16 dqueues, \ + const char *header), \ + TP_ARGS(sk, skb, dqueues, header)) +DEFINE_SK_EVENT(tipc_sk_dump); + +DECLARE_EVENT_CLASS(tipc_link_class, + + TP_PROTO(struct tipc_link *l, u16 dqueues, const char *header), + + TP_ARGS(l, dqueues, header), + + TP_STRUCT__entry( + __string(header, header) + __array(char, name, TIPC_MAX_LINK_NAME) + __dynamic_array(char, buf, (dqueues) ? LINK_LMAX : LINK_LMIN) + ), + + TP_fast_assign( + __assign_str(header, header); + tipc_link_name_ext(l, __entry->name); + tipc_link_dump(l, dqueues, __get_str(buf)); + ), + + TP_printk("<%s> %s\n%s", __entry->name, __get_str(header), + __get_str(buf)) +); + +#define DEFINE_LINK_EVENT(name) \ +DEFINE_EVENT(tipc_link_class, name, \ + TP_PROTO(struct tipc_link *l, u16 dqueues, const char *header), \ + TP_ARGS(l, dqueues, header)) +DEFINE_LINK_EVENT(tipc_link_dump); + +DECLARE_EVENT_CLASS(tipc_node_class, + + TP_PROTO(struct tipc_node *n, bool more, const char *header), + + TP_ARGS(n, more, header), + + TP_STRUCT__entry( + __string(header, header) + __field(u32, addr) + __dynamic_array(char, buf, (more) ? NODE_LMAX : NODE_LMIN) + ), + + TP_fast_assign( + __assign_str(header, header); + __entry->addr = tipc_node_get_addr(n); + tipc_node_dump(n, more, __get_str(buf)); + ), + + TP_printk("<%x> %s\n%s", __entry->addr, __get_str(header), + __get_str(buf)) +); + +#define DEFINE_NODE_EVENT(name) \ +DEFINE_EVENT(tipc_node_class, name, \ + TP_PROTO(struct tipc_node *n, bool more, const char *header), \ + TP_ARGS(n, more, header)) +DEFINE_NODE_EVENT(tipc_node_dump); + +#endif /* _TIPC_TRACE_H */ + +/* This part must be outside protection */ +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE trace +#include From patchwork Wed Dec 19 02:17:57 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tuong Lien X-Patchwork-Id: 1015801 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=dektech.com.au Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=dektech.com.au header.i=@dektech.com.au header.b="fmuvM/05"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43KJlf3FT9z9s2P for ; Wed, 19 Dec 2018 13:30:38 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727052AbeLSCah (ORCPT ); Tue, 18 Dec 2018 21:30:37 -0500 Received: from f0-dek.dektech.com.au ([210.10.221.142]:54407 "EHLO mail.dektech.com.au" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726652AbeLSCa3 (ORCPT ); Tue, 18 Dec 2018 21:30:29 -0500 Received: from localhost (localhost [127.0.0.1]) by mail.dektech.com.au (Postfix) with ESMTP id 3F02DF77A0; Wed, 19 Dec 2018 13:18:12 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=dektech.com.au; h=references:in-reply-to:x-mailer:message-id:date:date:subject :subject:from:from:received:received:received; s=mail_dkim; t= 1545185892; bh=efVe8k71GFdIHHMlTz70l7EWlFOur2l92hsGcN4l+fU=; b=f muvM/05j3BnDokV46USiHwhWvkRQYDPgvQAzbfTxZTdElPQD6VUXIjAI8aDcbB4R 5YKIG+I+begWTvQOuGnfrTk3DWXTnXic5IVCAYAuADdqYgdWf1qh8lBRyXEnbWt1 Hd6ChQgKqmyJqZVHp0LpkLZn2dMAgEgaxFPWcCF9VI= X-Virus-Scanned: amavisd-new at dektech.com.au Received: from mail.dektech.com.au ([127.0.0.1]) by localhost (mail2.dektech.com.au [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id c0gMjlJB8zik; Wed, 19 Dec 2018 13:18:12 +1100 (AEDT) Received: from mail.dektech.com.au (localhost [127.0.0.1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.dektech.com.au (Postfix) with ESMTPS id 1C31CF77AE; Wed, 19 Dec 2018 13:18:12 +1100 (AEDT) Received: from localhost.localdomain (unknown [14.161.14.188]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) by mail.dektech.com.au (Postfix) with ESMTPSA id 86207F77A0; Wed, 19 Dec 2018 13:18:10 +1100 (AEDT) From: Tuong Lien To: davem@davemloft.net, jon.maloy@ericsson.com, netdev@vger.kernel.org Cc: tipc-discussion@lists.sourceforge.net Subject: [net-next 2/5] tipc: add trace_events for tipc link Date: Wed, 19 Dec 2018 09:17:57 +0700 Message-Id: <20181219021800.21662-3-tuong.t.lien@dektech.com.au> X-Mailer: git-send-email 2.13.7 In-Reply-To: <20181219021800.21662-1-tuong.t.lien@dektech.com.au> References: <20181219021800.21662-1-tuong.t.lien@dektech.com.au> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The commit adds the new trace_events for TIPC link object: trace_tipc_link_timeout() trace_tipc_link_fsm() trace_tipc_link_reset() trace_tipc_link_too_silent() trace_tipc_link_retrans() trace_tipc_link_bc_ack() trace_tipc_link_conges() And the traces for PROTOCOL messages at building and receiving: trace_tipc_proto_build() trace_tipc_proto_rcv() Note: a) The 'tipc_link_too_silent' event will only happen when the 'silent_intv_cnt' is about to reach the 'abort_limit' value (and the event is enabled). The benefit for this kind of event is that we can get an early indication about TIPC link loss issue due to timeout, then can do some necessary actions for troubleshooting. For example: To trigger the 'tipc_proto_rcv' when the 'too_silent' event occurs: echo 'enable_event:tipc:tipc_proto_rcv' > \ events/tipc/tipc_link_too_silent/trigger And disable it when TIPC link is reset: echo 'disable_event:tipc:tipc_proto_rcv' > \ events/tipc/tipc_link_reset/trigger b) The 'tipc_link_retrans' or 'tipc_link_bc_ack' event is useful to trace TIPC retransmission issues. In addition, the commit adds the 'trace_tipc_list/link_dump()' at the 'retransmission failure' case. Then, if the issue occurs, the link 'transmq' along with the link data can be dumped for post-analysis. These dump events should be enabled by default since it will only take effect when the failure happens. The same approach is also applied for the faulty case that the validation of protocol message is failed. Acked-by: Ying Xue Tested-by: Ying Xue Acked-by: Jon Maloy Signed-off-by: Tuong Lien --- net/tipc/link.c | 33 ++++++++++++++- net/tipc/link.h | 1 + net/tipc/node.c | 8 +++- net/tipc/trace.h | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 164 insertions(+), 2 deletions(-) diff --git a/net/tipc/link.c b/net/tipc/link.c index 668dab529021..55c44d867d4b 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -357,9 +357,11 @@ void tipc_link_remove_bc_peer(struct tipc_link *snd_l, rcv_l->bc_peer_is_up = true; rcv_l->state = LINK_ESTABLISHED; tipc_link_bc_ack_rcv(rcv_l, ack, xmitq); + trace_tipc_link_reset(rcv_l, TIPC_DUMP_ALL, "bclink removed!"); tipc_link_reset(rcv_l); rcv_l->state = LINK_RESET; if (!snd_l->ackers) { + trace_tipc_link_reset(snd_l, TIPC_DUMP_ALL, "zero ackers!"); tipc_link_reset(snd_l); snd_l->state = LINK_RESET; __skb_queue_purge(xmitq); @@ -523,6 +525,7 @@ bool tipc_link_bc_create(struct net *net, u32 ownnode, u32 peer, l = *link; strcpy(l->name, tipc_bclink_name); + trace_tipc_link_reset(l, TIPC_DUMP_ALL, "bclink created!"); tipc_link_reset(l); l->state = LINK_RESET; l->ackers = 0; @@ -547,6 +550,7 @@ bool tipc_link_bc_create(struct net *net, u32 ownnode, u32 peer, int tipc_link_fsm_evt(struct tipc_link *l, int evt) { int rc = 0; + int old_state = l->state; switch (l->state) { case LINK_RESETTING: @@ -693,10 +697,12 @@ int tipc_link_fsm_evt(struct tipc_link *l, int evt) default: pr_err("Unknown FSM state %x in %s\n", l->state, l->name); } + trace_tipc_link_fsm(l->name, old_state, l->state, evt); return rc; illegal_evt: pr_err("Illegal FSM event %x in state %x on link %s\n", evt, l->state, l->name); + trace_tipc_link_fsm(l->name, old_state, l->state, evt); return rc; } @@ -741,6 +747,18 @@ static void link_profile_stats(struct tipc_link *l) l->stats.msg_length_profile[6]++; } +/** + * tipc_link_too_silent - check if link is "too silent" + * @l: tipc link to be checked + * + * Returns true if the link 'silent_intv_cnt' is about to reach the + * 'abort_limit' value, otherwise false + */ +bool tipc_link_too_silent(struct tipc_link *l) +{ + return (l->silent_intv_cnt + 2 > l->abort_limit); +} + /* tipc_link_timeout - perform periodic task as instructed from node timeout */ int tipc_link_timeout(struct tipc_link *l, struct sk_buff_head *xmitq) @@ -754,6 +772,8 @@ int tipc_link_timeout(struct tipc_link *l, struct sk_buff_head *xmitq) u16 bc_acked = l->bc_rcvlink->acked; struct tipc_mon_state *mstate = &l->mon_state; + trace_tipc_link_timeout(l, TIPC_DUMP_NONE, " "); + trace_tipc_link_too_silent(l, TIPC_DUMP_ALL, " "); switch (l->state) { case LINK_ESTABLISHED: case LINK_SYNCHING: @@ -816,6 +836,7 @@ static int link_schedule_user(struct tipc_link *l, struct tipc_msg *hdr) TIPC_SKB_CB(skb)->chain_imp = msg_importance(hdr); skb_queue_tail(&l->wakeupq, skb); l->stats.link_congs++; + trace_tipc_link_conges(l, TIPC_DUMP_ALL, "wakeup scheduled!"); return -ELINKCONG; } @@ -1037,6 +1058,7 @@ static int tipc_link_retrans(struct tipc_link *l, struct tipc_link *r, if (less(to, from)) return 0; + trace_tipc_link_retrans(r, from, to, &l->transmq); /* Detect repeated retransmit failures on same packet */ if (r->prev_from != from) { r->prev_from = from; @@ -1044,6 +1066,9 @@ static int tipc_link_retrans(struct tipc_link *l, struct tipc_link *r, r->stale_cnt = 0; } else if (++r->stale_cnt > 99 && time_after(jiffies, r->stale_limit)) { link_retransmit_failure(l, skb); + trace_tipc_list_dump(&l->transmq, true, "retrans failure!"); + trace_tipc_link_dump(l, TIPC_DUMP_NONE, "retrans failure!"); + trace_tipc_link_dump(r, TIPC_DUMP_NONE, "retrans failure!"); if (link_is_bc_sndlink(l)) return TIPC_LINK_DOWN_EVT; return tipc_link_fsm_evt(l, LINK_FAILURE_EVT); @@ -1403,6 +1428,7 @@ static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe, l->stats.sent_nacks++; skb->priority = TC_PRIO_CONTROL; __skb_queue_tail(xmitq, skb); + trace_tipc_proto_build(skb, false, l->name); } void tipc_link_create_dummy_tnl_msg(struct tipc_link *l, @@ -1566,6 +1592,7 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb, char *if_name; int rc = 0; + trace_tipc_proto_rcv(skb, false, l->name); if (tipc_link_is_blocked(l) || !xmitq) goto exit; @@ -1576,8 +1603,11 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb, hdr = buf_msg(skb); data = msg_data(hdr); - if (!tipc_link_validate_msg(l, hdr)) + if (!tipc_link_validate_msg(l, hdr)) { + trace_tipc_skb_dump(skb, false, "PROTO invalid (1)!"); + trace_tipc_link_dump(l, TIPC_DUMP_NONE, "PROTO invalid (1)!"); goto exit; + } switch (mtyp) { case RESET_MSG: @@ -1820,6 +1850,7 @@ void tipc_link_bc_ack_rcv(struct tipc_link *l, u16 acked, if (!more(acked, l->acked)) return; + trace_tipc_link_bc_ack(l, l->acked, acked, &snd_l->transmq); /* Skip over packets peer has already acked */ skb_queue_walk(&snd_l->transmq, skb) { if (more(buf_seqno(skb), l->acked)) diff --git a/net/tipc/link.h b/net/tipc/link.h index e8f692598e4d..8439e0ee53a8 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h @@ -148,4 +148,5 @@ int tipc_link_bc_sync_rcv(struct tipc_link *l, struct tipc_msg *hdr, struct sk_buff_head *xmitq); int tipc_link_bc_nack_rcv(struct tipc_link *l, struct sk_buff *skb, struct sk_buff_head *xmitq); +bool tipc_link_too_silent(struct tipc_link *l); #endif diff --git a/net/tipc/node.c b/net/tipc/node.c index cb10b889ebf5..cff42c95cef8 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -775,6 +775,7 @@ static void __tipc_node_link_down(struct tipc_node *n, int *bearer_id, if (tipc_link_peer_is_down(l)) tipc_node_fsm_evt(n, PEER_LOST_CONTACT_EVT); tipc_node_fsm_evt(n, SELF_LOST_CONTACT_EVT); + trace_tipc_link_reset(l, TIPC_DUMP_ALL, "link down!"); tipc_link_fsm_evt(l, LINK_RESET_EVT); tipc_link_reset(l); tipc_link_build_reset_msg(l, xmitq); @@ -792,6 +793,7 @@ static void __tipc_node_link_down(struct tipc_node *n, int *bearer_id, tipc_node_fsm_evt(n, NODE_SYNCH_END_EVT); n->sync_point = tipc_link_rcv_nxt(tnl) + (U16_MAX / 2 - 1); tipc_link_tnl_prepare(l, tnl, FAILOVER_MSG, xmitq); + trace_tipc_link_reset(l, TIPC_DUMP_ALL, "link down -> failover!"); tipc_link_reset(l); tipc_link_fsm_evt(l, LINK_RESET_EVT); tipc_link_fsm_evt(l, LINK_FAILOVER_BEGIN_EVT); @@ -1013,6 +1015,7 @@ void tipc_node_check_dest(struct net *net, u32 addr, *respond = false; goto exit; } + trace_tipc_link_reset(l, TIPC_DUMP_ALL, "link created!"); tipc_link_reset(l); tipc_link_fsm_evt(l, LINK_RESET_EVT); if (n->state == NODE_FAILINGOVER) @@ -1586,8 +1589,11 @@ static bool tipc_node_check_state(struct tipc_node *n, struct sk_buff *skb, } } - if (!tipc_link_validate_msg(l, hdr)) + if (!tipc_link_validate_msg(l, hdr)) { + trace_tipc_skb_dump(skb, false, "PROTO invalid (2)!"); + trace_tipc_link_dump(l, TIPC_DUMP_NONE, "PROTO invalid (2)!"); return false; + } /* Check and update node accesibility if applicable */ if (state == SELF_UP_PEER_COMING) { diff --git a/net/tipc/trace.h b/net/tipc/trace.h index 4c74927df685..535c8958651f 100644 --- a/net/tipc/trace.h +++ b/net/tipc/trace.h @@ -74,6 +74,45 @@ enum { }; #endif +/* Link & Node FSM states: */ +#define state_sym(val) \ + __print_symbolic(val, \ + {(0xe), "ESTABLISHED" },\ + {(0xe << 4), "ESTABLISHING" },\ + {(0x1 << 8), "RESET" },\ + {(0x2 << 12), "RESETTING" },\ + {(0xd << 16), "PEER_RESET" },\ + {(0xf << 20), "FAILINGOVER" },\ + {(0xc << 24), "SYNCHING" },\ + {(0xdd), "SELF_DOWN_PEER_DOWN" },\ + {(0xaa), "SELF_UP_PEER_UP" },\ + {(0xd1), "SELF_DOWN_PEER_LEAVING" },\ + {(0xac), "SELF_UP_PEER_COMING" },\ + {(0xca), "SELF_COMING_PEER_UP" },\ + {(0x1d), "SELF_LEAVING_PEER_DOWN" },\ + {(0xf0), "FAILINGOVER" },\ + {(0xcc), "SYNCHING" }) + +/* Link & Node FSM events: */ +#define evt_sym(val) \ + __print_symbolic(val, \ + {(0xec1ab1e), "ESTABLISH_EVT" },\ + {(0x9eed0e), "PEER_RESET_EVT" },\ + {(0xfa110e), "FAILURE_EVT" },\ + {(0x10ca1d0e), "RESET_EVT" },\ + {(0xfa110bee), "FAILOVER_BEGIN_EVT" },\ + {(0xfa110ede), "FAILOVER_END_EVT" },\ + {(0xc1ccbee), "SYNCH_BEGIN_EVT" },\ + {(0xc1ccede), "SYNCH_END_EVT" },\ + {(0xece), "SELF_ESTABL_CONTACT_EVT" },\ + {(0x1ce), "SELF_LOST_CONTACT_EVT" },\ + {(0x9ece), "PEER_ESTABL_CONTACT_EVT" },\ + {(0x91ce), "PEER_LOST_CONTACT_EVT" },\ + {(0xfbe), "FAILOVER_BEGIN_EVT" },\ + {(0xfee), "FAILOVER_END_EVT" },\ + {(0xcbe), "SYNCH_BEGIN_EVT" },\ + {(0xcee), "SYNCH_END_EVT" }) + int tipc_skb_dump(struct sk_buff *skb, bool more, char *buf); int tipc_list_dump(struct sk_buff_head *list, bool more, char *buf); int tipc_sk_dump(struct sock *sk, u16 dqueues, char *buf); @@ -104,6 +143,8 @@ DEFINE_EVENT(tipc_skb_class, name, \ TP_PROTO(struct sk_buff *skb, bool more, const char *header), \ TP_ARGS(skb, more, header)) DEFINE_SKB_EVENT(tipc_skb_dump); +DEFINE_SKB_EVENT(tipc_proto_build); +DEFINE_SKB_EVENT(tipc_proto_rcv); DECLARE_EVENT_CLASS(tipc_list_class, @@ -192,6 +233,58 @@ DEFINE_EVENT(tipc_link_class, name, \ TP_PROTO(struct tipc_link *l, u16 dqueues, const char *header), \ TP_ARGS(l, dqueues, header)) DEFINE_LINK_EVENT(tipc_link_dump); +DEFINE_LINK_EVENT(tipc_link_conges); +DEFINE_LINK_EVENT(tipc_link_timeout); +DEFINE_LINK_EVENT(tipc_link_reset); + +#define DEFINE_LINK_EVENT_COND(name, cond) \ +DEFINE_EVENT_CONDITION(tipc_link_class, name, \ + TP_PROTO(struct tipc_link *l, u16 dqueues, const char *header), \ + TP_ARGS(l, dqueues, header), \ + TP_CONDITION(cond)) +DEFINE_LINK_EVENT_COND(tipc_link_too_silent, tipc_link_too_silent(l)); + +DECLARE_EVENT_CLASS(tipc_link_transmq_class, + + TP_PROTO(struct tipc_link *r, u16 f, u16 t, struct sk_buff_head *tq), + + TP_ARGS(r, f, t, tq), + + TP_STRUCT__entry( + __array(char, name, TIPC_MAX_LINK_NAME) + __field(u16, from) + __field(u16, to) + __field(u32, len) + __field(u16, fseqno) + __field(u16, lseqno) + ), + + TP_fast_assign( + tipc_link_name_ext(r, __entry->name); + __entry->from = f; + __entry->to = t; + __entry->len = skb_queue_len(tq); + __entry->fseqno = msg_seqno(buf_msg(skb_peek(tq))); + __entry->lseqno = msg_seqno(buf_msg(skb_peek_tail(tq))); + ), + + TP_printk("<%s> retrans req: [%u-%u] transmq: %u [%u-%u]\n", + __entry->name, __entry->from, __entry->to, + __entry->len, __entry->fseqno, __entry->lseqno) +); + +DEFINE_EVENT(tipc_link_transmq_class, tipc_link_retrans, + TP_PROTO(struct tipc_link *r, u16 f, u16 t, struct sk_buff_head *tq), + TP_ARGS(r, f, t, tq) +); + +DEFINE_EVENT_PRINT(tipc_link_transmq_class, tipc_link_bc_ack, + TP_PROTO(struct tipc_link *r, u16 f, u16 t, struct sk_buff_head *tq), + TP_ARGS(r, f, t, tq), + TP_printk("<%s> acked: [%u-%u] transmq: %u [%u-%u]\n", + __entry->name, __entry->from, __entry->to, + __entry->len, __entry->fseqno, __entry->lseqno) +); DECLARE_EVENT_CLASS(tipc_node_class, @@ -221,6 +314,37 @@ DEFINE_EVENT(tipc_node_class, name, \ TP_ARGS(n, more, header)) DEFINE_NODE_EVENT(tipc_node_dump); +DECLARE_EVENT_CLASS(tipc_fsm_class, + + TP_PROTO(const char *name, u32 os, u32 ns, int evt), + + TP_ARGS(name, os, ns, evt), + + TP_STRUCT__entry( + __string(name, name) + __field(u32, os) + __field(u32, ns) + __field(u32, evt) + ), + + TP_fast_assign( + __assign_str(name, name); + __entry->os = os; + __entry->ns = ns; + __entry->evt = evt; + ), + + TP_printk("<%s> %s--(%s)->%s\n", __get_str(name), + state_sym(__entry->os), evt_sym(__entry->evt), + state_sym(__entry->ns)) +); + +#define DEFINE_FSM_EVENT(fsm_name) \ +DEFINE_EVENT(tipc_fsm_class, fsm_name, \ + TP_PROTO(const char *name, u32 os, u32 ns, int evt), \ + TP_ARGS(name, os, ns, evt)) +DEFINE_FSM_EVENT(tipc_link_fsm); + #endif /* _TIPC_TRACE_H */ /* This part must be outside protection */ From patchwork Wed Dec 19 02:17:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tuong Lien X-Patchwork-Id: 1015799 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=dektech.com.au Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=dektech.com.au header.i=@dektech.com.au header.b="Zp8nLmom"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43KJlX346zz9sCr for ; Wed, 19 Dec 2018 13:30:32 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726953AbeLSCab (ORCPT ); Tue, 18 Dec 2018 21:30:31 -0500 Received: from f0-dek.dektech.com.au ([210.10.221.142]:44998 "EHLO mail.dektech.com.au" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726716AbeLSCaa (ORCPT ); Tue, 18 Dec 2018 21:30:30 -0500 Received: from localhost (localhost [127.0.0.1]) by mail.dektech.com.au (Postfix) with ESMTP id 52794F77AE; Wed, 19 Dec 2018 13:18:14 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=dektech.com.au; h=references:in-reply-to:x-mailer:message-id:date:date:subject :subject:from:from:received:received:received; s=mail_dkim; t= 1545185894; bh=YqzSEft///G9/4ipM1lobN9Ftcxz5MWv7gQhpEwG/is=; b=Z p8nLmom2QAym2z0x5/ZYxaIKspUE9JdZGAr1YeSj19bDLWwHQ+EeG4dNTWwYdAXC c58ZCEumubIDtPzx1TR1tv71GXS/up4gSiseoWPfmviJdtKuNBApvTzBYZiaYW7D wxqg8EuKkZMrP5nK1BJrcQv86I5AO+3NDeGUzSuzDQ= X-Virus-Scanned: amavisd-new at dektech.com.au Received: from mail.dektech.com.au ([127.0.0.1]) by localhost (mail2.dektech.com.au [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id U_PQoShYK7nI; Wed, 19 Dec 2018 13:18:14 +1100 (AEDT) Received: from mail.dektech.com.au (localhost [127.0.0.1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.dektech.com.au (Postfix) with ESMTPS id 25297F77BE; Wed, 19 Dec 2018 13:18:14 +1100 (AEDT) Received: from localhost.localdomain (unknown [14.161.14.188]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) by mail.dektech.com.au (Postfix) with ESMTPSA id 8087FF77AE; Wed, 19 Dec 2018 13:18:12 +1100 (AEDT) From: Tuong Lien To: davem@davemloft.net, jon.maloy@ericsson.com, netdev@vger.kernel.org Cc: tipc-discussion@lists.sourceforge.net Subject: [net-next 3/5] tipc: add trace_events for tipc socket Date: Wed, 19 Dec 2018 09:17:58 +0700 Message-Id: <20181219021800.21662-4-tuong.t.lien@dektech.com.au> X-Mailer: git-send-email 2.13.7 In-Reply-To: <20181219021800.21662-1-tuong.t.lien@dektech.com.au> References: <20181219021800.21662-1-tuong.t.lien@dektech.com.au> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The commit adds the new trace_events for TIPC socket object: trace_tipc_sk_create() trace_tipc_sk_poll() trace_tipc_sk_sendmsg() trace_tipc_sk_sendmcast() trace_tipc_sk_sendstream() trace_tipc_sk_filter_rcv() trace_tipc_sk_advance_rx() trace_tipc_sk_rej_msg() trace_tipc_sk_drop_msg() trace_tipc_sk_release() trace_tipc_sk_shutdown() trace_tipc_sk_overlimit1() trace_tipc_sk_overlimit2() Also, enables the traces for the following cases: - When user creates a TIPC socket; - When user calls poll() on TIPC socket; - When user sends a dgram/mcast/stream message. - When a message is put into the socket 'sk_receive_queue'; - When a message is released from the socket 'sk_receive_queue'; - When a message is rejected (e.g. due to no port, invalid, etc.); - When a message is dropped (e.g. due to wrong message type); - When socket is released; - When socket is shutdown; - When socket rcvq's allocation is overlimit (> 90%); - When socket rcvq + bklq's allocation is overlimit (> 90%); - When the 'TIPC_ERR_OVERLOAD/2' issue happens; Note: a) All the socket traces are designed to be able to trace on a specific socket by either using the 'event filtering' feature on a known socket 'portid' value or the sysctl file: /proc/sys/net/tipc/sk_filter The file determines a 'tuple' for what socket should be traced: (portid, sock type, name type, name lower, name upper) where: + 'portid' is the socket portid generated at socket creating, can be found in the trace outputs or the 'tipc socket list' command printouts; + 'sock type' is the socket type (1 = SOCK_TREAM, ...); + 'name type', 'name lower' and 'name upper' are the service name being connected to or published by the socket. Value '0' means 'ANY', the default tuple value is (0, 0, 0, 0, 0) i.e. the traces happen for every sockets with no filter. b) The 'tipc_sk_overlimit1/2' event is also a conditional trace_event which happens when the socket receive queue (and backlog queue) is about to be overloaded, when the queue allocation is > 90%. Then, when the trace is enabled, the last skbs leading to the TIPC_ERR_OVERLOAD/2 issue can be traced. The trace event is designed as an 'upper watermark' notification that the other traces (e.g. 'tipc_sk_advance_rx' vs 'tipc_sk_filter_rcv') or actions can be triggerred in the meanwhile to see what is going on with the socket queue. In addition, the 'trace_tipc_sk_dump()' is also placed at the 'TIPC_ERR_OVERLOAD/2' case, so the socket and last skb can be dumped for post-analysis. Acked-by: Ying Xue Tested-by: Ying Xue Acked-by: Jon Maloy Signed-off-by: Tuong Lien --- net/tipc/socket.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- net/tipc/socket.h | 2 + net/tipc/sysctl.c | 8 ++++ net/tipc/trace.c | 6 +++ net/tipc/trace.h | 32 +++++++++++-- 5 files changed, 176 insertions(+), 9 deletions(-) diff --git a/net/tipc/socket.c b/net/tipc/socket.c index b6b2a94eb54e..291d6bbe85f4 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -234,6 +234,7 @@ static u16 tsk_inc(struct tipc_sock *tsk, int msglen) */ static void tsk_advance_rx_queue(struct sock *sk) { + trace_tipc_sk_advance_rx(sk, NULL, TIPC_DUMP_SK_RCVQ, " "); kfree_skb(__skb_dequeue(&sk->sk_receive_queue)); } @@ -248,6 +249,7 @@ static void tipc_sk_respond(struct sock *sk, struct sk_buff *skb, int err) if (!tipc_msg_reverse(onode, &skb, err)) return; + trace_tipc_sk_rej_msg(sk, skb, TIPC_DUMP_NONE, "@sk_respond!"); dnode = msg_destnode(buf_msg(skb)); selector = msg_origport(buf_msg(skb)); tipc_node_xmit_skb(sock_net(sk), skb, dnode, selector); @@ -483,6 +485,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock, tsk_set_unreliable(tsk, true); } + trace_tipc_sk_create(sk, NULL, TIPC_DUMP_NONE, " "); return 0; } @@ -572,6 +575,7 @@ static int tipc_release(struct socket *sock) tsk = tipc_sk(sk); lock_sock(sk); + trace_tipc_sk_release(sk, NULL, TIPC_DUMP_ALL, " "); __tipc_shutdown(sock, TIPC_ERR_NO_PORT); sk->sk_shutdown = SHUTDOWN_MASK; tipc_sk_leave(tsk); @@ -719,6 +723,7 @@ static __poll_t tipc_poll(struct file *file, struct socket *sock, __poll_t revents = 0; sock_poll_wait(file, sock, wait); + trace_tipc_sk_poll(sk, NULL, TIPC_DUMP_ALL, " "); if (sk->sk_shutdown & RCV_SHUTDOWN) revents |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM; @@ -805,9 +810,12 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq, rc = tipc_msg_build(hdr, msg, 0, dlen, mtu, &pkts); /* Send message if build was successful */ - if (unlikely(rc == dlen)) + if (unlikely(rc == dlen)) { + trace_tipc_sk_sendmcast(sk, skb_peek(&pkts), + TIPC_DUMP_SK_SNDQ, " "); rc = tipc_mcast_xmit(net, &pkts, method, &dsts, &tsk->cong_link_cnt); + } tipc_nlist_purge(&dsts); @@ -1209,8 +1217,10 @@ static void tipc_sk_conn_proto_rcv(struct tipc_sock *tsk, struct sk_buff *skb, bool conn_cong; /* Ignore if connection cannot be validated: */ - if (!tsk_peer_msg(tsk, hdr)) + if (!tsk_peer_msg(tsk, hdr)) { + trace_tipc_sk_drop_msg(sk, skb, TIPC_DUMP_NONE, "@proto_rcv!"); goto exit; + } if (unlikely(msg_errcode(hdr))) { tipc_set_sk_state(sk, TIPC_DISCONNECTING); @@ -1378,6 +1388,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dlen) if (unlikely(syn && !tipc_msg_skb_clone(&pkts, &sk->sk_write_queue))) return -ENOMEM; + trace_tipc_sk_sendmsg(sk, skb_peek(&pkts), TIPC_DUMP_SK_SNDQ, " "); rc = tipc_node_xmit(net, &pkts, dnode, tsk->portid); if (unlikely(rc == -ELINKCONG)) { tipc_dest_push(clinks, dnode, 0); @@ -1455,6 +1466,8 @@ static int __tipc_sendstream(struct socket *sock, struct msghdr *m, size_t dlen) if (unlikely(rc != send)) break; + trace_tipc_sk_sendstream(sk, skb_peek(&pkts), + TIPC_DUMP_SK_SNDQ, " "); rc = tipc_node_xmit(net, &pkts, dnode, tsk->portid); if (unlikely(rc == -ELINKCONG)) { tsk->cong_link_cnt = 1; @@ -2129,6 +2142,7 @@ static void tipc_sk_filter_rcv(struct sock *sk, struct sk_buff *skb, struct sk_buff_head inputq; int limit, err = TIPC_OK; + trace_tipc_sk_filter_rcv(sk, skb, TIPC_DUMP_ALL, " "); TIPC_SKB_CB(skb)->bytes_read = 0; __skb_queue_head_init(&inputq); __skb_queue_tail(&inputq, skb); @@ -2148,17 +2162,25 @@ static void tipc_sk_filter_rcv(struct sock *sk, struct sk_buff *skb, (!grp && msg_in_group(hdr))) err = TIPC_ERR_NO_PORT; else if (sk_rmem_alloc_get(sk) + skb->truesize >= limit) { + trace_tipc_sk_dump(sk, skb, TIPC_DUMP_ALL, + "err_overload2!"); atomic_inc(&sk->sk_drops); err = TIPC_ERR_OVERLOAD; } if (unlikely(err)) { - tipc_skb_reject(net, err, skb, xmitq); + if (tipc_msg_reverse(tipc_own_addr(net), &skb, err)) { + trace_tipc_sk_rej_msg(sk, skb, TIPC_DUMP_NONE, + "@filter_rcv!"); + __skb_queue_tail(xmitq, skb); + } err = TIPC_OK; continue; } __skb_queue_tail(&sk->sk_receive_queue, skb); skb_set_owner_r(skb, sk); + trace_tipc_sk_overlimit2(sk, skb, TIPC_DUMP_ALL, + "rcvq >90% allocated!"); sk->sk_data_ready(sk); } } @@ -2224,14 +2246,21 @@ static void tipc_sk_enqueue(struct sk_buff_head *inputq, struct sock *sk, if (!sk->sk_backlog.len) atomic_set(dcnt, 0); lim = rcvbuf_limit(sk, skb) + atomic_read(dcnt); - if (likely(!sk_add_backlog(sk, skb, lim))) + if (likely(!sk_add_backlog(sk, skb, lim))) { + trace_tipc_sk_overlimit1(sk, skb, TIPC_DUMP_ALL, + "bklg & rcvq >90% allocated!"); continue; + } + trace_tipc_sk_dump(sk, skb, TIPC_DUMP_ALL, "err_overload!"); /* Overload => reject message back to sender */ onode = tipc_own_addr(sock_net(sk)); atomic_inc(&sk->sk_drops); - if (tipc_msg_reverse(onode, &skb, TIPC_ERR_OVERLOAD)) + if (tipc_msg_reverse(onode, &skb, TIPC_ERR_OVERLOAD)) { + trace_tipc_sk_rej_msg(sk, skb, TIPC_DUMP_ALL, + "@sk_enqueue!"); __skb_queue_tail(xmitq, skb); + } break; } } @@ -2280,6 +2309,8 @@ void tipc_sk_rcv(struct net *net, struct sk_buff_head *inputq) /* Prepare for message rejection */ if (!tipc_msg_reverse(tipc_own_addr(net), &skb, err)) continue; + + trace_tipc_sk_rej_msg(NULL, skb, TIPC_DUMP_NONE, "@sk_rcv!"); xmit: dnode = msg_destnode(buf_msg(skb)); tipc_node_xmit_skb(net, skb, dnode, dport); @@ -2553,6 +2584,7 @@ static int tipc_shutdown(struct socket *sock, int how) lock_sock(sk); + trace_tipc_sk_shutdown(sk, NULL, TIPC_DUMP_ALL, " "); __tipc_shutdown(sock, TIPC_CONN_SHUTDOWN); sk->sk_shutdown = SEND_SHUTDOWN; @@ -3566,12 +3598,107 @@ int tipc_nl_publ_dump(struct sk_buff *skb, struct netlink_callback *cb) return skb->len; } +/** + * tipc_sk_filtering - check if a socket should be traced + * @sk: the socket to be examined + * @sysctl_tipc_sk_filter[]: the socket tuple for filtering, + * (portid, sock type, name type, name lower, name upper) + * + * Returns true if the socket meets the socket tuple data + * (value 0 = 'any') or when there is no tuple set (all = 0), + * otherwise false + */ +bool tipc_sk_filtering(struct sock *sk) +{ + struct tipc_sock *tsk; + struct publication *p; + u32 _port, _sktype, _type, _lower, _upper; + u32 type = 0, lower = 0, upper = 0; + + if (!sk) + return true; + + tsk = tipc_sk(sk); + + _port = sysctl_tipc_sk_filter[0]; + _sktype = sysctl_tipc_sk_filter[1]; + _type = sysctl_tipc_sk_filter[2]; + _lower = sysctl_tipc_sk_filter[3]; + _upper = sysctl_tipc_sk_filter[4]; + + if (!_port && !_sktype && !_type && !_lower && !_upper) + return true; + + if (_port) + return (_port == tsk->portid); + + if (_sktype && _sktype != sk->sk_type) + return false; + + if (tsk->published) { + p = list_first_entry_or_null(&tsk->publications, + struct publication, binding_sock); + if (p) { + type = p->type; + lower = p->lower; + upper = p->upper; + } + } + + if (!tipc_sk_type_connectionless(sk)) { + type = tsk->conn_type; + lower = tsk->conn_instance; + upper = tsk->conn_instance; + } + + if ((_type && _type != type) || (_lower && _lower != lower) || + (_upper && _upper != upper)) + return false; + + return true; +} + u32 tipc_sock_get_portid(struct sock *sk) { return (sk) ? (tipc_sk(sk))->portid : 0; } /** + * tipc_sk_overlimit1 - check if socket rx queue is about to be overloaded, + * both the rcv and backlog queues are considered + * @sk: tipc sk to be checked + * @skb: tipc msg to be checked + * + * Returns true if the socket rx queue allocation is > 90%, otherwise false + */ + +bool tipc_sk_overlimit1(struct sock *sk, struct sk_buff *skb) +{ + atomic_t *dcnt = &tipc_sk(sk)->dupl_rcvcnt; + unsigned int lim = rcvbuf_limit(sk, skb) + atomic_read(dcnt); + unsigned int qsize = sk->sk_backlog.len + sk_rmem_alloc_get(sk); + + return (qsize > lim * 90 / 100); +} + +/** + * tipc_sk_overlimit2 - check if socket rx queue is about to be overloaded, + * only the rcv queue is considered + * @sk: tipc sk to be checked + * @skb: tipc msg to be checked + * + * Returns true if the socket rx queue allocation is > 90%, otherwise false + */ + +bool tipc_sk_overlimit2(struct sock *sk, struct sk_buff *skb) +{ + unsigned int lim = rcvbuf_limit(sk, skb); + unsigned int qsize = sk_rmem_alloc_get(sk); + + return (qsize > lim * 90 / 100); +} + +/** * tipc_sk_dump - dump TIPC socket * @sk: tipc sk to be dumped * @dqueues: bitmask to decide if any socket queue to be dumped? diff --git a/net/tipc/socket.h b/net/tipc/socket.h index 07e36545b696..235b9679acee 100644 --- a/net/tipc/socket.h +++ b/net/tipc/socket.h @@ -72,5 +72,7 @@ int tipc_dump_start(struct netlink_callback *cb); int __tipc_dump_start(struct netlink_callback *cb, struct net *net); int tipc_dump_done(struct netlink_callback *cb); u32 tipc_sock_get_portid(struct sock *sk); +bool tipc_sk_overlimit1(struct sock *sk, struct sk_buff *skb); +bool tipc_sk_overlimit2(struct sock *sk, struct sk_buff *skb); #endif diff --git a/net/tipc/sysctl.c b/net/tipc/sysctl.c index 1a779b1e8510..3481e4906bd6 100644 --- a/net/tipc/sysctl.c +++ b/net/tipc/sysctl.c @@ -34,6 +34,7 @@ */ #include "core.h" +#include "trace.h" #include @@ -54,6 +55,13 @@ static struct ctl_table tipc_table[] = { .mode = 0644, .proc_handler = proc_dointvec, }, + { + .procname = "sk_filter", + .data = &sysctl_tipc_sk_filter, + .maxlen = sizeof(sysctl_tipc_sk_filter), + .mode = 0644, + .proc_handler = proc_doulongvec_minmax, + }, {} }; diff --git a/net/tipc/trace.c b/net/tipc/trace.c index 846196f0e810..964823841efe 100644 --- a/net/tipc/trace.c +++ b/net/tipc/trace.c @@ -37,6 +37,12 @@ #include "trace.h" /** + * socket tuples for filtering in socket traces: + * (portid, sock type, name type, name lower, name upper) + */ +unsigned long sysctl_tipc_sk_filter[5] __read_mostly = {0, }; + +/** * tipc_skb_dump - dump TIPC skb data * @skb: skb to be dumped * @more: dump more? diff --git a/net/tipc/trace.h b/net/tipc/trace.h index 535c8958651f..ebbfcd14627e 100644 --- a/net/tipc/trace.h +++ b/net/tipc/trace.h @@ -113,11 +113,14 @@ enum { {(0xcbe), "SYNCH_BEGIN_EVT" },\ {(0xcee), "SYNCH_END_EVT" }) +extern unsigned long sysctl_tipc_sk_filter[5] __read_mostly; + int tipc_skb_dump(struct sk_buff *skb, bool more, char *buf); int tipc_list_dump(struct sk_buff_head *list, bool more, char *buf); int tipc_sk_dump(struct sock *sk, u16 dqueues, char *buf); int tipc_link_dump(struct tipc_link *l, u16 dqueues, char *buf); int tipc_node_dump(struct tipc_node *n, bool more, char *buf); +bool tipc_sk_filtering(struct sock *sk); DECLARE_EVENT_CLASS(tipc_skb_class, @@ -199,12 +202,33 @@ DECLARE_EVENT_CLASS(tipc_sk_class, __get_str(skb_buf), __get_str(buf)) ); -#define DEFINE_SK_EVENT(name) \ -DEFINE_EVENT(tipc_sk_class, name, \ +#define DEFINE_SK_EVENT_FILTER(name) \ +DEFINE_EVENT_CONDITION(tipc_sk_class, name, \ + TP_PROTO(struct sock *sk, struct sk_buff *skb, u16 dqueues, \ + const char *header), \ + TP_ARGS(sk, skb, dqueues, header), \ + TP_CONDITION(tipc_sk_filtering(sk))) +DEFINE_SK_EVENT_FILTER(tipc_sk_dump); +DEFINE_SK_EVENT_FILTER(tipc_sk_create); +DEFINE_SK_EVENT_FILTER(tipc_sk_sendmcast); +DEFINE_SK_EVENT_FILTER(tipc_sk_sendmsg); +DEFINE_SK_EVENT_FILTER(tipc_sk_sendstream); +DEFINE_SK_EVENT_FILTER(tipc_sk_poll); +DEFINE_SK_EVENT_FILTER(tipc_sk_filter_rcv); +DEFINE_SK_EVENT_FILTER(tipc_sk_advance_rx); +DEFINE_SK_EVENT_FILTER(tipc_sk_rej_msg); +DEFINE_SK_EVENT_FILTER(tipc_sk_drop_msg); +DEFINE_SK_EVENT_FILTER(tipc_sk_release); +DEFINE_SK_EVENT_FILTER(tipc_sk_shutdown); + +#define DEFINE_SK_EVENT_FILTER_COND(name, cond) \ +DEFINE_EVENT_CONDITION(tipc_sk_class, name, \ TP_PROTO(struct sock *sk, struct sk_buff *skb, u16 dqueues, \ const char *header), \ - TP_ARGS(sk, skb, dqueues, header)) -DEFINE_SK_EVENT(tipc_sk_dump); + TP_ARGS(sk, skb, dqueues, header), \ + TP_CONDITION(tipc_sk_filtering(sk) && (cond))) +DEFINE_SK_EVENT_FILTER_COND(tipc_sk_overlimit1, tipc_sk_overlimit1(sk, skb)); +DEFINE_SK_EVENT_FILTER_COND(tipc_sk_overlimit2, tipc_sk_overlimit2(sk, skb)); DECLARE_EVENT_CLASS(tipc_link_class, From patchwork Wed Dec 19 02:17:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tuong Lien X-Patchwork-Id: 1015798 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=dektech.com.au Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=dektech.com.au header.i=@dektech.com.au header.b="sAgu0IBI"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43KJlV6bdDz9s6w for ; Wed, 19 Dec 2018 13:30:30 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726904AbeLSCa3 (ORCPT ); Tue, 18 Dec 2018 21:30:29 -0500 Received: from f0-dek.dektech.com.au ([210.10.221.142]:57549 "EHLO mail.dektech.com.au" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726614AbeLSCa2 (ORCPT ); Tue, 18 Dec 2018 21:30:28 -0500 Received: from localhost (localhost [127.0.0.1]) by mail.dektech.com.au (Postfix) with ESMTP id 023EDF77BE; Wed, 19 Dec 2018 13:18:16 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=dektech.com.au; h=references:in-reply-to:x-mailer:message-id:date:date:subject :subject:from:from:received:received:received; s=mail_dkim; t= 1545185895; bh=3B8Rh11a8b1sZjj5T3nstDpZqvXhilkeR3TtFOC9c9o=; b=s Agu0IBIIJsYotU5mEaj+aA9SD7TA7CkjFFR2jaiB9Hh3m+GpghUK+eDy5t64wZu5 HbYVtWtJGT1WQNxFOCdxFCLSffTTMG0YWMptnJp3kbxRK60HJphquWXiHQKVjnfi iPL908ZfdU1lfP3Wxlb8taKHXrDoRBj8lK22rHrXtM= X-Virus-Scanned: amavisd-new at dektech.com.au Received: from mail.dektech.com.au ([127.0.0.1]) by localhost (mail2.dektech.com.au [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id elPRduK8bDf5; Wed, 19 Dec 2018 13:18:15 +1100 (AEDT) Received: from mail.dektech.com.au (localhost [127.0.0.1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.dektech.com.au (Postfix) with ESMTPS id D7A03F77C9; Wed, 19 Dec 2018 13:18:15 +1100 (AEDT) Received: from localhost.localdomain (unknown [14.161.14.188]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) by mail.dektech.com.au (Postfix) with ESMTPSA id 966DFF77BE; Wed, 19 Dec 2018 13:18:14 +1100 (AEDT) From: Tuong Lien To: davem@davemloft.net, jon.maloy@ericsson.com, netdev@vger.kernel.org Cc: tipc-discussion@lists.sourceforge.net Subject: [net-next 4/5] tipc: add trace_events for tipc node Date: Wed, 19 Dec 2018 09:17:59 +0700 Message-Id: <20181219021800.21662-5-tuong.t.lien@dektech.com.au> X-Mailer: git-send-email 2.13.7 In-Reply-To: <20181219021800.21662-1-tuong.t.lien@dektech.com.au> References: <20181219021800.21662-1-tuong.t.lien@dektech.com.au> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The commit adds the new trace_events for TIPC node object: trace_tipc_node_create() trace_tipc_node_delete() trace_tipc_node_lost_contact() trace_tipc_node_timeout() trace_tipc_node_link_up() trace_tipc_node_link_down() trace_tipc_node_reset_links() trace_tipc_node_fsm_evt() trace_tipc_node_check_state() Also, enables the traces for the following cases: - When a node is created/deleted; - When a node contact is lost; - When a node timer is timed out; - When a node link is up/down; - When all node links are reset; - When node state is changed; - When a skb comes and node state needs to be checked/updated. Acked-by: Ying Xue Tested-by: Ying Xue Acked-by: Jon Maloy Signed-off-by: Tuong Lien --- net/tipc/node.c | 15 +++++++++++++++ net/tipc/trace.h | 9 +++++++++ 2 files changed, 24 insertions(+) diff --git a/net/tipc/node.c b/net/tipc/node.c index cff42c95cef8..a67c40bf6e6c 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -433,6 +433,7 @@ static struct tipc_node *tipc_node_create(struct net *net, u32 addr, break; } list_add_tail_rcu(&n->list, &temp_node->list); + trace_tipc_node_create(n, true, " "); exit: spin_unlock_bh(&tn->node_list_lock); return n; @@ -460,6 +461,7 @@ static void tipc_node_delete_from_list(struct tipc_node *node) static void tipc_node_delete(struct tipc_node *node) { + trace_tipc_node_delete(node, true, " "); tipc_node_delete_from_list(node); del_timer_sync(&node->timer); @@ -614,6 +616,7 @@ static void tipc_node_timeout(struct timer_list *t) int bearer_id; int rc = 0; + trace_tipc_node_timeout(n, false, " "); if (!node_is_up(n) && tipc_node_cleanup(n)) { /*Removing the reference of Timer*/ tipc_node_put(n); @@ -673,6 +676,7 @@ static void __tipc_node_link_up(struct tipc_node *n, int bearer_id, pr_debug("Established link <%s> on network plane %c\n", tipc_link_name(nl), tipc_link_plane(nl)); + trace_tipc_node_link_up(n, true, " "); /* Ensure that a STATE message goes first */ tipc_link_build_state_msg(nl, xmitq); @@ -826,6 +830,7 @@ static void tipc_node_link_down(struct tipc_node *n, int bearer_id, bool delete) /* Defuse pending tipc_node_link_up() */ tipc_link_fsm_evt(l, LINK_RESET_EVT); } + trace_tipc_node_link_down(n, true, "node link down or deleted!"); tipc_node_write_unlock(n); if (delete) tipc_mon_remove_peer(n->net, n->addr, old_bearer_id); @@ -1055,6 +1060,7 @@ static void tipc_node_reset_links(struct tipc_node *n) pr_warn("Resetting all links to %x\n", n->addr); + trace_tipc_node_reset_links(n, true, " "); for (i = 0; i < MAX_BEARERS; i++) { tipc_node_link_down(n, i, false); } @@ -1230,11 +1236,13 @@ static void tipc_node_fsm_evt(struct tipc_node *n, int evt) pr_err("Unknown node fsm state %x\n", state); break; } + trace_tipc_node_fsm(n->peer_id, n->state, state, evt); n->state = state; return; illegal_evt: pr_err("Illegal node fsm evt %x in state %x\n", evt, state); + trace_tipc_node_fsm(n->peer_id, n->state, state, evt); } static void node_lost_contact(struct tipc_node *n, @@ -1248,6 +1256,7 @@ static void node_lost_contact(struct tipc_node *n, pr_debug("Lost contact with %x\n", n->addr); n->delete_at = jiffies + msecs_to_jiffies(NODE_CLEANUP_AFTER); + trace_tipc_node_lost_contact(n, true, " "); /* Clean up broadcast state */ tipc_bcast_remove_peer(n->net, n->bc_entry.link); @@ -1572,6 +1581,10 @@ static bool tipc_node_check_state(struct tipc_node *n, struct sk_buff *skb, struct tipc_media_addr *maddr; int pb_id; + if (trace_tipc_node_check_state_enabled()) { + trace_tipc_skb_dump(skb, false, "skb for node state check"); + trace_tipc_node_check_state(n, true, " "); + } l = n->links[bearer_id].link; if (!l) return false; @@ -1623,6 +1636,8 @@ static bool tipc_node_check_state(struct tipc_node *n, struct sk_buff *skb, syncpt = oseqno + exp_pkts - 1; if (pl && tipc_link_is_up(pl)) { __tipc_node_link_down(n, &pb_id, xmitq, &maddr); + trace_tipc_node_link_down(n, true, + "node link down <- failover!"); tipc_skb_queue_splice_tail_init(tipc_link_inputq(pl), tipc_link_inputq(l)); } diff --git a/net/tipc/trace.h b/net/tipc/trace.h index ebbfcd14627e..4d05141866aa 100644 --- a/net/tipc/trace.h +++ b/net/tipc/trace.h @@ -337,6 +337,14 @@ DEFINE_EVENT(tipc_node_class, name, \ TP_PROTO(struct tipc_node *n, bool more, const char *header), \ TP_ARGS(n, more, header)) DEFINE_NODE_EVENT(tipc_node_dump); +DEFINE_NODE_EVENT(tipc_node_create); +DEFINE_NODE_EVENT(tipc_node_delete); +DEFINE_NODE_EVENT(tipc_node_lost_contact); +DEFINE_NODE_EVENT(tipc_node_timeout); +DEFINE_NODE_EVENT(tipc_node_link_up); +DEFINE_NODE_EVENT(tipc_node_link_down); +DEFINE_NODE_EVENT(tipc_node_reset_links); +DEFINE_NODE_EVENT(tipc_node_check_state); DECLARE_EVENT_CLASS(tipc_fsm_class, @@ -368,6 +376,7 @@ DEFINE_EVENT(tipc_fsm_class, fsm_name, \ TP_PROTO(const char *name, u32 os, u32 ns, int evt), \ TP_ARGS(name, os, ns, evt)) DEFINE_FSM_EVENT(tipc_link_fsm); +DEFINE_FSM_EVENT(tipc_node_fsm); #endif /* _TIPC_TRACE_H */ From patchwork Wed Dec 19 02:18:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tuong Lien X-Patchwork-Id: 1015802 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=dektech.com.au Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=dektech.com.au header.i=@dektech.com.au header.b="a+tEYb7S"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43KJlh18Wwz9s6w for ; Wed, 19 Dec 2018 13:30:40 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727074AbeLSCai (ORCPT ); Tue, 18 Dec 2018 21:30:38 -0500 Received: from f0-dek.dektech.com.au ([210.10.221.142]:46013 "EHLO mail.dektech.com.au" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726631AbeLSCaa (ORCPT ); Tue, 18 Dec 2018 21:30:30 -0500 Received: from localhost (localhost [127.0.0.1]) by mail.dektech.com.au (Postfix) with ESMTP id 9960CF77C9; Wed, 19 Dec 2018 13:18:17 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=dektech.com.au; h=references:in-reply-to:x-mailer:message-id:date:date:subject :subject:from:from:received:received:received; s=mail_dkim; t= 1545185897; bh=nrw2qWgxv5a7qk1Fub0tzwbjwgZ0VzatEKca9ulZtMQ=; b=a +tEYb7SPvhz6j8zD7tYb4saRGKyKr4XvfZOuXTxjTMCGi4pOkmHJcnIWdwu8RFuf Vk7PDgcmX4RYlTb909OwJJCAraF+TAr7O7gYjcpg/XecCxvBE215RVYA5TB5j5oU ViTeuXuz24fYLArGIb1d+/80X+FrK0gkFi9PufiC6c= X-Virus-Scanned: amavisd-new at dektech.com.au Received: from mail.dektech.com.au ([127.0.0.1]) by localhost (mail2.dektech.com.au [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id xfpYdjUG0P0v; Wed, 19 Dec 2018 13:18:17 +1100 (AEDT) Received: from mail.dektech.com.au (localhost [127.0.0.1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.dektech.com.au (Postfix) with ESMTPS id 8060BF77EF; Wed, 19 Dec 2018 13:18:17 +1100 (AEDT) Received: from localhost.localdomain (unknown [14.161.14.188]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) by mail.dektech.com.au (Postfix) with ESMTPSA id 41426F77C9; Wed, 19 Dec 2018 13:18:16 +1100 (AEDT) From: Tuong Lien To: davem@davemloft.net, jon.maloy@ericsson.com, netdev@vger.kernel.org Cc: tipc-discussion@lists.sourceforge.net Subject: [net-next 5/5] tipc: add trace_events for tipc bearer Date: Wed, 19 Dec 2018 09:18:00 +0700 Message-Id: <20181219021800.21662-6-tuong.t.lien@dektech.com.au> X-Mailer: git-send-email 2.13.7 In-Reply-To: <20181219021800.21662-1-tuong.t.lien@dektech.com.au> References: <20181219021800.21662-1-tuong.t.lien@dektech.com.au> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The commit adds the new trace_event for TIPC bearer, L2 device event: trace_tipc_l2_device_event() Also, it puts the trace at the tipc_l2_device_event() function, then the device/bearer events and related info can be traced out during runtime when needed. Acked-by: Ying Xue Tested-by: Ying Xue Acked-by: Jon Maloy Signed-off-by: Tuong Lien --- net/tipc/bearer.c | 2 ++ net/tipc/trace.h | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index e32294f37c29..fb2c0d8f359f 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -43,6 +43,7 @@ #include "bcast.h" #include "netlink.h" #include "udp_media.h" +#include "trace.h" #define MAX_ADDR_STR 60 @@ -608,6 +609,7 @@ static int tipc_l2_device_event(struct notifier_block *nb, unsigned long evt, if (!b) return NOTIFY_DONE; + trace_tipc_l2_device_event(dev, b, evt); switch (evt) { case NETDEV_CHANGE: if (netif_carrier_ok(dev) && netif_oper_up(dev)) { diff --git a/net/tipc/trace.h b/net/tipc/trace.h index 4d05141866aa..4d8e00483afc 100644 --- a/net/tipc/trace.h +++ b/net/tipc/trace.h @@ -113,6 +113,17 @@ enum { {(0xcbe), "SYNCH_BEGIN_EVT" },\ {(0xcee), "SYNCH_END_EVT" }) +/* Bearer, net device events: */ +#define dev_evt_sym(val) \ + __print_symbolic(val, \ + {(NETDEV_CHANGE), "NETDEV_CHANGE" },\ + {(NETDEV_GOING_DOWN), "NETDEV_GOING_DOWN" },\ + {(NETDEV_UP), "NETDEV_UP" },\ + {(NETDEV_CHANGEMTU), "NETDEV_CHANGEMTU" },\ + {(NETDEV_CHANGEADDR), "NETDEV_CHANGEADDR" },\ + {(NETDEV_UNREGISTER), "NETDEV_UNREGISTER" },\ + {(NETDEV_CHANGENAME), "NETDEV_CHANGENAME" }) + extern unsigned long sysctl_tipc_sk_filter[5] __read_mostly; int tipc_skb_dump(struct sk_buff *skb, bool more, char *buf); @@ -378,6 +389,38 @@ DEFINE_EVENT(tipc_fsm_class, fsm_name, \ DEFINE_FSM_EVENT(tipc_link_fsm); DEFINE_FSM_EVENT(tipc_node_fsm); +TRACE_EVENT(tipc_l2_device_event, + + TP_PROTO(struct net_device *dev, struct tipc_bearer *b, + unsigned long evt), + + TP_ARGS(dev, b, evt), + + TP_STRUCT__entry( + __string(dev_name, dev->name) + __string(b_name, b->name) + __field(unsigned long, evt) + __field(u8, b_up) + __field(u8, carrier) + __field(u8, oper) + ), + + TP_fast_assign( + __assign_str(dev_name, dev->name); + __assign_str(b_name, b->name); + __entry->evt = evt; + __entry->b_up = test_bit(0, &b->up); + __entry->carrier = netif_carrier_ok(dev); + __entry->oper = netif_oper_up(dev); + ), + + TP_printk("%s on: <%s>/<%s> oper: %s carrier: %s bearer: %s\n", + dev_evt_sym(__entry->evt), __get_str(dev_name), + __get_str(b_name), (__entry->oper) ? "up" : "down", + (__entry->carrier) ? "ok" : "notok", + (__entry->b_up) ? "up" : "down") +); + #endif /* _TIPC_TRACE_H */ /* This part must be outside protection */