Skip to content

Commit 93368b6

Browse files
committed
rxrpc: Move call state changes from recvmsg to I/O thread
Move the call state changes that are made in rxrpc_recvmsg() to the I/O thread. This means that, thenceforth, only the I/O thread does this and the call state lock can be removed. This requires the Rx phase to be ended when the last packet is received, not when it is processed. Since this now changes the rxrpc call state to SUCCEEDED before we've consumed all the data from it, rxrpc_kernel_check_life() mustn't say the call is dead until the recvmsg queue is empty (unless the call has failed). Signed-off-by: David Howells <[email protected]> cc: Marc Dionne <[email protected]> cc: [email protected]
1 parent 2d68942 commit 93368b6

File tree

5 files changed

+109
-111
lines changed

5 files changed

+109
-111
lines changed

fs/afs/rxrpc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,7 @@ int afs_extract_data(struct afs_call *call, bool want_more)
909909
ret = rxrpc_kernel_recv_data(net->socket, call->rxcall, iter,
910910
&call->iov_len, want_more, &remote_abort,
911911
&call->service_id);
912+
trace_afs_receive_data(call, call->iter, want_more, ret);
912913
if (ret == 0 || ret == -EAGAIN)
913914
return ret;
914915

net/rxrpc/af_rxrpc.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -373,13 +373,17 @@ EXPORT_SYMBOL(rxrpc_kernel_end_call);
373373
* @sock: The socket the call is on
374374
* @call: The call to check
375375
*
376-
* Allow a kernel service to find out whether a call is still alive -
377-
* ie. whether it has completed.
376+
* Allow a kernel service to find out whether a call is still alive - whether
377+
* it has completed successfully and all received data has been consumed.
378378
*/
379379
bool rxrpc_kernel_check_life(const struct socket *sock,
380380
const struct rxrpc_call *call)
381381
{
382-
return !rxrpc_call_is_complete(call);
382+
if (!rxrpc_call_is_complete(call))
383+
return true;
384+
if (call->completion != RXRPC_CALL_SUCCEEDED)
385+
return false;
386+
return !skb_queue_empty(&call->recvmsg_queue);
383387
}
384388
EXPORT_SYMBOL(rxrpc_kernel_check_life);
385389

net/rxrpc/ar-internal.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,8 @@ enum rxrpc_call_flag {
545545
RXRPC_CALL_KERNEL, /* The call was made by the kernel */
546546
RXRPC_CALL_UPGRADE, /* Service upgrade was requested for the call */
547547
RXRPC_CALL_EXCLUSIVE, /* The call uses a once-only connection */
548-
RXRPC_CALL_RX_IS_IDLE, /* Reception is idle - send an ACK */
548+
RXRPC_CALL_RX_IS_IDLE, /* recvmsg() is idle - send an ACK */
549+
RXRPC_CALL_RECVMSG_READ_ALL, /* recvmsg() read all of the received data */
549550
};
550551

551552
/*

net/rxrpc/input.c

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,41 @@ static bool rxrpc_receiving_reply(struct rxrpc_call *call)
319319
return true;
320320
}
321321

322+
/*
323+
* End the packet reception phase.
324+
*/
325+
static void rxrpc_end_rx_phase(struct rxrpc_call *call, rxrpc_serial_t serial)
326+
{
327+
rxrpc_seq_t whigh = READ_ONCE(call->rx_highest_seq);
328+
329+
_enter("%d,%s", call->debug_id, rxrpc_call_states[call->state]);
330+
331+
trace_rxrpc_receive(call, rxrpc_receive_end, 0, whigh);
332+
333+
if (rxrpc_call_state(call) == RXRPC_CALL_CLIENT_RECV_REPLY)
334+
rxrpc_propose_delay_ACK(call, serial, rxrpc_propose_ack_terminal_ack);
335+
336+
write_lock(&call->state_lock);
337+
338+
switch (call->state) {
339+
case RXRPC_CALL_CLIENT_RECV_REPLY:
340+
__rxrpc_call_completed(call);
341+
write_unlock(&call->state_lock);
342+
break;
343+
344+
case RXRPC_CALL_SERVER_RECV_REQUEST:
345+
call->state = RXRPC_CALL_SERVER_ACK_REQUEST;
346+
call->expect_req_by = jiffies + MAX_JIFFY_OFFSET;
347+
write_unlock(&call->state_lock);
348+
rxrpc_propose_delay_ACK(call, serial,
349+
rxrpc_propose_ack_processing_op);
350+
break;
351+
default:
352+
write_unlock(&call->state_lock);
353+
break;
354+
}
355+
}
356+
322357
static void rxrpc_input_update_ack_window(struct rxrpc_call *call,
323358
rxrpc_seq_t window, rxrpc_seq_t wtop)
324359
{
@@ -337,8 +372,9 @@ static void rxrpc_input_queue_data(struct rxrpc_call *call, struct sk_buff *skb,
337372

338373
__skb_queue_tail(&call->recvmsg_queue, skb);
339374
rxrpc_input_update_ack_window(call, window, wtop);
340-
341375
trace_rxrpc_receive(call, last ? why + 1 : why, sp->hdr.serial, sp->hdr.seq);
376+
if (last)
377+
rxrpc_end_rx_phase(call, sp->hdr.serial);
342378
}
343379

344380
/*

net/rxrpc/recvmsg.c

Lines changed: 62 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -100,42 +100,6 @@ static int rxrpc_recvmsg_term(struct rxrpc_call *call, struct msghdr *msg)
100100
return ret;
101101
}
102102

103-
/*
104-
* End the packet reception phase.
105-
*/
106-
static void rxrpc_end_rx_phase(struct rxrpc_call *call, rxrpc_serial_t serial)
107-
{
108-
rxrpc_seq_t whigh = READ_ONCE(call->rx_highest_seq);
109-
110-
_enter("%d,%s", call->debug_id, rxrpc_call_states[call->state]);
111-
112-
trace_rxrpc_receive(call, rxrpc_receive_end, 0, whigh);
113-
114-
if (rxrpc_call_state(call) == RXRPC_CALL_CLIENT_RECV_REPLY)
115-
rxrpc_propose_delay_ACK(call, serial, rxrpc_propose_ack_terminal_ack);
116-
117-
write_lock(&call->state_lock);
118-
119-
switch (call->state) {
120-
case RXRPC_CALL_CLIENT_RECV_REPLY:
121-
__rxrpc_call_completed(call);
122-
write_unlock(&call->state_lock);
123-
rxrpc_poke_call(call, rxrpc_call_poke_complete);
124-
break;
125-
126-
case RXRPC_CALL_SERVER_RECV_REQUEST:
127-
call->state = RXRPC_CALL_SERVER_ACK_REQUEST;
128-
call->expect_req_by = jiffies + MAX_JIFFY_OFFSET;
129-
write_unlock(&call->state_lock);
130-
rxrpc_propose_delay_ACK(call, serial,
131-
rxrpc_propose_ack_processing_op);
132-
break;
133-
default:
134-
write_unlock(&call->state_lock);
135-
break;
136-
}
137-
}
138-
139103
/*
140104
* Discard a packet we've used up and advance the Rx window by one.
141105
*/
@@ -166,10 +130,9 @@ static void rxrpc_rotate_rx_window(struct rxrpc_call *call)
166130

167131
trace_rxrpc_receive(call, last ? rxrpc_receive_rotate_last : rxrpc_receive_rotate,
168132
serial, call->rx_consumed);
169-
if (last) {
170-
rxrpc_end_rx_phase(call, serial);
171-
return;
172-
}
133+
134+
if (last)
135+
set_bit(RXRPC_CALL_RECVMSG_READ_ALL, &call->flags);
173136

174137
/* Check to see if there's an ACK that needs sending. */
175138
acked = atomic_add_return(call->rx_consumed - old_consumed,
@@ -194,7 +157,8 @@ static int rxrpc_verify_data(struct rxrpc_call *call, struct sk_buff *skb)
194157
/*
195158
* Deliver messages to a call. This keeps processing packets until the buffer
196159
* is filled and we find either more DATA (returns 0) or the end of the DATA
197-
* (returns 1). If more packets are required, it returns -EAGAIN.
160+
* (returns 1). If more packets are required, it returns -EAGAIN and if the
161+
* call has failed it returns -EIO.
198162
*/
199163
static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call,
200164
struct msghdr *msg, struct iov_iter *iter,
@@ -210,7 +174,13 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call,
210174
rx_pkt_offset = call->rx_pkt_offset;
211175
rx_pkt_len = call->rx_pkt_len;
212176

213-
if (rxrpc_call_state(call) >= RXRPC_CALL_SERVER_ACK_REQUEST) {
177+
if (rxrpc_call_has_failed(call)) {
178+
seq = lower_32_bits(atomic64_read(&call->ackr_window)) - 1;
179+
ret = -EIO;
180+
goto done;
181+
}
182+
183+
if (test_bit(RXRPC_CALL_RECVMSG_READ_ALL, &call->flags)) {
214184
seq = lower_32_bits(atomic64_read(&call->ackr_window)) - 1;
215185
ret = 1;
216186
goto done;
@@ -234,14 +204,15 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call,
234204

235205
if (rx_pkt_offset == 0) {
236206
ret2 = rxrpc_verify_data(call, skb);
237-
rx_pkt_offset = sp->offset;
238-
rx_pkt_len = sp->len;
239207
trace_rxrpc_recvdata(call, rxrpc_recvmsg_next, seq,
240-
rx_pkt_offset, rx_pkt_len, ret2);
208+
sp->offset, sp->len, ret2);
241209
if (ret2 < 0) {
210+
kdebug("verify = %d", ret2);
242211
ret = ret2;
243212
goto out;
244213
}
214+
rx_pkt_offset = sp->offset;
215+
rx_pkt_len = sp->len;
245216
} else {
246217
trace_rxrpc_recvdata(call, rxrpc_recvmsg_cont, seq,
247218
rx_pkt_offset, rx_pkt_len, 0);
@@ -416,36 +387,36 @@ int rxrpc_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
416387
msg->msg_namelen = len;
417388
}
418389

419-
switch (rxrpc_call_state(call)) {
420-
case RXRPC_CALL_CLIENT_RECV_REPLY:
421-
case RXRPC_CALL_SERVER_RECV_REQUEST:
422-
case RXRPC_CALL_SERVER_ACK_REQUEST:
423-
ret = rxrpc_recvmsg_data(sock, call, msg, &msg->msg_iter, len,
424-
flags, &copied);
425-
if (ret == -EAGAIN)
426-
ret = 0;
427-
428-
if (!skb_queue_empty(&call->recvmsg_queue))
429-
rxrpc_notify_socket(call);
430-
break;
431-
default:
390+
ret = rxrpc_recvmsg_data(sock, call, msg, &msg->msg_iter, len,
391+
flags, &copied);
392+
if (ret == -EAGAIN)
432393
ret = 0;
433-
break;
434-
}
435-
394+
if (ret == -EIO)
395+
goto call_failed;
436396
if (ret < 0)
437397
goto error_unlock_call;
438398

439-
if (rxrpc_call_is_complete(call)) {
440-
ret = rxrpc_recvmsg_term(call, msg);
441-
if (ret < 0)
442-
goto error_unlock_call;
443-
if (!(flags & MSG_PEEK))
444-
rxrpc_release_call(rx, call);
445-
msg->msg_flags |= MSG_EOR;
446-
ret = 1;
447-
}
399+
if (rxrpc_call_is_complete(call) &&
400+
skb_queue_empty(&call->recvmsg_queue))
401+
goto call_complete;
402+
if (rxrpc_call_has_failed(call))
403+
goto call_failed;
448404

405+
rxrpc_notify_socket(call);
406+
goto not_yet_complete;
407+
408+
call_failed:
409+
rxrpc_purge_queue(&call->recvmsg_queue);
410+
call_complete:
411+
ret = rxrpc_recvmsg_term(call, msg);
412+
if (ret < 0)
413+
goto error_unlock_call;
414+
if (!(flags & MSG_PEEK))
415+
rxrpc_release_call(rx, call);
416+
msg->msg_flags |= MSG_EOR;
417+
ret = 1;
418+
419+
not_yet_complete:
449420
if (ret == 0)
450421
msg->msg_flags |= MSG_MORE;
451422
else
@@ -508,49 +479,34 @@ int rxrpc_kernel_recv_data(struct socket *sock, struct rxrpc_call *call,
508479
size_t offset = 0;
509480
int ret;
510481

511-
_enter("{%d,%s},%zu,%d",
512-
call->debug_id, rxrpc_call_states[call->state],
513-
*_len, want_more);
514-
515-
ASSERTCMP(call->state, !=, RXRPC_CALL_SERVER_SECURING);
482+
_enter("{%d},%zu,%d", call->debug_id, *_len, want_more);
516483

517484
mutex_lock(&call->user_mutex);
518485

519-
switch (rxrpc_call_state(call)) {
520-
case RXRPC_CALL_CLIENT_RECV_REPLY:
521-
case RXRPC_CALL_SERVER_RECV_REQUEST:
522-
case RXRPC_CALL_SERVER_ACK_REQUEST:
523-
ret = rxrpc_recvmsg_data(sock, call, NULL, iter,
524-
*_len, 0, &offset);
525-
*_len -= offset;
526-
if (ret < 0)
527-
goto out;
528-
529-
/* We can only reach here with a partially full buffer if we
530-
* have reached the end of the data. We must otherwise have a
531-
* full buffer or have been given -EAGAIN.
532-
*/
533-
if (ret == 1) {
534-
if (iov_iter_count(iter) > 0)
535-
goto short_data;
536-
if (!want_more)
537-
goto read_phase_complete;
538-
ret = 0;
539-
goto out;
540-
}
541-
542-
if (!want_more)
543-
goto excess_data;
486+
ret = rxrpc_recvmsg_data(sock, call, NULL, iter, *_len, 0, &offset);
487+
*_len -= offset;
488+
if (ret == -EIO)
489+
goto call_failed;
490+
if (ret < 0)
544491
goto out;
545492

546-
case RXRPC_CALL_COMPLETE:
547-
goto call_complete;
548-
549-
default:
550-
ret = -EINPROGRESS;
493+
/* We can only reach here with a partially full buffer if we have
494+
* reached the end of the data. We must otherwise have a full buffer
495+
* or have been given -EAGAIN.
496+
*/
497+
if (ret == 1) {
498+
if (iov_iter_count(iter) > 0)
499+
goto short_data;
500+
if (!want_more)
501+
goto read_phase_complete;
502+
ret = 0;
551503
goto out;
552504
}
553505

506+
if (!want_more)
507+
goto excess_data;
508+
goto out;
509+
554510
read_phase_complete:
555511
ret = 1;
556512
out:
@@ -572,7 +528,7 @@ int rxrpc_kernel_recv_data(struct socket *sock, struct rxrpc_call *call,
572528
0, -EMSGSIZE);
573529
ret = -EMSGSIZE;
574530
goto out;
575-
call_complete:
531+
call_failed:
576532
*_abort = call->abort_code;
577533
ret = call->error;
578534
if (call->completion == RXRPC_CALL_SUCCEEDED) {

0 commit comments

Comments
 (0)