From: Alexander Bluhm Subject: Re: Please test: shared solock for all intet sockets within knote(9) routines To: Vitaliy Makkoveev Cc: tech@openbsd.org Date: Wed, 31 Jan 2024 22:25:47 +0100 On Tue, Jan 30, 2024 at 05:39:43PM +0300, Vitaliy Makkoveev wrote: > Please test it, but keep in mind, soassertlocked_readonly() could be > required in some more places. I panics on i386 during regress. From the timestamps of the logs I think it is one of these. Not that they run on two machines and the remote one crashes. -rw-r--r-- 1 root wsrc 4863 Jan 31 13:06 sys/kern/sosplice/error/make.log -rw-r--r-- 1 root wsrc 4510 Jan 31 13:07 sys/kern/sosplice/loop/make.log -rw-r--r-- 1 root wsrc 8872 Jan 31 13:08 sys/kern/sosplice/perf/make.log -rw-r--r-- 1 root wsrc 1490 Jan 31 14:08 sys/kern/sosplice/scapy/make.log -rw-r--r-- 1 root wsrc 40256 Jan 31 14:09 sys/kern/sosplice/tcp/make.log -rw-r--r-- 1 root wsrc 9162 Jan 31 14:10 sys/kern/sosplice/udp/make.log [-- MARK -- Wed Jan 31 13:05:00 2024] panic: mutex 0xd7dfd9a0 not held in klist_rcv_soassertlk Stopped at db_enter+0x4: popl %ebp TID PID UID PRFLAGS PFLAGS CPU COMMAND * 70542 31548 0 0x14000 0x200 1 softnet0 db_enter() at db_enter+0x4 panic(d0cbc0e4) at panic+0x7a klist_rcv_soassertlk(d7dfd92c) at klist_rcv_soassertlk+0x3b knote_locked(d7dfd9f0,0) at knote_locked+0x1a sohasoutofband(d7dfd92c) at sohasoutofband+0x25 tcp_input(f5802ea4,f5802ea0,6,2) at tcp_input+0x290d ip_deliver(f5802ea4,f5802ea0,6,2) at ip_deliver+0xf4 ipintr() at ipintr+0x52 if_netisr(0) at if_netisr+0xd2 taskq_thread(d82f5000) at taskq_thread+0x84 https://www.openbsd.org/ddb.html describes the minimum info required in bug reports. Insufficient info makes it difficult to find and fix bugs. ddb{1}> [-- MARK -- Wed Jan 31 13:10:00 2024] ddb{1}> trace db_enter() at db_enter+0x4 panic(d0cbc0e4) at panic+0x7a klist_rcv_soassertlk(d7dfd92c) at klist_rcv_soassertlk+0x3b knote_locked(d7dfd9f0,0) at knote_locked+0x1a sohasoutofband(d7dfd92c) at sohasoutofband+0x25 tcp_input(f5802ea4,f5802ea0,6,2) at tcp_input+0x290d ip_deliver(f5802ea4,f5802ea0,6,2) at ip_deliver+0xf4 ipintr() at ipintr+0x52 if_netisr(0) at if_netisr+0xd2 taskq_thread(d82f5000) at taskq_thread+0x84 ddb{1}> show panic *cpu1: mutex 0xd7dfd9a0 not held in klist_rcv_soassertlk ddb{1}> ps PID TID PPID UID S FLAGS WAIT COMMAND 33821 430179 72439 0 3 0x18000080 kqread perl 72439 85098 2270 0 3 0x18000082 nanoslp perl 2270 66435 91013 0 3 0x810008a sigsusp ksh 91013 468133 21885 0 3 0x1800009a kqread sshd 64251 467022 0 0 3 0x14200 bored sosplice 9320 326846 1 0 3 0x18100083 ttyin getty 35392 127174 1 0 3 0x18100083 ttyin getty 10539 445346 1 0 3 0x18100083 ttyin getty 69170 204127 1 0 3 0x18100083 ttyin getty 74889 176546 1 0 3 0x18100083 ttyin getty 54557 309338 1 0 3 0x18100083 ttyin getty 72820 218516 1 0 3 0x18100098 kqread cron 61729 496486 1 99 3 0x19100090 kqread sndiod 57746 452154 1 110 3 0x18100090 kqread sndiod 67789 418348 1 0 3 0x18100090 kqread inetd 42191 333292 16121 95 3 0x19100092 kqread smtpd 93475 54660 16121 103 3 0x19100092 kqread smtpd 83475 437999 16121 95 3 0x19100092 kqread smtpd 98829 69987 16121 95 3 0x18100092 kqread smtpd 78254 203427 16121 95 3 0x19100092 kqread smtpd 21246 167470 16121 95 3 0x19100092 kqread smtpd 16121 4669 1 0 3 0x18100080 kqread smtpd 81490 303280 70200 91 3 0x18000092 kqread snmpd_metrics 70200 361674 1 0 3 0x18100080 kqread snmpd 96626 136899 1 91 3 0x19100092 kqread snmpd 21885 411308 1 0 3 0x18000088 kqread sshd 37505 382412 0 0 3 0x14200 acct acct 56649 159907 0 0 3 0x14280 nfsidl nfsio 4116 120586 0 0 3 0x14280 nfsidl nfsio 72620 54685 0 0 3 0x14280 nfsidl nfsio 29121 302945 0 0 3 0x14280 nfsidl nfsio 34934 157798 1 0 3 0x18100080 kqread ntpd 38552 212157 56073 83 3 0x18100092 kqread ntpd 56073 223794 1 83 3 0x19100092 kqread ntpd 26595 370479 97754 74 3 0x19100092 bpf pflogd 97754 425118 1 0 3 0x18000080 netio pflogd 75792 233839 67399 73 3 0x19100090 kqread syslogd 67399 100208 1 0 3 0x18100082 netio syslogd 4765 57128 61338 77 3 0x18100092 kqread dhcpleased 68691 312270 61338 77 3 0x18100092 kqread dhcpleased 61338 374213 1 0 3 0x18000080 kqread dhcpleased 83483 92240 7393 115 3 0x18100092 kqread slaacd 52363 505486 7393 115 3 0x18100092 kqread slaacd 7393 383214 1 0 3 0x18100080 kqread slaacd 44149 1575 0 0 3 0x14200 bored smr 63153 12976 0 0 3 0x14200 pgzero zerothread 4242 209353 0 0 3 0x14200 aiodoned aiodoned 24241 217704 0 0 3 0x14200 syncer update 6943 12123 0 0 3 0x14200 cleaner cleaner 99116 172045 0 0 3 0x14200 reaper reaper 53902 79358 0 0 3 0x14200 pgdaemon pagedaemon 2943 241684 0 0 3 0x14200 bored wsdisplay0 69988 448119 0 0 3 0x14200 usbtsk usbtask 37311 173195 0 0 3 0x14200 usbatsk usbatsk 36678 79722 0 0 3 0x14200 bored sensors 73770 446641 0 0 3 0x40014200 acpi0 acpi0 92248 310035 0 0 7 0x40014200 idle7 67293 358588 0 0 7 0x40014200 idle6 66898 111169 0 0 7 0x40014200 idle5 4293 126154 0 0 7 0x40014200 idle4 4414 270352 0 0 7 0x40014200 idle3 68914 204664 0 0 7 0x40014200 idle2 91318 33572 0 0 3 0x40014200 idle1 32025 410254 0 0 3 0x14200 bored softnet3 88050 248985 0 0 3 0x14200 bored softnet2 12644 456866 0 0 3 0x14200 bored softnet1 *31548 70542 0 0 7 0x14200 softnet0 30395 235408 0 0 3 0x14200 bored systqmp 47861 432958 0 0 3 0x14200 bored systq 49949 66059 0 0 3 0x14200 tmoslp softclockmp 30081 350770 0 0 3 0x40014200 tmoslp softclock 28312 521561 0 0 7 0x40014200 idle0 12934 232778 0 0 3 0x14200 kmalloc kmthread 1 166358 0 0 3 0x8000082 wait init 0 0 -1 0 3 0x10200 scheduler swapper ddb{1}> show register ds 0x10 es 0x10 fs 0x20 gs 0 edi 0xd0cbc0e4 apollo_udma33_tim+0x3d24d esi 0 ebp 0xf5802d24 ebx 0xf55365d8 edx 0x3fd ecx 0x79e68b36 eax 0x39 eip 0xd0761854 db_enter+0x4 cs 0x8 eflags 0x202 esp 0xf5802d24 ss 0x10 db_enter+0x4: popl %ebp ddb{1}> show locks exclusive rwlock netlock r = 0 (0xd0ee12d4) shared rwlock softnet0 r = 0 (0xd82f5048) > Index: sys/kern/uipc_socket.c > =================================================================== > RCS file: /cvs/src/sys/kern/uipc_socket.c,v > retrieving revision 1.315 > diff -u -p -r1.315 uipc_socket.c > --- sys/kern/uipc_socket.c 26 Jan 2024 18:24:23 -0000 1.315 > +++ sys/kern/uipc_socket.c 30 Jan 2024 14:24:45 -0000 > @@ -72,26 +72,20 @@ int filt_soread(struct knote *kn, long h > void filt_sowdetach(struct knote *kn); > int filt_sowrite(struct knote *kn, long hint); > int filt_soexcept(struct knote *kn, long hint); > -int filt_solisten(struct knote *kn, long hint); > -int filt_somodify(struct kevent *kev, struct knote *kn); > -int filt_soprocess(struct knote *kn, struct kevent *kev); > > -const struct filterops solisten_filtops = { > - .f_flags = FILTEROP_ISFD | FILTEROP_MPSAFE, > - .f_attach = NULL, > - .f_detach = filt_sordetach, > - .f_event = filt_solisten, > - .f_modify = filt_somodify, > - .f_process = filt_soprocess, > -}; > +int filt_snd_somodify(struct kevent *kev, struct knote *kn); > +int filt_snd_soprocess(struct knote *kn, struct kevent *kev); > + > +int filt_rcv_somodify(struct kevent *kev, struct knote *kn); > +int filt_rcv_soprocess(struct knote *kn, struct kevent *kev); > > const struct filterops soread_filtops = { > .f_flags = FILTEROP_ISFD | FILTEROP_MPSAFE, > .f_attach = NULL, > .f_detach = filt_sordetach, > .f_event = filt_soread, > - .f_modify = filt_somodify, > - .f_process = filt_soprocess, > + .f_modify = filt_rcv_somodify, > + .f_process = filt_rcv_soprocess, > }; > > const struct filterops sowrite_filtops = { > @@ -99,8 +93,8 @@ const struct filterops sowrite_filtops = > .f_attach = NULL, > .f_detach = filt_sowdetach, > .f_event = filt_sowrite, > - .f_modify = filt_somodify, > - .f_process = filt_soprocess, > + .f_modify = filt_snd_somodify, > + .f_process = filt_snd_soprocess, > }; > > const struct filterops soexcept_filtops = { > @@ -108,18 +102,28 @@ const struct filterops soexcept_filtops > .f_attach = NULL, > .f_detach = filt_sordetach, > .f_event = filt_soexcept, > - .f_modify = filt_somodify, > - .f_process = filt_soprocess, > + .f_modify = filt_rcv_somodify, > + .f_process = filt_rcv_soprocess, > +}; > + > +void klist_snd_soassertlk(void *); > +int klist_snd_solock(void *); > +void klist_snd_sounlock(void *, int); > + > +const struct klistops socket_snd_klistops = { > + .klo_assertlk = klist_snd_soassertlk, > + .klo_lock = klist_snd_solock, > + .klo_unlock = klist_snd_sounlock, > }; > > -void klist_soassertlk(void *); > -int klist_solock(void *); > -void klist_sounlock(void *, int); > - > -const struct klistops socket_klistops = { > - .klo_assertlk = klist_soassertlk, > - .klo_lock = klist_solock, > - .klo_unlock = klist_sounlock, > +void klist_rcv_soassertlk(void *); > +int klist_rcv_solock(void *); > +void klist_rcv_sounlock(void *, int); > + > +const struct klistops socket_rcv_klistops = { > + .klo_assertlk = klist_rcv_soassertlk, > + .klo_lock = klist_rcv_solock, > + .klo_unlock = klist_rcv_sounlock, > }; > > #ifndef SOMINCONN > @@ -158,8 +162,10 @@ soalloc(const struct domain *dp, int wai > return (NULL); > rw_init_flags(&so->so_lock, dp->dom_name, RWL_DUPOK); > refcnt_init(&so->so_refcnt); > - klist_init(&so->so_rcv.sb_klist, &socket_klistops, so); > - klist_init(&so->so_snd.sb_klist, &socket_klistops, so); > + mtx_init(&so->so_rcv.sb_mtx, IPL_MPFLOOR); > + mtx_init(&so->so_snd.sb_mtx, IPL_MPFLOOR); > + klist_init(&so->so_rcv.sb_klist, &socket_rcv_klistops, so); > + klist_init(&so->so_snd.sb_klist, &socket_snd_klistops, so); > sigio_init(&so->so_sigio); > TAILQ_INIT(&so->so_q0); > TAILQ_INIT(&so->so_q); > @@ -1757,7 +1763,7 @@ somove(struct socket *so, int wait) > void > sorwakeup(struct socket *so) > { > - soassertlocked(so); > + soassertlocked_readonly(so); > > #ifdef SOCKET_SPLICE > if (so->so_rcv.sb_flags & SB_SPLICE) { > @@ -1785,7 +1791,7 @@ sorwakeup(struct socket *so) > void > sowwakeup(struct socket *so) > { > - soassertlocked(so); > + soassertlocked_readonly(so); > > #ifdef SOCKET_SPLICE > if (so->so_snd.sb_flags & SB_SPLICE) > @@ -2137,19 +2143,54 @@ sohasoutofband(struct socket *so) > knote_locked(&so->so_rcv.sb_klist, 0); > } > > +void > +sofilt_lock(struct socket *so, struct sockbuf *sb) > +{ > + switch (so->so_proto->pr_domain->dom_family) { > + case PF_INET: > + case PF_INET6: > + NET_LOCK_SHARED(); > + break; > + default: > + rw_enter_write(&so->so_lock); > + break; > + } > + > + mtx_enter(&sb->sb_mtx); > +} > + > +void > +sofilt_unlock(struct socket *so, struct sockbuf *sb) > +{ > + mtx_leave(&sb->sb_mtx); > + > + switch (so->so_proto->pr_domain->dom_family) { > + case PF_INET: > + case PF_INET6: > + NET_UNLOCK_SHARED(); > + break; > + default: > + rw_exit_write(&so->so_lock); > + break; > + } > +} > + > +static inline void > +sofilt_assert_locked(struct socket *so, struct sockbuf *sb) > +{ > + MUTEX_ASSERT_LOCKED(&sb->sb_mtx); > + soassertlocked_readonly(so); > +} > + > int > soo_kqfilter(struct file *fp, struct knote *kn) > { > struct socket *so = kn->kn_fp->f_data; > struct sockbuf *sb; > > - solock(so); > switch (kn->kn_filter) { > case EVFILT_READ: > - if (so->so_options & SO_ACCEPTCONN) > - kn->kn_fop = &solisten_filtops; > - else > - kn->kn_fop = &soread_filtops; > + kn->kn_fop = &soread_filtops; > sb = &so->so_rcv; > break; > case EVFILT_WRITE: > @@ -2161,12 +2202,12 @@ soo_kqfilter(struct file *fp, struct kno > sb = &so->so_rcv; > break; > default: > - sounlock(so); > return (EINVAL); > } > > + mtx_enter(&sb->sb_mtx); > klist_insert_locked(&sb->sb_klist, kn); > - sounlock(so); > + mtx_leave(&sb->sb_mtx); > > return (0); > } > @@ -2185,7 +2226,23 @@ filt_soread(struct knote *kn, long hint) > struct socket *so = kn->kn_fp->f_data; > int rv = 0; > > - soassertlocked(so); > + sofilt_assert_locked(so, &so->so_rcv); > + > + if (so->so_options & SO_ACCEPTCONN) { > + kn->kn_data = so->so_qlen; > + rv = (kn->kn_data != 0); > + > + if (kn->kn_flags & (__EV_POLL | __EV_SELECT)) { > + if (so->so_state & SS_ISDISCONNECTED) { > + kn->kn_flags |= __EV_HUP; > + rv = 1; > + } else { > + rv = soreadable(so); > + } > + } > + > + return rv; > + } > > kn->kn_data = so->so_rcv.sb_cc; > #ifdef SOCKET_SPLICE > @@ -2226,7 +2283,7 @@ filt_sowrite(struct knote *kn, long hint > struct socket *so = kn->kn_fp->f_data; > int rv; > > - soassertlocked(so); > + sofilt_assert_locked(so, &so->so_snd); > > kn->kn_data = sbspace(so, &so->so_snd); > if (so->so_snd.sb_state & SS_CANTSENDMORE) { > @@ -2257,7 +2314,7 @@ filt_soexcept(struct knote *kn, long hin > struct socket *so = kn->kn_fp->f_data; > int rv = 0; > > - soassertlocked(so); > + sofilt_assert_locked(so, &so->so_rcv); > > #ifdef SOCKET_SPLICE > if (isspliced(so)) { > @@ -2283,77 +2340,105 @@ filt_soexcept(struct knote *kn, long hin > } > > int > -filt_solisten(struct knote *kn, long hint) > +filt_snd_somodify(struct kevent *kev, struct knote *kn) > { > struct socket *so = kn->kn_fp->f_data; > - int active; > + int rv; > > - soassertlocked(so); > + sofilt_lock(so, &so->so_snd); > + rv = knote_modify(kev, kn); > + sofilt_unlock(so, &so->so_snd); > > - kn->kn_data = so->so_qlen; > - active = (kn->kn_data != 0); > + return (rv); > +} > > - if (kn->kn_flags & (__EV_POLL | __EV_SELECT)) { > - if (so->so_state & SS_ISDISCONNECTED) { > - kn->kn_flags |= __EV_HUP; > - active = 1; > - } else { > - active = soreadable(so); > - } > - } > +int > +filt_snd_soprocess(struct knote *kn, struct kevent *kev) > +{ > + struct socket *so = kn->kn_fp->f_data; > + int rv; > + > + sofilt_lock(so, &so->so_snd); > + rv = knote_process(kn, kev); > + sofilt_unlock(so, &so->so_snd); > > - return (active); > + return (rv); > } > > int > -filt_somodify(struct kevent *kev, struct knote *kn) > +filt_rcv_somodify(struct kevent *kev, struct knote *kn) > { > struct socket *so = kn->kn_fp->f_data; > int rv; > > - solock(so); > + sofilt_lock(so, &so->so_rcv); > rv = knote_modify(kev, kn); > - sounlock(so); > + sofilt_unlock(so, &so->so_rcv); > > return (rv); > } > > int > -filt_soprocess(struct knote *kn, struct kevent *kev) > +filt_rcv_soprocess(struct knote *kn, struct kevent *kev) > { > struct socket *so = kn->kn_fp->f_data; > int rv; > > - solock(so); > + sofilt_lock(so, &so->so_rcv); > rv = knote_process(kn, kev); > - sounlock(so); > + sofilt_unlock(so, &so->so_rcv); > > return (rv); > } > > void > -klist_soassertlk(void *arg) > +klist_snd_soassertlk(void *arg) > { > struct socket *so = arg; > > - soassertlocked(so); > + MUTEX_ASSERT_LOCKED(&so->so_snd.sb_mtx); > } > > int > -klist_solock(void *arg) > +klist_snd_solock(void *arg) > { > struct socket *so = arg; > > - solock(so); > + mtx_enter(&so->so_snd.sb_mtx); > return (1); > } > > void > -klist_sounlock(void *arg, int ls) > +klist_snd_sounlock(void *arg, int ls) > { > struct socket *so = arg; > > - sounlock(so); > + mtx_leave(&so->so_snd.sb_mtx); > +} > + > +void > +klist_rcv_soassertlk(void *arg) > +{ > + struct socket *so = arg; > + > + MUTEX_ASSERT_LOCKED(&so->so_rcv.sb_mtx); > +} > + > +int > +klist_rcv_solock(void *arg) > +{ > + struct socket *so = arg; > + > + mtx_enter(&so->so_rcv.sb_mtx); > + return (1); > +} > + > +void > +klist_rcv_sounlock(void *arg, int ls) > +{ > + struct socket *so = arg; > + > + mtx_leave(&so->so_rcv.sb_mtx); > } > > #ifdef DDB > Index: sys/kern/uipc_socket2.c > =================================================================== > RCS file: /cvs/src/sys/kern/uipc_socket2.c,v > retrieving revision 1.140 > diff -u -p -r1.140 uipc_socket2.c > --- sys/kern/uipc_socket2.c 11 Jan 2024 14:15:11 -0000 1.140 > +++ sys/kern/uipc_socket2.c 30 Jan 2024 14:24:45 -0000 > @@ -439,7 +439,7 @@ sounlock_shared(struct socket *so) > } > > void > -soassertlocked(struct socket *so) > +soassertlocked_readonly(struct socket *so) > { > switch (so->so_proto->pr_domain->dom_family) { > case PF_INET: > @@ -452,6 +452,27 @@ soassertlocked(struct socket *so) > } > } > > +void > +soassertlocked(struct socket *so) > +{ > + switch (so->so_proto->pr_domain->dom_family) { > + case PF_INET: > + case PF_INET6: > + if (rw_status(&netlock) == RW_READ) { > + NET_ASSERT_LOCKED(); > + > + if (splassert_ctl > 0 && pru_locked(so) == 0 && > + rw_status(&so->so_lock) != RW_WRITE) > + splassert_fail(0, RW_WRITE, __func__); > + } else > + NET_ASSERT_LOCKED_EXCLUSIVE(); > + break; > + default: > + rw_assert_wrlock(&so->so_lock); > + break; > + } > +} > + > int > sosleep_nsec(struct socket *so, void *ident, int prio, const char *wmesg, > uint64_t nsecs) > @@ -489,46 +510,62 @@ sbwait(struct socket *so, struct sockbuf > > soassertlocked(so); > > + mtx_enter(&sb->sb_mtx); > sb->sb_flags |= SB_WAIT; > + mtx_leave(&sb->sb_mtx); > + > return sosleep_nsec(so, &sb->sb_cc, prio, "netio", sb->sb_timeo_nsecs); > } > > int > sblock(struct socket *so, struct sockbuf *sb, int flags) > { > - int error, prio = PSOCK; > + int error = 0, prio = PSOCK; > > soassertlocked(so); > > + mtx_enter(&sb->sb_mtx); > if ((sb->sb_flags & SB_LOCK) == 0) { > sb->sb_flags |= SB_LOCK; > - return (0); > + goto out; > + } > + if ((flags & SBL_WAIT) == 0) { > + error = EWOULDBLOCK; > + goto out; > } > - if ((flags & SBL_WAIT) == 0) > - return (EWOULDBLOCK); > if (!(flags & SBL_NOINTR || sb->sb_flags & SB_NOINTR)) > prio |= PCATCH; > > while (sb->sb_flags & SB_LOCK) { > sb->sb_flags |= SB_WANT; > + mtx_leave(&sb->sb_mtx); > error = sosleep_nsec(so, &sb->sb_flags, prio, "netlck", INFSLP); > if (error) > return (error); > + mtx_enter(&sb->sb_mtx); > } > sb->sb_flags |= SB_LOCK; > +out: > + mtx_leave(&sb->sb_mtx); > + > return (0); > } > > void > sbunlock(struct socket *so, struct sockbuf *sb) > { > - soassertlocked(so); > + int dowakeup = 0; > > + mtx_enter(&sb->sb_mtx); > sb->sb_flags &= ~SB_LOCK; > if (sb->sb_flags & SB_WANT) { > sb->sb_flags &= ~SB_WANT; > - wakeup(&sb->sb_flags); > + dowakeup = 1; > } > + mtx_leave(&sb->sb_mtx); > + > + if (dowakeup) > + wakeup(&sb->sb_flags); > } > > /* > @@ -539,15 +576,24 @@ sbunlock(struct socket *so, struct sockb > void > sowakeup(struct socket *so, struct sockbuf *sb) > { > - soassertlocked(so); > + int dowakeup = 0, dopgsigio = 0; > > + mtx_enter(&sb->sb_mtx); > if (sb->sb_flags & SB_WAIT) { > sb->sb_flags &= ~SB_WAIT; > - wakeup(&sb->sb_cc); > + dowakeup = 1; > } > if (sb->sb_flags & SB_ASYNC) > - pgsigio(&so->so_sigio, SIGIO, 0); > + dopgsigio = 1; > + > knote_locked(&sb->sb_klist, 0); > + mtx_leave(&sb->sb_mtx); > + > + if (dowakeup) > + wakeup(&sb->sb_cc); > + > + if (dopgsigio) > + pgsigio(&so->so_sigio, SIGIO, 0); > } > > /* > Index: sys/kern/uipc_syscalls.c > =================================================================== > RCS file: /cvs/src/sys/kern/uipc_syscalls.c,v > retrieving revision 1.216 > diff -u -p -r1.216 uipc_syscalls.c > --- sys/kern/uipc_syscalls.c 3 Jan 2024 11:07:04 -0000 1.216 > +++ sys/kern/uipc_syscalls.c 30 Jan 2024 14:24:45 -0000 > @@ -326,7 +326,9 @@ doaccept(struct proc *p, int sock, struc > : (flags & SOCK_NONBLOCK ? FNONBLOCK : 0); > > /* connection has been removed from the listen queue */ > + mtx_enter(&head->so_rcv.sb_mtx); > knote_locked(&head->so_rcv.sb_klist, 0); > + mtx_leave(&head->so_rcv.sb_mtx); > > if (persocket) > sounlock(head); > Index: sys/netinet/ip_divert.c > =================================================================== > RCS file: /cvs/src/sys/netinet/ip_divert.c,v > retrieving revision 1.92 > diff -u -p -r1.92 ip_divert.c > --- sys/netinet/ip_divert.c 16 Sep 2023 09:33:27 -0000 1.92 > +++ sys/netinet/ip_divert.c 30 Jan 2024 14:24:45 -0000 > @@ -67,6 +67,7 @@ const struct pr_usrreqs divert_usrreqs = > .pru_detach = divert_detach, > .pru_lock = divert_lock, > .pru_unlock = divert_unlock, > + .pru_locked = divert_locked, > .pru_bind = divert_bind, > .pru_shutdown = divert_shutdown, > .pru_send = divert_send, > @@ -311,6 +312,14 @@ divert_unlock(struct socket *so) > > NET_ASSERT_LOCKED(); > mtx_leave(&inp->inp_mtx); > +} > + > +int > +divert_locked(struct socket *so) > +{ > + struct inpcb *inp = sotoinpcb(so); > + > + return mtx_owned(&inp->inp_mtx); > } > > int > Index: sys/netinet/ip_divert.h > =================================================================== > RCS file: /cvs/src/sys/netinet/ip_divert.h,v > retrieving revision 1.24 > diff -u -p -r1.24 ip_divert.h > --- sys/netinet/ip_divert.h 17 Oct 2022 14:49:02 -0000 1.24 > +++ sys/netinet/ip_divert.h 30 Jan 2024 14:24:45 -0000 > @@ -74,6 +74,7 @@ int divert_attach(struct socket *, int, > int divert_detach(struct socket *); > void divert_lock(struct socket *); > void divert_unlock(struct socket *); > +int divert_locked(struct socket *); > int divert_bind(struct socket *, struct mbuf *, struct proc *); > int divert_shutdown(struct socket *); > int divert_send(struct socket *, struct mbuf *, struct mbuf *, > Index: sys/netinet/ip_var.h > =================================================================== > RCS file: /cvs/src/sys/netinet/ip_var.h,v > retrieving revision 1.110 > diff -u -p -r1.110 ip_var.h > --- sys/netinet/ip_var.h 26 Nov 2023 22:08:10 -0000 1.110 > +++ sys/netinet/ip_var.h 30 Jan 2024 14:24:45 -0000 > @@ -260,6 +260,7 @@ int rip_attach(struct socket *, int, in > int rip_detach(struct socket *); > void rip_lock(struct socket *); > void rip_unlock(struct socket *); > +int rip_locked(struct socket *); > int rip_bind(struct socket *, struct mbuf *, struct proc *); > int rip_connect(struct socket *, struct mbuf *); > int rip_disconnect(struct socket *); > Index: sys/netinet/raw_ip.c > =================================================================== > RCS file: /cvs/src/sys/netinet/raw_ip.c,v > retrieving revision 1.154 > diff -u -p -r1.154 raw_ip.c > --- sys/netinet/raw_ip.c 21 Jan 2024 01:17:20 -0000 1.154 > +++ sys/netinet/raw_ip.c 30 Jan 2024 14:24:45 -0000 > @@ -108,6 +108,7 @@ const struct pr_usrreqs rip_usrreqs = { > .pru_detach = rip_detach, > .pru_lock = rip_lock, > .pru_unlock = rip_unlock, > + .pru_locked = rip_locked, > .pru_bind = rip_bind, > .pru_connect = rip_connect, > .pru_disconnect = rip_disconnect, > @@ -522,6 +523,14 @@ rip_unlock(struct socket *so) > > NET_ASSERT_LOCKED(); > mtx_leave(&inp->inp_mtx); > +} > + > +int > +rip_locked(struct socket *so) > +{ > + struct inpcb *inp = sotoinpcb(so); > + > + return mtx_owned(&inp->inp_mtx); > } > > int > Index: sys/netinet/udp_usrreq.c > =================================================================== > RCS file: /cvs/src/sys/netinet/udp_usrreq.c,v > retrieving revision 1.316 > diff -u -p -r1.316 udp_usrreq.c > --- sys/netinet/udp_usrreq.c 28 Jan 2024 20:34:25 -0000 1.316 > +++ sys/netinet/udp_usrreq.c 30 Jan 2024 14:24:45 -0000 > @@ -127,6 +127,7 @@ const struct pr_usrreqs udp_usrreqs = { > .pru_detach = udp_detach, > .pru_lock = udp_lock, > .pru_unlock = udp_unlock, > + .pru_locked = udp_locked, > .pru_bind = udp_bind, > .pru_connect = udp_connect, > .pru_disconnect = udp_disconnect, > @@ -143,6 +144,7 @@ const struct pr_usrreqs udp6_usrreqs = { > .pru_detach = udp_detach, > .pru_lock = udp_lock, > .pru_unlock = udp_unlock, > + .pru_locked = udp_locked, > .pru_bind = udp_bind, > .pru_connect = udp_connect, > .pru_disconnect = udp_disconnect, > @@ -1154,6 +1156,14 @@ udp_unlock(struct socket *so) > > NET_ASSERT_LOCKED(); > mtx_leave(&inp->inp_mtx); > +} > + > +int > +udp_locked(struct socket *so) > +{ > + struct inpcb *inp = sotoinpcb(so); > + > + return mtx_owned(&inp->inp_mtx); > } > > int > Index: sys/netinet/udp_var.h > =================================================================== > RCS file: /cvs/src/sys/netinet/udp_var.h,v > retrieving revision 1.50 > diff -u -p -r1.50 udp_var.h > --- sys/netinet/udp_var.h 10 Jan 2024 16:44:30 -0000 1.50 > +++ sys/netinet/udp_var.h 30 Jan 2024 14:24:45 -0000 > @@ -147,6 +147,7 @@ int udp_attach(struct socket *, int, in > int udp_detach(struct socket *); > void udp_lock(struct socket *); > void udp_unlock(struct socket *); > +int udp_locked(struct socket *); > int udp_bind(struct socket *, struct mbuf *, struct proc *); > int udp_connect(struct socket *, struct mbuf *); > int udp_disconnect(struct socket *); > Index: sys/netinet6/ip6_mroute.c > =================================================================== > RCS file: /cvs/src/sys/netinet6/ip6_mroute.c,v > retrieving revision 1.138 > diff -u -p -r1.138 ip6_mroute.c > --- sys/netinet6/ip6_mroute.c 6 Dec 2023 09:27:17 -0000 1.138 > +++ sys/netinet6/ip6_mroute.c 30 Jan 2024 14:24:45 -0000 > @@ -861,12 +861,12 @@ socket6_send(struct socket *so, struct m > > mtx_enter(&inp->inp_mtx); > ret = sbappendaddr(so, &so->so_rcv, sin6tosa(src), mm, NULL); > + if (ret != 0) > + sorwakeup(so); > mtx_leave(&inp->inp_mtx); > > - if (ret != 0) { > - sorwakeup(so); > + if (ret != 0) > return 0; > - } > } > m_freem(mm); > return -1; > Index: sys/netinet6/ip6_var.h > =================================================================== > RCS file: /cvs/src/sys/netinet6/ip6_var.h,v > retrieving revision 1.109 > diff -u -p -r1.109 ip6_var.h > --- sys/netinet6/ip6_var.h 3 Dec 2023 20:36:24 -0000 1.109 > +++ sys/netinet6/ip6_var.h 30 Jan 2024 14:24:45 -0000 > @@ -353,6 +353,7 @@ int rip6_attach(struct socket *, int, in > int rip6_detach(struct socket *); > void rip6_lock(struct socket *); > void rip6_unlock(struct socket *); > +int rip6_locked(struct socket *); > int rip6_bind(struct socket *, struct mbuf *, struct proc *); > int rip6_connect(struct socket *, struct mbuf *); > int rip6_disconnect(struct socket *); > Index: sys/netinet6/raw_ip6.c > =================================================================== > RCS file: /cvs/src/sys/netinet6/raw_ip6.c,v > retrieving revision 1.179 > diff -u -p -r1.179 raw_ip6.c > --- sys/netinet6/raw_ip6.c 21 Jan 2024 01:17:20 -0000 1.179 > +++ sys/netinet6/raw_ip6.c 30 Jan 2024 14:24:45 -0000 > @@ -110,6 +110,7 @@ const struct pr_usrreqs rip6_usrreqs = { > .pru_detach = rip6_detach, > .pru_lock = rip6_lock, > .pru_unlock = rip6_unlock, > + .pru_locked = rip6_locked, > .pru_bind = rip6_bind, > .pru_connect = rip6_connect, > .pru_disconnect = rip6_disconnect, > @@ -651,6 +652,14 @@ rip6_unlock(struct socket *so) > > NET_ASSERT_LOCKED(); > mtx_leave(&inp->inp_mtx); > +} > + > +int > +rip6_locked(struct socket *so) > +{ > + struct inpcb *inp = sotoinpcb(so); > + > + return mtx_owned(&inp->inp_mtx); > } > > int > Index: sys/sys/mutex.h > =================================================================== > RCS file: /cvs/src/sys/sys/mutex.h,v > retrieving revision 1.19 > diff -u -p -r1.19 mutex.h > --- sys/sys/mutex.h 1 Dec 2023 14:37:22 -0000 1.19 > +++ sys/sys/mutex.h 30 Jan 2024 14:24:46 -0000 > @@ -127,6 +127,9 @@ void mtx_leave(struct mutex *); > > #define mtx_init(m, ipl) mtx_init_flags(m, ipl, NULL, 0) > > +#define mtx_owned(mtx) \ > + (((mtx)->mtx_owner == curcpu()) || panicstr || db_active) > + > #ifdef WITNESS > > void _mtx_init_flags(struct mutex *, int, const char *, int, > Index: sys/sys/protosw.h > =================================================================== > RCS file: /cvs/src/sys/sys/protosw.h,v > retrieving revision 1.64 > diff -u -p -r1.64 protosw.h > --- sys/sys/protosw.h 11 Jan 2024 14:15:12 -0000 1.64 > +++ sys/sys/protosw.h 30 Jan 2024 14:24:46 -0000 > @@ -69,6 +69,7 @@ struct pr_usrreqs { > int (*pru_detach)(struct socket *); > void (*pru_lock)(struct socket *); > void (*pru_unlock)(struct socket *); > + int (*pru_locked)(struct socket *so); > int (*pru_bind)(struct socket *, struct mbuf *, struct proc *); > int (*pru_listen)(struct socket *); > int (*pru_connect)(struct socket *, struct mbuf *); > @@ -294,6 +295,14 @@ pru_unlock(struct socket *so) > { > if (so->so_proto->pr_usrreqs->pru_unlock) > (*so->so_proto->pr_usrreqs->pru_unlock)(so); > +} > + > +static inline int > +pru_locked(struct socket *so) > +{ > + if (so->so_proto->pr_usrreqs->pru_locked) > + return (*so->so_proto->pr_usrreqs->pru_locked)(so); > + return (0); > } > > static inline int > Index: sys/sys/socketvar.h > =================================================================== > RCS file: /cvs/src/sys/sys/socketvar.h,v > retrieving revision 1.121 > diff -u -p -r1.121 socketvar.h > --- sys/sys/socketvar.h 11 Jan 2024 14:15:12 -0000 1.121 > +++ sys/sys/socketvar.h 30 Jan 2024 14:24:46 -0000 > @@ -40,6 +40,7 @@ > #include /* for struct sigio_ref */ > #include > #include > +#include > #include > #include > > @@ -105,6 +106,7 @@ struct socket { > * Variables for socket buffering. > */ > struct sockbuf { > + struct mutex sb_mtx; > /* The following fields are all zeroed on flush. */ > #define sb_startzero sb_cc > u_long sb_cc; /* actual chars in buffer */ > @@ -174,6 +176,7 @@ struct socket { > #include > > void soassertlocked(struct socket *); > +void soassertlocked_readonly(struct socket *); > > static inline void > soref(struct socket *so) > @@ -211,10 +214,12 @@ sb_notify(struct socket *so, struct sock > * still be negative (cc > hiwat or mbcnt > mbmax). Should detect > * overflow and return 0. > */ > + > static inline long > sbspace(struct socket *so, struct sockbuf *sb) > { > - soassertlocked(so); > + soassertlocked_readonly(so); > + > return lmin(sb->sb_hiwat - sb->sb_cc, sb->sb_mbmax - sb->sb_mbcnt); > } > > @@ -230,7 +235,7 @@ sbspace(struct socket *so, struct sockbu > static inline int > soreadable(struct socket *so) > { > - soassertlocked(so); > + soassertlocked_readonly(so); > if (isspliced(so)) > return 0; > return (so->so_rcv.sb_state & SS_CANTRCVMORE) || so->so_qlen || > @@ -241,7 +246,7 @@ soreadable(struct socket *so) > static inline int > sowriteable(struct socket *so) > { > - soassertlocked(so); > + soassertlocked_readonly(so); > return ((sbspace(so, &so->so_snd) >= so->so_snd.sb_lowat && > ((so->so_state & SS_ISCONNECTED) || > (so->so_proto->pr_flags & PR_CONNREQUIRED)==0)) ||