Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rxrpc: Move call state changes from sendmsg to I/O thread

Move all the call state changes that are made in rxrpc_sendmsg() to the I/O
thread. This is a step towards removing the call state lock.

This requires the switch to the RXRPC_CALL_CLIENT_AWAIT_REPLY and
RXRPC_CALL_SERVER_SEND_REPLY states to be done when the last packet is
decanted from ->tx_sendmsg to ->tx_buffer in the I/O thread, not when it is
added to ->tx_sendmsg by sendmsg().

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org

+63 -60
+2 -2
Documentation/networking/rxrpc.rst
··· 880 880 881 881 notify_end_rx can be NULL or it can be used to specify a function to be 882 882 called when the call changes state to end the Tx phase. This function is 883 - called with the call-state spinlock held to prevent any reply or final ACK 884 - from being delivered first. 883 + called with a spinlock held to prevent the last DATA packet from being 884 + transmitted until the function returns. 885 885 886 886 (#) Receive data from a call:: 887 887
+48 -2
net/rxrpc/call_event.c
··· 251 251 _leave(""); 252 252 } 253 253 254 + /* 255 + * Start transmitting the reply to a service. This cancels the need to ACK the 256 + * request if we haven't yet done so. 257 + */ 258 + static void rxrpc_begin_service_reply(struct rxrpc_call *call) 259 + { 260 + unsigned long now; 261 + 262 + write_lock(&call->state_lock); 263 + 264 + if (call->state == RXRPC_CALL_SERVER_ACK_REQUEST) { 265 + now = jiffies; 266 + call->state = RXRPC_CALL_SERVER_SEND_REPLY; 267 + WRITE_ONCE(call->delay_ack_at, now + MAX_JIFFY_OFFSET); 268 + if (call->ackr_reason == RXRPC_ACK_DELAY) 269 + call->ackr_reason = 0; 270 + trace_rxrpc_timer(call, rxrpc_timer_init_for_send_reply, now); 271 + } 272 + 273 + write_unlock(&call->state_lock); 274 + } 275 + 276 + /* 277 + * Close the transmission phase. After this point there is no more data to be 278 + * transmitted in the call. 279 + */ 280 + static void rxrpc_close_tx_phase(struct rxrpc_call *call) 281 + { 282 + _debug("________awaiting reply/ACK__________"); 283 + 284 + write_lock(&call->state_lock); 285 + switch (call->state) { 286 + case RXRPC_CALL_CLIENT_SEND_REQUEST: 287 + call->state = RXRPC_CALL_CLIENT_AWAIT_REPLY; 288 + break; 289 + case RXRPC_CALL_SERVER_SEND_REPLY: 290 + call->state = RXRPC_CALL_SERVER_AWAIT_ACK; 291 + break; 292 + default: 293 + break; 294 + } 295 + write_unlock(&call->state_lock); 296 + } 297 + 254 298 static bool rxrpc_tx_window_has_space(struct rxrpc_call *call) 255 299 { 256 300 unsigned int winsize = min_t(unsigned int, call->tx_winsize, ··· 329 285 call->tx_top = txb->seq; 330 286 list_add_tail(&txb->call_link, &call->tx_buffer); 331 287 288 + if (txb->wire.flags & RXRPC_LAST_PACKET) 289 + rxrpc_close_tx_phase(call); 290 + 332 291 rxrpc_transmit_one(call, txb); 333 292 334 293 if (!rxrpc_tx_window_has_space(call)) ··· 345 298 case RXRPC_CALL_SERVER_ACK_REQUEST: 346 299 if (list_empty(&call->tx_sendmsg)) 347 300 return; 301 + rxrpc_begin_service_reply(call); 348 302 fallthrough; 349 303 350 304 case RXRPC_CALL_SERVER_SEND_REPLY: 351 - case RXRPC_CALL_SERVER_AWAIT_ACK: 352 305 case RXRPC_CALL_CLIENT_SEND_REQUEST: 353 - case RXRPC_CALL_CLIENT_AWAIT_REPLY: 354 306 if (!rxrpc_tx_window_has_space(call)) 355 307 return; 356 308 if (list_empty(&call->tx_sendmsg)) {
+13 -56
net/rxrpc/sendmsg.c
··· 189 189 struct rxrpc_txbuf *txb, 190 190 rxrpc_notify_end_tx_t notify_end_tx) 191 191 { 192 - unsigned long now; 193 192 rxrpc_seq_t seq = txb->seq; 194 193 bool last = test_bit(RXRPC_TXBUF_LAST, &txb->flags), poke; 195 194 ··· 211 212 poke = list_empty(&call->tx_sendmsg); 212 213 list_add_tail(&txb->call_link, &call->tx_sendmsg); 213 214 call->tx_prepared = seq; 215 + if (last) 216 + rxrpc_notify_end_tx(rx, call, notify_end_tx); 214 217 spin_unlock(&call->tx_lock); 215 - 216 - if (last || call->state == RXRPC_CALL_SERVER_ACK_REQUEST) { 217 - _debug("________awaiting reply/ACK__________"); 218 - write_lock(&call->state_lock); 219 - switch (call->state) { 220 - case RXRPC_CALL_CLIENT_SEND_REQUEST: 221 - call->state = RXRPC_CALL_CLIENT_AWAIT_REPLY; 222 - rxrpc_notify_end_tx(rx, call, notify_end_tx); 223 - break; 224 - case RXRPC_CALL_SERVER_ACK_REQUEST: 225 - call->state = RXRPC_CALL_SERVER_SEND_REPLY; 226 - now = jiffies; 227 - WRITE_ONCE(call->delay_ack_at, now + MAX_JIFFY_OFFSET); 228 - if (call->ackr_reason == RXRPC_ACK_DELAY) 229 - call->ackr_reason = 0; 230 - trace_rxrpc_timer(call, rxrpc_timer_init_for_send_reply, now); 231 - if (!last) 232 - break; 233 - fallthrough; 234 - case RXRPC_CALL_SERVER_SEND_REPLY: 235 - call->state = RXRPC_CALL_SERVER_AWAIT_ACK; 236 - rxrpc_notify_end_tx(rx, call, notify_end_tx); 237 - break; 238 - default: 239 - break; 240 - } 241 - write_unlock(&call->state_lock); 242 - } 243 218 244 219 if (poke) 245 220 rxrpc_poke_call(call, rxrpc_call_poke_start); ··· 253 280 ret = -EPROTO; 254 281 if (state != RXRPC_CALL_CLIENT_SEND_REQUEST && 255 282 state != RXRPC_CALL_SERVER_ACK_REQUEST && 256 - state != RXRPC_CALL_SERVER_SEND_REPLY) 283 + state != RXRPC_CALL_SERVER_SEND_REPLY) { 284 + /* Request phase complete for this client call */ 285 + trace_rxrpc_abort(call->debug_id, rxrpc_sendmsg_late_send, 286 + call->cid, call->call_id, call->rx_consumed, 287 + 0, -EPROTO); 257 288 goto maybe_error; 289 + } 258 290 259 291 ret = -EMSGSIZE; 260 292 if (call->tx_total_len != -1) { ··· 551 573 int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len) 552 574 __releases(&rx->sk.sk_lock.slock) 553 575 { 554 - enum rxrpc_call_state state; 555 576 struct rxrpc_call *call; 556 577 unsigned long now, j; 557 578 bool dropped_lock = false; ··· 649 672 break; 650 673 } 651 674 652 - state = rxrpc_call_state(call); 653 - _debug("CALL %d USR %lx ST %d on CONN %p", 654 - call->debug_id, call->user_call_ID, state, call->conn); 655 - 656 - if (state >= RXRPC_CALL_COMPLETE) { 675 + if (rxrpc_call_is_complete(call)) { 657 676 /* it's too late for this call */ 658 677 ret = -ESHUTDOWN; 659 678 } else if (p.command == RXRPC_CMD_SEND_ABORT) { ··· 695 722 bool dropped_lock = false; 696 723 int ret; 697 724 698 - _enter("{%d,%s},", call->debug_id, rxrpc_call_states[call->state]); 725 + _enter("{%d},", call->debug_id); 699 726 700 727 ASSERTCMP(msg->msg_name, ==, NULL); 701 728 ASSERTCMP(msg->msg_control, ==, NULL); ··· 705 732 _debug("CALL %d USR %lx ST %d on CONN %p", 706 733 call->debug_id, call->user_call_ID, call->state, call->conn); 707 734 708 - switch (rxrpc_call_state(call)) { 709 - case RXRPC_CALL_CLIENT_SEND_REQUEST: 710 - case RXRPC_CALL_SERVER_ACK_REQUEST: 711 - case RXRPC_CALL_SERVER_SEND_REPLY: 712 - ret = rxrpc_send_data(rxrpc_sk(sock->sk), call, msg, len, 713 - notify_end_tx, &dropped_lock); 714 - break; 715 - case RXRPC_CALL_COMPLETE: 716 - read_lock(&call->state_lock); 735 + ret = rxrpc_send_data(rxrpc_sk(sock->sk), call, msg, len, 736 + notify_end_tx, &dropped_lock); 737 + if (ret == -ESHUTDOWN) 717 738 ret = call->error; 718 - read_unlock(&call->state_lock); 719 - break; 720 - default: 721 - /* Request phase complete for this client call */ 722 - trace_rxrpc_abort(call->debug_id, rxrpc_sendmsg_late_send, 723 - call->cid, call->call_id, call->rx_consumed, 724 - 0, -EPROTO); 725 - ret = -EPROTO; 726 - break; 727 - } 728 739 729 740 if (!dropped_lock) 730 741 mutex_unlock(&call->user_mutex);