aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/link.c
diff options
context:
space:
mode:
authorTuong Lien <tuong.t.lien@dektech.com.au>2018-12-18 21:17:57 -0500
committerDavid S. Miller <davem@davemloft.net>2018-12-19 14:49:24 -0500
commit26574db0c17fb29fac8b57f94ed1dfd46cc89887 (patch)
tree16e8309ffb799eacb56d89d230ce91fa491cc55b /net/tipc/link.c
parentb4b9771bcbbd5839b0f77aba55e2f85989ed6779 (diff)
tipc: add trace_events for tipc link
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 <ying.xue@windriver.com> Tested-by: Ying Xue <ying.xue@windriver.com> Acked-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: Tuong Lien <tuong.t.lien@dektech.com.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/link.c')
-rw-r--r--net/tipc/link.c33
1 files changed, 32 insertions, 1 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,
357 rcv_l->bc_peer_is_up = true; 357 rcv_l->bc_peer_is_up = true;
358 rcv_l->state = LINK_ESTABLISHED; 358 rcv_l->state = LINK_ESTABLISHED;
359 tipc_link_bc_ack_rcv(rcv_l, ack, xmitq); 359 tipc_link_bc_ack_rcv(rcv_l, ack, xmitq);
360 trace_tipc_link_reset(rcv_l, TIPC_DUMP_ALL, "bclink removed!");
360 tipc_link_reset(rcv_l); 361 tipc_link_reset(rcv_l);
361 rcv_l->state = LINK_RESET; 362 rcv_l->state = LINK_RESET;
362 if (!snd_l->ackers) { 363 if (!snd_l->ackers) {
364 trace_tipc_link_reset(snd_l, TIPC_DUMP_ALL, "zero ackers!");
363 tipc_link_reset(snd_l); 365 tipc_link_reset(snd_l);
364 snd_l->state = LINK_RESET; 366 snd_l->state = LINK_RESET;
365 __skb_queue_purge(xmitq); 367 __skb_queue_purge(xmitq);
@@ -523,6 +525,7 @@ bool tipc_link_bc_create(struct net *net, u32 ownnode, u32 peer,
523 525
524 l = *link; 526 l = *link;
525 strcpy(l->name, tipc_bclink_name); 527 strcpy(l->name, tipc_bclink_name);
528 trace_tipc_link_reset(l, TIPC_DUMP_ALL, "bclink created!");
526 tipc_link_reset(l); 529 tipc_link_reset(l);
527 l->state = LINK_RESET; 530 l->state = LINK_RESET;
528 l->ackers = 0; 531 l->ackers = 0;
@@ -547,6 +550,7 @@ bool tipc_link_bc_create(struct net *net, u32 ownnode, u32 peer,
547int tipc_link_fsm_evt(struct tipc_link *l, int evt) 550int tipc_link_fsm_evt(struct tipc_link *l, int evt)
548{ 551{
549 int rc = 0; 552 int rc = 0;
553 int old_state = l->state;
550 554
551 switch (l->state) { 555 switch (l->state) {
552 case LINK_RESETTING: 556 case LINK_RESETTING:
@@ -693,10 +697,12 @@ int tipc_link_fsm_evt(struct tipc_link *l, int evt)
693 default: 697 default:
694 pr_err("Unknown FSM state %x in %s\n", l->state, l->name); 698 pr_err("Unknown FSM state %x in %s\n", l->state, l->name);
695 } 699 }
700 trace_tipc_link_fsm(l->name, old_state, l->state, evt);
696 return rc; 701 return rc;
697illegal_evt: 702illegal_evt:
698 pr_err("Illegal FSM event %x in state %x on link %s\n", 703 pr_err("Illegal FSM event %x in state %x on link %s\n",
699 evt, l->state, l->name); 704 evt, l->state, l->name);
705 trace_tipc_link_fsm(l->name, old_state, l->state, evt);
700 return rc; 706 return rc;
701} 707}
702 708
@@ -741,6 +747,18 @@ static void link_profile_stats(struct tipc_link *l)
741 l->stats.msg_length_profile[6]++; 747 l->stats.msg_length_profile[6]++;
742} 748}
743 749
750/**
751 * tipc_link_too_silent - check if link is "too silent"
752 * @l: tipc link to be checked
753 *
754 * Returns true if the link 'silent_intv_cnt' is about to reach the
755 * 'abort_limit' value, otherwise false
756 */
757bool tipc_link_too_silent(struct tipc_link *l)
758{
759 return (l->silent_intv_cnt + 2 > l->abort_limit);
760}
761
744/* tipc_link_timeout - perform periodic task as instructed from node timeout 762/* tipc_link_timeout - perform periodic task as instructed from node timeout
745 */ 763 */
746int tipc_link_timeout(struct tipc_link *l, struct sk_buff_head *xmitq) 764int 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)
754 u16 bc_acked = l->bc_rcvlink->acked; 772 u16 bc_acked = l->bc_rcvlink->acked;
755 struct tipc_mon_state *mstate = &l->mon_state; 773 struct tipc_mon_state *mstate = &l->mon_state;
756 774
775 trace_tipc_link_timeout(l, TIPC_DUMP_NONE, " ");
776 trace_tipc_link_too_silent(l, TIPC_DUMP_ALL, " ");
757 switch (l->state) { 777 switch (l->state) {
758 case LINK_ESTABLISHED: 778 case LINK_ESTABLISHED:
759 case LINK_SYNCHING: 779 case LINK_SYNCHING:
@@ -816,6 +836,7 @@ static int link_schedule_user(struct tipc_link *l, struct tipc_msg *hdr)
816 TIPC_SKB_CB(skb)->chain_imp = msg_importance(hdr); 836 TIPC_SKB_CB(skb)->chain_imp = msg_importance(hdr);
817 skb_queue_tail(&l->wakeupq, skb); 837 skb_queue_tail(&l->wakeupq, skb);
818 l->stats.link_congs++; 838 l->stats.link_congs++;
839 trace_tipc_link_conges(l, TIPC_DUMP_ALL, "wakeup scheduled!");
819 return -ELINKCONG; 840 return -ELINKCONG;
820} 841}
821 842
@@ -1037,6 +1058,7 @@ static int tipc_link_retrans(struct tipc_link *l, struct tipc_link *r,
1037 if (less(to, from)) 1058 if (less(to, from))
1038 return 0; 1059 return 0;
1039 1060
1061 trace_tipc_link_retrans(r, from, to, &l->transmq);
1040 /* Detect repeated retransmit failures on same packet */ 1062 /* Detect repeated retransmit failures on same packet */
1041 if (r->prev_from != from) { 1063 if (r->prev_from != from) {
1042 r->prev_from = from; 1064 r->prev_from = from;
@@ -1044,6 +1066,9 @@ static int tipc_link_retrans(struct tipc_link *l, struct tipc_link *r,
1044 r->stale_cnt = 0; 1066 r->stale_cnt = 0;
1045 } else if (++r->stale_cnt > 99 && time_after(jiffies, r->stale_limit)) { 1067 } else if (++r->stale_cnt > 99 && time_after(jiffies, r->stale_limit)) {
1046 link_retransmit_failure(l, skb); 1068 link_retransmit_failure(l, skb);
1069 trace_tipc_list_dump(&l->transmq, true, "retrans failure!");
1070 trace_tipc_link_dump(l, TIPC_DUMP_NONE, "retrans failure!");
1071 trace_tipc_link_dump(r, TIPC_DUMP_NONE, "retrans failure!");
1047 if (link_is_bc_sndlink(l)) 1072 if (link_is_bc_sndlink(l))
1048 return TIPC_LINK_DOWN_EVT; 1073 return TIPC_LINK_DOWN_EVT;
1049 return tipc_link_fsm_evt(l, LINK_FAILURE_EVT); 1074 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,
1403 l->stats.sent_nacks++; 1428 l->stats.sent_nacks++;
1404 skb->priority = TC_PRIO_CONTROL; 1429 skb->priority = TC_PRIO_CONTROL;
1405 __skb_queue_tail(xmitq, skb); 1430 __skb_queue_tail(xmitq, skb);
1431 trace_tipc_proto_build(skb, false, l->name);
1406} 1432}
1407 1433
1408void tipc_link_create_dummy_tnl_msg(struct tipc_link *l, 1434void 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,
1566 char *if_name; 1592 char *if_name;
1567 int rc = 0; 1593 int rc = 0;
1568 1594
1595 trace_tipc_proto_rcv(skb, false, l->name);
1569 if (tipc_link_is_blocked(l) || !xmitq) 1596 if (tipc_link_is_blocked(l) || !xmitq)
1570 goto exit; 1597 goto exit;
1571 1598
@@ -1576,8 +1603,11 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
1576 hdr = buf_msg(skb); 1603 hdr = buf_msg(skb);
1577 data = msg_data(hdr); 1604 data = msg_data(hdr);
1578 1605
1579 if (!tipc_link_validate_msg(l, hdr)) 1606 if (!tipc_link_validate_msg(l, hdr)) {
1607 trace_tipc_skb_dump(skb, false, "PROTO invalid (1)!");
1608 trace_tipc_link_dump(l, TIPC_DUMP_NONE, "PROTO invalid (1)!");
1580 goto exit; 1609 goto exit;
1610 }
1581 1611
1582 switch (mtyp) { 1612 switch (mtyp) {
1583 case RESET_MSG: 1613 case RESET_MSG:
@@ -1820,6 +1850,7 @@ void tipc_link_bc_ack_rcv(struct tipc_link *l, u16 acked,
1820 if (!more(acked, l->acked)) 1850 if (!more(acked, l->acked))
1821 return; 1851 return;
1822 1852
1853 trace_tipc_link_bc_ack(l, l->acked, acked, &snd_l->transmq);
1823 /* Skip over packets peer has already acked */ 1854 /* Skip over packets peer has already acked */
1824 skb_queue_walk(&snd_l->transmq, skb) { 1855 skb_queue_walk(&snd_l->transmq, skb) {
1825 if (more(buf_seqno(skb), l->acked)) 1856 if (more(buf_seqno(skb), l->acked))