Date: Sat, 21 Oct 2017 10:48:06 +0000 (UTC) From: Andriy Voskoboinyk <avos@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r324813 - stable/10/sys/net Message-ID: <201710211048.v9LAm60P099737@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: avos Date: Sat Oct 21 10:48:06 2017 New Revision: 324813 URL: https://svnweb.freebsd.org/changeset/base/324813 Log: MFC r324672: 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 Differential Revision: https://reviews.freebsd.org/D12551 Modified: stable/10/sys/net/if_clone.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/net/if_clone.c ============================================================================== --- stable/10/sys/net/if_clone.c Sat Oct 21 10:21:34 2017 (r324812) +++ stable/10/sys/net/if_clone.c Sat Oct 21 10:48:06 2017 (r324813) @@ -602,44 +602,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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201710211048.v9LAm60P099737>