Commit 013dc9d5 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'tipc-tracepoints'



Tuong Lien says:

====================
tipc: tracepoints and trace_events in TIPC

The patch series is the first step of introducing a tracing framework in
TIPC, which will assist in collecting complete & plentiful data for post
analysis, even in the case of a single failure occurrence e.g. when the
failure is unreproducible.

The tracing code in TIPC utilizes the powerful kernel tracepoints, trace
events features along with particular dump functions to trace the TIPC
object data and events (incl. bearer, link, socket, node, etc.).

The tracing code should generate zero-load to TIPC when the trace events
are not enabled.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 4a54877e cf5f55f7
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -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
+6 −3
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@
#include "bcast.h"
#include "netlink.h"
#include "udp_media.h"
#include "trace.h"

#define MAX_ADDR_STR 60

@@ -99,7 +100,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 +115,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;
}

/**
@@ -607,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)) {
+1 −1
Original line number Diff line number Diff line
@@ -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);
+152 −1
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@
#include "discover.h"
#include "netlink.h"
#include "monitor.h"
#include "trace.h"

#include <linux/pkt_sched.h>

@@ -356,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);
@@ -522,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;
@@ -546,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:
@@ -692,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;
}

@@ -740,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)
@@ -753,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:
@@ -815,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;
}

@@ -1036,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;
@@ -1043,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);
@@ -1402,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,
@@ -1565,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;

@@ -1575,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:
@@ -1819,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))
@@ -2222,3 +2254,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;
}
+2 −0
Original line number Diff line number Diff line
@@ -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);
@@ -147,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
Loading