Author: jamie Date: Mon Mar 28 22:18:37 2016 New Revision: 297367 URL: https://svnweb.freebsd.org/changeset/base/297367
Log: Move the various per-type arrays of OSD data into a single structure array. Modified: head/sys/kern/kern_osd.c Modified: head/sys/kern/kern_osd.c ============================================================================== --- head/sys/kern/kern_osd.c Mon Mar 28 21:51:56 2016 (r297366) +++ head/sys/kern/kern_osd.c Mon Mar 28 22:18:37 2016 (r297367) @@ -44,6 +44,23 @@ __FBSDID("$FreeBSD$"); /* OSD (Object Specific Data) */ +/* + * Lock key: + * (m) osd_module_lock + * (o) osd_object_lock + * (l) osd_list_lock + */ +struct osd_master { + struct sx osd_module_lock; + struct rmlock osd_object_lock; + struct mtx osd_list_lock; + LIST_HEAD(, osd) osd_list; /* (m) */ + osd_destructor_t *osd_destructors; /* (o) */ + osd_method_t *osd_methods; /* (m) */ + u_int osd_ntslots; /* (m) */ + const u_int osd_nmethods; +}; + static MALLOC_DEFINE(M_OSD, "osd", "Object Specific Data"); static int osd_debug = 0; @@ -61,25 +78,12 @@ static void do_osd_del(u_int type, struc int list_locked); /* - * Lists of objects with OSD. - * - * Lock key: - * (m) osd_module_lock - * (o) osd_object_lock - * (l) osd_list_lock + * List of objects with OSD. */ -static LIST_HEAD(, osd) osd_list[OSD_LAST + 1]; /* (m) */ -static osd_method_t *osd_methods[OSD_LAST + 1]; /* (m) */ -static u_int osd_nslots[OSD_LAST + 1]; /* (m) */ -static osd_destructor_t *osd_destructors[OSD_LAST + 1]; /* (o) */ -static const u_int osd_nmethods[OSD_LAST + 1] = { - [OSD_JAIL] = PR_MAXMETHOD, +struct osd_master osdm[OSD_LAST + 1] = { + [OSD_JAIL] = { .osd_nmethods = PR_MAXMETHOD }, }; -static struct sx osd_module_lock[OSD_LAST + 1]; -static struct rmlock osd_object_lock[OSD_LAST + 1]; -static struct mtx osd_list_lock[OSD_LAST + 1]; - static void osd_default_destructor(void *value __unused) { @@ -101,12 +105,12 @@ osd_register(u_int type, osd_destructor_ if (destructor == NULL) destructor = osd_default_destructor; - sx_xlock(&osd_module_lock[type]); + sx_xlock(&osdm[type].osd_module_lock); /* * First, we try to find unused slot. */ - for (i = 0; i < osd_nslots[type]; i++) { - if (osd_destructors[type][i] == NULL) { + 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); break; @@ -115,31 +119,31 @@ osd_register(u_int type, osd_destructor_ /* * If no unused slot was found, allocate one. */ - if (i == osd_nslots[type]) { - osd_nslots[type]++; - if (osd_nmethods[type] != 0) - osd_methods[type] = realloc(osd_methods[type], - sizeof(osd_method_t) * osd_nslots[type] * - osd_nmethods[type], M_OSD, M_WAITOK); - newptr = malloc(sizeof(osd_destructor_t) * osd_nslots[type], - M_OSD, M_WAITOK); - rm_wlock(&osd_object_lock[type]); - bcopy(osd_destructors[type], newptr, + if (i == osdm[type].osd_ntslots) { + osdm[type].osd_ntslots++; + 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_WAITOK); + newptr = malloc(sizeof(osd_destructor_t) * + osdm[type].osd_ntslots, M_OSD, M_WAITOK); + rm_wlock(&osdm[type].osd_object_lock); + bcopy(osdm[type].osd_destructors, newptr, sizeof(osd_destructor_t) * i); - free(osd_destructors[type], M_OSD); - osd_destructors[type] = newptr; - rm_wunlock(&osd_object_lock[type]); + free(osdm[type].osd_destructors, M_OSD); + osdm[type].osd_destructors = newptr; + rm_wunlock(&osdm[type].osd_object_lock); OSD_DEBUG("New slot allocated (type=%u, slot=%u).", type, i + 1); } - osd_destructors[type][i] = destructor; - if (osd_nmethods[type] != 0) { - for (m = 0; m < osd_nmethods[type]; m++) - osd_methods[type][i * osd_nmethods[type] + m] = - methods != NULL ? methods[m] : NULL; + osdm[type].osd_destructors[i] = destructor; + if (osdm[type].osd_nmethods != 0) { + for (m = 0; m < osdm[type].osd_nmethods; m++) + osdm[type].osd_methods[i * osdm[type].osd_nmethods + m] + = methods != NULL ? methods[m] : NULL; } - sx_xunlock(&osd_module_lock[type]); + sx_xunlock(&osdm[type].osd_module_lock); return (i + 1); } @@ -150,45 +154,45 @@ osd_deregister(u_int type, u_int slot) KASSERT(type >= OSD_FIRST && type <= OSD_LAST, ("Invalid type.")); KASSERT(slot > 0, ("Invalid slot.")); - KASSERT(osd_destructors[type][slot - 1] != NULL, ("Unused slot.")); + KASSERT(osdm[type].osd_destructors[slot - 1] != NULL, ("Unused slot.")); - sx_xlock(&osd_module_lock[type]); - rm_wlock(&osd_object_lock[type]); + sx_xlock(&osdm[type].osd_module_lock); + rm_wlock(&osdm[type].osd_object_lock); /* * Free all OSD for the given slot. */ - mtx_lock(&osd_list_lock[type]); - LIST_FOREACH_SAFE(osd, &osd_list[type], osd_next, tosd) + mtx_lock(&osdm[type].osd_list_lock); + LIST_FOREACH_SAFE(osd, &osdm[type].osd_list, osd_next, tosd) do_osd_del(type, osd, slot, 1); - mtx_unlock(&osd_list_lock[type]); + mtx_unlock(&osdm[type].osd_list_lock); /* * Set destructor to NULL to free the slot. */ - osd_destructors[type][slot - 1] = NULL; - if (slot == osd_nslots[type]) { - osd_nslots[type]--; - osd_destructors[type] = realloc(osd_destructors[type], - sizeof(osd_destructor_t) * osd_nslots[type], M_OSD, + 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 (osd_nmethods[type] != 0) - osd_methods[type] = realloc(osd_methods[type], - sizeof(osd_method_t) * osd_nslots[type] * - osd_nmethods[type], 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(osd_destructors[type] != NULL && - (osd_nmethods[type] == 0 || osd_methods[type] != NULL), - ("realloc() failed")); + 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); } - rm_wunlock(&osd_object_lock[type]); - sx_xunlock(&osd_module_lock[type]); + rm_wunlock(&osdm[type].osd_object_lock); + sx_xunlock(&osdm[type].osd_module_lock); } int @@ -198,15 +202,15 @@ osd_set(u_int type, struct osd *osd, u_i KASSERT(type >= OSD_FIRST && type <= OSD_LAST, ("Invalid type.")); KASSERT(slot > 0, ("Invalid slot.")); - KASSERT(osd_destructors[type][slot - 1] != NULL, ("Unused slot.")); + KASSERT(osdm[type].osd_destructors[slot - 1] != NULL, ("Unused slot.")); - rm_rlock(&osd_object_lock[type], &tracker); + rm_rlock(&osdm[type].osd_object_lock, &tracker); if (slot > osd->osd_nslots) { if (value == NULL) { OSD_DEBUG( "Not allocating null slot (type=%u, slot=%u).", type, slot); - rm_runlock(&osd_object_lock[type], &tracker); + rm_runlock(&osdm[type].osd_object_lock, &tracker); return (0); } else if (osd->osd_nslots == 0) { /* @@ -216,13 +220,14 @@ osd_set(u_int type, struct osd *osd, u_i osd->osd_slots = malloc(sizeof(void *) * slot, M_OSD, M_NOWAIT | M_ZERO); if (osd->osd_slots == NULL) { - rm_runlock(&osd_object_lock[type], &tracker); + rm_runlock(&osdm[type].osd_object_lock, + &tracker); return (ENOMEM); } osd->osd_nslots = slot; - mtx_lock(&osd_list_lock[type]); - LIST_INSERT_HEAD(&osd_list[type], osd, osd_next); - mtx_unlock(&osd_list_lock[type]); + mtx_lock(&osdm[type].osd_list_lock); + LIST_INSERT_HEAD(&osdm[type].osd_list, osd, osd_next); + mtx_unlock(&osdm[type].osd_list_lock); OSD_DEBUG("Setting first slot (type=%u).", type); } else { void *newptr; @@ -234,7 +239,8 @@ osd_set(u_int type, struct osd *osd, u_i newptr = realloc(osd->osd_slots, sizeof(void *) * slot, M_OSD, M_NOWAIT | M_ZERO); if (newptr == NULL) { - rm_runlock(&osd_object_lock[type], &tracker); + rm_runlock(&osdm[type].osd_object_lock, + &tracker); return (ENOMEM); } osd->osd_slots = newptr; @@ -245,7 +251,7 @@ osd_set(u_int type, struct osd *osd, u_i OSD_DEBUG("Setting slot value (type=%u, slot=%u, value=%p).", type, slot, value); osd->osd_slots[slot - 1] = value; - rm_runlock(&osd_object_lock[type], &tracker); + rm_runlock(&osdm[type].osd_object_lock, &tracker); return (0); } @@ -257,9 +263,9 @@ osd_get(u_int type, struct osd *osd, u_i KASSERT(type >= OSD_FIRST && type <= OSD_LAST, ("Invalid type.")); KASSERT(slot > 0, ("Invalid slot.")); - KASSERT(osd_destructors[type][slot - 1] != NULL, ("Unused slot.")); + KASSERT(osdm[type].osd_destructors[slot - 1] != NULL, ("Unused slot.")); - rm_rlock(&osd_object_lock[type], &tracker); + rm_rlock(&osdm[type].osd_object_lock, &tracker); if (slot > osd->osd_nslots) { value = NULL; OSD_DEBUG("Slot doesn't exist (type=%u, slot=%u).", type, slot); @@ -268,7 +274,7 @@ osd_get(u_int type, struct osd *osd, u_i OSD_DEBUG("Returning slot value (type=%u, slot=%u, value=%p).", type, slot, value); } - rm_runlock(&osd_object_lock[type], &tracker); + rm_runlock(&osdm[type].osd_object_lock, &tracker); return (value); } @@ -277,9 +283,9 @@ osd_del(u_int type, struct osd *osd, u_i { struct rm_priotracker tracker; - rm_rlock(&osd_object_lock[type], &tracker); + rm_rlock(&osdm[type].osd_object_lock, &tracker); do_osd_del(type, osd, slot, 0); - rm_runlock(&osd_object_lock[type], &tracker); + rm_runlock(&osdm[type].osd_object_lock, &tracker); } static void @@ -289,7 +295,7 @@ do_osd_del(u_int type, struct osd *osd, KASSERT(type >= OSD_FIRST && type <= OSD_LAST, ("Invalid type.")); KASSERT(slot > 0, ("Invalid slot.")); - KASSERT(osd_destructors[type][slot - 1] != NULL, ("Unused slot.")); + KASSERT(osdm[type].osd_destructors[slot - 1] != NULL, ("Unused slot.")); OSD_DEBUG("Deleting slot (type=%u, slot=%u).", type, slot); @@ -298,7 +304,7 @@ do_osd_del(u_int type, struct osd *osd, return; } if (osd->osd_slots[slot - 1] != NULL) { - osd_destructors[type][slot - 1](osd->osd_slots[slot - 1]); + osdm[type].osd_destructors[slot - 1](osd->osd_slots[slot - 1]); osd->osd_slots[slot - 1] = NULL; } for (i = osd->osd_nslots - 1; i >= 0; i--) { @@ -312,10 +318,10 @@ do_osd_del(u_int type, struct osd *osd, /* No values left for this object. */ OSD_DEBUG("No more slots left (type=%u).", type); if (!list_locked) - mtx_lock(&osd_list_lock[type]); + mtx_lock(&osdm[type].osd_list_lock); LIST_REMOVE(osd, osd_next); if (!list_locked) - mtx_unlock(&osd_list_lock[type]); + mtx_unlock(&osdm[type].osd_list_lock); free(osd->osd_slots, M_OSD); osd->osd_slots = NULL; osd->osd_nslots = 0; @@ -341,21 +347,21 @@ osd_call(u_int type, u_int method, void int error, i; KASSERT(type >= OSD_FIRST && type <= OSD_LAST, ("Invalid type.")); - KASSERT(method < osd_nmethods[type], ("Invalid method.")); + KASSERT(method < osdm[type].osd_nmethods, ("Invalid method.")); /* * Call this method for every slot that defines it, stopping if an * error is encountered. */ error = 0; - sx_slock(&osd_module_lock[type]); - for (i = 0; i < osd_nslots[type]; i++) { - methodfun = - osd_methods[type][i * osd_nmethods[type] + method]; + sx_slock(&osdm[type].osd_module_lock); + for (i = 0; i < osdm[type].osd_ntslots; i++) { + methodfun = osdm[type].osd_methods[i * osdm[type].osd_nmethods + + method]; if (methodfun != NULL && (error = methodfun(obj, data)) != 0) break; } - sx_sunlock(&osd_module_lock[type]); + sx_sunlock(&osdm[type].osd_module_lock); return (error); } @@ -373,14 +379,14 @@ osd_exit(u_int type, struct osd *osd) return; } - rm_rlock(&osd_object_lock[type], &tracker); + rm_rlock(&osdm[type].osd_object_lock, &tracker); for (i = 1; i <= osd->osd_nslots; i++) { - if (osd_destructors[type][i - 1] != NULL) + if (osdm[type].osd_destructors[i - 1] != NULL) do_osd_del(type, osd, i, 0); else OSD_DEBUG("Unused slot (type=%u, slot=%u).", type, i); } - rm_runlock(&osd_object_lock[type], &tracker); + rm_runlock(&osdm[type].osd_object_lock, &tracker); OSD_DEBUG("Object exit (type=%u).", type); } @@ -390,13 +396,13 @@ osd_init(void *arg __unused) u_int i; for (i = OSD_FIRST; i <= OSD_LAST; i++) { - osd_nslots[i] = 0; - LIST_INIT(&osd_list[i]); - sx_init(&osd_module_lock[i], "osd_module"); - rm_init(&osd_object_lock[i], "osd_object"); - mtx_init(&osd_list_lock[i], "osd_list", NULL, MTX_DEF); - osd_destructors[i] = NULL; - osd_methods[i] = NULL; + sx_init(&osdm[i].osd_module_lock, "osd_module"); + rm_init(&osdm[i].osd_object_lock, "osd_object"); + mtx_init(&osdm[i].osd_list_lock, "osd_list", NULL, MTX_DEF); + LIST_INIT(&osdm[i].osd_list); + osdm[i].osd_destructors = NULL; + osdm[i].osd_ntslots = 0; + osdm[i].osd_methods = NULL; } } SYSINIT(osd, SI_SUB_LOCK, SI_ORDER_ANY, osd_init, NULL); _______________________________________________ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"