rxrpc: Add re-sent Tx annotation
Add a Tx-phase annotation for packet buffers to indicate that a buffer has already been retransmitted. This will be used by future congestion management. Re-retransmissions of a packet don't affect the congestion window managment in the same way as initial retransmissions. Signed-off-by: David Howells <dhowells@redhat.com>
This commit is contained in:
parent
5a924b8951
commit
f07373ead4
|
@ -505,6 +505,8 @@ struct rxrpc_call {
|
|||
#define RXRPC_TX_ANNO_UNACK 1
|
||||
#define RXRPC_TX_ANNO_NAK 2
|
||||
#define RXRPC_TX_ANNO_RETRANS 3
|
||||
#define RXRPC_TX_ANNO_MASK 0x03
|
||||
#define RXRPC_TX_ANNO_RESENT 0x04
|
||||
#define RXRPC_RX_ANNO_JUMBO 0x3f /* Jumbo subpacket number + 1 if not zero */
|
||||
#define RXRPC_RX_ANNO_JLAST 0x40 /* Set if last element of a jumbo packet */
|
||||
#define RXRPC_RX_ANNO_VERIFIED 0x80 /* Set if verified and decrypted */
|
||||
|
|
|
@ -144,7 +144,7 @@ static void rxrpc_resend(struct rxrpc_call *call)
|
|||
rxrpc_seq_t cursor, seq, top;
|
||||
unsigned long resend_at, now;
|
||||
int ix;
|
||||
u8 annotation;
|
||||
u8 annotation, anno_type;
|
||||
|
||||
_enter("{%d,%d}", call->tx_hard_ack, call->tx_top);
|
||||
|
||||
|
@ -165,14 +165,16 @@ static void rxrpc_resend(struct rxrpc_call *call)
|
|||
for (seq = cursor + 1; before_eq(seq, top); seq++) {
|
||||
ix = seq & RXRPC_RXTX_BUFF_MASK;
|
||||
annotation = call->rxtx_annotations[ix];
|
||||
if (annotation == RXRPC_TX_ANNO_ACK)
|
||||
anno_type = annotation & RXRPC_TX_ANNO_MASK;
|
||||
annotation &= ~RXRPC_TX_ANNO_MASK;
|
||||
if (anno_type == RXRPC_TX_ANNO_ACK)
|
||||
continue;
|
||||
|
||||
skb = call->rxtx_buffer[ix];
|
||||
rxrpc_see_skb(skb, rxrpc_skb_tx_seen);
|
||||
sp = rxrpc_skb(skb);
|
||||
|
||||
if (annotation == RXRPC_TX_ANNO_UNACK) {
|
||||
if (anno_type == RXRPC_TX_ANNO_UNACK) {
|
||||
if (time_after(sp->resend_at, now)) {
|
||||
if (time_before(sp->resend_at, resend_at))
|
||||
resend_at = sp->resend_at;
|
||||
|
@ -181,7 +183,7 @@ static void rxrpc_resend(struct rxrpc_call *call)
|
|||
}
|
||||
|
||||
/* Okay, we need to retransmit a packet. */
|
||||
call->rxtx_annotations[ix] = RXRPC_TX_ANNO_RETRANS;
|
||||
call->rxtx_annotations[ix] = RXRPC_TX_ANNO_RETRANS | annotation;
|
||||
}
|
||||
|
||||
call->resend_at = resend_at;
|
||||
|
@ -194,7 +196,8 @@ static void rxrpc_resend(struct rxrpc_call *call)
|
|||
for (seq = cursor + 1; before_eq(seq, top); seq++) {
|
||||
ix = seq & RXRPC_RXTX_BUFF_MASK;
|
||||
annotation = call->rxtx_annotations[ix];
|
||||
if (annotation != RXRPC_TX_ANNO_RETRANS)
|
||||
anno_type = annotation & RXRPC_TX_ANNO_MASK;
|
||||
if (anno_type != RXRPC_TX_ANNO_RETRANS)
|
||||
continue;
|
||||
|
||||
skb = call->rxtx_buffer[ix];
|
||||
|
@ -220,10 +223,17 @@ static void rxrpc_resend(struct rxrpc_call *call)
|
|||
* received and the packet might have been hard-ACK'd (in which
|
||||
* case it will no longer be in the buffer).
|
||||
*/
|
||||
if (after(seq, call->tx_hard_ack) &&
|
||||
(call->rxtx_annotations[ix] == RXRPC_TX_ANNO_RETRANS ||
|
||||
call->rxtx_annotations[ix] == RXRPC_TX_ANNO_NAK))
|
||||
call->rxtx_annotations[ix] = RXRPC_TX_ANNO_UNACK;
|
||||
if (after(seq, call->tx_hard_ack)) {
|
||||
annotation = call->rxtx_annotations[ix];
|
||||
anno_type = annotation & RXRPC_TX_ANNO_MASK;
|
||||
if (anno_type == RXRPC_TX_ANNO_RETRANS ||
|
||||
anno_type == RXRPC_TX_ANNO_NAK) {
|
||||
annotation &= ~RXRPC_TX_ANNO_MASK;
|
||||
annotation |= RXRPC_TX_ANNO_UNACK;
|
||||
}
|
||||
annotation |= RXRPC_TX_ANNO_RESENT;
|
||||
call->rxtx_annotations[ix] = annotation;
|
||||
}
|
||||
|
||||
if (after(call->tx_hard_ack, seq))
|
||||
seq = call->tx_hard_ack;
|
||||
|
|
|
@ -388,17 +388,25 @@ static void rxrpc_input_soft_acks(struct rxrpc_call *call, u8 *acks,
|
|||
{
|
||||
bool resend = false;
|
||||
int ix;
|
||||
u8 annotation, anno_type;
|
||||
|
||||
for (; nr_acks > 0; nr_acks--, seq++) {
|
||||
ix = seq & RXRPC_RXTX_BUFF_MASK;
|
||||
annotation = call->rxtx_annotations[ix];
|
||||
anno_type = annotation & RXRPC_TX_ANNO_MASK;
|
||||
annotation &= ~RXRPC_TX_ANNO_MASK;
|
||||
switch (*acks++) {
|
||||
case RXRPC_ACK_TYPE_ACK:
|
||||
call->rxtx_annotations[ix] = RXRPC_TX_ANNO_ACK;
|
||||
if (anno_type == RXRPC_TX_ANNO_ACK)
|
||||
continue;
|
||||
call->rxtx_annotations[ix] =
|
||||
RXRPC_TX_ANNO_ACK | annotation;
|
||||
break;
|
||||
case RXRPC_ACK_TYPE_NACK:
|
||||
if (call->rxtx_annotations[ix] == RXRPC_TX_ANNO_NAK)
|
||||
if (anno_type == RXRPC_TX_ANNO_NAK)
|
||||
continue;
|
||||
call->rxtx_annotations[ix] = RXRPC_TX_ANNO_NAK;
|
||||
call->rxtx_annotations[ix] =
|
||||
RXRPC_TX_ANNO_NAK | annotation;
|
||||
resend = true;
|
||||
break;
|
||||
default:
|
||||
|
|
Loading…
Reference in New Issue