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?