While doing isspliced() and issplicedback() we need to perform two checks of so_sp pointer and so_sp->ssp_socket or so_sp->ssp_soback pointers. But we always set SB_SPLICE flag on sockets buffer flags together with ssp_socket and ssp_soback. Therefore the conditions "so_rcv.sb_flags & SB_SPLICE)" and the "so_sp->ssp_socket != NULL" are the same as the "so_snd.sb_flags & SB_SPLICE" and "so_sp->ssp_soback != NULL" conditions. But the flag check doesn't require to check so_sp pointer, so we do less comparisons.
Also, for the future standalone sockets buffer lock the `sb_flags' check requires only socket's buffer lock to be held. Since we never release `so_sp', so if socket's buffer already has this flag set we don't need to lock socket to protect so_sp and so_sp->ssp_socket or so_sp->ssp_soback dereference. This makes the future socket buffer locking much easier. Within sorwakeup() the "if (so_rcv.sb_flags & SB_SPLICE)" block was merged with "if (isspliced(so))" block, as the "if (issplicedback(so))" and "if (so_rcv.sb_flags & SB_SPLICE)" blocks within sowwakeup() because now these checks are obvious the same. I left the "if (so_rcv.sb_flags & SB_SPLICE)" notation, but I have no objections to replace it by "if (isspliced(so))". Also, within sofree() the so_sp check is not required before isspliced() and issplicedback() checks, so it also was removed. Index: sys/kern/uipc_socket.c =================================================================== RCS file: /cvs/src/sys/kern/uipc_socket.c,v retrieving revision 1.298 diff -u -p -r1.298 uipc_socket.c --- sys/kern/uipc_socket.c 27 Jan 2023 18:46:34 -0000 1.298 +++ sys/kern/uipc_socket.c 27 Jan 2023 21:59:44 -0000 @@ -306,21 +306,19 @@ sofree(struct socket *so, int keep_lock) klist_free(&so->so_rcv.sb_klist); klist_free(&so->so_snd.sb_klist); #ifdef SOCKET_SPLICE - if (so->so_sp) { - if (issplicedback(so)) { - int freeing = SOSP_FREEING_WRITE; + if (issplicedback(so)) { + int freeing = SOSP_FREEING_WRITE; - if (so->so_sp->ssp_soback == so) - freeing |= SOSP_FREEING_READ; - sounsplice(so->so_sp->ssp_soback, so, freeing); - } - if (isspliced(so)) { - int freeing = SOSP_FREEING_READ; - - if (so == so->so_sp->ssp_socket) - freeing |= SOSP_FREEING_WRITE; - sounsplice(so, so->so_sp->ssp_socket, freeing); - } + if (so->so_sp->ssp_soback == so) + freeing |= SOSP_FREEING_READ; + sounsplice(so->so_sp->ssp_soback, so, freeing); + } + if (isspliced(so)) { + int freeing = SOSP_FREEING_READ; + + if (so == so->so_sp->ssp_socket) + freeing |= SOSP_FREEING_WRITE; + sounsplice(so, so->so_sp->ssp_socket, freeing); } #endif /* SOCKET_SPLICE */ sbrelease(so, &so->so_snd); @@ -1749,9 +1747,8 @@ sorwakeup(struct socket *so) task_add(sosplice_taskq, &so->so_splicetask); else somove(so, M_DONTWAIT); - } - if (isspliced(so)) return; + } #endif sowakeup(so, &so->so_rcv); if (so->so_upcall) @@ -1764,10 +1761,10 @@ sowwakeup(struct socket *so) soassertlocked(so); #ifdef SOCKET_SPLICE - if (so->so_snd.sb_flags & SB_SPLICE) + if (so->so_snd.sb_flags & SB_SPLICE) { task_add(sosplice_taskq, &so->so_sp->ssp_soback->so_splicetask); - if (issplicedback(so)) return; + } #endif sowakeup(so, &so->so_snd); } Index: sys/sys/socketvar.h =================================================================== RCS file: /cvs/src/sys/sys/socketvar.h,v retrieving revision 1.119 diff -u -p -r1.119 socketvar.h --- sys/sys/socketvar.h 27 Jan 2023 18:46:34 -0000 1.119 +++ sys/sys/socketvar.h 27 Jan 2023 21:59:44 -0000 @@ -191,8 +191,8 @@ sorele(struct socket *so) * Macros for sockets and socket buffering. */ -#define isspliced(so) ((so)->so_sp && (so)->so_sp->ssp_socket) -#define issplicedback(so) ((so)->so_sp && (so)->so_sp->ssp_soback) +#define isspliced(so) ((so)->so_rcv.sb_flags & SB_SPLICE) +#define issplicedback(so) ((so)->so_snd.sb_flags & SB_SPLICE) /* * Do we need to notify the other side when I/O is possible?