This is a slightly tweaked version of the FRELE() memory barrier patch.
The barriers aim to provide clearer memory access behaviour around the
f_count 1->0 transition. With the barriers, the transition splits the
memory activity into preceding and succeeding stages that do not
overlap.
OK?
Index: share/man/man9/file.9
===================================================================
RCS file: src/share/man/man9/file.9,v
retrieving revision 1.22
diff -u -p -r1.22 file.9
--- share/man/man9/file.9 3 Jan 2020 05:37:00 -0000 1.22
+++ share/man/man9/file.9 13 Mar 2022 11:40:12 -0000
@@ -148,6 +148,14 @@ The function
.Fn FRELE
decreases the use count, and releases the file descriptor if the use count
becomes zero.
+.Pp
+.Fn FRELE
+provides release memory ordering.
+Prior memory loads and stores are completed before the use count is decreased.
+After the use count drops to zero,
+.Fn FRELE
+enforces acquire memory ordering so that the file release code sees all updates
+done during the lifetime of the file.
.Sh CODE REFERENCES
The majority of those functions are implemented in
.Pa sys/kern/kern_descrip.c .
Index: sys/kern/kern_descrip.c
===================================================================
RCS file: src/sys/kern/kern_descrip.c,v
retrieving revision 1.205
diff -u -p -r1.205 kern_descrip.c
--- sys/kern/kern_descrip.c 20 Jan 2022 11:06:57 -0000 1.205
+++ sys/kern/kern_descrip.c 13 Mar 2022 11:40:13 -0000
@@ -1268,7 +1268,12 @@ fdrop(struct file *fp, struct proc *p)
{
int error;
- KASSERTMSG(fp->f_count == 0, "count (%u) != 0", fp->f_count);
+ membar_exit_before_atomic();
+ if (atomic_dec_int_nv(&fp->f_count) > 0)
+ return 0;
+
+ /* Provide acquire ordering after f_count 1->0 transition. */
+ membar_enter_after_atomic();
mtx_enter(&fhdlk);
if (fp->f_iflags & FIF_INSERTED)
Index: sys/sys/file.h
===================================================================
RCS file: src/sys/sys/file.h,v
retrieving revision 1.65
diff -u -p -r1.65 file.h
--- sys/sys/file.h 20 Jan 2022 03:43:31 -0000 1.65
+++ sys/sys/file.h 13 Mar 2022 11:40:13 -0000
@@ -113,8 +113,7 @@ struct file {
atomic_inc_int(&(fp)->f_count); \
} while (0)
-#define FRELE(fp,p) \
- (atomic_dec_int_nv(&fp->f_count) == 0 ? fdrop(fp, p) : 0)
+#define FRELE(fp, p) fdrop(fp, p)
#define FDUP_MAX_COUNT (UINT_MAX - 2 * MAXCPUS)