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)
 

Reply via email to