Download raw body.
replace sbmtxassertlocked with MUTEX_ASSERT_LOCKED
On Fri, Feb 14, 2025 at 01:44:08AM +0100, Alexander Bluhm wrote:
> On Fri, Feb 14, 2025 at 02:11:32AM +0300, Vitaliy Makkoveev wrote:
> > > On 14 Feb 2025, at 01:29, Alexander Bluhm <bluhm@openbsd.org> wrote:
> > >
> > > 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().
> > >
> >
> > As you said, sbspace_locked() is trivial, do we really need assertion
> > within?
>
> The assertion is not about the trivial code in sbspace_locked(),
> but the code that is calling it. And not in all callers it is
> obvious that the mutex is held.
>
> On the other hand, there are a lot of locking assertions around.
> Not sure if we need all of them.
>
> I am undecided. I tried both ways and ended with this diff.
>
This could be something trivial like below. I introduced mtx_owned()
specially for sbmtxassertlocked() so it could go too.
I tested it with and without DIAGNOSTIC
Index: sys/kern/uipc_socket2.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_socket2.c,v
diff -u -p -r1.178 uipc_socket2.c
--- sys/kern/uipc_socket2.c 13 Feb 2025 14:44:33 -0000 1.178
+++ sys/kern/uipc_socket2.c 14 Feb 2025 09:40:17 -0000
@@ -502,12 +502,13 @@ sosleep_nsec(struct socket *so, void *id
return ret;
}
+#ifdef DIAGNOSTIC
void
sbmtxassertlocked(struct sockbuf *sb)
{
- if (splassert_ctl > 0 && mtx_owned(&sb->sb_mtx) == 0)
- splassert_fail(0, RW_WRITE, __func__);
+ MUTEX_ASSERT_LOCKED(&sb->sb_mtx);
}
+#endif
/*
* Wait for data to arrive at/drain from a socket buffer.
Index: sys/sys/mutex.h
===================================================================
RCS file: /cvs/src/sys/sys/mutex.h,v
diff -u -p -r1.22 mutex.h
--- sys/sys/mutex.h 16 May 2024 09:30:03 -0000 1.22
+++ sys/sys/mutex.h 14 Feb 2025 09:40:18 -0000
@@ -127,9 +127,6 @@ 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/socketvar.h
===================================================================
RCS file: /cvs/src/sys/sys/socketvar.h,v
diff -u -p -r1.150 socketvar.h
--- sys/sys/socketvar.h 13 Feb 2025 14:44:33 -0000 1.150
+++ sys/sys/socketvar.h 14 Feb 2025 09:40:18 -0000
@@ -224,7 +224,11 @@ 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)
+#ifdef DIAGNOSTIC
void sbmtxassertlocked(struct sockbuf *);
+#else
+#define sbmtxassertlocked(sb) do { (void)(sb); } while(0)
+#endif
/*
* Do we need to notify the other side when I/O is possible?
replace sbmtxassertlocked with MUTEX_ASSERT_LOCKED