RxRPC development
-----BEGIN PGP SIGNATURE----- iQIVAwUAW2GoxPu3V2unywtrAQJf6A//TXRbmUri7DBFXf5iDPaA7ItPFG0wBmmu E68/SAMsWZsYnpAY5HGIDufjjdvPl9R7TMSsurIyZl1ZMwzwFiO7LtK5pXvfe17a UJbZc1jPRn8sUuC3bDhRlAtLETqw9Wx0n9GAbLW06XdQsrwnBrg4yGA6HUc2iy8w l0b56G9VhPV27hgKDIvhtkL4c+Ek8qjV6f6bcPSGNtmoepPVh9Jg0fJY7zZbRWm4 tFiPv1nTd/ojQm0MMsyPodCkK+oG3tCji17fy0ZYiXv2nupBXDS6NOoNActRJ1CA RE3hINoeTLtm7h5hlzCEwkG1qr6QPNE9QmSoJY9aViuJTjJKlIJGa/0i2Nl0rpgu HLzg3ifpcrI//KywkTFVxLk1Fp/A6JZK5fNPibpXXoVB6U6Zl+BfpaHoJ7kmnODT xX3NbM0qRV5bbzHWnxiG1UieXDQWr7Sc+0cJslz0sTj/64ktJ4ldwJLdO5El2xrU QHCOIQEsB5YXTx7vAmsXDnMNDmKgnlXXzkzjcG1dJPlOvcLmtm/5HOOaum2/A7ox HuV6wbtHwOTr8KvZnbcsa0pMCctC0icEpbg9TyZf43zEmMdWNmep3A/vRf72fxv4 EFCsx5jc1A3KHDc0HaK8pmTVqUxW6al56iLH5gzn/KRwqgx392iutBJ/2y5WM4Z0 8kzM5XMDpQg= =pQXe -----END PGP SIGNATURE----- Merge tag 'rxrpc-next-20180801' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs David Howells says: ==================== rxrpc: Development Here are some patches that add some more tracepoints to AF_RXRPC and fix some issues therein. The most significant points are: (1) Display the call timeout information in /proc/net/rxrpc/calls. (2) Save the call's debug_id in the rxrpc_channel struct so that it can be used in traces after the rxrpc_call struct has been destroyed. (3) Increase the size of the kAFS Rx window from 32 to 63 to be about the same as the Auristor server. (4) Propose the terminal ACK for a client call after it has received all its data to be transmitted after a short interval so that it will get transmitted if not first superseded by a new call on the same channel. (5) Flush ACKs during the data reception if we detect that we've run out of data.[*] (6) Trace successful packet transmission and softirq to process context socket notification. [*] Note that on a uncontended gigabit network, rxrpc runs in to trouble with ACK packets getting batched together (up to ~32 at a time) somewhere between the IP transmit queue on the client and the ethernet receive queue on the server. I can see the kernel afs filesystem client and Auristor userspace server stalling occasionally on a 512MB single read. Sticking tracepoints in the network driver at either end seems to show that, although the ACK transmissions made by the client are reasonably spaced timewise, the received ACKs come in batches from the network card on the server. I'm not sure what, if anything, can be done about this. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
b69ab96ab1
@ -211,18 +211,18 @@ enum rxrpc_congest_change {
|
||||
rxrpc_cong_saw_nack,
|
||||
};
|
||||
|
||||
enum rxrpc_tx_fail_trace {
|
||||
rxrpc_tx_fail_call_abort,
|
||||
rxrpc_tx_fail_call_ack,
|
||||
rxrpc_tx_fail_call_data_frag,
|
||||
rxrpc_tx_fail_call_data_nofrag,
|
||||
rxrpc_tx_fail_call_final_resend,
|
||||
rxrpc_tx_fail_conn_abort,
|
||||
rxrpc_tx_fail_conn_challenge,
|
||||
rxrpc_tx_fail_conn_response,
|
||||
rxrpc_tx_fail_reject,
|
||||
rxrpc_tx_fail_version_keepalive,
|
||||
rxrpc_tx_fail_version_reply,
|
||||
enum rxrpc_tx_point {
|
||||
rxrpc_tx_point_call_abort,
|
||||
rxrpc_tx_point_call_ack,
|
||||
rxrpc_tx_point_call_data_frag,
|
||||
rxrpc_tx_point_call_data_nofrag,
|
||||
rxrpc_tx_point_call_final_resend,
|
||||
rxrpc_tx_point_conn_abort,
|
||||
rxrpc_tx_point_rxkad_challenge,
|
||||
rxrpc_tx_point_rxkad_response,
|
||||
rxrpc_tx_point_reject,
|
||||
rxrpc_tx_point_version_keepalive,
|
||||
rxrpc_tx_point_version_reply,
|
||||
};
|
||||
|
||||
#endif /* end __RXRPC_DECLARE_TRACE_ENUMS_ONCE_ONLY */
|
||||
@ -396,7 +396,7 @@ enum rxrpc_tx_fail_trace {
|
||||
#define rxrpc_propose_ack_outcomes \
|
||||
EM(rxrpc_propose_ack_subsume, " Subsume") \
|
||||
EM(rxrpc_propose_ack_update, " Update") \
|
||||
E_(rxrpc_propose_ack_use, "")
|
||||
E_(rxrpc_propose_ack_use, " New")
|
||||
|
||||
#define rxrpc_congest_modes \
|
||||
EM(RXRPC_CALL_CONGEST_AVOIDANCE, "CongAvoid") \
|
||||
@ -452,18 +452,18 @@ enum rxrpc_tx_fail_trace {
|
||||
EM(RXRPC_CALL_LOCAL_ERROR, "LocalError") \
|
||||
E_(RXRPC_CALL_NETWORK_ERROR, "NetError")
|
||||
|
||||
#define rxrpc_tx_fail_traces \
|
||||
EM(rxrpc_tx_fail_call_abort, "CallAbort") \
|
||||
EM(rxrpc_tx_fail_call_ack, "CallAck") \
|
||||
EM(rxrpc_tx_fail_call_data_frag, "CallDataFrag") \
|
||||
EM(rxrpc_tx_fail_call_data_nofrag, "CallDataNofrag") \
|
||||
EM(rxrpc_tx_fail_call_final_resend, "CallFinalResend") \
|
||||
EM(rxrpc_tx_fail_conn_abort, "ConnAbort") \
|
||||
EM(rxrpc_tx_fail_conn_challenge, "ConnChall") \
|
||||
EM(rxrpc_tx_fail_conn_response, "ConnResp") \
|
||||
EM(rxrpc_tx_fail_reject, "Reject") \
|
||||
EM(rxrpc_tx_fail_version_keepalive, "VerKeepalive") \
|
||||
E_(rxrpc_tx_fail_version_reply, "VerReply")
|
||||
#define rxrpc_tx_points \
|
||||
EM(rxrpc_tx_point_call_abort, "CallAbort") \
|
||||
EM(rxrpc_tx_point_call_ack, "CallAck") \
|
||||
EM(rxrpc_tx_point_call_data_frag, "CallDataFrag") \
|
||||
EM(rxrpc_tx_point_call_data_nofrag, "CallDataNofrag") \
|
||||
EM(rxrpc_tx_point_call_final_resend, "CallFinalResend") \
|
||||
EM(rxrpc_tx_point_conn_abort, "ConnAbort") \
|
||||
EM(rxrpc_tx_point_reject, "Reject") \
|
||||
EM(rxrpc_tx_point_rxkad_challenge, "RxkadChall") \
|
||||
EM(rxrpc_tx_point_rxkad_response, "RxkadResp") \
|
||||
EM(rxrpc_tx_point_version_keepalive, "VerKeepalive") \
|
||||
E_(rxrpc_tx_point_version_reply, "VerReply")
|
||||
|
||||
/*
|
||||
* Export enum symbols via userspace.
|
||||
@ -488,7 +488,7 @@ rxrpc_propose_ack_traces;
|
||||
rxrpc_propose_ack_outcomes;
|
||||
rxrpc_congest_modes;
|
||||
rxrpc_congest_changes;
|
||||
rxrpc_tx_fail_traces;
|
||||
rxrpc_tx_points;
|
||||
|
||||
/*
|
||||
* Now redefine the EM() and E_() macros to map the enums to the strings that
|
||||
@ -801,7 +801,7 @@ TRACE_EVENT(rxrpc_transmit,
|
||||
);
|
||||
|
||||
TRACE_EVENT(rxrpc_rx_data,
|
||||
TP_PROTO(struct rxrpc_call *call, rxrpc_seq_t seq,
|
||||
TP_PROTO(unsigned int call, rxrpc_seq_t seq,
|
||||
rxrpc_serial_t serial, u8 flags, u8 anno),
|
||||
|
||||
TP_ARGS(call, seq, serial, flags, anno),
|
||||
@ -815,7 +815,7 @@ TRACE_EVENT(rxrpc_rx_data,
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->call = call->debug_id;
|
||||
__entry->call = call;
|
||||
__entry->seq = seq;
|
||||
__entry->serial = serial;
|
||||
__entry->flags = flags;
|
||||
@ -918,6 +918,37 @@ TRACE_EVENT(rxrpc_rx_rwind_change,
|
||||
__entry->wake ? " wake" : "")
|
||||
);
|
||||
|
||||
TRACE_EVENT(rxrpc_tx_packet,
|
||||
TP_PROTO(unsigned int call_id, struct rxrpc_wire_header *whdr,
|
||||
enum rxrpc_tx_point where),
|
||||
|
||||
TP_ARGS(call_id, whdr, where),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(unsigned int, call )
|
||||
__field(enum rxrpc_tx_point, where )
|
||||
__field_struct(struct rxrpc_wire_header, whdr )
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->call = call_id;
|
||||
memcpy(&__entry->whdr, whdr, sizeof(__entry->whdr));
|
||||
),
|
||||
|
||||
TP_printk("c=%08x %08x:%08x:%08x:%04x %08x %08x %02x %02x %s %s",
|
||||
__entry->call,
|
||||
ntohl(__entry->whdr.epoch),
|
||||
ntohl(__entry->whdr.cid),
|
||||
ntohl(__entry->whdr.callNumber),
|
||||
ntohs(__entry->whdr.serviceId),
|
||||
ntohl(__entry->whdr.serial),
|
||||
ntohl(__entry->whdr.seq),
|
||||
__entry->whdr.type, __entry->whdr.flags,
|
||||
__entry->whdr.type <= 15 ?
|
||||
__print_symbolic(__entry->whdr.type, rxrpc_pkts) : "?UNK",
|
||||
__print_symbolic(__entry->where, rxrpc_tx_points))
|
||||
);
|
||||
|
||||
TRACE_EVENT(rxrpc_tx_data,
|
||||
TP_PROTO(struct rxrpc_call *call, rxrpc_seq_t seq,
|
||||
rxrpc_serial_t serial, u8 flags, bool retrans, bool lose),
|
||||
@ -928,6 +959,8 @@ TRACE_EVENT(rxrpc_tx_data,
|
||||
__field(unsigned int, call )
|
||||
__field(rxrpc_seq_t, seq )
|
||||
__field(rxrpc_serial_t, serial )
|
||||
__field(u32, cid )
|
||||
__field(u32, call_id )
|
||||
__field(u8, flags )
|
||||
__field(bool, retrans )
|
||||
__field(bool, lose )
|
||||
@ -935,6 +968,8 @@ TRACE_EVENT(rxrpc_tx_data,
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->call = call->debug_id;
|
||||
__entry->cid = call->cid;
|
||||
__entry->call_id = call->call_id;
|
||||
__entry->seq = seq;
|
||||
__entry->serial = serial;
|
||||
__entry->flags = flags;
|
||||
@ -942,8 +977,10 @@ TRACE_EVENT(rxrpc_tx_data,
|
||||
__entry->lose = lose;
|
||||
),
|
||||
|
||||
TP_printk("c=%08x DATA %08x q=%08x fl=%02x%s%s",
|
||||
TP_printk("c=%08x DATA %08x:%08x %08x q=%08x fl=%02x%s%s",
|
||||
__entry->call,
|
||||
__entry->cid,
|
||||
__entry->call_id,
|
||||
__entry->serial,
|
||||
__entry->seq,
|
||||
__entry->flags,
|
||||
@ -952,7 +989,7 @@ TRACE_EVENT(rxrpc_tx_data,
|
||||
);
|
||||
|
||||
TRACE_EVENT(rxrpc_tx_ack,
|
||||
TP_PROTO(struct rxrpc_call *call, rxrpc_serial_t serial,
|
||||
TP_PROTO(unsigned int call, rxrpc_serial_t serial,
|
||||
rxrpc_seq_t ack_first, rxrpc_serial_t ack_serial,
|
||||
u8 reason, u8 n_acks),
|
||||
|
||||
@ -968,7 +1005,7 @@ TRACE_EVENT(rxrpc_tx_ack,
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->call = call ? call->debug_id : 0;
|
||||
__entry->call = call;
|
||||
__entry->serial = serial;
|
||||
__entry->ack_first = ack_first;
|
||||
__entry->ack_serial = ack_serial;
|
||||
@ -1434,29 +1471,29 @@ TRACE_EVENT(rxrpc_rx_icmp,
|
||||
|
||||
TRACE_EVENT(rxrpc_tx_fail,
|
||||
TP_PROTO(unsigned int debug_id, rxrpc_serial_t serial, int ret,
|
||||
enum rxrpc_tx_fail_trace what),
|
||||
enum rxrpc_tx_point where),
|
||||
|
||||
TP_ARGS(debug_id, serial, ret, what),
|
||||
TP_ARGS(debug_id, serial, ret, where),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(unsigned int, debug_id )
|
||||
__field(rxrpc_serial_t, serial )
|
||||
__field(int, ret )
|
||||
__field(enum rxrpc_tx_fail_trace, what )
|
||||
__field(enum rxrpc_tx_point, where )
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->debug_id = debug_id;
|
||||
__entry->serial = serial;
|
||||
__entry->ret = ret;
|
||||
__entry->what = what;
|
||||
__entry->where = where;
|
||||
),
|
||||
|
||||
TP_printk("c=%08x r=%x ret=%d %s",
|
||||
__entry->debug_id,
|
||||
__entry->serial,
|
||||
__entry->ret,
|
||||
__print_symbolic(__entry->what, rxrpc_tx_fail_traces))
|
||||
__print_symbolic(__entry->where, rxrpc_tx_points))
|
||||
);
|
||||
|
||||
TRACE_EVENT(rxrpc_call_reset,
|
||||
@ -1491,6 +1528,26 @@ TRACE_EVENT(rxrpc_call_reset,
|
||||
__entry->tx_seq, __entry->rx_seq)
|
||||
);
|
||||
|
||||
TRACE_EVENT(rxrpc_notify_socket,
|
||||
TP_PROTO(unsigned int debug_id, rxrpc_serial_t serial),
|
||||
|
||||
TP_ARGS(debug_id, serial),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(unsigned int, debug_id )
|
||||
__field(rxrpc_serial_t, serial )
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->debug_id = debug_id;
|
||||
__entry->serial = serial;
|
||||
),
|
||||
|
||||
TP_printk("c=%08x r=%08x",
|
||||
__entry->debug_id,
|
||||
__entry->serial)
|
||||
);
|
||||
|
||||
#endif /* _TRACE_RXRPC_H */
|
||||
|
||||
/* This part must be outside protection */
|
||||
|
@ -420,6 +420,7 @@ struct rxrpc_connection {
|
||||
struct rxrpc_channel {
|
||||
unsigned long final_ack_at; /* Time at which to issue final ACK */
|
||||
struct rxrpc_call __rcu *call; /* Active call */
|
||||
unsigned int call_debug_id; /* call->debug_id */
|
||||
u32 call_id; /* ID of current call */
|
||||
u32 call_counter; /* Call ID counter */
|
||||
u32 last_call; /* ID of last call */
|
||||
@ -478,6 +479,7 @@ enum rxrpc_call_flag {
|
||||
RXRPC_CALL_RETRANS_TIMEOUT, /* Retransmission due to timeout occurred */
|
||||
RXRPC_CALL_BEGAN_RX_TIMER, /* We began the expect_rx_by timer */
|
||||
RXRPC_CALL_RX_HEARD, /* The peer responded at least once to this call */
|
||||
RXRPC_CALL_RX_UNDERRUN, /* Got data underrun */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -588,7 +590,7 @@ struct rxrpc_call {
|
||||
*/
|
||||
#define RXRPC_RXTX_BUFF_SIZE 64
|
||||
#define RXRPC_RXTX_BUFF_MASK (RXRPC_RXTX_BUFF_SIZE - 1)
|
||||
#define RXRPC_INIT_RX_WINDOW_SIZE 32
|
||||
#define RXRPC_INIT_RX_WINDOW_SIZE 63
|
||||
struct sk_buff **rxtx_buffer;
|
||||
u8 *rxtx_annotations;
|
||||
#define RXRPC_TX_ANNO_ACK 0
|
||||
|
@ -162,7 +162,6 @@ static void rxrpc_congestion_timeout(struct rxrpc_call *call)
|
||||
*/
|
||||
static void rxrpc_resend(struct rxrpc_call *call, unsigned long now_j)
|
||||
{
|
||||
struct rxrpc_skb_priv *sp;
|
||||
struct sk_buff *skb;
|
||||
unsigned long resend_at;
|
||||
rxrpc_seq_t cursor, seq, top;
|
||||
@ -207,7 +206,6 @@ static void rxrpc_resend(struct rxrpc_call *call, unsigned long now_j)
|
||||
|
||||
skb = call->rxtx_buffer[ix];
|
||||
rxrpc_see_skb(skb, rxrpc_skb_tx_seen);
|
||||
sp = rxrpc_skb(skb);
|
||||
|
||||
if (anno_type == RXRPC_TX_ANNO_UNACK) {
|
||||
if (ktime_after(skb->tstamp, max_age)) {
|
||||
|
@ -590,6 +590,7 @@ static void rxrpc_activate_one_channel(struct rxrpc_connection *conn,
|
||||
*/
|
||||
smp_wmb();
|
||||
chan->call_id = call_id;
|
||||
chan->call_debug_id = call->debug_id;
|
||||
rcu_assign_pointer(chan->call, call);
|
||||
wake_up(&call->waitq);
|
||||
}
|
||||
@ -1051,7 +1052,6 @@ void rxrpc_discard_expired_client_conns(struct work_struct *work)
|
||||
container_of(work, struct rxrpc_net, client_conn_reaper);
|
||||
unsigned long expiry, conn_expires_at, now;
|
||||
unsigned int nr_conns;
|
||||
bool did_discard = false;
|
||||
|
||||
_enter("");
|
||||
|
||||
@ -1113,7 +1113,6 @@ next:
|
||||
* If someone re-sets the flag and re-gets the ref, that's fine.
|
||||
*/
|
||||
rxrpc_put_connection(conn);
|
||||
did_discard = true;
|
||||
nr_conns--;
|
||||
goto next;
|
||||
|
||||
|
@ -129,8 +129,10 @@ static void rxrpc_conn_retransmit_call(struct rxrpc_connection *conn,
|
||||
_proto("Tx ABORT %%%u { %d } [re]", serial, conn->local_abort);
|
||||
break;
|
||||
case RXRPC_PACKET_TYPE_ACK:
|
||||
trace_rxrpc_tx_ack(NULL, serial, chan->last_seq, 0,
|
||||
RXRPC_ACK_DUPLICATE, 0);
|
||||
trace_rxrpc_tx_ack(chan->call_debug_id, serial,
|
||||
ntohl(pkt.ack.firstPacket),
|
||||
ntohl(pkt.ack.serial),
|
||||
pkt.ack.reason, 0);
|
||||
_proto("Tx ACK %%%u [re]", serial);
|
||||
break;
|
||||
}
|
||||
@ -138,8 +140,11 @@ static void rxrpc_conn_retransmit_call(struct rxrpc_connection *conn,
|
||||
ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, ioc, len);
|
||||
conn->params.peer->last_tx_at = ktime_get_real();
|
||||
if (ret < 0)
|
||||
trace_rxrpc_tx_fail(conn->debug_id, serial, ret,
|
||||
rxrpc_tx_fail_call_final_resend);
|
||||
trace_rxrpc_tx_fail(chan->call_debug_id, serial, ret,
|
||||
rxrpc_tx_point_call_final_resend);
|
||||
else
|
||||
trace_rxrpc_tx_packet(chan->call_debug_id, &pkt.whdr,
|
||||
rxrpc_tx_point_call_final_resend);
|
||||
|
||||
_leave("");
|
||||
}
|
||||
@ -240,11 +245,13 @@ static int rxrpc_abort_connection(struct rxrpc_connection *conn,
|
||||
ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, 2, len);
|
||||
if (ret < 0) {
|
||||
trace_rxrpc_tx_fail(conn->debug_id, serial, ret,
|
||||
rxrpc_tx_fail_conn_abort);
|
||||
rxrpc_tx_point_conn_abort);
|
||||
_debug("sendmsg failed: %d", ret);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
trace_rxrpc_tx_packet(conn->debug_id, &whdr, rxrpc_tx_point_conn_abort);
|
||||
|
||||
conn->params.peer->last_tx_at = ktime_get_real();
|
||||
|
||||
_leave(" = 0");
|
||||
|
@ -496,7 +496,7 @@ next_subpacket:
|
||||
return rxrpc_proto_abort("LSA", call, seq);
|
||||
}
|
||||
|
||||
trace_rxrpc_rx_data(call, seq, serial, flags, annotation);
|
||||
trace_rxrpc_rx_data(call->debug_id, seq, serial, flags, annotation);
|
||||
if (before_eq(seq, hard_ack)) {
|
||||
ack = RXRPC_ACK_DUPLICATE;
|
||||
ack_serial = serial;
|
||||
@ -592,9 +592,15 @@ ack:
|
||||
rxrpc_propose_ACK(call, ack, skew, ack_serial,
|
||||
immediate_ack, true,
|
||||
rxrpc_propose_ack_input_data);
|
||||
else
|
||||
rxrpc_propose_ACK(call, RXRPC_ACK_DELAY, skew, serial,
|
||||
false, true,
|
||||
rxrpc_propose_ack_input_data);
|
||||
|
||||
if (sp->hdr.seq == READ_ONCE(call->rx_hard_ack) + 1)
|
||||
if (sp->hdr.seq == READ_ONCE(call->rx_hard_ack) + 1) {
|
||||
trace_rxrpc_notify_socket(call->debug_id, serial);
|
||||
rxrpc_notify_socket(call);
|
||||
}
|
||||
_leave(" [queued]");
|
||||
}
|
||||
|
||||
@ -1262,6 +1268,11 @@ void rxrpc_data_ready(struct sock *udp_sk)
|
||||
/* But otherwise we need to retransmit the final packet
|
||||
* from data cached in the connection record.
|
||||
*/
|
||||
if (sp->hdr.type == RXRPC_PACKET_TYPE_DATA)
|
||||
trace_rxrpc_rx_data(chan->call_debug_id,
|
||||
sp->hdr.seq,
|
||||
sp->hdr.serial,
|
||||
sp->hdr.flags, 0);
|
||||
rxrpc_post_packet_to_conn(conn, skb);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
@ -72,7 +72,10 @@ static void rxrpc_send_version_request(struct rxrpc_local *local,
|
||||
ret = kernel_sendmsg(local->socket, &msg, iov, 2, len);
|
||||
if (ret < 0)
|
||||
trace_rxrpc_tx_fail(local->debug_id, 0, ret,
|
||||
rxrpc_tx_fail_version_reply);
|
||||
rxrpc_tx_point_version_reply);
|
||||
else
|
||||
trace_rxrpc_tx_packet(local->debug_id, &whdr,
|
||||
rxrpc_tx_point_version_reply);
|
||||
|
||||
_leave("");
|
||||
}
|
||||
|
@ -183,7 +183,7 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call, bool ping,
|
||||
|
||||
serial = atomic_inc_return(&conn->serial);
|
||||
pkt->whdr.serial = htonl(serial);
|
||||
trace_rxrpc_tx_ack(call, serial,
|
||||
trace_rxrpc_tx_ack(call->debug_id, serial,
|
||||
ntohl(pkt->ack.firstPacket),
|
||||
ntohl(pkt->ack.serial),
|
||||
pkt->ack.reason, pkt->ack.nAcks);
|
||||
@ -212,7 +212,10 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call, bool ping,
|
||||
conn->params.peer->last_tx_at = ktime_get_real();
|
||||
if (ret < 0)
|
||||
trace_rxrpc_tx_fail(call->debug_id, serial, ret,
|
||||
rxrpc_tx_fail_call_ack);
|
||||
rxrpc_tx_point_call_ack);
|
||||
else
|
||||
trace_rxrpc_tx_packet(call->debug_id, &pkt->whdr,
|
||||
rxrpc_tx_point_call_ack);
|
||||
|
||||
if (call->state < RXRPC_CALL_COMPLETE) {
|
||||
if (ret < 0) {
|
||||
@ -299,7 +302,10 @@ int rxrpc_send_abort_packet(struct rxrpc_call *call)
|
||||
conn->params.peer->last_tx_at = ktime_get_real();
|
||||
if (ret < 0)
|
||||
trace_rxrpc_tx_fail(call->debug_id, serial, ret,
|
||||
rxrpc_tx_fail_call_abort);
|
||||
rxrpc_tx_point_call_abort);
|
||||
else
|
||||
trace_rxrpc_tx_packet(call->debug_id, &pkt.whdr,
|
||||
rxrpc_tx_point_call_abort);
|
||||
|
||||
|
||||
rxrpc_put_connection(conn);
|
||||
@ -396,7 +402,10 @@ int rxrpc_send_data_packet(struct rxrpc_call *call, struct sk_buff *skb,
|
||||
up_read(&conn->params.local->defrag_sem);
|
||||
if (ret < 0)
|
||||
trace_rxrpc_tx_fail(call->debug_id, serial, ret,
|
||||
rxrpc_tx_fail_call_data_nofrag);
|
||||
rxrpc_tx_point_call_data_nofrag);
|
||||
else
|
||||
trace_rxrpc_tx_packet(call->debug_id, &whdr,
|
||||
rxrpc_tx_point_call_data_nofrag);
|
||||
if (ret == -EMSGSIZE)
|
||||
goto send_fragmentable;
|
||||
|
||||
@ -488,7 +497,10 @@ send_fragmentable:
|
||||
|
||||
if (ret < 0)
|
||||
trace_rxrpc_tx_fail(call->debug_id, serial, ret,
|
||||
rxrpc_tx_fail_call_data_frag);
|
||||
rxrpc_tx_point_call_data_frag);
|
||||
else
|
||||
trace_rxrpc_tx_packet(call->debug_id, &whdr,
|
||||
rxrpc_tx_point_call_data_frag);
|
||||
|
||||
up_write(&conn->params.local->defrag_sem);
|
||||
goto done;
|
||||
@ -545,7 +557,10 @@ void rxrpc_reject_packets(struct rxrpc_local *local)
|
||||
ret = kernel_sendmsg(local->socket, &msg, iov, 2, size);
|
||||
if (ret < 0)
|
||||
trace_rxrpc_tx_fail(local->debug_id, 0, ret,
|
||||
rxrpc_tx_fail_reject);
|
||||
rxrpc_tx_point_reject);
|
||||
else
|
||||
trace_rxrpc_tx_packet(local->debug_id, &whdr,
|
||||
rxrpc_tx_point_reject);
|
||||
}
|
||||
|
||||
rxrpc_free_skb(skb, rxrpc_skb_rx_freed);
|
||||
@ -597,7 +612,10 @@ void rxrpc_send_keepalive(struct rxrpc_peer *peer)
|
||||
ret = kernel_sendmsg(peer->local->socket, &msg, iov, 2, len);
|
||||
if (ret < 0)
|
||||
trace_rxrpc_tx_fail(peer->debug_id, 0, ret,
|
||||
rxrpc_tx_fail_version_keepalive);
|
||||
rxrpc_tx_point_version_keepalive);
|
||||
else
|
||||
trace_rxrpc_tx_packet(peer->debug_id, &whdr,
|
||||
rxrpc_tx_point_version_keepalive);
|
||||
|
||||
peer->last_tx_at = ktime_get_real();
|
||||
_leave("");
|
||||
|
@ -63,6 +63,7 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v)
|
||||
struct rxrpc_peer *peer;
|
||||
struct rxrpc_call *call;
|
||||
struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
|
||||
unsigned long timeout = 0, nowj;
|
||||
rxrpc_seq_t tx_hard_ack, rx_hard_ack;
|
||||
char lbuff[50], rbuff[50];
|
||||
|
||||
@ -71,7 +72,7 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v)
|
||||
"Proto Local "
|
||||
" Remote "
|
||||
" SvID ConnID CallID End Use State Abort "
|
||||
" UserID\n");
|
||||
" UserID TxSeq TW RxSeq RW RxSerial RxTimo\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -94,11 +95,17 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v)
|
||||
else
|
||||
strcpy(rbuff, "no_connection");
|
||||
|
||||
if (call->state != RXRPC_CALL_SERVER_PREALLOC) {
|
||||
timeout = READ_ONCE(call->expect_rx_by);
|
||||
nowj = jiffies;
|
||||
timeout -= jiffies;
|
||||
}
|
||||
|
||||
tx_hard_ack = READ_ONCE(call->tx_hard_ack);
|
||||
rx_hard_ack = READ_ONCE(call->rx_hard_ack);
|
||||
seq_printf(seq,
|
||||
"UDP %-47.47s %-47.47s %4x %08x %08x %s %3u"
|
||||
" %-8.8s %08x %lx %08x %02x %08x %02x\n",
|
||||
" %-8.8s %08x %lx %08x %02x %08x %02x %08x %06lx\n",
|
||||
lbuff,
|
||||
rbuff,
|
||||
call->service_id,
|
||||
@ -110,7 +117,9 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v)
|
||||
call->abort_code,
|
||||
call->user_call_ID,
|
||||
tx_hard_ack, READ_ONCE(call->tx_top) - tx_hard_ack,
|
||||
rx_hard_ack, READ_ONCE(call->rx_top) - rx_hard_ack);
|
||||
rx_hard_ack, READ_ONCE(call->rx_top) - rx_hard_ack,
|
||||
call->rx_serial,
|
||||
timeout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -179,7 +188,7 @@ static int rxrpc_connection_seq_show(struct seq_file *seq, void *v)
|
||||
print:
|
||||
seq_printf(seq,
|
||||
"UDP %-47.47s %-47.47s %4x %08x %s %3u"
|
||||
" %s %08x %08x %08x\n",
|
||||
" %s %08x %08x %08x %08x %08x %08x %08x\n",
|
||||
lbuff,
|
||||
rbuff,
|
||||
conn->service_id,
|
||||
@ -189,7 +198,11 @@ print:
|
||||
rxrpc_conn_states[conn->state],
|
||||
key_serial(conn->params.key),
|
||||
atomic_read(&conn->serial),
|
||||
conn->hi_serial);
|
||||
conn->hi_serial,
|
||||
conn->channels[0].call_id,
|
||||
conn->channels[1].call_id,
|
||||
conn->channels[2].call_id,
|
||||
conn->channels[3].call_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -144,13 +144,11 @@ static void rxrpc_end_rx_phase(struct rxrpc_call *call, rxrpc_serial_t serial)
|
||||
trace_rxrpc_receive(call, rxrpc_receive_end, 0, call->rx_top);
|
||||
ASSERTCMP(call->rx_hard_ack, ==, call->rx_top);
|
||||
|
||||
#if 0 // TODO: May want to transmit final ACK under some circumstances anyway
|
||||
if (call->state == RXRPC_CALL_CLIENT_RECV_REPLY) {
|
||||
rxrpc_propose_ACK(call, RXRPC_ACK_IDLE, 0, serial, true, false,
|
||||
rxrpc_propose_ACK(call, RXRPC_ACK_IDLE, 0, serial, false, true,
|
||||
rxrpc_propose_ack_terminal_ack);
|
||||
rxrpc_send_ack_packet(call, false, NULL);
|
||||
//rxrpc_send_ack_packet(call, false, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
write_lock_bh(&call->state_lock);
|
||||
|
||||
@ -315,6 +313,10 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call,
|
||||
unsigned int rx_pkt_offset, rx_pkt_len;
|
||||
int ix, copy, ret = -EAGAIN, ret2;
|
||||
|
||||
if (test_and_clear_bit(RXRPC_CALL_RX_UNDERRUN, &call->flags) &&
|
||||
call->ackr_reason)
|
||||
rxrpc_send_ack_packet(call, false, NULL);
|
||||
|
||||
rx_pkt_offset = call->rx_pkt_offset;
|
||||
rx_pkt_len = call->rx_pkt_len;
|
||||
|
||||
@ -414,6 +416,8 @@ out:
|
||||
done:
|
||||
trace_rxrpc_recvmsg(call, rxrpc_recvmsg_data_return, seq,
|
||||
rx_pkt_offset, rx_pkt_len, ret);
|
||||
if (ret == -EAGAIN)
|
||||
set_bit(RXRPC_CALL_RX_UNDERRUN, &call->flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -686,6 +690,17 @@ int rxrpc_kernel_recv_data(struct socket *sock, struct rxrpc_call *call,
|
||||
read_phase_complete:
|
||||
ret = 1;
|
||||
out:
|
||||
switch (call->ackr_reason) {
|
||||
case RXRPC_ACK_IDLE:
|
||||
break;
|
||||
case RXRPC_ACK_DELAY:
|
||||
if (ret != -EAGAIN)
|
||||
break;
|
||||
/* Fall through */
|
||||
default:
|
||||
rxrpc_send_ack_packet(call, false, NULL);
|
||||
}
|
||||
|
||||
if (_service)
|
||||
*_service = call->service_id;
|
||||
mutex_unlock(&call->user_mutex);
|
||||
|
@ -665,11 +665,13 @@ static int rxkad_issue_challenge(struct rxrpc_connection *conn)
|
||||
ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, 2, len);
|
||||
if (ret < 0) {
|
||||
trace_rxrpc_tx_fail(conn->debug_id, serial, ret,
|
||||
rxrpc_tx_fail_conn_challenge);
|
||||
rxrpc_tx_point_rxkad_challenge);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
conn->params.peer->last_tx_at = ktime_get_real();
|
||||
trace_rxrpc_tx_packet(conn->debug_id, &whdr,
|
||||
rxrpc_tx_point_rxkad_challenge);
|
||||
_leave(" = 0");
|
||||
return 0;
|
||||
}
|
||||
@ -721,11 +723,12 @@ static int rxkad_send_response(struct rxrpc_connection *conn,
|
||||
ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, 3, len);
|
||||
if (ret < 0) {
|
||||
trace_rxrpc_tx_fail(conn->debug_id, serial, ret,
|
||||
rxrpc_tx_fail_conn_response);
|
||||
rxrpc_tx_point_rxkad_response);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
conn->params.peer->last_tx_at = ktime_get_real();
|
||||
trace_rxrpc_tx_packet(0, &whdr, rxrpc_tx_point_rxkad_response);
|
||||
_leave(" = 0");
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user