Module Name: src Committed By: riastradh Date: Thu Feb 23 02:58:28 UTC 2023
Modified Files: src/sys/kern: kern_descrip.c Log Message: kern_descrip.c: Fix membars around reference count decrement. In general, the `last one out hit the lights' style of reference counting (as opposed to the `whoever's destroying must wait for pending users to finish' style) requires memory barriers like so: ... usage of resources associated with object ... membar_release(); if (atomic_dec_uint_nv(&obj->refcnt) != 0) return; membar_acquire(); ... freeing of resources associated with object ... This way, all usage happens-before all freeing. This fixes several errors: - fd_close failed to ensure whatever its caller did would happen-before the freeing, in the case where another thread is concurrently trying to close the fd (ff->ff_file == NULL). Fix: Add membar_release before atomic_dec_uint(&ff->ff_refcnt) in that branch. - fd_close failed to ensure all loads its caller had issued will have happened-before the freeing, in the case where the fd is still in use by another thread (fdp->fd_refcnt > 1 and ff->ff_refcnt-- > 0). Fix: Change membar_producer to membar_release before atomic_dec_uint(&ff->ff_refcnt). - fd_close failed to ensure that any usage of fp by other callers would happen-before any freeing it does. Fix: Add membar_acquire after atomic_dec_uint_nv(&ff->ff_refcnt). - fd_free failed to ensure that any usage of fdp by other callers would happen-before any freeing it does. Fix: Add membar_acquire after atomic_dec_uint_nv(&fdp->fd_refcnt). While here, change membar_exit -> membar_release. No semantic change, just updating away from the legacy API. XXX pullup-8 XXX pullup-9 XXX pullup-10 To generate a diff of this commit: cvs rdiff -u -r1.251 -r1.252 src/sys/kern/kern_descrip.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/kern_descrip.c diff -u src/sys/kern/kern_descrip.c:1.251 src/sys/kern/kern_descrip.c:1.252 --- src/sys/kern/kern_descrip.c:1.251 Tue Jun 29 22:40:53 2021 +++ src/sys/kern/kern_descrip.c Thu Feb 23 02:58:28 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_descrip.c,v 1.251 2021/06/29 22:40:53 dholland Exp $ */ +/* $NetBSD: kern_descrip.c,v 1.252 2023/02/23 02:58:28 riastradh Exp $ */ /*- * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. @@ -70,7 +70,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_descrip.c,v 1.251 2021/06/29 22:40:53 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_descrip.c,v 1.252 2023/02/23 02:58:28 riastradh Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -451,7 +451,7 @@ fd_putfile(unsigned fd) * CPU. */ #ifndef __HAVE_ATOMIC_AS_MEMBAR - membar_exit(); + membar_release(); #endif /* @@ -602,6 +602,9 @@ fd_close(unsigned fd) * waiting for other users of the file to drain. Release * our reference, and wake up the closer. */ +#ifndef __HAVE_ATOMIC_AS_MEMBAR + membar_release(); +#endif atomic_dec_uint(&ff->ff_refcnt); cv_broadcast(&ff->ff_closing); mutex_exit(&fdp->fd_lock); @@ -637,9 +640,12 @@ fd_close(unsigned fd) } else { /* Multi threaded. */ #ifndef __HAVE_ATOMIC_AS_MEMBAR - membar_producer(); + membar_release(); #endif refcnt = atomic_dec_uint_nv(&ff->ff_refcnt); +#ifndef __HAVE_ATOMIC_AS_MEMBAR + membar_acquire(); +#endif } if (__predict_false(refcnt != 0)) { /* @@ -1532,10 +1538,13 @@ fd_free(void) KASSERT(fdp->fd_dtbuiltin.dt_link == NULL); #ifndef __HAVE_ATOMIC_AS_MEMBAR - membar_exit(); + membar_release(); #endif if (atomic_dec_uint_nv(&fdp->fd_refcnt) > 0) return; +#ifndef __HAVE_ATOMIC_AS_MEMBAR + membar_acquire(); +#endif /* * Close any files that the process holds open.