Download raw body.
Please test: shared solock for all intet sockets within knote(9) routines
Please test: shared solock for all intet sockets within knote(9) routines
Please test: shared solock for all intet sockets within knote(9) routines
Please test: shared solock for all intet sockets within knote(9) routines
On Wed, Jan 31, 2024 at 10:25:47PM +0100, Alexander Bluhm wrote:
> 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]
Sorry, I forgot to change knote_locked() to knote() within
sohasoutofband(). This diff fixes it. Also sblock() fix included.
Since the `sb_klist' uses `sb_mtx' mutex(9) for protection, special
`socket_klistops' is not required anymore and was removed.
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 31 Jan 2024 22:06:44 -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,8 @@ const struct filterops soexcept_filtops
.f_attach = NULL,
.f_detach = filt_sordetach,
.f_event = filt_soexcept,
- .f_modify = filt_somodify,
- .f_process = filt_soprocess,
-};
-
-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,
+ .f_modify = filt_rcv_somodify,
+ .f_process = filt_rcv_soprocess,
};
#ifndef SOMINCONN
@@ -158,8 +142,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_mutex(&so->so_rcv.sb_klist, &so->so_rcv.sb_mtx);
+ klist_init_mutex(&so->so_snd.sb_klist, &so->so_snd.sb_mtx);
sigio_init(&so->so_sigio);
TAILQ_INIT(&so->so_q0);
TAILQ_INIT(&so->so_q);
@@ -1757,7 +1743,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 +1771,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)
@@ -2134,7 +2120,46 @@ void
sohasoutofband(struct socket *so)
{
pgsigio(&so->so_sigio, SIGURG, 0);
- knote_locked(&so->so_rcv.sb_klist, 0);
+ knote(&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
@@ -2143,13 +2168,9 @@ soo_kqfilter(struct file *fp, struct kno
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 +2182,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 +2206,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 +2263,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 +2294,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 +2320,55 @@ 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;
-
- soassertlocked(so);
-
- kn->kn_data = so->so_qlen;
- active = (kn->kn_data != 0);
+ int 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);
- }
- }
+ sofilt_lock(so, &so->so_snd);
+ rv = knote_modify(kev, kn);
+ sofilt_unlock(so, &so->so_snd);
- return (active);
+ return (rv);
}
int
-filt_somodify(struct kevent *kev, struct knote *kn)
+filt_snd_soprocess(struct knote *kn, struct kevent *kev)
{
struct socket *so = kn->kn_fp->f_data;
int rv;
- solock(so);
- rv = knote_modify(kev, kn);
- sounlock(so);
+ sofilt_lock(so, &so->so_snd);
+ rv = knote_process(kn, kev);
+ sofilt_unlock(so, &so->so_snd);
return (rv);
}
int
-filt_soprocess(struct knote *kn, struct kevent *kev)
+filt_rcv_somodify(struct kevent *kev, struct knote *kn)
{
struct socket *so = kn->kn_fp->f_data;
int rv;
- solock(so);
- rv = knote_process(kn, kev);
- sounlock(so);
+ sofilt_lock(so, &so->so_rcv);
+ rv = knote_modify(kev, kn);
+ sofilt_unlock(so, &so->so_rcv);
return (rv);
}
-void
-klist_soassertlk(void *arg)
-{
- struct socket *so = arg;
-
- soassertlocked(so);
-}
-
int
-klist_solock(void *arg)
+filt_rcv_soprocess(struct knote *kn, struct kevent *kev)
{
- struct socket *so = arg;
-
- solock(so);
- return (1);
-}
+ struct socket *so = kn->kn_fp->f_data;
+ int rv;
-void
-klist_sounlock(void *arg, int ls)
-{
- struct socket *so = arg;
+ sofilt_lock(so, &so->so_rcv);
+ rv = knote_process(kn, kev);
+ sofilt_unlock(so, &so->so_rcv);
- sounlock(so);
+ return (rv);
}
#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 31 Jan 2024 22:06:44 -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;
- return (0);
+out:
+ mtx_leave(&sb->sb_mtx);
+
+ return (error);
}
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 31 Jan 2024 22:06:44 -0000
@@ -326,7 +326,7 @@ doaccept(struct proc *p, int sock, struc
: (flags & SOCK_NONBLOCK ? FNONBLOCK : 0);
/* connection has been removed from the listen queue */
- knote_locked(&head->so_rcv.sb_klist, 0);
+ knote(&head->so_rcv.sb_klist, 0);
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 31 Jan 2024 22:06:44 -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 31 Jan 2024 22:06:44 -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 31 Jan 2024 22:06:44 -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 31 Jan 2024 22:06:44 -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 31 Jan 2024 22:06:44 -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 31 Jan 2024 22:06:44 -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 31 Jan 2024 22:06:44 -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 31 Jan 2024 22:06:44 -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 31 Jan 2024 22:06:44 -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 31 Jan 2024 22:06:44 -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 31 Jan 2024 22:06:44 -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 31 Jan 2024 22:06:44 -0000
@@ -40,6 +40,7 @@
#include <sys/sigio.h> /* for struct sigio_ref */
#include <sys/task.h>
#include <sys/timeout.h>
+#include <sys/mutex.h>
#include <sys/rwlock.h>
#include <sys/refcnt.h>
@@ -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 <lib/libkern/libkern.h>
void soassertlocked(struct socket *);
+void soassertlocked_readonly(struct socket *);
static inline void
soref(struct socket *so)
@@ -200,9 +203,16 @@ sorele(struct socket *so)
static inline int
sb_notify(struct socket *so, struct sockbuf *sb)
{
+ int rv;
+
soassertlocked(so);
- return ((sb->sb_flags & (SB_WAIT|SB_ASYNC|SB_SPLICE)) != 0 ||
+
+ mtx_enter(&sb->sb_mtx);
+ rv = ((sb->sb_flags & (SB_WAIT|SB_ASYNC|SB_SPLICE)) != 0 ||
!klist_empty(&sb->sb_klist));
+ mtx_leave(&sb->sb_mtx);
+
+ return rv;
}
/*
@@ -211,10 +221,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 +242,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 +253,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)) ||
Please test: shared solock for all intet sockets within knote(9) routines
Please test: shared solock for all intet sockets within knote(9) routines
Please test: shared solock for all intet sockets within knote(9) routines
Please test: shared solock for all intet sockets within knote(9) routines