Skip to content

Commit f5c17aa

Browse files
committed
rxrpc: Calls should only have one terminal state
Condense the terminal states of a call state machine to a single state, plus a separate completion type value. The value is then set, along with error and abort code values, only when the call is transitioned to the completion state. Helpers are provided to simplify this. Signed-off-by: David Howells <[email protected]>
1 parent ccbd3db commit f5c17aa

File tree

12 files changed

+226
-184
lines changed

12 files changed

+226
-184
lines changed

net/rxrpc/ar-internal.h

Lines changed: 90 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -289,8 +289,6 @@ enum rxrpc_conn_proto_state {
289289
RXRPC_CONN_SERVICE, /* Service secured connection */
290290
RXRPC_CONN_REMOTELY_ABORTED, /* Conn aborted by peer */
291291
RXRPC_CONN_LOCALLY_ABORTED, /* Conn aborted locally */
292-
RXRPC_CONN_NETWORK_ERROR, /* Conn terminated by network error */
293-
RXRPC_CONN_LOCAL_ERROR, /* Conn terminated by local error */
294292
RXRPC_CONN__NR_STATES
295293
};
296294

@@ -344,7 +342,6 @@ struct rxrpc_connection {
344342
enum rxrpc_conn_proto_state state : 8; /* current state of connection */
345343
u32 local_abort; /* local abort code */
346344
u32 remote_abort; /* remote abort code */
347-
int error; /* local error incurred */
348345
int debug_id; /* debug ID for printks */
349346
atomic_t serial; /* packet serial number counter */
350347
unsigned int hi_serial; /* highest serial number received */
@@ -411,13 +408,22 @@ enum rxrpc_call_state {
411408
RXRPC_CALL_SERVER_ACK_REQUEST, /* - server pending ACK of request */
412409
RXRPC_CALL_SERVER_SEND_REPLY, /* - server sending reply */
413410
RXRPC_CALL_SERVER_AWAIT_ACK, /* - server awaiting final ACK */
414-
RXRPC_CALL_COMPLETE, /* - call completed */
411+
RXRPC_CALL_COMPLETE, /* - call complete */
412+
RXRPC_CALL_DEAD, /* - call is dead */
413+
NR__RXRPC_CALL_STATES
414+
};
415+
416+
/*
417+
* Call completion condition (state == RXRPC_CALL_COMPLETE).
418+
*/
419+
enum rxrpc_call_completion {
420+
RXRPC_CALL_SUCCEEDED, /* - Normal termination */
415421
RXRPC_CALL_SERVER_BUSY, /* - call rejected by busy server */
416422
RXRPC_CALL_REMOTELY_ABORTED, /* - call aborted by peer */
417423
RXRPC_CALL_LOCALLY_ABORTED, /* - call aborted locally on error or close */
424+
RXRPC_CALL_LOCAL_ERROR, /* - call failed due to local error */
418425
RXRPC_CALL_NETWORK_ERROR, /* - call terminated by network error */
419-
RXRPC_CALL_DEAD, /* - call is dead */
420-
NR__RXRPC_CALL_STATES
426+
NR__RXRPC_CALL_COMPLETIONS
421427
};
422428

423429
/*
@@ -451,14 +457,13 @@ struct rxrpc_call {
451457
unsigned long events;
452458
spinlock_t lock;
453459
rwlock_t state_lock; /* lock for state transition */
460+
u32 abort_code; /* Local/remote abort code */
461+
int error; /* Local error incurred */
462+
enum rxrpc_call_state state : 8; /* current state of call */
463+
enum rxrpc_call_completion completion : 8; /* Call completion condition */
454464
atomic_t usage;
455465
atomic_t skb_count; /* Outstanding packets on this call */
456466
atomic_t sequence; /* Tx data packet sequence counter */
457-
u32 local_abort; /* local abort code */
458-
u32 remote_abort; /* remote abort code */
459-
int error_report; /* Network error (ICMP/local transport) */
460-
int error; /* Local error incurred */
461-
enum rxrpc_call_state state : 8; /* current state of call */
462467
u16 service_id; /* service ID */
463468
u32 call_id; /* call ID on connection */
464469
u32 cid; /* connection ID plus channel index */
@@ -493,20 +498,6 @@ struct rxrpc_call {
493498
unsigned long ackr_window[RXRPC_ACKR_WINDOW_ASZ + 1];
494499
};
495500

496-
/*
497-
* locally abort an RxRPC call
498-
*/
499-
static inline void rxrpc_abort_call(struct rxrpc_call *call, u32 abort_code)
500-
{
501-
write_lock_bh(&call->state_lock);
502-
if (call->state < RXRPC_CALL_COMPLETE) {
503-
call->local_abort = abort_code;
504-
call->state = RXRPC_CALL_LOCALLY_ABORTED;
505-
set_bit(RXRPC_CALL_EV_ABORT, &call->events);
506-
}
507-
write_unlock_bh(&call->state_lock);
508-
}
509-
510501
#include <trace/events/rxrpc.h>
511502

512503
/*
@@ -534,6 +525,8 @@ void rxrpc_process_call(struct work_struct *);
534525
/*
535526
* call_object.c
536527
*/
528+
extern const char *const rxrpc_call_states[];
529+
extern const char *const rxrpc_call_completions[];
537530
extern unsigned int rxrpc_max_call_lifetime;
538531
extern unsigned int rxrpc_dead_call_expiry;
539532
extern struct kmem_cache *rxrpc_call_jar;
@@ -563,6 +556,78 @@ static inline bool rxrpc_is_client_call(const struct rxrpc_call *call)
563556
return !rxrpc_is_service_call(call);
564557
}
565558

559+
/*
560+
* Transition a call to the complete state.
561+
*/
562+
static inline bool __rxrpc_set_call_completion(struct rxrpc_call *call,
563+
enum rxrpc_call_completion compl,
564+
u32 abort_code,
565+
int error)
566+
{
567+
if (call->state < RXRPC_CALL_COMPLETE) {
568+
call->abort_code = abort_code;
569+
call->error = error;
570+
call->completion = compl,
571+
call->state = RXRPC_CALL_COMPLETE;
572+
return true;
573+
}
574+
return false;
575+
}
576+
577+
static inline bool rxrpc_set_call_completion(struct rxrpc_call *call,
578+
enum rxrpc_call_completion compl,
579+
u32 abort_code,
580+
int error)
581+
{
582+
int ret;
583+
584+
write_lock_bh(&call->state_lock);
585+
ret = __rxrpc_set_call_completion(call, compl, abort_code, error);
586+
write_unlock_bh(&call->state_lock);
587+
return ret;
588+
}
589+
590+
/*
591+
* Record that a call successfully completed.
592+
*/
593+
static inline void __rxrpc_call_completed(struct rxrpc_call *call)
594+
{
595+
__rxrpc_set_call_completion(call, RXRPC_CALL_SUCCEEDED, 0, 0);
596+
}
597+
598+
static inline void rxrpc_call_completed(struct rxrpc_call *call)
599+
{
600+
write_lock_bh(&call->state_lock);
601+
__rxrpc_call_completed(call);
602+
write_unlock_bh(&call->state_lock);
603+
}
604+
605+
/*
606+
* Record that a call is locally aborted.
607+
*/
608+
static inline bool __rxrpc_abort_call(struct rxrpc_call *call,
609+
u32 abort_code, int error)
610+
{
611+
if (__rxrpc_set_call_completion(call,
612+
RXRPC_CALL_LOCALLY_ABORTED,
613+
abort_code, error)) {
614+
set_bit(RXRPC_CALL_EV_ABORT, &call->events);
615+
return true;
616+
}
617+
return false;
618+
}
619+
620+
static inline bool rxrpc_abort_call(struct rxrpc_call *call,
621+
u32 abort_code, int error)
622+
{
623+
bool ret;
624+
625+
write_lock_bh(&call->state_lock);
626+
ret = __rxrpc_abort_call(call, abort_code, error);
627+
write_unlock_bh(&call->state_lock);
628+
return ret;
629+
}
630+
566631
/*
567632
* conn_client.c
568633
*/
@@ -778,7 +843,6 @@ static inline void rxrpc_put_peer(struct rxrpc_peer *peer)
778843
/*
779844
* proc.c
780845
*/
781-
extern const char *const rxrpc_call_states[];
782846
extern const struct file_operations rxrpc_call_seq_fops;
783847
extern const struct file_operations rxrpc_connection_seq_fops;
784848

net/rxrpc/call_accept.c

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -329,12 +329,8 @@ struct rxrpc_call *rxrpc_accept_call(struct rxrpc_sock *rx,
329329
case RXRPC_CALL_SERVER_ACCEPTING:
330330
call->state = RXRPC_CALL_SERVER_RECV_REQUEST;
331331
break;
332-
case RXRPC_CALL_REMOTELY_ABORTED:
333-
case RXRPC_CALL_LOCALLY_ABORTED:
334-
ret = -ECONNABORTED;
335-
goto out_release;
336-
case RXRPC_CALL_NETWORK_ERROR:
337-
ret = call->conn->error;
332+
case RXRPC_CALL_COMPLETE:
333+
ret = call->error;
338334
goto out_release;
339335
case RXRPC_CALL_DEAD:
340336
ret = -ETIME;
@@ -403,17 +399,14 @@ int rxrpc_reject_call(struct rxrpc_sock *rx)
403399
write_lock_bh(&call->state_lock);
404400
switch (call->state) {
405401
case RXRPC_CALL_SERVER_ACCEPTING:
406-
call->state = RXRPC_CALL_SERVER_BUSY;
402+
__rxrpc_set_call_completion(call, RXRPC_CALL_SERVER_BUSY,
403+
0, ECONNABORTED);
407404
if (test_and_set_bit(RXRPC_CALL_EV_REJECT_BUSY, &call->events))
408405
rxrpc_queue_call(call);
409406
ret = 0;
410407
goto out_release;
411-
case RXRPC_CALL_REMOTELY_ABORTED:
412-
case RXRPC_CALL_LOCALLY_ABORTED:
413-
ret = -ECONNABORTED;
414-
goto out_release;
415-
case RXRPC_CALL_NETWORK_ERROR:
416-
ret = call->conn->error;
408+
case RXRPC_CALL_COMPLETE:
409+
ret = call->error;
417410
goto out_release;
418411
case RXRPC_CALL_DEAD:
419412
ret = -ETIME;

net/rxrpc/call_event.c

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason,
9595
_debug("cancel timer %%%u", serial);
9696
try_to_del_timer_sync(&call->ack_timer);
9797
read_lock_bh(&call->state_lock);
98-
if (call->state <= RXRPC_CALL_COMPLETE &&
98+
if (call->state < RXRPC_CALL_COMPLETE &&
9999
!test_and_set_bit(RXRPC_CALL_EV_ACK, &call->events))
100100
rxrpc_queue_call(call);
101101
read_unlock_bh(&call->state_lock);
@@ -123,7 +123,7 @@ static void rxrpc_set_resend(struct rxrpc_call *call, u8 resend,
123123
unsigned long resend_at)
124124
{
125125
read_lock_bh(&call->state_lock);
126-
if (call->state >= RXRPC_CALL_COMPLETE)
126+
if (call->state == RXRPC_CALL_COMPLETE)
127127
resend = 0;
128128

129129
if (resend & 1) {
@@ -230,7 +230,7 @@ static void rxrpc_resend_timer(struct rxrpc_call *call)
230230
_enter("%d,%d,%d",
231231
call->acks_tail, call->acks_unacked, call->acks_head);
232232

233-
if (call->state >= RXRPC_CALL_COMPLETE)
233+
if (call->state == RXRPC_CALL_COMPLETE)
234234
return;
235235

236236
resend = 0;
@@ -711,7 +711,7 @@ static int rxrpc_process_rx_queue(struct rxrpc_call *call,
711711
break;
712712
case RXRPC_CALL_SERVER_AWAIT_ACK:
713713
_debug("srv complete");
714-
call->state = RXRPC_CALL_COMPLETE;
714+
__rxrpc_call_completed(call);
715715
post_ACK = true;
716716
break;
717717
case RXRPC_CALL_CLIENT_SEND_REQUEST:
@@ -875,32 +875,30 @@ void rxrpc_process_call(struct work_struct *work)
875875
clear_bit(RXRPC_CALL_EV_REJECT_BUSY, &call->events);
876876
clear_bit(RXRPC_CALL_EV_ABORT, &call->events);
877877

878-
error = call->error_report;
879-
if (error < RXRPC_LOCAL_ERROR_OFFSET) {
878+
if (call->completion == RXRPC_CALL_NETWORK_ERROR) {
880879
mark = RXRPC_SKB_MARK_NET_ERROR;
881880
_debug("post net error %d", error);
882881
} else {
883882
mark = RXRPC_SKB_MARK_LOCAL_ERROR;
884-
error -= RXRPC_LOCAL_ERROR_OFFSET;
885883
_debug("post net local error %d", error);
886884
}
887885

888-
if (rxrpc_post_message(call, mark, error, true) < 0)
886+
if (rxrpc_post_message(call, mark, call->error, true) < 0)
889887
goto no_mem;
890888
clear_bit(RXRPC_CALL_EV_RCVD_ERROR, &call->events);
891889
goto kill_ACKs;
892890
}
893891

894892
if (test_bit(RXRPC_CALL_EV_CONN_ABORT, &call->events)) {
895-
ASSERTCMP(call->state, >, RXRPC_CALL_COMPLETE);
893+
ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE);
896894

897895
clear_bit(RXRPC_CALL_EV_REJECT_BUSY, &call->events);
898896
clear_bit(RXRPC_CALL_EV_ABORT, &call->events);
899897

900898
_debug("post conn abort");
901899

902900
if (rxrpc_post_message(call, RXRPC_SKB_MARK_LOCAL_ERROR,
903-
call->conn->error, true) < 0)
901+
call->error, true) < 0)
904902
goto no_mem;
905903
clear_bit(RXRPC_CALL_EV_CONN_ABORT, &call->events);
906904
goto kill_ACKs;
@@ -913,13 +911,13 @@ void rxrpc_process_call(struct work_struct *work)
913911
}
914912

915913
if (test_bit(RXRPC_CALL_EV_ABORT, &call->events)) {
916-
ASSERTCMP(call->state, >, RXRPC_CALL_COMPLETE);
914+
ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE);
917915

918916
if (rxrpc_post_message(call, RXRPC_SKB_MARK_LOCAL_ERROR,
919-
ECONNABORTED, true) < 0)
917+
call->error, true) < 0)
920918
goto no_mem;
921919
whdr.type = RXRPC_PACKET_TYPE_ABORT;
922-
data = htonl(call->local_abort);
920+
data = htonl(call->abort_code);
923921
iov[1].iov_base = &data;
924922
iov[1].iov_len = sizeof(data);
925923
genbit = RXRPC_CALL_EV_ABORT;
@@ -979,13 +977,7 @@ void rxrpc_process_call(struct work_struct *work)
979977
}
980978

981979
if (test_bit(RXRPC_CALL_EV_LIFE_TIMER, &call->events)) {
982-
write_lock_bh(&call->state_lock);
983-
if (call->state <= RXRPC_CALL_COMPLETE) {
984-
call->state = RXRPC_CALL_LOCALLY_ABORTED;
985-
call->local_abort = RX_CALL_TIMEOUT;
986-
set_bit(RXRPC_CALL_EV_ABORT, &call->events);
987-
}
988-
write_unlock_bh(&call->state_lock);
980+
rxrpc_abort_call(call, RX_CALL_TIMEOUT, ETIME);
989981

990982
_debug("post timeout");
991983
if (rxrpc_post_message(call, RXRPC_SKB_MARK_LOCAL_ERROR,
@@ -998,7 +990,8 @@ void rxrpc_process_call(struct work_struct *work)
998990

999991
/* deal with assorted inbound messages */
1000992
if (!skb_queue_empty(&call->rx_queue)) {
1001-
switch (rxrpc_process_rx_queue(call, &abort_code)) {
993+
ret = rxrpc_process_rx_queue(call, &abort_code);
994+
switch (ret) {
1002995
case 0:
1003996
case -EAGAIN:
1004997
break;
@@ -1007,7 +1000,7 @@ void rxrpc_process_call(struct work_struct *work)
10071000
case -EKEYEXPIRED:
10081001
case -EKEYREJECTED:
10091002
case -EPROTO:
1010-
rxrpc_abort_call(call, abort_code);
1003+
rxrpc_abort_call(call, abort_code, -ret);
10111004
goto kill_ACKs;
10121005
}
10131006
}
@@ -1232,10 +1225,7 @@ void rxrpc_process_call(struct work_struct *work)
12321225
goto kill_ACKs;
12331226

12341227
case RXRPC_CALL_EV_ACK_FINAL:
1235-
write_lock_bh(&call->state_lock);
1236-
if (call->state == RXRPC_CALL_CLIENT_FINAL_ACK)
1237-
call->state = RXRPC_CALL_COMPLETE;
1238-
write_unlock_bh(&call->state_lock);
1228+
rxrpc_call_completed(call);
12391229
goto kill_ACKs;
12401230

12411231
default:

0 commit comments

Comments
 (0)