Author: avos Date: Mon Oct 16 21:21:31 2017 New Revision: 324672 URL: https://svnweb.freebsd.org/changeset/base/324672
Log: ifnet(9): split ifc_alloc_unit() (should simplify code flow) Allocate smallest unit number from pool via ifc_alloc_unit_next() and exact unit number (if available) via ifc_alloc_unit_specific(). While here, address possible deadlock (mentioned in PR). PR: 217401 MFC after: 5 days Differential Revision: https://reviews.freebsd.org/D12551 Modified: head/sys/net/if_clone.c Modified: head/sys/net/if_clone.c ============================================================================== --- head/sys/net/if_clone.c Mon Oct 16 20:21:51 2017 (r324671) +++ head/sys/net/if_clone.c Mon Oct 16 21:21:31 2017 (r324672) @@ -595,44 +595,56 @@ ifc_name2unit(const char *name, int *unit) return (0); } -int -ifc_alloc_unit(struct if_clone *ifc, int *unit) +static int +ifc_alloc_unit_specific(struct if_clone *ifc, int *unit) { char name[IFNAMSIZ]; - int wildcard; - wildcard = (*unit < 0); -retry: if (*unit > ifc->ifc_maxunit) return (ENOSPC); - if (*unit < 0) { - *unit = alloc_unr(ifc->ifc_unrhdr); - if (*unit == -1) - return (ENOSPC); - } else { - *unit = alloc_unr_specific(ifc->ifc_unrhdr, *unit); - if (*unit == -1) { - if (wildcard) { - (*unit)++; - goto retry; - } else - return (EEXIST); - } - } + if (alloc_unr_specific(ifc->ifc_unrhdr, *unit) == -1) + return (EEXIST); + snprintf(name, IFNAMSIZ, "%s%d", ifc->ifc_name, *unit); if (ifunit(name) != NULL) { free_unr(ifc->ifc_unrhdr, *unit); - if (wildcard) { - (*unit)++; - goto retry; - } else - return (EEXIST); + return (EEXIST); } IF_CLONE_ADDREF(ifc); return (0); +} + +static int +ifc_alloc_unit_next(struct if_clone *ifc, int *unit) +{ + int error; + + *unit = alloc_unr(ifc->ifc_unrhdr); + if (*unit == -1) + return (ENOSPC); + + free_unr(ifc->ifc_unrhdr, *unit); + for (;;) { + error = ifc_alloc_unit_specific(ifc, unit); + if (error != EEXIST) + break; + + (*unit)++; + } + + return (error); +} + +int +ifc_alloc_unit(struct if_clone *ifc, int *unit) +{ + if (*unit < 0) + return (ifc_alloc_unit_next(ifc, unit)); + else + return (ifc_alloc_unit_specific(ifc, unit)); } void _______________________________________________ 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"