pserialize(9): Lift rule that pserialize_perform be serialized.

There may have been a technical reason for this back when we were
following the expired passive serialization patent to the letter, but
no more -- and this is a real burden for some applications.
This commit is contained in:
riastradh 2021-10-10 11:20:46 +00:00
parent 1ca2737798
commit 97eadbd13e
2 changed files with 12 additions and 18 deletions

View File

@ -1,4 +1,4 @@
.\" $NetBSD: pserialize.9,v 1.13 2017/07/03 21:28:48 wiz Exp $
.\" $NetBSD: pserialize.9,v 1.14 2021/10/10 11:20:46 riastradh Exp $
.\"
.\" Copyright (c) 2011 The NetBSD Foundation, Inc.
.\" All rights reserved.
@ -67,9 +67,10 @@ Takes the IPL value returned by
.It Fn pserialize_perform
Perform the passive serialization on the writer side.
Passing of this function ensures that no readers are in action.
Writers must be additionally serialized with a separate mechanism,
e.g.
.Xr mutex 9 .
Writers are typically additionally serialized with a separate
mechanism, e.g.
.Xr mutex 9 ,
to remove objects used by readers from a published list.
Operation blocks and it may only be performed from thread context.
.El
.\" -----
@ -152,14 +153,15 @@ readers:
break;
}
}
mutex_exit(&frobbotzim.lock);
/*
* Wait for all existing readers to complete. New readers will
* not see f because the list no longer points to it.
*/
pserialize_perform(frobbotzim.psz);
/* Now nobody else can be touching f, so it is safe to free. */
mutex_exit(&frobbotzim.lock);
/* Now nobody else can be touching f, so it is safe to free. */
if (f != NULL)
pool_put(&frotz_pool, f);
.Ed

View File

@ -1,4 +1,4 @@
/* $NetBSD: subr_pserialize.c,v 1.17 2019/12/05 03:21:29 riastradh Exp $ */
/* $NetBSD: subr_pserialize.c,v 1.18 2021/10/10 11:20:46 riastradh Exp $ */
/*-
* Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: subr_pserialize.c,v 1.17 2019/12/05 03:21:29 riastradh Exp $");
__KERNEL_RCSID(0, "$NetBSD: subr_pserialize.c,v 1.18 2021/10/10 11:20:46 riastradh Exp $");
#include <sys/param.h>
#include <sys/atomic.h>
@ -43,7 +43,7 @@ __KERNEL_RCSID(0, "$NetBSD: subr_pserialize.c,v 1.17 2019/12/05 03:21:29 riastra
#include <sys/xcall.h>
struct pserialize {
lwp_t * psz_owner;
char psz_dummy;
};
static kmutex_t psz_lock __cacheline_aligned;
@ -86,16 +86,13 @@ void
pserialize_destroy(pserialize_t psz)
{
KASSERT(psz->psz_owner == NULL);
kmem_free(psz, sizeof(*psz));
}
/*
* pserialize_perform:
*
* Perform the write side of passive serialization. This operation
* MUST be serialized at a caller level (e.g. with a mutex or by a
* single-threaded use).
* Perform the write side of passive serialization.
*/
void
pserialize_perform(pserialize_t psz)
@ -107,22 +104,17 @@ pserialize_perform(pserialize_t psz)
if (__predict_false(panicstr != NULL)) {
return;
}
KASSERT(psz->psz_owner == NULL);
if (__predict_false(mp_online == false)) {
psz_ev_excl.ev_count++;
return;
}
psz->psz_owner = curlwp;
/*
* Broadcast a NOP to all CPUs and wait until all of them complete.
*/
xc_barrier(XC_HIGHPRI);
KASSERT(psz->psz_owner == curlwp);
psz->psz_owner = NULL;
mutex_enter(&psz_lock);
psz_ev_excl.ev_count++;
mutex_exit(&psz_lock);