rxrpc: De-atomic call->ackr_window and call->ackr_nr_unacked
call->ackr_window doesn't need to be atomic as ACK generation and ACK transmission are now done in the same thread, so drop the atomic64 handling and split it into two separate members. Similarly, call->ackr_nr_unacked doesn't need to be atomic now either. Signed-off-by: David Howells <dhowells@redhat.com> cc: Marc Dionne <marc.dionne@auristor.com> cc: linux-afs@lists.infradead.org
This commit is contained in:
parent
84e28aa513
commit
5bbf953382
@ -1152,7 +1152,8 @@ TRACE_EVENT(rxrpc_receive,
|
|||||||
__field(enum rxrpc_receive_trace, why)
|
__field(enum rxrpc_receive_trace, why)
|
||||||
__field(rxrpc_serial_t, serial)
|
__field(rxrpc_serial_t, serial)
|
||||||
__field(rxrpc_seq_t, seq)
|
__field(rxrpc_seq_t, seq)
|
||||||
__field(u64, window)
|
__field(rxrpc_seq_t, window)
|
||||||
|
__field(rxrpc_seq_t, wtop)
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_fast_assign(
|
TP_fast_assign(
|
||||||
@ -1160,7 +1161,8 @@ TRACE_EVENT(rxrpc_receive,
|
|||||||
__entry->why = why;
|
__entry->why = why;
|
||||||
__entry->serial = serial;
|
__entry->serial = serial;
|
||||||
__entry->seq = seq;
|
__entry->seq = seq;
|
||||||
__entry->window = atomic64_read(&call->ackr_window);
|
__entry->window = call->ackr_window;
|
||||||
|
__entry->wtop = call->ackr_wtop;
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_printk("c=%08x %s r=%08x q=%08x w=%08x-%08x",
|
TP_printk("c=%08x %s r=%08x q=%08x w=%08x-%08x",
|
||||||
@ -1168,8 +1170,8 @@ TRACE_EVENT(rxrpc_receive,
|
|||||||
__print_symbolic(__entry->why, rxrpc_receive_traces),
|
__print_symbolic(__entry->why, rxrpc_receive_traces),
|
||||||
__entry->serial,
|
__entry->serial,
|
||||||
__entry->seq,
|
__entry->seq,
|
||||||
lower_32_bits(__entry->window),
|
__entry->window,
|
||||||
upper_32_bits(__entry->window))
|
__entry->wtop)
|
||||||
);
|
);
|
||||||
|
|
||||||
TRACE_EVENT(rxrpc_recvmsg,
|
TRACE_EVENT(rxrpc_recvmsg,
|
||||||
|
@ -692,8 +692,9 @@ struct rxrpc_call {
|
|||||||
/* Receive-phase ACK management (ACKs we send). */
|
/* Receive-phase ACK management (ACKs we send). */
|
||||||
u8 ackr_reason; /* reason to ACK */
|
u8 ackr_reason; /* reason to ACK */
|
||||||
rxrpc_serial_t ackr_serial; /* serial of packet being ACK'd */
|
rxrpc_serial_t ackr_serial; /* serial of packet being ACK'd */
|
||||||
atomic64_t ackr_window; /* Base (in LSW) and top (in MSW) of SACK window */
|
rxrpc_seq_t ackr_window; /* Base of SACK window */
|
||||||
atomic_t ackr_nr_unacked; /* Number of unacked packets */
|
rxrpc_seq_t ackr_wtop; /* Base of SACK window */
|
||||||
|
unsigned int ackr_nr_unacked; /* Number of unacked packets */
|
||||||
atomic_t ackr_nr_consumed; /* Number of packets needing hard ACK */
|
atomic_t ackr_nr_consumed; /* Number of packets needing hard ACK */
|
||||||
struct {
|
struct {
|
||||||
#define RXRPC_SACK_SIZE 256
|
#define RXRPC_SACK_SIZE 256
|
||||||
|
@ -498,7 +498,7 @@ bool rxrpc_input_call_event(struct rxrpc_call *call, struct sk_buff *skb)
|
|||||||
rxrpc_send_ACK(call, RXRPC_ACK_IDLE, 0,
|
rxrpc_send_ACK(call, RXRPC_ACK_IDLE, 0,
|
||||||
rxrpc_propose_ack_rx_idle);
|
rxrpc_propose_ack_rx_idle);
|
||||||
|
|
||||||
if (atomic_read(&call->ackr_nr_unacked) > 2) {
|
if (call->ackr_nr_unacked > 2) {
|
||||||
if (call->peer->rtt_count < 3)
|
if (call->peer->rtt_count < 3)
|
||||||
rxrpc_send_ACK(call, RXRPC_ACK_PING, 0,
|
rxrpc_send_ACK(call, RXRPC_ACK_PING, 0,
|
||||||
rxrpc_propose_ack_ping_for_rtt);
|
rxrpc_propose_ack_ping_for_rtt);
|
||||||
|
@ -167,7 +167,8 @@ struct rxrpc_call *rxrpc_alloc_call(struct rxrpc_sock *rx, gfp_t gfp,
|
|||||||
call->tx_total_len = -1;
|
call->tx_total_len = -1;
|
||||||
call->next_rx_timo = 20 * HZ;
|
call->next_rx_timo = 20 * HZ;
|
||||||
call->next_req_timo = 1 * HZ;
|
call->next_req_timo = 1 * HZ;
|
||||||
atomic64_set(&call->ackr_window, 0x100000001ULL);
|
call->ackr_window = 1;
|
||||||
|
call->ackr_wtop = 1;
|
||||||
|
|
||||||
memset(&call->sock_node, 0xed, sizeof(call->sock_node));
|
memset(&call->sock_node, 0xed, sizeof(call->sock_node));
|
||||||
|
|
||||||
|
@ -338,7 +338,8 @@ static void rxrpc_end_rx_phase(struct rxrpc_call *call, rxrpc_serial_t serial)
|
|||||||
static void rxrpc_input_update_ack_window(struct rxrpc_call *call,
|
static void rxrpc_input_update_ack_window(struct rxrpc_call *call,
|
||||||
rxrpc_seq_t window, rxrpc_seq_t wtop)
|
rxrpc_seq_t window, rxrpc_seq_t wtop)
|
||||||
{
|
{
|
||||||
atomic64_set_release(&call->ackr_window, ((u64)wtop) << 32 | window);
|
call->ackr_window = window;
|
||||||
|
call->ackr_wtop = wtop;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -367,9 +368,8 @@ static void rxrpc_input_data_one(struct rxrpc_call *call, struct sk_buff *skb,
|
|||||||
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
|
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
|
||||||
struct sk_buff *oos;
|
struct sk_buff *oos;
|
||||||
rxrpc_serial_t serial = sp->hdr.serial;
|
rxrpc_serial_t serial = sp->hdr.serial;
|
||||||
u64 win = atomic64_read(&call->ackr_window);
|
rxrpc_seq_t window = call->ackr_window;
|
||||||
rxrpc_seq_t window = lower_32_bits(win);
|
rxrpc_seq_t wtop = call->ackr_wtop;
|
||||||
rxrpc_seq_t wtop = upper_32_bits(win);
|
|
||||||
rxrpc_seq_t wlimit = window + call->rx_winsize - 1;
|
rxrpc_seq_t wlimit = window + call->rx_winsize - 1;
|
||||||
rxrpc_seq_t seq = sp->hdr.seq;
|
rxrpc_seq_t seq = sp->hdr.seq;
|
||||||
bool last = sp->hdr.flags & RXRPC_LAST_PACKET;
|
bool last = sp->hdr.flags & RXRPC_LAST_PACKET;
|
||||||
@ -419,7 +419,7 @@ static void rxrpc_input_data_one(struct rxrpc_call *call, struct sk_buff *skb,
|
|||||||
else if (!skb_queue_empty(&call->rx_oos_queue))
|
else if (!skb_queue_empty(&call->rx_oos_queue))
|
||||||
ack_reason = RXRPC_ACK_DELAY;
|
ack_reason = RXRPC_ACK_DELAY;
|
||||||
else
|
else
|
||||||
atomic_inc_return(&call->ackr_nr_unacked);
|
call->ackr_nr_unacked++;
|
||||||
|
|
||||||
window++;
|
window++;
|
||||||
if (after(window, wtop))
|
if (after(window, wtop))
|
||||||
@ -567,8 +567,8 @@ static void rxrpc_input_data(struct rxrpc_call *call, struct sk_buff *skb)
|
|||||||
rxrpc_serial_t serial = sp->hdr.serial;
|
rxrpc_serial_t serial = sp->hdr.serial;
|
||||||
rxrpc_seq_t seq0 = sp->hdr.seq;
|
rxrpc_seq_t seq0 = sp->hdr.seq;
|
||||||
|
|
||||||
_enter("{%llx,%x},{%u,%x}",
|
_enter("{%x,%x,%x},{%u,%x}",
|
||||||
atomic64_read(&call->ackr_window), call->rx_highest_seq,
|
call->ackr_window, call->ackr_wtop, call->rx_highest_seq,
|
||||||
skb->len, seq0);
|
skb->len, seq0);
|
||||||
|
|
||||||
if (__rxrpc_call_is_complete(call))
|
if (__rxrpc_call_is_complete(call))
|
||||||
|
@ -86,20 +86,18 @@ static size_t rxrpc_fill_out_ack(struct rxrpc_connection *conn,
|
|||||||
unsigned int qsize;
|
unsigned int qsize;
|
||||||
rxrpc_seq_t window, wtop, wrap_point, ix, first;
|
rxrpc_seq_t window, wtop, wrap_point, ix, first;
|
||||||
int rsize;
|
int rsize;
|
||||||
u64 wtmp;
|
|
||||||
u32 mtu, jmax;
|
u32 mtu, jmax;
|
||||||
u8 *ackp = txb->acks;
|
u8 *ackp = txb->acks;
|
||||||
u8 sack_buffer[sizeof(call->ackr_sack_table)] __aligned(8);
|
u8 sack_buffer[sizeof(call->ackr_sack_table)] __aligned(8);
|
||||||
|
|
||||||
atomic_set(&call->ackr_nr_unacked, 0);
|
call->ackr_nr_unacked = 0;
|
||||||
atomic_set(&call->ackr_nr_consumed, 0);
|
atomic_set(&call->ackr_nr_consumed, 0);
|
||||||
rxrpc_inc_stat(call->rxnet, stat_tx_ack_fill);
|
rxrpc_inc_stat(call->rxnet, stat_tx_ack_fill);
|
||||||
|
|
||||||
/* Barrier against rxrpc_input_data(). */
|
/* Barrier against rxrpc_input_data(). */
|
||||||
retry:
|
retry:
|
||||||
wtmp = atomic64_read_acquire(&call->ackr_window);
|
window = call->ackr_window;
|
||||||
window = lower_32_bits(wtmp);
|
wtop = call->ackr_wtop;
|
||||||
wtop = upper_32_bits(wtmp);
|
|
||||||
txb->ack.firstPacket = htonl(window);
|
txb->ack.firstPacket = htonl(window);
|
||||||
txb->ack.nAcks = 0;
|
txb->ack.nAcks = 0;
|
||||||
|
|
||||||
@ -111,9 +109,8 @@ retry:
|
|||||||
*/
|
*/
|
||||||
memcpy(sack_buffer, call->ackr_sack_table, sizeof(sack_buffer));
|
memcpy(sack_buffer, call->ackr_sack_table, sizeof(sack_buffer));
|
||||||
wrap_point = window + RXRPC_SACK_SIZE - 1;
|
wrap_point = window + RXRPC_SACK_SIZE - 1;
|
||||||
wtmp = atomic64_read_acquire(&call->ackr_window);
|
window = call->ackr_window;
|
||||||
window = lower_32_bits(wtmp);
|
wtop = call->ackr_wtop;
|
||||||
wtop = upper_32_bits(wtmp);
|
|
||||||
if (after(wtop, wrap_point)) {
|
if (after(wtop, wrap_point)) {
|
||||||
cond_resched();
|
cond_resched();
|
||||||
goto retry;
|
goto retry;
|
||||||
|
@ -55,7 +55,6 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v)
|
|||||||
unsigned long timeout = 0;
|
unsigned long timeout = 0;
|
||||||
rxrpc_seq_t acks_hard_ack;
|
rxrpc_seq_t acks_hard_ack;
|
||||||
char lbuff[50], rbuff[50];
|
char lbuff[50], rbuff[50];
|
||||||
u64 wtmp;
|
|
||||||
|
|
||||||
if (v == &rxnet->calls) {
|
if (v == &rxnet->calls) {
|
||||||
seq_puts(seq,
|
seq_puts(seq,
|
||||||
@ -83,7 +82,6 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v)
|
|||||||
}
|
}
|
||||||
|
|
||||||
acks_hard_ack = READ_ONCE(call->acks_hard_ack);
|
acks_hard_ack = READ_ONCE(call->acks_hard_ack);
|
||||||
wtmp = atomic64_read_acquire(&call->ackr_window);
|
|
||||||
seq_printf(seq,
|
seq_printf(seq,
|
||||||
"UDP %-47.47s %-47.47s %4x %08x %08x %s %3u"
|
"UDP %-47.47s %-47.47s %4x %08x %08x %s %3u"
|
||||||
" %-8.8s %08x %08x %08x %02x %08x %02x %08x %02x %06lx\n",
|
" %-8.8s %08x %08x %08x %02x %08x %02x %08x %02x %06lx\n",
|
||||||
@ -98,7 +96,7 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v)
|
|||||||
call->abort_code,
|
call->abort_code,
|
||||||
call->debug_id,
|
call->debug_id,
|
||||||
acks_hard_ack, READ_ONCE(call->tx_top) - acks_hard_ack,
|
acks_hard_ack, READ_ONCE(call->tx_top) - acks_hard_ack,
|
||||||
lower_32_bits(wtmp), upper_32_bits(wtmp) - lower_32_bits(wtmp),
|
call->ackr_window, call->ackr_wtop - call->ackr_window,
|
||||||
call->rx_serial,
|
call->rx_serial,
|
||||||
call->cong_cwnd,
|
call->cong_cwnd,
|
||||||
timeout);
|
timeout);
|
||||||
|
@ -95,7 +95,7 @@ static int rxrpc_recvmsg_term(struct rxrpc_call *call, struct msghdr *msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
trace_rxrpc_recvdata(call, rxrpc_recvmsg_terminal,
|
trace_rxrpc_recvdata(call, rxrpc_recvmsg_terminal,
|
||||||
lower_32_bits(atomic64_read(&call->ackr_window)) - 1,
|
call->ackr_window - 1,
|
||||||
call->rx_pkt_offset, call->rx_pkt_len, ret);
|
call->rx_pkt_offset, call->rx_pkt_len, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -175,13 +175,13 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call,
|
|||||||
rx_pkt_len = call->rx_pkt_len;
|
rx_pkt_len = call->rx_pkt_len;
|
||||||
|
|
||||||
if (rxrpc_call_has_failed(call)) {
|
if (rxrpc_call_has_failed(call)) {
|
||||||
seq = lower_32_bits(atomic64_read(&call->ackr_window)) - 1;
|
seq = call->ackr_window - 1;
|
||||||
ret = -EIO;
|
ret = -EIO;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (test_bit(RXRPC_CALL_RECVMSG_READ_ALL, &call->flags)) {
|
if (test_bit(RXRPC_CALL_RECVMSG_READ_ALL, &call->flags)) {
|
||||||
seq = lower_32_bits(atomic64_read(&call->ackr_window)) - 1;
|
seq = call->ackr_window - 1;
|
||||||
ret = 1;
|
ret = 1;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user