Commit c479d5f2 authored by David Howells's avatar David Howells

rxrpc: Don't check RXRPC_CALL_TX_LAST after calling rxrpc_rotate_tx_window()

We should only call the function to end a call's Tx phase if we rotated the
marked-last packet out of the transmission buffer.

Make rxrpc_rotate_tx_window() return an indication of whether it just
rotated the packet marked as the last out of the transmit buffer, carrying
the information out of the locked section in that function.

We can then check the return value instead of examining RXRPC_CALL_TX_LAST.

Fixes: 70790dbe ("rxrpc: Pass the last Tx packet marker in the annotation buffer")
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
parent bfd28211
...@@ -216,10 +216,11 @@ static void rxrpc_send_ping(struct rxrpc_call *call, struct sk_buff *skb, ...@@ -216,10 +216,11 @@ static void rxrpc_send_ping(struct rxrpc_call *call, struct sk_buff *skb,
/* /*
* Apply a hard ACK by advancing the Tx window. * Apply a hard ACK by advancing the Tx window.
*/ */
static void rxrpc_rotate_tx_window(struct rxrpc_call *call, rxrpc_seq_t to, static bool rxrpc_rotate_tx_window(struct rxrpc_call *call, rxrpc_seq_t to,
struct rxrpc_ack_summary *summary) struct rxrpc_ack_summary *summary)
{ {
struct sk_buff *skb, *list = NULL; struct sk_buff *skb, *list = NULL;
bool rot_last = false;
int ix; int ix;
u8 annotation; u8 annotation;
...@@ -243,15 +244,17 @@ static void rxrpc_rotate_tx_window(struct rxrpc_call *call, rxrpc_seq_t to, ...@@ -243,15 +244,17 @@ static void rxrpc_rotate_tx_window(struct rxrpc_call *call, rxrpc_seq_t to,
skb->next = list; skb->next = list;
list = skb; list = skb;
if (annotation & RXRPC_TX_ANNO_LAST) if (annotation & RXRPC_TX_ANNO_LAST) {
set_bit(RXRPC_CALL_TX_LAST, &call->flags); set_bit(RXRPC_CALL_TX_LAST, &call->flags);
rot_last = true;
}
if ((annotation & RXRPC_TX_ANNO_MASK) != RXRPC_TX_ANNO_ACK) if ((annotation & RXRPC_TX_ANNO_MASK) != RXRPC_TX_ANNO_ACK)
summary->nr_rot_new_acks++; summary->nr_rot_new_acks++;
} }
spin_unlock(&call->lock); spin_unlock(&call->lock);
trace_rxrpc_transmit(call, (test_bit(RXRPC_CALL_TX_LAST, &call->flags) ? trace_rxrpc_transmit(call, (rot_last ?
rxrpc_transmit_rotate_last : rxrpc_transmit_rotate_last :
rxrpc_transmit_rotate)); rxrpc_transmit_rotate));
wake_up(&call->waitq); wake_up(&call->waitq);
...@@ -262,6 +265,8 @@ static void rxrpc_rotate_tx_window(struct rxrpc_call *call, rxrpc_seq_t to, ...@@ -262,6 +265,8 @@ static void rxrpc_rotate_tx_window(struct rxrpc_call *call, rxrpc_seq_t to,
skb->next = NULL; skb->next = NULL;
rxrpc_free_skb(skb, rxrpc_skb_tx_freed); rxrpc_free_skb(skb, rxrpc_skb_tx_freed);
} }
return rot_last;
} }
/* /*
...@@ -332,11 +337,11 @@ static bool rxrpc_receiving_reply(struct rxrpc_call *call) ...@@ -332,11 +337,11 @@ static bool rxrpc_receiving_reply(struct rxrpc_call *call)
trace_rxrpc_timer(call, rxrpc_timer_init_for_reply, now); trace_rxrpc_timer(call, rxrpc_timer_init_for_reply, now);
} }
if (!test_bit(RXRPC_CALL_TX_LAST, &call->flags))
rxrpc_rotate_tx_window(call, top, &summary);
if (!test_bit(RXRPC_CALL_TX_LAST, &call->flags)) { if (!test_bit(RXRPC_CALL_TX_LAST, &call->flags)) {
rxrpc_proto_abort("TXL", call, top); if (!rxrpc_rotate_tx_window(call, top, &summary)) {
return false; rxrpc_proto_abort("TXL", call, top);
return false;
}
} }
if (!rxrpc_end_tx_phase(call, true, "ETD")) if (!rxrpc_end_tx_phase(call, true, "ETD"))
return false; return false;
...@@ -897,8 +902,12 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb, ...@@ -897,8 +902,12 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb,
if (nr_acks > call->tx_top - hard_ack) if (nr_acks > call->tx_top - hard_ack)
return rxrpc_proto_abort("AKN", call, 0); return rxrpc_proto_abort("AKN", call, 0);
if (after(hard_ack, call->tx_hard_ack)) if (after(hard_ack, call->tx_hard_ack)) {
rxrpc_rotate_tx_window(call, hard_ack, &summary); if (rxrpc_rotate_tx_window(call, hard_ack, &summary)) {
rxrpc_end_tx_phase(call, false, "ETA");
return;
}
}
if (nr_acks > 0) { if (nr_acks > 0) {
if (skb_copy_bits(skb, offset, buf.acks, nr_acks) < 0) if (skb_copy_bits(skb, offset, buf.acks, nr_acks) < 0)
...@@ -907,11 +916,6 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb, ...@@ -907,11 +916,6 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb,
&summary); &summary);
} }
if (test_bit(RXRPC_CALL_TX_LAST, &call->flags)) {
rxrpc_end_tx_phase(call, false, "ETA");
return;
}
if (call->rxtx_annotations[call->tx_top & RXRPC_RXTX_BUFF_MASK] & if (call->rxtx_annotations[call->tx_top & RXRPC_RXTX_BUFF_MASK] &
RXRPC_TX_ANNO_LAST && RXRPC_TX_ANNO_LAST &&
summary.nr_acks == call->tx_top - hard_ack && summary.nr_acks == call->tx_top - hard_ack &&
...@@ -933,8 +937,7 @@ static void rxrpc_input_ackall(struct rxrpc_call *call, struct sk_buff *skb) ...@@ -933,8 +937,7 @@ static void rxrpc_input_ackall(struct rxrpc_call *call, struct sk_buff *skb)
_proto("Rx ACKALL %%%u", sp->hdr.serial); _proto("Rx ACKALL %%%u", sp->hdr.serial);
rxrpc_rotate_tx_window(call, call->tx_top, &summary); if (rxrpc_rotate_tx_window(call, call->tx_top, &summary))
if (test_bit(RXRPC_CALL_TX_LAST, &call->flags))
rxrpc_end_tx_phase(call, false, "ETL"); rxrpc_end_tx_phase(call, false, "ETL");
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment