Page MenuHomeFreeBSD

D60658.id.diff
No OneTemporary

D60658.id.diff

diff --git a/sys/kern/kern_rmlock.c b/sys/kern/kern_rmlock.c
--- a/sys/kern/kern_rmlock.c
+++ b/sys/kern/kern_rmlock.c
@@ -875,7 +875,9 @@
*
* Neither rms_rlock nor rms_runlock use thread fences. Instead interrupt
* fences are inserted to ensure ordering with the code executed in the IPI
- * handler.
+ * handler. Writers interrupt all CPUs both to block readers and to unblock
+ * them, so a reader that sees no writer also sees what the last writer
+ * stored.
*
* No attempt is made to track which CPUs read locked at least once,
* consequently write locking sends IPIs to all of them. This will become a
@@ -1171,7 +1173,7 @@
#endif
static void
-rms_wlock_switch(struct rmslock *rms)
+rms_block_readers(struct rmslock *rms)
{
struct rmslock_ipi rmsipi;
@@ -1188,6 +1190,19 @@
&rmsipi.srcra);
}
+/*
+ * Order the writer's stores before the count readers check without a fence.
+ */
+static void
+rms_unblock_readers(struct rmslock *rms)
+{
+
+ MPASS(rms->readers == 0);
+ MPASS(rms->writers == 1);
+
+ cpus_fence_seq_cst();
+}
+
void
rms_wlock(struct rmslock *rms)
{
@@ -1210,7 +1225,7 @@
KASSERT(rms->owner == RMS_NOOWNER,
("%s: unexpected owner value %p\n", __func__, rms->owner));
- rms_wlock_switch(rms);
+ rms_block_readers(rms);
rms_assert_no_pcpu_readers(rms);
if (rms->readers > 0) {
@@ -1235,6 +1250,8 @@
("%s: unexpected owner value %p\n", __func__, rms->owner));
MPASS(rms->writers >= 1);
MPASS(rms->readers == 0);
+ if (rms->writers == 1)
+ rms_unblock_readers(rms);
rms->writers--;
if (rms->writers > 0) {
wakeup_one(&rms->owner);

File Metadata

Mime Type
text/plain
Expires
Fri, Oct 16, 12:02 PM (15 h, 41 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40768611
Default Alt Text
D60658.id.diff (1 KB)

Event Timeline