Skip to content

Commit

Permalink
tipc: improve broadcast retransmission algorithm
Browse files Browse the repository at this point in the history
Currently, the broadcast retransmission algorithm is using the
'prev_retr' field in struct tipc_link to time stamp the latest broadcast
retransmission occasion. This helps to restrict retransmission of
individual broadcast packets to max once per 10 milliseconds, even
though all other criteria for retransmission are met.

We now move this time stamp to the control block of each individual
packet, and remove other limiting criteria. This simplifies the
retransmission algorithm, and eliminates any risk of logical errors
in selecting which packets can be retransmitted.

Acked-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: LUU Duc Canh <canh.d.luu@dektech.com.au>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
LUU Duc Canh authored and David S. Miller committed Nov 11, 2018
1 parent bb5e6a8 commit 31c4f4c
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 46 deletions.
59 changes: 13 additions & 46 deletions net/tipc/link.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ struct tipc_stats {
* @transmitq: queue for sent, non-acked messages
* @backlogq: queue for messages waiting to be sent
* @snt_nxt: next sequence number to use for outbound messages
* @last_retransmitted: sequence number of most recently retransmitted message
* @prev_from: sequence number of most previous retransmission request
* @stale_cnt: counter for number of identical retransmit attempts
* @stale_limit: time when repeated identical retransmits must force link reset
* @ackers: # of peers that needs to ack each packet before it can be released
Expand Down Expand Up @@ -163,7 +163,7 @@ struct tipc_link {
u16 limit;
} backlog[5];
u16 snd_nxt;
u16 last_retransm;
u16 prev_from;
u16 window;
u16 stale_cnt;
unsigned long stale_limit;
Expand All @@ -186,9 +186,6 @@ struct tipc_link {
u16 acked;
struct tipc_link *bc_rcvlink;
struct tipc_link *bc_sndlink;
unsigned long prev_retr;
u16 prev_from;
u16 prev_to;
u8 nack_state;
bool bc_peer_is_up;

Expand All @@ -210,7 +207,7 @@ enum {
BC_NACK_SND_SUPPRESS,
};

#define TIPC_BC_RETR_LIMIT 10 /* [ms] */
#define TIPC_BC_RETR_LIM msecs_to_jiffies(10) /* [ms] */

/*
* Interval between NACKs when packets arrive out of order
Expand Down Expand Up @@ -1036,10 +1033,12 @@ static int tipc_link_retrans(struct tipc_link *l, struct tipc_link *r,

if (!skb)
return 0;
if (less(to, from))
return 0;

/* Detect repeated retransmit failures on same packet */
if (r->last_retransm != buf_seqno(skb)) {
r->last_retransm = buf_seqno(skb);
if (r->prev_from != from) {
r->prev_from = from;
r->stale_limit = jiffies + msecs_to_jiffies(r->tolerance);
r->stale_cnt = 0;
} else if (++r->stale_cnt > 99 && time_after(jiffies, r->stale_limit)) {
Expand All @@ -1055,6 +1054,11 @@ static int tipc_link_retrans(struct tipc_link *l, struct tipc_link *r,
continue;
if (more(msg_seqno(hdr), to))
break;
if (link_is_bc_sndlink(l)) {
if (time_before(jiffies, TIPC_SKB_CB(skb)->nxt_retr))
continue;
TIPC_SKB_CB(skb)->nxt_retr = jiffies + TIPC_BC_RETR_LIM;
}
_skb = __pskb_copy(skb, MIN_H_SIZE, GFP_ATOMIC);
if (!_skb)
return 0;
Expand Down Expand Up @@ -1734,42 +1738,6 @@ void tipc_link_bc_init_rcv(struct tipc_link *l, struct tipc_msg *hdr)
l->rcv_nxt = peers_snd_nxt;
}

/* link_bc_retr eval()- check if the indicated range can be retransmitted now
* - Adjust permitted range if there is overlap with previous retransmission
*/
static bool link_bc_retr_eval(struct tipc_link *l, u16 *from, u16 *to)
{
unsigned long elapsed = jiffies_to_msecs(jiffies - l->prev_retr);

if (less(*to, *from))
return false;

/* New retransmission request */
if ((elapsed > TIPC_BC_RETR_LIMIT) ||
less(*to, l->prev_from) || more(*from, l->prev_to)) {
l->prev_from = *from;
l->prev_to = *to;
l->prev_retr = jiffies;
return true;
}

/* Inside range of previous retransmit */
if (!less(*from, l->prev_from) && !more(*to, l->prev_to))
return false;

/* Fully or partially outside previous range => exclude overlap */
if (less(*from, l->prev_from)) {
*to = l->prev_from - 1;
l->prev_from = *from;
}
if (more(*to, l->prev_to)) {
*from = l->prev_to + 1;
l->prev_to = *to;
}
l->prev_retr = jiffies;
return true;
}

/* tipc_link_bc_sync_rcv - update rcv link according to peer's send state
*/
int tipc_link_bc_sync_rcv(struct tipc_link *l, struct tipc_msg *hdr,
Expand Down Expand Up @@ -1800,8 +1768,7 @@ int tipc_link_bc_sync_rcv(struct tipc_link *l, struct tipc_msg *hdr,
if (more(peers_snd_nxt, l->rcv_nxt + l->window))
return rc;

if (link_bc_retr_eval(snd_l, &from, &to))
rc = tipc_link_retrans(snd_l, l, from, to, xmitq);
rc = tipc_link_retrans(snd_l, l, from, to, xmitq);

l->snd_nxt = peers_snd_nxt;
if (link_bc_rcv_gap(l))
Expand Down
1 change: 1 addition & 0 deletions net/tipc/msg.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ struct tipc_skb_cb {
u32 bytes_read;
u32 orig_member;
struct sk_buff *tail;
unsigned long nxt_retr;
bool validated;
u16 chain_imp;
u16 ackers;
Expand Down

0 comments on commit 31c4f4c

Please sign in to comment.