Skip to content

Commit 07a86b0

Browse files
committed
Merge tag 'rxrpc-fixes-20200605' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs
David Howells says: ==================== rxrpc: Fix hang due to missing notification Here's a fix for AF_RXRPC. Occasionally calls hang because there are circumstances in which rxrpc generate a notification when a call is completed - primarily because initial packet transmission failed and the call was killed off and an error returned. But the AFS filesystem driver doesn't check this under all circumstances, expecting failure to be delivered by asynchronous notification. There are two patches: the first moves the problematic bits out-of-line and the second contains the fix. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 8e60eed + 5ac0d62 commit 07a86b0

File tree

7 files changed

+111
-110
lines changed

7 files changed

+111
-110
lines changed

net/rxrpc/ar-internal.h

Lines changed: 25 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -809,100 +809,6 @@ static inline bool rxrpc_is_client_call(const struct rxrpc_call *call)
809809
return !rxrpc_is_service_call(call);
810810
}
811811

812-
/*
813-
* Transition a call to the complete state.
814-
*/
815-
static inline bool __rxrpc_set_call_completion(struct rxrpc_call *call,
816-
enum rxrpc_call_completion compl,
817-
u32 abort_code,
818-
int error)
819-
{
820-
if (call->state < RXRPC_CALL_COMPLETE) {
821-
call->abort_code = abort_code;
822-
call->error = error;
823-
call->completion = compl,
824-
call->state = RXRPC_CALL_COMPLETE;
825-
trace_rxrpc_call_complete(call);
826-
wake_up(&call->waitq);
827-
return true;
828-
}
829-
return false;
830-
}
831-
832-
static inline bool rxrpc_set_call_completion(struct rxrpc_call *call,
833-
enum rxrpc_call_completion compl,
834-
u32 abort_code,
835-
int error)
836-
{
837-
bool ret;
838-
839-
write_lock_bh(&call->state_lock);
840-
ret = __rxrpc_set_call_completion(call, compl, abort_code, error);
841-
write_unlock_bh(&call->state_lock);
842-
return ret;
843-
}
844-
845-
/*
846-
* Record that a call successfully completed.
847-
*/
848-
static inline bool __rxrpc_call_completed(struct rxrpc_call *call)
849-
{
850-
return __rxrpc_set_call_completion(call, RXRPC_CALL_SUCCEEDED, 0, 0);
851-
}
852-
853-
static inline bool rxrpc_call_completed(struct rxrpc_call *call)
854-
{
855-
bool ret;
856-
857-
write_lock_bh(&call->state_lock);
858-
ret = __rxrpc_call_completed(call);
859-
write_unlock_bh(&call->state_lock);
860-
return ret;
861-
}
862-
863-
/*
864-
* Record that a call is locally aborted.
865-
*/
866-
static inline bool __rxrpc_abort_call(const char *why, struct rxrpc_call *call,
867-
rxrpc_seq_t seq,
868-
u32 abort_code, int error)
869-
{
870-
trace_rxrpc_abort(call->debug_id, why, call->cid, call->call_id, seq,
871-
abort_code, error);
872-
return __rxrpc_set_call_completion(call, RXRPC_CALL_LOCALLY_ABORTED,
873-
abort_code, error);
874-
}
875-
876-
static inline bool rxrpc_abort_call(const char *why, struct rxrpc_call *call,
877-
rxrpc_seq_t seq, u32 abort_code, int error)
878-
{
879-
bool ret;
880-
881-
write_lock_bh(&call->state_lock);
882-
ret = __rxrpc_abort_call(why, call, seq, abort_code, error);
883-
write_unlock_bh(&call->state_lock);
884-
return ret;
885-
}
886-
887-
/*
888-
* Abort a call due to a protocol error.
889-
*/
890-
static inline bool __rxrpc_abort_eproto(struct rxrpc_call *call,
891-
struct sk_buff *skb,
892-
const char *eproto_why,
893-
const char *why,
894-
u32 abort_code)
895-
{
896-
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
897-
898-
trace_rxrpc_rx_eproto(call, sp->hdr.serial, eproto_why);
899-
return rxrpc_abort_call(why, call, sp->hdr.seq, abort_code, -EPROTO);
900-
}
901-
902-
#define rxrpc_abort_eproto(call, skb, eproto_why, abort_why, abort_code) \
903-
__rxrpc_abort_eproto((call), (skb), tracepoint_string(eproto_why), \
904-
(abort_why), (abort_code))
905-
906812
/*
907813
* conn_client.c
908814
*/
@@ -1101,8 +1007,33 @@ extern const struct seq_operations rxrpc_peer_seq_ops;
11011007
* recvmsg.c
11021008
*/
11031009
void rxrpc_notify_socket(struct rxrpc_call *);
1010+
bool __rxrpc_set_call_completion(struct rxrpc_call *, enum rxrpc_call_completion, u32, int);
1011+
bool rxrpc_set_call_completion(struct rxrpc_call *, enum rxrpc_call_completion, u32, int);
1012+
bool __rxrpc_call_completed(struct rxrpc_call *);
1013+
bool rxrpc_call_completed(struct rxrpc_call *);
1014+
bool __rxrpc_abort_call(const char *, struct rxrpc_call *, rxrpc_seq_t, u32, int);
1015+
bool rxrpc_abort_call(const char *, struct rxrpc_call *, rxrpc_seq_t, u32, int);
11041016
int rxrpc_recvmsg(struct socket *, struct msghdr *, size_t, int);
11051017

1018+
/*
1019+
* Abort a call due to a protocol error.
1020+
*/
1021+
static inline bool __rxrpc_abort_eproto(struct rxrpc_call *call,
1022+
struct sk_buff *skb,
1023+
const char *eproto_why,
1024+
const char *why,
1025+
u32 abort_code)
1026+
{
1027+
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
1028+
1029+
trace_rxrpc_rx_eproto(call, sp->hdr.serial, eproto_why);
1030+
return rxrpc_abort_call(why, call, sp->hdr.seq, abort_code, -EPROTO);
1031+
}
1032+
1033+
#define rxrpc_abort_eproto(call, skb, eproto_why, abort_why, abort_code) \
1034+
__rxrpc_abort_eproto((call), (skb), tracepoint_string(eproto_why), \
1035+
(abort_why), (abort_code))
1036+
11061037
/*
11071038
* rtt.c
11081039
*/

net/rxrpc/call_event.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,6 @@ void rxrpc_process_call(struct work_struct *work)
320320

321321
if (call->state == RXRPC_CALL_COMPLETE) {
322322
del_timer_sync(&call->timer);
323-
rxrpc_notify_socket(call);
324323
goto out_put;
325324
}
326325

net/rxrpc/conn_event.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,10 +173,9 @@ static void rxrpc_abort_calls(struct rxrpc_connection *conn,
173173
else
174174
trace_rxrpc_rx_abort(call, serial,
175175
conn->abort_code);
176-
if (rxrpc_set_call_completion(call, compl,
177-
conn->abort_code,
178-
conn->error))
179-
rxrpc_notify_socket(call);
176+
rxrpc_set_call_completion(call, compl,
177+
conn->abort_code,
178+
conn->error);
180179
}
181180
}
182181

net/rxrpc/input.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,6 @@ static bool rxrpc_end_tx_phase(struct rxrpc_call *call, bool reply_begun,
275275

276276
case RXRPC_CALL_SERVER_AWAIT_ACK:
277277
__rxrpc_call_completed(call);
278-
rxrpc_notify_socket(call);
279278
state = call->state;
280279
break;
281280

@@ -1013,9 +1012,8 @@ static void rxrpc_input_abort(struct rxrpc_call *call, struct sk_buff *skb)
10131012

10141013
_proto("Rx ABORT %%%u { %x }", sp->hdr.serial, abort_code);
10151014

1016-
if (rxrpc_set_call_completion(call, RXRPC_CALL_REMOTELY_ABORTED,
1017-
abort_code, -ECONNABORTED))
1018-
rxrpc_notify_socket(call);
1015+
rxrpc_set_call_completion(call, RXRPC_CALL_REMOTELY_ABORTED,
1016+
abort_code, -ECONNABORTED);
10191017
}
10201018

10211019
/*
@@ -1102,7 +1100,6 @@ static void rxrpc_input_implicit_end_call(struct rxrpc_sock *rx,
11021100
spin_lock(&rx->incoming_lock);
11031101
__rxrpc_disconnect_call(conn, call);
11041102
spin_unlock(&rx->incoming_lock);
1105-
rxrpc_notify_socket(call);
11061103
}
11071104

11081105
/*

net/rxrpc/peer_event.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -292,9 +292,7 @@ static void rxrpc_distribute_error(struct rxrpc_peer *peer, int error,
292292

293293
hlist_for_each_entry_rcu(call, &peer->error_targets, error_link) {
294294
rxrpc_see_call(call);
295-
if (call->state < RXRPC_CALL_COMPLETE &&
296-
rxrpc_set_call_completion(call, compl, 0, -error))
297-
rxrpc_notify_socket(call);
295+
rxrpc_set_call_completion(call, compl, 0, -error);
298296
}
299297
}
300298

net/rxrpc/recvmsg.c

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,85 @@ void rxrpc_notify_socket(struct rxrpc_call *call)
5858
_leave("");
5959
}
6060

61+
/*
62+
* Transition a call to the complete state.
63+
*/
64+
bool __rxrpc_set_call_completion(struct rxrpc_call *call,
65+
enum rxrpc_call_completion compl,
66+
u32 abort_code,
67+
int error)
68+
{
69+
if (call->state < RXRPC_CALL_COMPLETE) {
70+
call->abort_code = abort_code;
71+
call->error = error;
72+
call->completion = compl,
73+
call->state = RXRPC_CALL_COMPLETE;
74+
trace_rxrpc_call_complete(call);
75+
wake_up(&call->waitq);
76+
rxrpc_notify_socket(call);
77+
return true;
78+
}
79+
return false;
80+
}
81+
82+
bool rxrpc_set_call_completion(struct rxrpc_call *call,
83+
enum rxrpc_call_completion compl,
84+
u32 abort_code,
85+
int error)
86+
{
87+
bool ret = false;
88+
89+
if (call->state < RXRPC_CALL_COMPLETE) {
90+
write_lock_bh(&call->state_lock);
91+
ret = __rxrpc_set_call_completion(call, compl, abort_code, error);
92+
write_unlock_bh(&call->state_lock);
93+
}
94+
return ret;
95+
}
96+
97+
/*
98+
* Record that a call successfully completed.
99+
*/
100+
bool __rxrpc_call_completed(struct rxrpc_call *call)
101+
{
102+
return __rxrpc_set_call_completion(call, RXRPC_CALL_SUCCEEDED, 0, 0);
103+
}
104+
105+
bool rxrpc_call_completed(struct rxrpc_call *call)
106+
{
107+
bool ret = false;
108+
109+
if (call->state < RXRPC_CALL_COMPLETE) {
110+
write_lock_bh(&call->state_lock);
111+
ret = __rxrpc_call_completed(call);
112+
write_unlock_bh(&call->state_lock);
113+
}
114+
return ret;
115+
}
116+
117+
/*
118+
* Record that a call is locally aborted.
119+
*/
120+
bool __rxrpc_abort_call(const char *why, struct rxrpc_call *call,
121+
rxrpc_seq_t seq, u32 abort_code, int error)
122+
{
123+
trace_rxrpc_abort(call->debug_id, why, call->cid, call->call_id, seq,
124+
abort_code, error);
125+
return __rxrpc_set_call_completion(call, RXRPC_CALL_LOCALLY_ABORTED,
126+
abort_code, error);
127+
}
128+
129+
bool rxrpc_abort_call(const char *why, struct rxrpc_call *call,
130+
rxrpc_seq_t seq, u32 abort_code, int error)
131+
{
132+
bool ret;
133+
134+
write_lock_bh(&call->state_lock);
135+
ret = __rxrpc_abort_call(why, call, seq, abort_code, error);
136+
write_unlock_bh(&call->state_lock);
137+
return ret;
138+
}
139+
61140
/*
62141
* Pass a call terminating message to userspace.
63142
*/

net/rxrpc/sendmsg.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -261,10 +261,8 @@ static int rxrpc_queue_packet(struct rxrpc_sock *rx, struct rxrpc_call *call,
261261
case -ENETUNREACH:
262262
case -EHOSTUNREACH:
263263
case -ECONNREFUSED:
264-
rxrpc_set_call_completion(call,
265-
RXRPC_CALL_LOCAL_ERROR,
264+
rxrpc_set_call_completion(call, RXRPC_CALL_LOCAL_ERROR,
266265
0, ret);
267-
rxrpc_notify_socket(call);
268266
goto out;
269267
}
270268
_debug("need instant resend %d", ret);

0 commit comments

Comments
 (0)