git: ca2a7262df5e - main - Free UMA zones when a pass(4) instance goes away.
Date: Thu, 13 Jan 2022 15:56:39 UTC
The branch main has been updated by ken:
URL: https://cgit.FreeBSD.org/src/commit/?id=ca2a7262df5ec5fd07d4ac61738947f48c9cd7f2
commit ca2a7262df5ec5fd07d4ac61738947f48c9cd7f2
Author: Kenneth D. Merry <ken@FreeBSD.org>
AuthorDate: 2022-01-13 15:50:40 +0000
Commit: Kenneth D. Merry <ken@FreeBSD.org>
CommitDate: 2022-01-13 15:54:56 +0000
Free UMA zones when a pass(4) instance goes away.
If the UMA zones are not freed, we get warnings about re-using the
sysctl variables associated with the UMA zones, and we're leaking
the other memory associated with the zone structures. e.g.:
sysctl_warn_reuse: can't re-use a leaf (vm.uma.pass44.size)!
sysctl_warn_reuse: can't re-use a leaf (vm.uma.pass44.flags)!
sysctl_warn_reuse: can't re-use a leaf (vm.uma.pass44.bucket_size)!
sysctl_warn_reuse: can't re-use a leaf (vm.uma.pass44.bucket_size_max)!
sysctl_warn_reuse: can't re-use a leaf (vm.uma.pass44.keg.name)!
sysctl_warn_reuse: can't re-use a leaf (vm.uma.pass44.keg.rsize)!
sysctl_warn_reuse: can't re-use a leaf (vm.uma.pass44.keg.ppera)!
sysctl_warn_reuse: can't re-use a leaf (vm.uma.pass44.keg.ipers)!
Also, correctly clear the PASS_FLAG_ZONE_INPROG flag in
passcreatezone(). The way it was previously done, it would have
had set the flag and cleared all other flags that were set at
that point.
MFC after: 1 week
Sponsored by: Spectra Logic
---
sys/cam/scsi/scsi_pass.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/sys/cam/scsi/scsi_pass.c b/sys/cam/scsi/scsi_pass.c
index 5d6febe74539..e74e19acc409 100644
--- a/sys/cam/scsi/scsi_pass.c
+++ b/sys/cam/scsi/scsi_pass.c
@@ -397,6 +397,18 @@ passcleanup(struct cam_periph *periph)
*/
taskqueue_drain(taskqueue_thread, &softc->add_physpath_task);
+ /*
+ * It should be safe to destroy the zones from here, because all
+ * of the references to this peripheral have been freed, and all
+ * I/O has been terminated and freed. We check the zones for NULL
+ * because they may not have been allocated yet if the device went
+ * away before any asynchronous I/O has been issued.
+ */
+ if (softc->pass_zone != NULL)
+ uma_zdestroy(softc->pass_zone);
+ if (softc->pass_io_zone != NULL)
+ uma_zdestroy(softc->pass_io_zone);
+
cam_periph_lock(periph);
free(softc, M_DEVBUF);
@@ -1073,7 +1085,7 @@ passcreatezone(struct cam_periph *periph)
/*
* Set the flags appropriately and notify any other waiters.
*/
- softc->flags &= PASS_FLAG_ZONE_INPROG;
+ softc->flags &= ~PASS_FLAG_ZONE_INPROG;
softc->flags |= PASS_FLAG_ZONE_VALID;
wakeup(&softc->pass_zone);
} else {