Download raw body.
merge sosplice_solock_pair() into solock_pair()
Hi,
sosplice_solock_pair() is basically shared netlock plus solock_pair().
By making solock_pair() generic for inet and unix sockets, the
socket code needs less special locking paths.
ok?
bluhm
Index: kern/uipc_socket.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/kern/uipc_socket.c,v
diff -u -p -r1.367 uipc_socket.c
--- kern/uipc_socket.c 30 Jan 2025 14:40:50 -0000 1.367
+++ kern/uipc_socket.c 31 Jan 2025 12:12:17 -0000
@@ -537,18 +537,12 @@ soconnect(struct socket *so, struct mbuf
int
soconnect2(struct socket *so1, struct socket *so2)
{
- int persocket, error;
-
- if ((persocket = solock_persocket(so1)))
- solock_pair(so1, so2);
- else
- solock(so1);
+ int error;
+ solock_pair(so1, so2);
error = pru_connect2(so1, so2);
+ sounlock_pair(so1, so2);
- if (persocket)
- sounlock(so2);
- sounlock(so1);
return (error);
}
@@ -1300,38 +1294,6 @@ sorflush(struct socket *so)
#define so_idleto so_sp->ssp_idleto
#define so_splicetask so_sp->ssp_task
-void
-sosplice_solock_pair(struct socket *so1, struct socket *so2)
-{
- NET_LOCK_SHARED();
-
- if (so1 == so2)
- rw_enter_write(&so1->so_lock);
- else if (so1 < so2) {
- rw_enter_write(&so1->so_lock);
- rw_enter_write(&so2->so_lock);
- } else {
- rw_enter_write(&so2->so_lock);
- rw_enter_write(&so1->so_lock);
- }
-}
-
-void
-sosplice_sounlock_pair(struct socket *so1, struct socket *so2)
-{
- if (so1 == so2)
- rw_exit_write(&so1->so_lock);
- else if (so1 < so2) {
- rw_exit_write(&so2->so_lock);
- rw_exit_write(&so1->so_lock);
- } else {
- rw_exit_write(&so1->so_lock);
- rw_exit_write(&so2->so_lock);
- }
-
- NET_UNLOCK_SHARED();
-}
-
int
sosplice(struct socket *so, int fd, off_t max, struct timeval *tv)
{
@@ -1397,7 +1359,7 @@ sosplice(struct socket *so, int fd, off_
sbunlock(&so->so_rcv);
goto frele;
}
- sosplice_solock_pair(so, sosp);
+ solock_pair(so, sosp);
if ((so->so_options & SO_ACCEPTCONN) ||
(sosp->so_options & SO_ACCEPTCONN)) {
@@ -1458,7 +1420,7 @@ sosplice(struct socket *so, int fd, off_
mtx_leave(&sosp->so_snd.sb_mtx);
mtx_leave(&so->so_rcv.sb_mtx);
- sosplice_sounlock_pair(so, sosp);
+ sounlock_pair(so, sosp);
sbunlock(&sosp->so_snd);
if (somove(so, M_WAIT)) {
@@ -1475,7 +1437,7 @@ sosplice(struct socket *so, int fd, off_
return (0);
release:
- sosplice_sounlock_pair(so, sosp);
+ sounlock_pair(so, sosp);
sbunlock(&sosp->so_snd);
sbunlock(&so->so_rcv);
frele:
Index: kern/uipc_socket2.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/kern/uipc_socket2.c,v
diff -u -p -r1.173 uipc_socket2.c
--- kern/uipc_socket2.c 31 Jan 2025 07:53:10 -0000 1.173
+++ kern/uipc_socket2.c 31 Jan 2025 12:12:17 -0000
@@ -373,16 +373,22 @@ solock_persocket(struct socket *so)
void
solock_pair(struct socket *so1, struct socket *so2)
{
- KASSERT(so1 != so2);
KASSERT(so1->so_type == so2->so_type);
- KASSERT(solock_persocket(so1));
- if (so1 < so2) {
- solock(so1);
- solock(so2);
+ switch (so1->so_proto->pr_domain->dom_family) {
+ case PF_INET:
+ case PF_INET6:
+ NET_LOCK_SHARED();
+ break;
+ }
+ if (so1 == so2) {
+ rw_enter_write(&so1->so_lock);
+ } else if (so1 < so2) {
+ rw_enter_write(&so1->so_lock);
+ rw_enter_write(&so2->so_lock);
} else {
- solock(so2);
- solock(so1);
+ rw_enter_write(&so2->so_lock);
+ rw_enter_write(&so1->so_lock);
}
}
@@ -416,6 +422,26 @@ void
sounlock_nonet(struct socket *so)
{
rw_exit_write(&so->so_lock);
+}
+
+void
+sounlock_pair(struct socket *so1, struct socket *so2)
+{
+ if (so1 == so2)
+ rw_exit_write(&so1->so_lock);
+ else if (so1 < so2) {
+ rw_exit_write(&so2->so_lock);
+ rw_exit_write(&so1->so_lock);
+ } else {
+ rw_exit_write(&so1->so_lock);
+ rw_exit_write(&so2->so_lock);
+ }
+ switch (so1->so_proto->pr_domain->dom_family) {
+ case PF_INET:
+ case PF_INET6:
+ NET_UNLOCK_SHARED();
+ break;
+ }
}
void
Index: kern/uipc_usrreq.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/kern/uipc_usrreq.c,v
diff -u -p -r1.214 uipc_usrreq.c
--- kern/uipc_usrreq.c 25 Jan 2025 22:06:41 -0000 1.214
+++ kern/uipc_usrreq.c 31 Jan 2025 12:12:17 -0000
@@ -924,22 +924,15 @@ unp_connect(struct socket *so, struct mb
}
so2 = so3;
- } else {
- if (so2 != so)
- solock_pair(so, so2);
- else
- solock(so);
- }
+ } else
+ solock_pair(so, so2);
error = unp_connect2(so, so2);
- sounlock(so);
-
/*
* `so2' can't be PRU_ABORT'ed concurrently
*/
- if (so2 != so)
- sounlock(so2);
+ sounlock_pair(so, so2);
put:
vput(vp);
unlock:
Index: sys/socketvar.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/sys/socketvar.h,v
diff -u -p -r1.145 socketvar.h
--- sys/socketvar.h 31 Jan 2025 07:53:10 -0000 1.145
+++ sys/socketvar.h 31 Jan 2025 12:12:17 -0000
@@ -436,6 +436,7 @@ void solock_pair(struct socket *, struct
void sounlock(struct socket *);
void sounlock_shared(struct socket *);
void sounlock_nonet(struct socket *);
+void sounlock_pair(struct socket *, struct socket *);
int sendit(struct proc *, int, struct msghdr *, int, register_t *);
int recvit(struct proc *, int, struct msghdr *, caddr_t, register_t *);
merge sosplice_solock_pair() into solock_pair()