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)