git: a76629cb0381 - main - kern: osd: stop downsizing arrays when the last slot deregisters
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 18 Aug 2023 04:09:17 UTC
The branch main has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=a76629cb0381ee1ccd9b233259ca8130a53b6583 commit a76629cb0381ee1ccd9b233259ca8130a53b6583 Author: Kyle Evans <kevans@FreeBSD.org> AuthorDate: 2023-08-18 04:05:55 +0000 Commit: Kyle Evans <kevans@FreeBSD.org> CommitDate: 2023-08-18 04:06:12 +0000 kern: osd: stop downsizing arrays when the last slot deregisters It was noted in D41404 that these reallocations aren't actually guaranteed to succeed, despite assertions to the contrary. We're talking relatively small allocations, so just free up the individual slot to be reused later as needed. Note that this doesn't track the last active slot as of this moment, but this could be done later if we find it's worth the complexity for what little that would allow to be optimized (osd_call, slightly). While we're here, fix the debug message that indicates which slot we just allocated when we find an unused one; the slot # is actually one higher than the index. Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D41409 --- sys/kern/kern_osd.c | 34 ++++++++++------------------------ 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/sys/kern/kern_osd.c b/sys/kern/kern_osd.c index 1b623d822cee..1f93f7021201 100644 --- a/sys/kern/kern_osd.c +++ b/sys/kern/kern_osd.c @@ -112,7 +112,7 @@ osd_register(u_int type, osd_destructor_t destructor, osd_method_t *methods) for (i = 0; i < osdm[type].osd_ntslots; i++) { if (osdm[type].osd_destructors[i] == NULL) { OSD_DEBUG("Unused slot found (type=%u, slot=%u).", - type, i); + type, i + 1); break; } } @@ -166,32 +166,18 @@ osd_deregister(u_int type, u_int slot) LIST_FOREACH_SAFE(osd, &osdm[type].osd_list, osd_next, tosd) do_osd_del(type, osd, slot, 1); mtx_unlock(&osdm[type].osd_list_lock); + /* - * Set destructor to NULL to free the slot. + * Set destructor to NULL to free the slot. We don't bother actually + * freeing any memory here because we'll gracefully reuse any freed + * slots, and reallocating the arrays as a smaller chunk of memory isn't + * actually guaranteed to succeed. As such, we'll err on the side of + * caution and just leave it be since these are generally modestly sized + * allocations. */ osdm[type].osd_destructors[slot - 1] = NULL; - if (slot == osdm[type].osd_ntslots) { - osdm[type].osd_ntslots--; - osdm[type].osd_destructors = realloc(osdm[type].osd_destructors, - sizeof(osd_destructor_t) * osdm[type].osd_ntslots, M_OSD, - M_NOWAIT | M_ZERO); - if (osdm[type].osd_nmethods != 0) - osdm[type].osd_methods = realloc(osdm[type].osd_methods, - sizeof(osd_method_t) * osdm[type].osd_ntslots * - osdm[type].osd_nmethods, M_OSD, M_NOWAIT | M_ZERO); - /* - * We always reallocate to smaller size, so we assume it will - * always succeed. - */ - KASSERT(osdm[type].osd_destructors != NULL && - (osdm[type].osd_nmethods == 0 || - osdm[type].osd_methods != NULL), ("realloc() failed")); - OSD_DEBUG("Deregistration of the last slot (type=%u, slot=%u).", - type, slot); - } else { - OSD_DEBUG("Slot deregistration (type=%u, slot=%u).", - type, slot); - } + OSD_DEBUG("Slot deregistration (type=%u, slot=%u).", type, slot); + rm_wunlock(&osdm[type].osd_object_lock); sx_xunlock(&osdm[type].osd_module_lock); }