aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2015-05-14 10:46:16 -0400
committerDavid S. Miller <davem@davemloft.net>2015-05-14 12:24:46 -0400
commitcd4eee3c2e3e01590df5cada0d56b396dd726d05 (patch)
tree0c9475e8f7be10e84a3a52357685bf7657e4ecda /net/tipc
parenta97b9d3fa9bce0d78dc83a14a9e1ebb3bf5cc414 (diff)
tipc: simplify link supervision checkpointing
We change the sequence number checkpointing that is performed by the timer in order to discover if the peer is active. Currently, we store a checkpoint of the next expected sequence number "rcv_nxt" at each timer expiration, and compare it to the current expected number at next timeout expiration. Instead, we now use the already existing field "silent_intv_cnt" for this task. We step the counter at each timeout expiration, and zero it at each valid received packet. If no valid packet has been received from the peer after "abort_limit" number of silent timer intervals, the link is declared faulty and reset. We also remove the multiple instances of timer activation from inside the FSM function "link_state_event()", and now do it at only one place; at the end of the timer function itself. Reviewed-by: Erik Hugne <erik.hugne@ericsson.com> Reviewed-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/link.c81
-rw-r--r--net/tipc/link.h2
2 files changed, 22 insertions, 61 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c
index c39543e8112d..a5ea19e9690f 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -86,7 +86,7 @@ static const struct nla_policy tipc_nl_prop_policy[TIPC_NLA_PROP_MAX + 1] = {
86 */ 86 */
87#define STARTING_EVT 856384768 /* link processing trigger */ 87#define STARTING_EVT 856384768 /* link processing trigger */
88#define TRAFFIC_MSG_EVT 560815u /* rx'd ??? */ 88#define TRAFFIC_MSG_EVT 560815u /* rx'd ??? */
89#define TIMEOUT_EVT 560817u /* link timer expired */ 89#define SILENCE_EVT 560817u /* timer dicovered silence from peer */
90 90
91/* 91/*
92 * State value stored in 'failover_pkts' 92 * State value stored in 'failover_pkts'
@@ -106,6 +106,7 @@ static void tipc_link_sync_rcv(struct tipc_node *n, struct sk_buff *buf);
106static void tipc_link_input(struct tipc_link *l, struct sk_buff *skb); 106static void tipc_link_input(struct tipc_link *l, struct sk_buff *skb);
107static bool tipc_data_input(struct tipc_link *l, struct sk_buff *skb); 107static bool tipc_data_input(struct tipc_link *l, struct sk_buff *skb);
108static bool tipc_link_failover_rcv(struct tipc_link *l, struct sk_buff **skb); 108static bool tipc_link_failover_rcv(struct tipc_link *l, struct sk_buff **skb);
109static void link_set_timer(struct tipc_link *link, unsigned long time);
109/* 110/*
110 * Simple link routines 111 * Simple link routines
111 */ 112 */
@@ -197,11 +198,12 @@ static void link_timeout(unsigned long data)
197 } 198 }
198 199
199 /* do all other link processing performed on a periodic basis */ 200 /* do all other link processing performed on a periodic basis */
200 link_state_event(l_ptr, TIMEOUT_EVT); 201 if (l_ptr->silent_intv_cnt || tipc_bclink_acks_missing(l_ptr->owner))
201 202 link_state_event(l_ptr, SILENCE_EVT);
203 l_ptr->silent_intv_cnt++;
202 if (skb_queue_len(&l_ptr->backlogq)) 204 if (skb_queue_len(&l_ptr->backlogq))
203 tipc_link_push_packets(l_ptr); 205 tipc_link_push_packets(l_ptr);
204 206 link_set_timer(l_ptr, l_ptr->keepalive_intv);
205 tipc_node_unlock(l_ptr->owner); 207 tipc_node_unlock(l_ptr->owner);
206 tipc_link_put(l_ptr); 208 tipc_link_put(l_ptr);
207} 209}
@@ -261,7 +263,6 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
261 /* note: peer i/f name is updated by reset/activate message */ 263 /* note: peer i/f name is updated by reset/activate message */
262 memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr)); 264 memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr));
263 l_ptr->owner = n_ptr; 265 l_ptr->owner = n_ptr;
264 l_ptr->checkpoint = 1;
265 l_ptr->peer_session = INVALID_SESSION; 266 l_ptr->peer_session = INVALID_SESSION;
266 l_ptr->bearer_id = b_ptr->identity; 267 l_ptr->bearer_id = b_ptr->identity;
267 link_set_supervision_props(l_ptr, b_ptr->tolerance); 268 link_set_supervision_props(l_ptr, b_ptr->tolerance);
@@ -468,7 +469,6 @@ void tipc_link_reset(struct tipc_link *l_ptr)
468 tipc_link_purge_backlog(l_ptr); 469 tipc_link_purge_backlog(l_ptr);
469 l_ptr->reasm_buf = NULL; 470 l_ptr->reasm_buf = NULL;
470 l_ptr->rcv_unacked = 0; 471 l_ptr->rcv_unacked = 0;
471 l_ptr->checkpoint = 1;
472 l_ptr->snd_nxt = 1; 472 l_ptr->snd_nxt = 1;
473 l_ptr->silent_intv_cnt = 0; 473 l_ptr->silent_intv_cnt = 0;
474 l_ptr->stale_count = 0; 474 l_ptr->stale_count = 0;
@@ -481,6 +481,7 @@ static void link_activate(struct tipc_link *link)
481 481
482 link->rcv_nxt = 1; 482 link->rcv_nxt = 1;
483 link->stats.recv_info = 1; 483 link->stats.recv_info = 1;
484 link->silent_intv_cnt = 0;
484 tipc_node_link_up(node, link); 485 tipc_node_link_up(node, link);
485 tipc_bearer_add_dest(node->net, link->bearer_id, link->addr); 486 tipc_bearer_add_dest(node->net, link->bearer_id, link->addr);
486} 487}
@@ -501,45 +502,33 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
501 if (!(l_ptr->flags & LINK_STARTED) && (event != STARTING_EVT)) 502 if (!(l_ptr->flags & LINK_STARTED) && (event != STARTING_EVT))
502 return; /* Not yet. */ 503 return; /* Not yet. */
503 504
504 if (l_ptr->flags & LINK_FAILINGOVER) { 505 if (l_ptr->flags & LINK_FAILINGOVER)
505 if (event == TIMEOUT_EVT)
506 link_set_timer(l_ptr, timer_intv);
507 return; 506 return;
508 }
509 507
510 switch (l_ptr->state) { 508 switch (l_ptr->state) {
511 case WORKING_WORKING: 509 case WORKING_WORKING:
512 switch (event) { 510 switch (event) {
513 case TRAFFIC_MSG_EVT: 511 case TRAFFIC_MSG_EVT:
514 case ACTIVATE_MSG: 512 case ACTIVATE_MSG:
513 l_ptr->silent_intv_cnt = 0;
515 break; 514 break;
516 case TIMEOUT_EVT: 515 case SILENCE_EVT:
517 if (l_ptr->rcv_nxt != l_ptr->checkpoint) { 516 if (!l_ptr->silent_intv_cnt) {
518 l_ptr->checkpoint = l_ptr->rcv_nxt; 517 if (tipc_bclink_acks_missing(l_ptr->owner))
519 if (tipc_bclink_acks_missing(l_ptr->owner)) {
520 tipc_link_proto_xmit(l_ptr, STATE_MSG, 518 tipc_link_proto_xmit(l_ptr, STATE_MSG,
521 0, 0, 0, 0); 519 0, 0, 0, 0);
522 l_ptr->silent_intv_cnt++;
523 }
524 link_set_timer(l_ptr, timer_intv);
525 break; 520 break;
526 } 521 }
527 l_ptr->state = WORKING_UNKNOWN; 522 l_ptr->state = WORKING_UNKNOWN;
528 l_ptr->silent_intv_cnt = 0;
529 tipc_link_proto_xmit(l_ptr, STATE_MSG, 1, 0, 0, 0); 523 tipc_link_proto_xmit(l_ptr, STATE_MSG, 1, 0, 0, 0);
530 l_ptr->silent_intv_cnt++;
531 link_set_timer(l_ptr, timer_intv);
532 break; 524 break;
533 case RESET_MSG: 525 case RESET_MSG:
534 pr_debug("%s<%s>, requested by peer\n", 526 pr_debug("%s<%s>, requested by peer\n",
535 link_rst_msg, l_ptr->name); 527 link_rst_msg, l_ptr->name);
536 tipc_link_reset(l_ptr); 528 tipc_link_reset(l_ptr);
537 l_ptr->state = RESET_RESET; 529 l_ptr->state = RESET_RESET;
538 l_ptr->silent_intv_cnt = 0;
539 tipc_link_proto_xmit(l_ptr, ACTIVATE_MSG, 530 tipc_link_proto_xmit(l_ptr, ACTIVATE_MSG,
540 0, 0, 0, 0); 531 0, 0, 0, 0);
541 l_ptr->silent_intv_cnt++;
542 link_set_timer(l_ptr, timer_intv);
543 break; 532 break;
544 default: 533 default:
545 pr_debug("%s%u in WW state\n", link_unk_evt, event); 534 pr_debug("%s%u in WW state\n", link_unk_evt, event);
@@ -551,46 +540,32 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
551 case ACTIVATE_MSG: 540 case ACTIVATE_MSG:
552 l_ptr->state = WORKING_WORKING; 541 l_ptr->state = WORKING_WORKING;
553 l_ptr->silent_intv_cnt = 0; 542 l_ptr->silent_intv_cnt = 0;
554 link_set_timer(l_ptr, timer_intv);
555 break; 543 break;
556 case RESET_MSG: 544 case RESET_MSG:
557 pr_debug("%s<%s>, requested by peer while probing\n", 545 pr_debug("%s<%s>, requested by peer while probing\n",
558 link_rst_msg, l_ptr->name); 546 link_rst_msg, l_ptr->name);
559 tipc_link_reset(l_ptr); 547 tipc_link_reset(l_ptr);
560 l_ptr->state = RESET_RESET; 548 l_ptr->state = RESET_RESET;
561 l_ptr->silent_intv_cnt = 0;
562 tipc_link_proto_xmit(l_ptr, ACTIVATE_MSG, 549 tipc_link_proto_xmit(l_ptr, ACTIVATE_MSG,
563 0, 0, 0, 0); 550 0, 0, 0, 0);
564 l_ptr->silent_intv_cnt++;
565 link_set_timer(l_ptr, timer_intv);
566 break; 551 break;
567 case TIMEOUT_EVT: 552 case SILENCE_EVT:
568 if (l_ptr->rcv_nxt != l_ptr->checkpoint) { 553 if (!l_ptr->silent_intv_cnt) {
569 l_ptr->state = WORKING_WORKING; 554 l_ptr->state = WORKING_WORKING;
570 l_ptr->silent_intv_cnt = 0; 555 if (tipc_bclink_acks_missing(l_ptr->owner))
571 l_ptr->checkpoint = l_ptr->rcv_nxt;
572 if (tipc_bclink_acks_missing(l_ptr->owner)) {
573 tipc_link_proto_xmit(l_ptr, STATE_MSG, 556 tipc_link_proto_xmit(l_ptr, STATE_MSG,
574 0, 0, 0, 0); 557 0, 0, 0, 0);
575 l_ptr->silent_intv_cnt++;
576 }
577 link_set_timer(l_ptr, timer_intv);
578 } else if (l_ptr->silent_intv_cnt < 558 } else if (l_ptr->silent_intv_cnt <
579 l_ptr->abort_limit) { 559 l_ptr->abort_limit) {
580 tipc_link_proto_xmit(l_ptr, STATE_MSG, 560 tipc_link_proto_xmit(l_ptr, STATE_MSG,
581 1, 0, 0, 0); 561 1, 0, 0, 0);
582 l_ptr->silent_intv_cnt++;
583 link_set_timer(l_ptr, timer_intv);
584 } else { /* Link has failed */ 562 } else { /* Link has failed */
585 pr_debug("%s<%s>, peer not responding\n", 563 pr_debug("%s<%s>, peer not responding\n",
586 link_rst_msg, l_ptr->name); 564 link_rst_msg, l_ptr->name);
587 tipc_link_reset(l_ptr); 565 tipc_link_reset(l_ptr);
588 l_ptr->state = RESET_UNKNOWN; 566 l_ptr->state = RESET_UNKNOWN;
589 l_ptr->silent_intv_cnt = 0;
590 tipc_link_proto_xmit(l_ptr, RESET_MSG, 567 tipc_link_proto_xmit(l_ptr, RESET_MSG,
591 0, 0, 0, 0); 568 0, 0, 0, 0);
592 l_ptr->silent_intv_cnt++;
593 link_set_timer(l_ptr, timer_intv);
594 } 569 }
595 break; 570 break;
596 default: 571 default:
@@ -606,31 +581,22 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
606 if (other && link_working_unknown(other)) 581 if (other && link_working_unknown(other))
607 break; 582 break;
608 l_ptr->state = WORKING_WORKING; 583 l_ptr->state = WORKING_WORKING;
609 l_ptr->silent_intv_cnt = 0;
610 link_activate(l_ptr); 584 link_activate(l_ptr);
611 tipc_link_proto_xmit(l_ptr, STATE_MSG, 1, 0, 0, 0); 585 tipc_link_proto_xmit(l_ptr, STATE_MSG, 1, 0, 0, 0);
612 l_ptr->silent_intv_cnt++;
613 if (l_ptr->owner->working_links == 1) 586 if (l_ptr->owner->working_links == 1)
614 tipc_link_sync_xmit(l_ptr); 587 tipc_link_sync_xmit(l_ptr);
615 link_set_timer(l_ptr, timer_intv);
616 break; 588 break;
617 case RESET_MSG: 589 case RESET_MSG:
618 l_ptr->state = RESET_RESET; 590 l_ptr->state = RESET_RESET;
619 l_ptr->silent_intv_cnt = 0;
620 tipc_link_proto_xmit(l_ptr, ACTIVATE_MSG, 591 tipc_link_proto_xmit(l_ptr, ACTIVATE_MSG,
621 1, 0, 0, 0); 592 1, 0, 0, 0);
622 l_ptr->silent_intv_cnt++;
623 link_set_timer(l_ptr, timer_intv);
624 break; 593 break;
625 case STARTING_EVT: 594 case STARTING_EVT:
626 l_ptr->flags |= LINK_STARTED; 595 l_ptr->flags |= LINK_STARTED;
627 l_ptr->silent_intv_cnt++;
628 link_set_timer(l_ptr, timer_intv); 596 link_set_timer(l_ptr, timer_intv);
629 break; 597 break;
630 case TIMEOUT_EVT: 598 case SILENCE_EVT:
631 tipc_link_proto_xmit(l_ptr, RESET_MSG, 0, 0, 0, 0); 599 tipc_link_proto_xmit(l_ptr, RESET_MSG, 0, 0, 0, 0);
632 l_ptr->silent_intv_cnt++;
633 link_set_timer(l_ptr, timer_intv);
634 break; 600 break;
635 default: 601 default:
636 pr_err("%s%u in RU state\n", link_unk_evt, event); 602 pr_err("%s%u in RU state\n", link_unk_evt, event);
@@ -644,21 +610,16 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
644 if (other && link_working_unknown(other)) 610 if (other && link_working_unknown(other))
645 break; 611 break;
646 l_ptr->state = WORKING_WORKING; 612 l_ptr->state = WORKING_WORKING;
647 l_ptr->silent_intv_cnt = 0;
648 link_activate(l_ptr); 613 link_activate(l_ptr);
649 tipc_link_proto_xmit(l_ptr, STATE_MSG, 1, 0, 0, 0); 614 tipc_link_proto_xmit(l_ptr, STATE_MSG, 1, 0, 0, 0);
650 l_ptr->silent_intv_cnt++;
651 if (l_ptr->owner->working_links == 1) 615 if (l_ptr->owner->working_links == 1)
652 tipc_link_sync_xmit(l_ptr); 616 tipc_link_sync_xmit(l_ptr);
653 link_set_timer(l_ptr, timer_intv);
654 break; 617 break;
655 case RESET_MSG: 618 case RESET_MSG:
656 break; 619 break;
657 case TIMEOUT_EVT: 620 case SILENCE_EVT:
658 tipc_link_proto_xmit(l_ptr, ACTIVATE_MSG, 621 tipc_link_proto_xmit(l_ptr, ACTIVATE_MSG,
659 0, 0, 0, 0); 622 0, 0, 0, 0);
660 l_ptr->silent_intv_cnt++;
661 link_set_timer(l_ptr, timer_intv);
662 break; 623 break;
663 default: 624 default:
664 pr_err("%s%u in RR state\n", link_unk_evt, event); 625 pr_err("%s%u in RR state\n", link_unk_evt, event);
@@ -1126,6 +1087,8 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr)
1126 skb = NULL; 1087 skb = NULL;
1127 goto unlock; 1088 goto unlock;
1128 } 1089 }
1090 l_ptr->silent_intv_cnt = 0;
1091
1129 /* Synchronize with parallel link if applicable */ 1092 /* Synchronize with parallel link if applicable */
1130 if (unlikely((l_ptr->flags & LINK_SYNCHING) && !msg_dup(msg))) { 1093 if (unlikely((l_ptr->flags & LINK_SYNCHING) && !msg_dup(msg))) {
1131 if (!link_synch(l_ptr)) 1094 if (!link_synch(l_ptr))
@@ -1295,8 +1258,8 @@ static void link_handle_out_of_seq_msg(struct tipc_link *l_ptr,
1295 return; 1258 return;
1296 } 1259 }
1297 1260
1298 /* Record OOS packet arrival (force mismatch on next timeout) */ 1261 /* Record OOS packet arrival */
1299 l_ptr->checkpoint--; 1262 l_ptr->silent_intv_cnt = 0;
1300 1263
1301 /* 1264 /*
1302 * Discard packet if a duplicate; otherwise add it to deferred queue 1265 * Discard packet if a duplicate; otherwise add it to deferred queue
@@ -1480,7 +1443,7 @@ static void tipc_link_proto_rcv(struct tipc_link *l_ptr,
1480 } 1443 }
1481 1444
1482 /* Record reception; force mismatch at next timeout: */ 1445 /* Record reception; force mismatch at next timeout: */
1483 l_ptr->checkpoint--; 1446 l_ptr->silent_intv_cnt = 0;
1484 1447
1485 link_state_event(l_ptr, TRAFFIC_MSG_EVT); 1448 link_state_event(l_ptr, TRAFFIC_MSG_EVT);
1486 l_ptr->stats.recv_states++; 1449 l_ptr->stats.recv_states++;
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 74d2d12fc120..0c02c973e985 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -107,7 +107,6 @@ struct tipc_stats {
107 * @owner: pointer to peer node 107 * @owner: pointer to peer node
108 * @refcnt: reference counter for permanent references (owner node & timer) 108 * @refcnt: reference counter for permanent references (owner node & timer)
109 * @flags: execution state flags for link endpoint instance 109 * @flags: execution state flags for link endpoint instance
110 * @checkpoint: reference point for triggering link continuity checking
111 * @peer_session: link session # being used by peer end of link 110 * @peer_session: link session # being used by peer end of link
112 * @peer_bearer_id: bearer id used by link's peer endpoint 111 * @peer_bearer_id: bearer id used by link's peer endpoint
113 * @bearer_id: local bearer id used by link 112 * @bearer_id: local bearer id used by link
@@ -151,7 +150,6 @@ struct tipc_link {
151 150
152 /* Management and link supervision data */ 151 /* Management and link supervision data */
153 unsigned int flags; 152 unsigned int flags;
154 u16 checkpoint;
155 u32 peer_session; 153 u32 peer_session;
156 u32 peer_bearer_id; 154 u32 peer_bearer_id;
157 u32 bearer_id; 155 u32 bearer_id;