Don't take solock() in soreceive() for SOCK_RAW inet sockets.
authormvs <mvs@openbsd.org>
Thu, 11 Apr 2024 13:32:51 +0000 (13:32 +0000)
committermvs <mvs@openbsd.org>
Thu, 11 Apr 2024 13:32:51 +0000 (13:32 +0000)
commit1baa51d9481f74d21e434002fb195a48a7fc3443
treedc7c64c590f1bf8158eee9592ae4b836b6c22dd5
parent510c9557683335cb890c866e0ef31431ca739fa5
Don't take solock() in soreceive() for SOCK_RAW inet sockets.

For inet sockets solock() is the netlock wrapper, so soreceive() could
be performed simultaneous with exclusively locked code paths.

These sockets are not connection oriented, they don't call pru_rcvd(),
they can't be spliced, they don't set `so_error'. Nothing to protect
with solock() in soreceive() path.

`so_rcv' buffer protected by `sb_mtx' mutex(9), but since it released,
sblock() required to serialize concurrent soreceive() and sorflush()
threads. Current sblock() is some kind of rwlock(9) implementation, so
introduce `sb_lock' rwlock(9) and use it directly for that purpose.

The sorflush() and callers were refactored to avoid solock() for raw
inet sockets. This was done to avoid packet processing stop.

Tested and ok bluhm.
sys/kern/uipc_socket.c
sys/kern/uipc_socket2.c
sys/sys/socketvar.h