Download raw body.
replace sbmtxassertlocked with MUTEX_ASSERT_LOCKED
Hi,
Working on socket buffer protection has been stable for a while.
I think it is time to convert this soft failure to mutex assertion.
Fail early, fail hard.
MUTEX_ASSERT_LOCKED() cannot be used in header file due to missing
include dependencies. So I moved sbspace_locked() into .c file.
It is not more overhead than before when we called sbmtxassertlocked().
I am not a big fan of much code in header inline functions anyway.
The implementation is so trivial that I copied it to sbspace().
ok?
bluhm
Index: kern/uipc_socket2.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/kern/uipc_socket2.c,v
diff -u -p -r1.177 uipc_socket2.c
--- kern/uipc_socket2.c 6 Feb 2025 13:39:31 -0000 1.177
+++ kern/uipc_socket2.c 13 Feb 2025 18:06:59 -0000
@@ -502,13 +502,6 @@ sosleep_nsec(struct socket *so, void *id
return ret;
}
-void
-sbmtxassertlocked(struct sockbuf *sb)
-{
- if (splassert_ctl > 0 && mtx_owned(&sb->sb_mtx) == 0)
- splassert_fail(0, RW_WRITE, __func__);
-}
-
/*
* Wait for data to arrive at/drain from a socket buffer.
*/
@@ -646,7 +639,7 @@ bad:
int
sbreserve(struct socket *so, struct sockbuf *sb, u_long cc)
{
- sbmtxassertlocked(sb);
+ MUTEX_ASSERT_LOCKED(&sb->sb_mtx);
if (cc == 0 || cc > sb_max)
return (1);
@@ -688,6 +681,14 @@ sbchecklowmem(void)
return (atomic_load_int(&sblowmem));
}
+long
+sbspace_locked(struct sockbuf *sb)
+{
+ MUTEX_ASSERT_LOCKED(&sb->sb_mtx);
+
+ return lmin(sb->sb_hiwat - sb->sb_cc, sb->sb_mbmax - sb->sb_mbcnt);
+}
+
/*
* Free mbufs held by a socket, and reserved mbuf space.
*/
@@ -790,10 +791,11 @@ sbappend(struct socket *so, struct sockb
{
struct mbuf *n;
+ MUTEX_ASSERT_LOCKED(&sb->sb_mtx);
+
if (m == NULL)
return;
- sbmtxassertlocked(sb);
SBLASTRECORDCHK(sb, "sbappend 1");
if ((n = sb->sb_lastrecord) != NULL) {
@@ -827,7 +829,7 @@ sbappend(struct socket *so, struct sockb
void
sbappendstream(struct socket *so, struct sockbuf *sb, struct mbuf *m)
{
- sbmtxassertlocked(sb);
+ MUTEX_ASSERT_LOCKED(&sb->sb_mtx);
KDASSERT(m->m_nextpkt == NULL);
KASSERT(sb->sb_mb == sb->sb_lastrecord);
@@ -873,7 +875,7 @@ sbappendrecord(struct socket *so, struct
{
struct mbuf *m;
- sbmtxassertlocked(sb);
+ MUTEX_ASSERT_LOCKED(&sb->sb_mtx);
if (m0 == NULL)
return;
@@ -908,7 +910,7 @@ sbappendaddr(struct socket *so, struct s
struct mbuf *m, *n, *nlast;
int space = asa->sa_len;
- sbmtxassertlocked(sb);
+ MUTEX_ASSERT_LOCKED(&sb->sb_mtx);
if (m0 && (m0->m_flags & M_PKTHDR) == 0)
panic("sbappendaddr");
@@ -957,7 +959,7 @@ sbappendcontrol(struct socket *so, struc
struct mbuf *m, *mlast, *n;
int eor = 0, space = 0;
- sbmtxassertlocked(sb);
+ MUTEX_ASSERT_LOCKED(&sb->sb_mtx);
if (control == NULL)
panic("sbappendcontrol");
@@ -1082,7 +1084,7 @@ sbdrop(struct sockbuf *sb, int len)
struct mbuf *m, *mn;
struct mbuf *next;
- sbmtxassertlocked(sb);
+ MUTEX_ASSERT_LOCKED(&sb->sb_mtx);
next = (m = sb->sb_mb) ? m->m_nextpkt : NULL;
while (len > 0) {
Index: sys/socketvar.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/sys/socketvar.h,v
diff -u -p -r1.149 socketvar.h
--- sys/socketvar.h 6 Feb 2025 13:39:31 -0000 1.149
+++ sys/socketvar.h 13 Feb 2025 18:06:24 -0000
@@ -224,8 +224,6 @@ soref(struct socket *so)
#define isspliced(so) ((so)->so_sp && (so)->so_sp->ssp_socket)
#define issplicedback(so) ((so)->so_sp && (so)->so_sp->ssp_soback)
-void sbmtxassertlocked(struct sockbuf *);
-
/*
* Do we need to notify the other side when I/O is possible?
*/
@@ -250,20 +248,12 @@ sb_notify(struct sockbuf *sb)
*/
static inline long
-sbspace_locked(struct sockbuf *sb)
-{
- sbmtxassertlocked(sb);
-
- return lmin(sb->sb_hiwat - sb->sb_cc, sb->sb_mbmax - sb->sb_mbcnt);
-}
-
-static inline long
sbspace(struct sockbuf *sb)
{
long ret;
mtx_enter(&sb->sb_mtx);
- ret = sbspace_locked(sb);
+ ret = lmin(sb->sb_hiwat - sb->sb_cc, sb->sb_mbmax - sb->sb_mbcnt);
mtx_leave(&sb->sb_mtx);
return ret;
@@ -389,6 +379,7 @@ void sbflush(struct sockbuf *);
void sbrelease(struct socket *, struct sockbuf *);
int sbcheckreserve(u_long, u_long);
int sbchecklowmem(void);
+long sbspace_locked(struct sockbuf *);
int sbreserve(struct socket *, struct sockbuf *, u_long);
int sbwait(struct sockbuf *);
void soinit(void);
replace sbmtxassertlocked with MUTEX_ASSERT_LOCKED