summaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorTuong Lien <tuong.t.lien@dektech.com.au>2019-06-17 01:15:42 -0400
committerDavid S. Miller <davem@davemloft.net>2019-06-17 16:27:32 -0400
commit6a6b5c8bff89c76b09a921ef05b042fdee940f2a (patch)
treeae40dc030f1726f75b5386ae6f4709859b9364f7 /net/tipc
parent9ed68ca0d90b53ba00745cb61ef105599532226f (diff)
tipc: include retrans failure detection for unicast
In patch series, commit 9195948fbf34 ("tipc: improve TIPC throughput by Gap ACK blocks"), as for simplicity, the repeated retransmit failures' detection in the function - "tipc_link_retrans()" was kept there for broadcast retransmissions only. This commit now reapplies this feature for link unicast retransmissions that has been done via the function - "tipc_link_advance_transmq()". Also, the "tipc_link_retrans()" is renamed to "tipc_link_bc_retrans()" as it is used only for broadcast. Acked-by: Jon Maloy <jon.maloy@ericsson.se> Signed-off-by: Tuong Lien <tuong.t.lien@dektech.com.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/link.c106
1 files changed, 70 insertions, 36 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c
index f5cd986e1e50..d5ed509e0660 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -249,9 +249,9 @@ static void tipc_link_build_bc_init_msg(struct tipc_link *l,
249 struct sk_buff_head *xmitq); 249 struct sk_buff_head *xmitq);
250static bool tipc_link_release_pkts(struct tipc_link *l, u16 to); 250static bool tipc_link_release_pkts(struct tipc_link *l, u16 to);
251static u16 tipc_build_gap_ack_blks(struct tipc_link *l, void *data); 251static u16 tipc_build_gap_ack_blks(struct tipc_link *l, void *data);
252static void tipc_link_advance_transmq(struct tipc_link *l, u16 acked, u16 gap, 252static int tipc_link_advance_transmq(struct tipc_link *l, u16 acked, u16 gap,
253 struct tipc_gap_ack_blks *ga, 253 struct tipc_gap_ack_blks *ga,
254 struct sk_buff_head *xmitq); 254 struct sk_buff_head *xmitq);
255 255
256/* 256/*
257 * Simple non-static link routines (i.e. referenced outside this file) 257 * Simple non-static link routines (i.e. referenced outside this file)
@@ -1044,32 +1044,69 @@ static void tipc_link_advance_backlog(struct tipc_link *l,
1044 l->snd_nxt = seqno; 1044 l->snd_nxt = seqno;
1045} 1045}
1046 1046
1047static void link_retransmit_failure(struct tipc_link *l, struct sk_buff *skb) 1047/**
1048 * link_retransmit_failure() - Detect repeated retransmit failures
1049 * @l: tipc link sender
1050 * @r: tipc link receiver (= l in case of unicast)
1051 * @from: seqno of the 1st packet in retransmit request
1052 * @rc: returned code
1053 *
1054 * Return: true if the repeated retransmit failures happens, otherwise
1055 * false
1056 */
1057static bool link_retransmit_failure(struct tipc_link *l, struct tipc_link *r,
1058 u16 from, int *rc)
1048{ 1059{
1049 struct tipc_msg *hdr = buf_msg(skb); 1060 struct sk_buff *skb = skb_peek(&l->transmq);
1061 struct tipc_msg *hdr;
1062
1063 if (!skb)
1064 return false;
1065 hdr = buf_msg(skb);
1066
1067 /* Detect repeated retransmit failures on same packet */
1068 if (r->prev_from != from) {
1069 r->prev_from = from;
1070 r->stale_limit = jiffies + msecs_to_jiffies(r->tolerance);
1071 r->stale_cnt = 0;
1072 } else if (++r->stale_cnt > 99 && time_after(jiffies, r->stale_limit)) {
1073 pr_warn("Retransmission failure on link <%s>\n", l->name);
1074 link_print(l, "State of link ");
1075 pr_info("Failed msg: usr %u, typ %u, len %u, err %u\n",
1076 msg_user(hdr), msg_type(hdr), msg_size(hdr),
1077 msg_errcode(hdr));
1078 pr_info("sqno %u, prev: %x, src: %x\n",
1079 msg_seqno(hdr), msg_prevnode(hdr), msg_orignode(hdr));
1080
1081 trace_tipc_list_dump(&l->transmq, true, "retrans failure!");
1082 trace_tipc_link_dump(l, TIPC_DUMP_NONE, "retrans failure!");
1083 trace_tipc_link_dump(r, TIPC_DUMP_NONE, "retrans failure!");
1084
1085 if (link_is_bc_sndlink(l))
1086 *rc = TIPC_LINK_DOWN_EVT;
1087
1088 *rc = tipc_link_fsm_evt(l, LINK_FAILURE_EVT);
1089 return true;
1090 }
1050 1091
1051 pr_warn("Retransmission failure on link <%s>\n", l->name); 1092 return false;
1052 link_print(l, "State of link ");
1053 pr_info("Failed msg: usr %u, typ %u, len %u, err %u\n",
1054 msg_user(hdr), msg_type(hdr), msg_size(hdr), msg_errcode(hdr));
1055 pr_info("sqno %u, prev: %x, src: %x\n",
1056 msg_seqno(hdr), msg_prevnode(hdr), msg_orignode(hdr));
1057} 1093}
1058 1094
1059/* tipc_link_retrans() - retransmit one or more packets 1095/* tipc_link_bc_retrans() - retransmit zero or more packets
1060 * @l: the link to transmit on 1096 * @l: the link to transmit on
1061 * @r: the receiving link ordering the retransmit. Same as l if unicast 1097 * @r: the receiving link ordering the retransmit. Same as l if unicast
1062 * @from: retransmit from (inclusive) this sequence number 1098 * @from: retransmit from (inclusive) this sequence number
1063 * @to: retransmit to (inclusive) this sequence number 1099 * @to: retransmit to (inclusive) this sequence number
1064 * xmitq: queue for accumulating the retransmitted packets 1100 * xmitq: queue for accumulating the retransmitted packets
1065 */ 1101 */
1066static int tipc_link_retrans(struct tipc_link *l, struct tipc_link *r, 1102static int tipc_link_bc_retrans(struct tipc_link *l, struct tipc_link *r,
1067 u16 from, u16 to, struct sk_buff_head *xmitq) 1103 u16 from, u16 to, struct sk_buff_head *xmitq)
1068{ 1104{
1069 struct sk_buff *_skb, *skb = skb_peek(&l->transmq); 1105 struct sk_buff *_skb, *skb = skb_peek(&l->transmq);
1070 u16 bc_ack = l->bc_rcvlink->rcv_nxt - 1; 1106 u16 bc_ack = l->bc_rcvlink->rcv_nxt - 1;
1071 u16 ack = l->rcv_nxt - 1; 1107 u16 ack = l->rcv_nxt - 1;
1072 struct tipc_msg *hdr; 1108 struct tipc_msg *hdr;
1109 int rc = 0;
1073 1110
1074 if (!skb) 1111 if (!skb)
1075 return 0; 1112 return 0;
@@ -1077,20 +1114,9 @@ static int tipc_link_retrans(struct tipc_link *l, struct tipc_link *r,
1077 return 0; 1114 return 0;
1078 1115
1079 trace_tipc_link_retrans(r, from, to, &l->transmq); 1116 trace_tipc_link_retrans(r, from, to, &l->transmq);
1080 /* Detect repeated retransmit failures on same packet */ 1117
1081 if (r->prev_from != from) { 1118 if (link_retransmit_failure(l, r, from, &rc))
1082 r->prev_from = from; 1119 return rc;
1083 r->stale_limit = jiffies + msecs_to_jiffies(r->tolerance);
1084 r->stale_cnt = 0;
1085 } else if (++r->stale_cnt > 99 && time_after(jiffies, r->stale_limit)) {
1086 link_retransmit_failure(l, skb);
1087 trace_tipc_list_dump(&l->transmq, true, "retrans failure!");
1088 trace_tipc_link_dump(l, TIPC_DUMP_NONE, "retrans failure!");
1089 trace_tipc_link_dump(r, TIPC_DUMP_NONE, "retrans failure!");
1090 if (link_is_bc_sndlink(l))
1091 return TIPC_LINK_DOWN_EVT;
1092 return tipc_link_fsm_evt(l, LINK_FAILURE_EVT);
1093 }
1094 1120
1095 skb_queue_walk(&l->transmq, skb) { 1121 skb_queue_walk(&l->transmq, skb) {
1096 hdr = buf_msg(skb); 1122 hdr = buf_msg(skb);
@@ -1324,17 +1350,23 @@ exit:
1324 * @gap: # of gap packets 1350 * @gap: # of gap packets
1325 * @ga: buffer pointer to Gap ACK blocks from peer 1351 * @ga: buffer pointer to Gap ACK blocks from peer
1326 * @xmitq: queue for accumulating the retransmitted packets if any 1352 * @xmitq: queue for accumulating the retransmitted packets if any
1353 *
1354 * In case of a repeated retransmit failures, the call will return shortly
1355 * with a returned code (e.g. TIPC_LINK_DOWN_EVT)
1327 */ 1356 */
1328static void tipc_link_advance_transmq(struct tipc_link *l, u16 acked, u16 gap, 1357static int tipc_link_advance_transmq(struct tipc_link *l, u16 acked, u16 gap,
1329 struct tipc_gap_ack_blks *ga, 1358 struct tipc_gap_ack_blks *ga,
1330 struct sk_buff_head *xmitq) 1359 struct sk_buff_head *xmitq)
1331{ 1360{
1332 struct sk_buff *skb, *_skb, *tmp; 1361 struct sk_buff *skb, *_skb, *tmp;
1333 struct tipc_msg *hdr; 1362 struct tipc_msg *hdr;
1334 u16 bc_ack = l->bc_rcvlink->rcv_nxt - 1; 1363 u16 bc_ack = l->bc_rcvlink->rcv_nxt - 1;
1335 u16 ack = l->rcv_nxt - 1; 1364 u16 ack = l->rcv_nxt - 1;
1336 u16 seqno; 1365 u16 seqno, n = 0;
1337 u16 n = 0; 1366 int rc = 0;
1367
1368 if (gap && link_retransmit_failure(l, l, acked + 1, &rc))
1369 return rc;
1338 1370
1339 skb_queue_walk_safe(&l->transmq, skb, tmp) { 1371 skb_queue_walk_safe(&l->transmq, skb, tmp) {
1340 seqno = buf_seqno(skb); 1372 seqno = buf_seqno(skb);
@@ -1369,6 +1401,8 @@ next_gap_ack:
1369 goto next_gap_ack; 1401 goto next_gap_ack;
1370 } 1402 }
1371 } 1403 }
1404
1405 return 0;
1372} 1406}
1373 1407
1374/* tipc_link_build_state_msg: prepare link state message for transmission 1408/* tipc_link_build_state_msg: prepare link state message for transmission
@@ -1919,7 +1953,7 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
1919 tipc_link_build_proto_msg(l, STATE_MSG, 0, reply, 1953 tipc_link_build_proto_msg(l, STATE_MSG, 0, reply,
1920 rcvgap, 0, 0, xmitq); 1954 rcvgap, 0, 0, xmitq);
1921 1955
1922 tipc_link_advance_transmq(l, ack, gap, ga, xmitq); 1956 rc |= tipc_link_advance_transmq(l, ack, gap, ga, xmitq);
1923 1957
1924 /* If NACK, retransmit will now start at right position */ 1958 /* If NACK, retransmit will now start at right position */
1925 if (gap) 1959 if (gap)
@@ -2036,7 +2070,7 @@ int tipc_link_bc_sync_rcv(struct tipc_link *l, struct tipc_msg *hdr,
2036 if (more(peers_snd_nxt, l->rcv_nxt + l->window)) 2070 if (more(peers_snd_nxt, l->rcv_nxt + l->window))
2037 return rc; 2071 return rc;
2038 2072
2039 rc = tipc_link_retrans(snd_l, l, from, to, xmitq); 2073 rc = tipc_link_bc_retrans(snd_l, l, from, to, xmitq);
2040 2074
2041 l->snd_nxt = peers_snd_nxt; 2075 l->snd_nxt = peers_snd_nxt;
2042 if (link_bc_rcv_gap(l)) 2076 if (link_bc_rcv_gap(l))
@@ -2132,7 +2166,7 @@ int tipc_link_bc_nack_rcv(struct tipc_link *l, struct sk_buff *skb,
2132 2166
2133 if (dnode == tipc_own_addr(l->net)) { 2167 if (dnode == tipc_own_addr(l->net)) {
2134 tipc_link_bc_ack_rcv(l, acked, xmitq); 2168 tipc_link_bc_ack_rcv(l, acked, xmitq);
2135 rc = tipc_link_retrans(l->bc_sndlink, l, from, to, xmitq); 2169 rc = tipc_link_bc_retrans(l->bc_sndlink, l, from, to, xmitq);
2136 l->stats.recv_nacks++; 2170 l->stats.recv_nacks++;
2137 return rc; 2171 return rc;
2138 } 2172 }