Skip to content

Commit a158bdd

Browse files
committed
rxrpc: Fix call timeouts
Fix the rxrpc call expiration timeouts and make them settable from userspace. By analogy with other rx implementations, there should be three timeouts: (1) "Normal timeout" This is set for all calls and is triggered if we haven't received any packets from the peer in a while. It is measured from the last time we received any packet on that call. This is not reset by any connection packets (such as CHALLENGE/RESPONSE packets). If a service operation takes a long time, the server should generate PING ACKs at a duration that's substantially less than the normal timeout so is to keep both sides alive. This is set at 1/6 of normal timeout. (2) "Idle timeout" This is set only for a service call and is triggered if we stop receiving the DATA packets that comprise the request data. It is measured from the last time we received a DATA packet. (3) "Hard timeout" This can be set for a call and specified the maximum lifetime of that call. It should not be specified by default. Some operations (such as volume transfer) take a long time. Allow userspace to set/change the timeouts on a call with sendmsg, using a control message: RXRPC_SET_CALL_TIMEOUTS The data to the message is a number of 32-bit words, not all of which need be given: u32 hard_timeout; /* sec from first packet */ u32 idle_timeout; /* msec from packet Rx */ u32 normal_timeout; /* msec from data Rx */ This can be set in combination with any other sendmsg() that affects a call. Signed-off-by: David Howells <[email protected]>
1 parent 4812417 commit a158bdd

File tree

11 files changed

+290
-201
lines changed

11 files changed

+290
-201
lines changed

include/trace/events/rxrpc.h

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,20 @@ enum rxrpc_rtt_rx_trace {
138138

139139
enum rxrpc_timer_trace {
140140
rxrpc_timer_begin,
141+
rxrpc_timer_exp_ack,
142+
rxrpc_timer_exp_hard,
143+
rxrpc_timer_exp_idle,
144+
rxrpc_timer_exp_normal,
145+
rxrpc_timer_exp_ping,
146+
rxrpc_timer_exp_resend,
141147
rxrpc_timer_expired,
142148
rxrpc_timer_init_for_reply,
143149
rxrpc_timer_init_for_send_reply,
150+
rxrpc_timer_restart,
144151
rxrpc_timer_set_for_ack,
152+
rxrpc_timer_set_for_hard,
153+
rxrpc_timer_set_for_idle,
154+
rxrpc_timer_set_for_normal,
145155
rxrpc_timer_set_for_ping,
146156
rxrpc_timer_set_for_resend,
147157
rxrpc_timer_set_for_send,
@@ -296,12 +306,22 @@ enum rxrpc_congest_change {
296306
#define rxrpc_timer_traces \
297307
EM(rxrpc_timer_begin, "Begin ") \
298308
EM(rxrpc_timer_expired, "*EXPR*") \
309+
EM(rxrpc_timer_exp_ack, "ExpAck") \
310+
EM(rxrpc_timer_exp_hard, "ExpHrd") \
311+
EM(rxrpc_timer_exp_idle, "ExpIdl") \
312+
EM(rxrpc_timer_exp_normal, "ExpNml") \
313+
EM(rxrpc_timer_exp_ping, "ExpPng") \
314+
EM(rxrpc_timer_exp_resend, "ExpRsn") \
299315
EM(rxrpc_timer_init_for_reply, "IniRpl") \
300316
EM(rxrpc_timer_init_for_send_reply, "SndRpl") \
317+
EM(rxrpc_timer_restart, "Restrt") \
301318
EM(rxrpc_timer_set_for_ack, "SetAck") \
319+
EM(rxrpc_timer_set_for_hard, "SetHrd") \
320+
EM(rxrpc_timer_set_for_idle, "SetIdl") \
321+
EM(rxrpc_timer_set_for_normal, "SetNml") \
302322
EM(rxrpc_timer_set_for_ping, "SetPng") \
303323
EM(rxrpc_timer_set_for_resend, "SetRTx") \
304-
E_(rxrpc_timer_set_for_send, "SetTx ")
324+
E_(rxrpc_timer_set_for_send, "SetSnd")
305325

306326
#define rxrpc_propose_ack_traces \
307327
EM(rxrpc_propose_ack_client_tx_end, "ClTxEnd") \
@@ -932,39 +952,44 @@ TRACE_EVENT(rxrpc_rtt_rx,
932952

933953
TRACE_EVENT(rxrpc_timer,
934954
TP_PROTO(struct rxrpc_call *call, enum rxrpc_timer_trace why,
935-
ktime_t now, unsigned long now_j),
955+
unsigned long now),
936956

937-
TP_ARGS(call, why, now, now_j),
957+
TP_ARGS(call, why, now),
938958

939959
TP_STRUCT__entry(
940960
__field(struct rxrpc_call *, call )
941961
__field(enum rxrpc_timer_trace, why )
942-
__field_struct(ktime_t, now )
943-
__field_struct(ktime_t, expire_at )
944-
__field_struct(ktime_t, ack_at )
945-
__field_struct(ktime_t, resend_at )
946-
__field(unsigned long, now_j )
947-
__field(unsigned long, timer )
962+
__field(long, now )
963+
__field(long, ack_at )
964+
__field(long, resend_at )
965+
__field(long, ping_at )
966+
__field(long, expect_rx_by )
967+
__field(long, expect_req_by )
968+
__field(long, expect_term_by )
969+
__field(long, timer )
948970
),
949971

950972
TP_fast_assign(
951-
__entry->call = call;
952-
__entry->why = why;
953-
__entry->now = now;
954-
__entry->expire_at = call->expire_at;
955-
__entry->ack_at = call->ack_at;
956-
__entry->resend_at = call->resend_at;
957-
__entry->now_j = now_j;
958-
__entry->timer = call->timer.expires;
973+
__entry->call = call;
974+
__entry->why = why;
975+
__entry->now = now;
976+
__entry->ack_at = call->ack_at;
977+
__entry->resend_at = call->resend_at;
978+
__entry->expect_rx_by = call->expect_rx_by;
979+
__entry->expect_req_by = call->expect_req_by;
980+
__entry->expect_term_by = call->expect_term_by;
981+
__entry->timer = call->timer.expires;
959982
),
960983

961-
TP_printk("c=%p %s x=%lld a=%lld r=%lld t=%ld",
984+
TP_printk("c=%p %s a=%ld r=%ld xr=%ld xq=%ld xt=%ld t=%ld",
962985
__entry->call,
963986
__print_symbolic(__entry->why, rxrpc_timer_traces),
964-
ktime_to_ns(ktime_sub(__entry->expire_at, __entry->now)),
965-
ktime_to_ns(ktime_sub(__entry->ack_at, __entry->now)),
966-
ktime_to_ns(ktime_sub(__entry->resend_at, __entry->now)),
967-
__entry->timer - __entry->now_j)
987+
__entry->ack_at - __entry->now,
988+
__entry->resend_at - __entry->now,
989+
__entry->expect_rx_by - __entry->now,
990+
__entry->expect_req_by - __entry->now,
991+
__entry->expect_term_by - __entry->now,
992+
__entry->timer - __entry->now)
968993
);
969994

970995
TRACE_EVENT(rxrpc_rx_lose,

include/uapi/linux/rxrpc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ enum rxrpc_cmsg_type {
5959
RXRPC_EXCLUSIVE_CALL = 10, /* s-: Call should be on exclusive connection */
6060
RXRPC_UPGRADE_SERVICE = 11, /* s-: Request service upgrade for client call */
6161
RXRPC_TX_LENGTH = 12, /* s-: Total length of Tx data */
62+
RXRPC_SET_CALL_TIMEOUT = 13, /* s-: Set one or more call timeouts */
6263
RXRPC__SUPPORTED
6364
};
6465

net/rxrpc/ar-internal.h

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -468,9 +468,9 @@ enum rxrpc_call_flag {
468468
enum rxrpc_call_event {
469469
RXRPC_CALL_EV_ACK, /* need to generate ACK */
470470
RXRPC_CALL_EV_ABORT, /* need to generate abort */
471-
RXRPC_CALL_EV_TIMER, /* Timer expired */
472471
RXRPC_CALL_EV_RESEND, /* Tx resend required */
473472
RXRPC_CALL_EV_PING, /* Ping send required */
473+
RXRPC_CALL_EV_EXPIRED, /* Expiry occurred */
474474
};
475475

476476
/*
@@ -514,10 +514,14 @@ struct rxrpc_call {
514514
struct rxrpc_peer *peer; /* Peer record for remote address */
515515
struct rxrpc_sock __rcu *socket; /* socket responsible */
516516
struct mutex user_mutex; /* User access mutex */
517-
ktime_t ack_at; /* When deferred ACK needs to happen */
518-
ktime_t resend_at; /* When next resend needs to happen */
519-
ktime_t ping_at; /* When next to send a ping */
520-
ktime_t expire_at; /* When the call times out */
517+
unsigned long ack_at; /* When deferred ACK needs to happen */
518+
unsigned long resend_at; /* When next resend needs to happen */
519+
unsigned long ping_at; /* When next to send a ping */
520+
unsigned long expect_rx_by; /* When we expect to get a packet by */
521+
unsigned long expect_req_by; /* When we expect to get a request DATA packet by */
522+
unsigned long expect_term_by; /* When we expect call termination by */
523+
u32 next_rx_timo; /* Timeout for next Rx packet (jif) */
524+
u32 next_req_timo; /* Timeout for next Rx request packet (jif) */
521525
struct timer_list timer; /* Combined event timer */
522526
struct work_struct processor; /* Event processor */
523527
rxrpc_notify_rx_t notify_rx; /* kernel service Rx notification function */
@@ -697,12 +701,19 @@ int rxrpc_reject_call(struct rxrpc_sock *);
697701
/*
698702
* call_event.c
699703
*/
700-
void __rxrpc_set_timer(struct rxrpc_call *, enum rxrpc_timer_trace, ktime_t);
701-
void rxrpc_set_timer(struct rxrpc_call *, enum rxrpc_timer_trace, ktime_t);
702704
void rxrpc_propose_ACK(struct rxrpc_call *, u8, u16, u32, bool, bool,
703705
enum rxrpc_propose_ack_trace);
704706
void rxrpc_process_call(struct work_struct *);
705707

708+
static inline void rxrpc_reduce_call_timer(struct rxrpc_call *call,
709+
unsigned long expire_at,
710+
unsigned long now,
711+
enum rxrpc_timer_trace why)
712+
{
713+
trace_rxrpc_timer(call, why, now);
714+
timer_reduce(&call->timer, expire_at);
715+
}
716+
706717
/*
707718
* call_object.c
708719
*/
@@ -843,8 +854,8 @@ static inline bool __rxrpc_abort_eproto(struct rxrpc_call *call,
843854
*/
844855
extern unsigned int rxrpc_max_client_connections;
845856
extern unsigned int rxrpc_reap_client_connections;
846-
extern unsigned int rxrpc_conn_idle_client_expiry;
847-
extern unsigned int rxrpc_conn_idle_client_fast_expiry;
857+
extern unsigned long rxrpc_conn_idle_client_expiry;
858+
extern unsigned long rxrpc_conn_idle_client_fast_expiry;
848859
extern struct idr rxrpc_client_conn_ids;
849860

850861
void rxrpc_destroy_client_conn_ids(void);
@@ -976,13 +987,13 @@ static inline void rxrpc_queue_local(struct rxrpc_local *local)
976987
* misc.c
977988
*/
978989
extern unsigned int rxrpc_max_backlog __read_mostly;
979-
extern unsigned int rxrpc_requested_ack_delay;
980-
extern unsigned int rxrpc_soft_ack_delay;
981-
extern unsigned int rxrpc_idle_ack_delay;
990+
extern unsigned long rxrpc_requested_ack_delay;
991+
extern unsigned long rxrpc_soft_ack_delay;
992+
extern unsigned long rxrpc_idle_ack_delay;
982993
extern unsigned int rxrpc_rx_window_size;
983994
extern unsigned int rxrpc_rx_mtu;
984995
extern unsigned int rxrpc_rx_jumbo_max;
985-
extern unsigned int rxrpc_resend_timeout;
996+
extern unsigned long rxrpc_resend_timeout;
986997

987998
extern const s8 rxrpc_ack_priority[];
988999

0 commit comments

Comments
 (0)