[PATCH net-next 00/32] rxrpc: Increasing SACK size and moving away from softirq, part 4

From: David Howells
Date: Tue Dec 06 2022 - 10:59:49 EST



Here's the fourth part of patches in the process of moving rxrpc from doing
a lot of its stuff in softirq context to doing it in an I/O thread in
process context and thereby making it easier to support a larger SACK
table.

The full description is in the description for the first part[1] which is
already in net-next. The second and third parts have also been pulled[2].

The fourth part includes some more moving of stuff to the I/O thread:

(1) Changing the state of a call. This gets the last bits of changing
call state out of sendmsg() and recvmsg() so that all call state
transitions happen in the call event handler in the I/O thread.

(2) Aborting of calls. sendmsg() and recvmsg() are no longer allowed to
shift a call's state and send an ABORT packet; rather they stash the
details in the rxrpc_call struct and send an event and the state
change and transmission happen in the I/O thread.

(3) Connection of client calls. The app thread allocates a call and then
asks the I/O thread to connect it, waiting until the resources are
attached to it. Responsibility for setting up the crypto for the
connection is then delegated to the app thread.

(4) Disconnection of calls. Calls are now disconnected by their event
handers in the I/O thread when they reach the completed state.

(5) Management of client connections. The tree containing the client
connection IDs is moved to the local endpoint and put under the
management of the I/O thread.

(6) Completion of service connection security. When a RESPONSE packet has
been successfully verified in the conn's service thread, the packet is
marked specially and passed back to the I/O thread so that relevant
calls can be woken up.

With the above, a call's lifetime is almost entirely managed by the I/O
thread and this allows a lot of locking to be removed as the singular I/O
thread itself provides the necessary exclusion:

(6) Remove the call->state_lock and wrap the call state transition
handling into helper functions to insert the appropriate barriers.
The barriers allow the abort state to be read locklessly after the
completion state is set.

(7) Don't use call->tx_lock to access ->tx_buffer as that is only accessed
inside the I/O thread. sendmsg() loads onto ->tx_sendmsg and the I/O
thread decants from that to the buffer.

(8) Convert ->recvmsg_lock to a spinlock as it's only ever locked
exclusively.

(9) Make ->ackr_window and ->ackr_nr_unacked non-atomic as they're only
used in the I/O thread.

(10) Remove local->defrag_sem as DATA packets are transmitted serially by
the I/O thread.

Some other bits are done also:

(11) Fix a missing unlock in rxrpc_do_sendmsg().

(12) Fix propagation of the security settings on new calls.

(13) Simplify the SACK table maintenance and ACK generation. Now that both
parts are done in the same thread, there's no possibility of a race
and no need to try and be cunning to avoid taking a BH spinlock whilst
copying the SACK table (which in the future will be up to 2K) and no
need to rotate the copy to fit the ACK packet table.

(14) Use SKB_CONSUMED when freeing received DATA packets (stop dropwatch
complaining).

(15) Tidy up the abort generation, in particular to have one tracepoint and
a big enum of trace reasons rather than copying in a string. If the
input functions want to return an abort, they just tag the received
skbuff and return false; rxrpc_io_thread() will reject the packet on
their behalf.

(16) Add a debugging option to allow a delay to be injected into packet
reception to help investigate the behaviour over longer links than
just a few cm.

Tested-by: Marc Dionne <marc.dionne@xxxxxxxxxxxx>
Tested-by: kafs-testing+fedora36_64checkkafs-build-153@xxxxxxxxxxxx
Link: https://lore.kernel.org/r/166794587113.2389296.16484814996876530222.stgit@xxxxxxxxxxxxxxxxxxxxxx/ [1]
Link: https://lore.kernel.org/r/166994010342.1732290.13771061038178613124.stgit@xxxxxxxxxxxxxxxxxxxxxx/ [2]

---
The patches are tagged here:

git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git tags/rxrpc-next-20221206

And can be found on this branch:

http://git.kernel.org/cgit/linux/kernel/git/dhowells/linux-fs.git/log/?h=rxrpc-next

David
---
David Howells (32):
rxrpc: Fix missing unlock in rxrpc_do_sendmsg()
rxrpc: Fix security setting propagation
rxrpc: Simplify rxrpc_implicit_end_call()
rxrpc: Separate call retransmission from other conn events
rxrpc: Convert call->recvmsg_lock to a spinlock
rxrpc: Convert call->state_lock to a spinlock
rxrpc: Only set/transmit aborts in the I/O thread
rxrpc: Only disconnect calls in the I/O thread
rxrpc: Allow a delay to be injected into packet reception
rxrpc: Generate extra pings for RTT during heavy-receive call
rxrpc: De-atomic call->ackr_window and call->ackr_nr_unacked
rxrpc: Simplify ACK handling
rxrpc: Don't lock call->tx_lock to access call->tx_buffer
rxrpc: Remove local->defrag_sem
rxrpc: Implement a mechanism to send an event notification to a connection
rxrpc: Clean up connection abort
rxrpc: Tidy up abort generation infrastructure
rxrpc: Stash the network namespace pointer in rxrpc_local
rxrpc: Make the set of connection IDs per local endpoint
rxrpc: Offload the completion of service conn security to the I/O thread
rxrpc: Set up a connection bundle from a call, not rxrpc_conn_parameters
rxrpc: Split out the call state changing functions into their own file
rxrpc: Wrap accesses to get call state to put the barrier in one place
rxrpc: Move call state changes from sendmsg to I/O thread
rxrpc: Move call state changes from recvmsg to I/O thread
rxrpc: Remove call->state_lock
rxrpc: Make the local endpoint hold a ref on a connected call
rxrpc: Move the client conn cache management to the I/O thread
rxrpc: Show consumed and freed packets as non-dropped in dropwatch
rxrpc: Change rx_packet tracepoint to display securityIndex not type twice
rxrpc: Move client call connection to the I/O thread
rxrpc: Kill service bundle


Documentation/networking/rxrpc.rst | 4 +-
fs/afs/cmservice.c | 6 +-
fs/afs/rxrpc.c | 24 +-
include/net/af_rxrpc.h | 3 +-
include/trace/events/rxrpc.h | 213 +++++++--
net/rxrpc/Kconfig | 9 +
net/rxrpc/Makefile | 1 +
net/rxrpc/af_rxrpc.c | 21 +-
net/rxrpc/ar-internal.h | 203 ++++++---
net/rxrpc/call_accept.c | 31 +-
net/rxrpc/call_event.c | 99 +++-
net/rxrpc/call_object.c | 121 +++--
net/rxrpc/call_state.c | 69 +++
net/rxrpc/conn_client.c | 701 ++++++++---------------------
net/rxrpc/conn_event.c | 381 ++++++----------
net/rxrpc/conn_object.c | 46 +-
net/rxrpc/conn_service.c | 8 -
net/rxrpc/input.c | 233 +++++-----
net/rxrpc/insecure.c | 20 +-
net/rxrpc/io_thread.c | 249 ++++++----
net/rxrpc/local_object.c | 42 +-
net/rxrpc/misc.c | 7 +
net/rxrpc/net_ns.c | 17 -
net/rxrpc/output.c | 129 ++++--
net/rxrpc/peer_object.c | 23 +-
net/rxrpc/proc.c | 21 +-
net/rxrpc/recvmsg.c | 272 ++++-------
net/rxrpc/rxkad.c | 356 ++++++---------
net/rxrpc/rxperf.c | 17 +-
net/rxrpc/security.c | 54 +--
net/rxrpc/sendmsg.c | 196 ++++----
net/rxrpc/skbuff.c | 4 +-
net/rxrpc/sysctl.c | 17 +-
net/rxrpc/txbuf.c | 12 +-
34 files changed, 1755 insertions(+), 1854 deletions(-)
create mode 100644 net/rxrpc/call_state.c