diff options
Diffstat (limited to 'net/tipc/link.c')
-rw-r--r-- | net/tipc/link.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c index 5aee1ed23ba9..1f2cde0d025f 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
@@ -209,6 +209,7 @@ enum { | |||
209 | }; | 209 | }; |
210 | 210 | ||
211 | #define TIPC_BC_RETR_LIM msecs_to_jiffies(10) /* [ms] */ | 211 | #define TIPC_BC_RETR_LIM msecs_to_jiffies(10) /* [ms] */ |
212 | #define TIPC_UC_RETR_TIME (jiffies + msecs_to_jiffies(1)) | ||
212 | 213 | ||
213 | /* | 214 | /* |
214 | * Interval between NACKs when packets arrive out of order | 215 | * Interval between NACKs when packets arrive out of order |
@@ -1305,6 +1306,10 @@ next_gap_ack: | |||
1305 | kfree_skb(skb); | 1306 | kfree_skb(skb); |
1306 | } else if (less_eq(seqno, acked + gap)) { | 1307 | } else if (less_eq(seqno, acked + gap)) { |
1307 | /* retransmit skb */ | 1308 | /* retransmit skb */ |
1309 | if (time_before(jiffies, TIPC_SKB_CB(skb)->nxt_retr)) | ||
1310 | continue; | ||
1311 | TIPC_SKB_CB(skb)->nxt_retr = TIPC_UC_RETR_TIME; | ||
1312 | |||
1308 | _skb = __pskb_copy(skb, MIN_H_SIZE, GFP_ATOMIC); | 1313 | _skb = __pskb_copy(skb, MIN_H_SIZE, GFP_ATOMIC); |
1309 | if (!_skb) | 1314 | if (!_skb) |
1310 | continue; | 1315 | continue; |
@@ -1380,6 +1385,7 @@ static int tipc_link_build_nack_msg(struct tipc_link *l, | |||
1380 | struct sk_buff_head *xmitq) | 1385 | struct sk_buff_head *xmitq) |
1381 | { | 1386 | { |
1382 | u32 def_cnt = ++l->stats.deferred_recv; | 1387 | u32 def_cnt = ++l->stats.deferred_recv; |
1388 | u32 defq_len = skb_queue_len(&l->deferdq); | ||
1383 | int match1, match2; | 1389 | int match1, match2; |
1384 | 1390 | ||
1385 | if (link_is_bc_rcvlink(l)) { | 1391 | if (link_is_bc_rcvlink(l)) { |
@@ -1390,7 +1396,7 @@ static int tipc_link_build_nack_msg(struct tipc_link *l, | |||
1390 | return 0; | 1396 | return 0; |
1391 | } | 1397 | } |
1392 | 1398 | ||
1393 | if ((skb_queue_len(&l->deferdq) == 1) || !(def_cnt % TIPC_NACK_INTV)) | 1399 | if (defq_len >= 3 && !((defq_len - 3) % 16)) |
1394 | tipc_link_build_proto_msg(l, STATE_MSG, 0, 0, 0, 0, 0, xmitq); | 1400 | tipc_link_build_proto_msg(l, STATE_MSG, 0, 0, 0, 0, 0, xmitq); |
1395 | return 0; | 1401 | return 0; |
1396 | } | 1402 | } |
@@ -1404,29 +1410,29 @@ int tipc_link_rcv(struct tipc_link *l, struct sk_buff *skb, | |||
1404 | struct sk_buff_head *xmitq) | 1410 | struct sk_buff_head *xmitq) |
1405 | { | 1411 | { |
1406 | struct sk_buff_head *defq = &l->deferdq; | 1412 | struct sk_buff_head *defq = &l->deferdq; |
1407 | struct tipc_msg *hdr; | 1413 | struct tipc_msg *hdr = buf_msg(skb); |
1408 | u16 seqno, rcv_nxt, win_lim; | 1414 | u16 seqno, rcv_nxt, win_lim; |
1409 | int rc = 0; | 1415 | int rc = 0; |
1410 | 1416 | ||
1417 | /* Verify and update link state */ | ||
1418 | if (unlikely(msg_user(hdr) == LINK_PROTOCOL)) | ||
1419 | return tipc_link_proto_rcv(l, skb, xmitq); | ||
1420 | |||
1421 | /* Don't send probe at next timeout expiration */ | ||
1422 | l->silent_intv_cnt = 0; | ||
1423 | |||
1411 | do { | 1424 | do { |
1412 | hdr = buf_msg(skb); | 1425 | hdr = buf_msg(skb); |
1413 | seqno = msg_seqno(hdr); | 1426 | seqno = msg_seqno(hdr); |
1414 | rcv_nxt = l->rcv_nxt; | 1427 | rcv_nxt = l->rcv_nxt; |
1415 | win_lim = rcv_nxt + TIPC_MAX_LINK_WIN; | 1428 | win_lim = rcv_nxt + TIPC_MAX_LINK_WIN; |
1416 | 1429 | ||
1417 | /* Verify and update link state */ | ||
1418 | if (unlikely(msg_user(hdr) == LINK_PROTOCOL)) | ||
1419 | return tipc_link_proto_rcv(l, skb, xmitq); | ||
1420 | |||
1421 | if (unlikely(!link_is_up(l))) { | 1430 | if (unlikely(!link_is_up(l))) { |
1422 | if (l->state == LINK_ESTABLISHING) | 1431 | if (l->state == LINK_ESTABLISHING) |
1423 | rc = TIPC_LINK_UP_EVT; | 1432 | rc = TIPC_LINK_UP_EVT; |
1424 | goto drop; | 1433 | goto drop; |
1425 | } | 1434 | } |
1426 | 1435 | ||
1427 | /* Don't send probe at next timeout expiration */ | ||
1428 | l->silent_intv_cnt = 0; | ||
1429 | |||
1430 | /* Drop if outside receive window */ | 1436 | /* Drop if outside receive window */ |
1431 | if (unlikely(less(seqno, rcv_nxt) || more(seqno, win_lim))) { | 1437 | if (unlikely(less(seqno, rcv_nxt) || more(seqno, win_lim))) { |
1432 | l->stats.duplicates++; | 1438 | l->stats.duplicates++; |
@@ -1457,7 +1463,7 @@ int tipc_link_rcv(struct tipc_link *l, struct sk_buff *skb, | |||
1457 | rc |= tipc_link_build_state_msg(l, xmitq); | 1463 | rc |= tipc_link_build_state_msg(l, xmitq); |
1458 | if (unlikely(rc & ~TIPC_LINK_SND_STATE)) | 1464 | if (unlikely(rc & ~TIPC_LINK_SND_STATE)) |
1459 | break; | 1465 | break; |
1460 | } while ((skb = __skb_dequeue(defq))); | 1466 | } while ((skb = __tipc_skb_dequeue(defq, l->rcv_nxt))); |
1461 | 1467 | ||
1462 | return rc; | 1468 | return rc; |
1463 | drop: | 1469 | drop: |