From nobody Mon Dec 06 17:32:48 2021 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 5A56A18C4D1A; Mon, 6 Dec 2021 17:32:50 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4J79Vm743Fz3jXZ; Mon, 6 Dec 2021 17:32:48 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id AF83C7F2A; Mon, 6 Dec 2021 17:32:48 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 1B6HWmZm068582; Mon, 6 Dec 2021 17:32:48 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 1B6HWmbl068581; Mon, 6 Dec 2021 17:32:48 GMT (envelope-from git) Date: Mon, 6 Dec 2021 17:32:48 GMT Message-Id: <202112061732.1B6HWmbl068581@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Gleb Smirnoff Subject: git: 7b40b00fad16 - main - ifnet: merge ifindex_alloc(), ifnet_setbyindex(), if_grow() and call magic List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: glebius X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 7b40b00fad1606eaa98a7b116ba8651221d55f62 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1638811969; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Ehqt3FKgZNLlpfxGAU4mIbPeg8W6U1pyOtyXFbYhFpk=; b=GQDRCX2nA63sifDhHSHmPaSg4UVQB5qbhJuz75vy9ozHON7XqNE9Jgnx892xNAC4ID1bfK QzOszTG1iycSobUOD8fJcKXeTlKpBNmZeLZtzyV2Zz5PbTNnLJM7BoDc7WMPUGjlFz54WP 7XtT9WySH0Y3+ZYZf/hjZK7Kzc7e9A1BDQ720p9PTlGm+9XqKRDx/PfZj/BnNPDRmdvEPX wuE9GFJxFT0USzDWIC3/UvI7eQ5dFRadCSdZ3KJcc9Tr0cpEjGxz3jpl1sGas3SjFbcBLM vElXeglP8/ysPlSlWWYysCdf/ummKcvlaCav44yJ+VKDvqMGmmF16Bfhr7CGvg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1638811969; a=rsa-sha256; cv=none; b=ZJjGNYq17Myhvo8oMbcwsvaWBZ8aHjfy2M9Wm7cGNtIE5c5BgjvV5hsoJgftFGDAxU+rtW TzrQvLGAi3KAWTaN9Z7XX6xNFG9KPbS3B/FnKEcQljiu73bHVt8vmJeBCLIcZNaNK5GHuT QZG8UiSrJRsWgI+sXF7uPlcW1UiEtN2M022ri6uqNnwlFTvx8dJvEnlFcRw8/5BdAflw7W mqBoBmu9a78EITzKpJJVieGqKaDMzUgAqFS9Br/z0VALiWT1LNVjr7yQVdo2WIKRbjM4eF g69C7AKg1vG/jW2jzPR1Ga5TVqoVfv9LeZlFqVYQOdR7dkGV5NoIP5eBroxozw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by glebius: URL: https://cgit.FreeBSD.org/src/commit/?id=7b40b00fad1606eaa98a7b116ba8651221d55f62 commit 7b40b00fad1606eaa98a7b116ba8651221d55f62 Author: Gleb Smirnoff AuthorDate: 2021-12-04 17:49:35 +0000 Commit: Gleb Smirnoff CommitDate: 2021-12-06 17:32:31 +0000 ifnet: merge ifindex_alloc(), ifnet_setbyindex(), if_grow() and call magic Now it is possible to just merge all this complexity into single linear function. Note that IFNET_WLOCK() is a sleepable lock, so we can M_WAITOK and epoch_wait_preempt(). Reviewed by: melifaro, bz, kp Differential revision: https://reviews.freebsd.org/D33262 --- sys/net/if.c | 95 ++++++++++++++---------------------------------------------- 1 file changed, 21 insertions(+), 74 deletions(-) diff --git a/sys/net/if.c b/sys/net/if.c index 079ad734812b..ad6d0bcf827a 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -273,7 +273,6 @@ struct mbuf *(*tbr_dequeue_ptr)(struct ifaltq *, int) = NULL; static void if_attachdomain(void *); static void if_attachdomain1(struct ifnet *); static int ifconf(u_long, caddr_t); -static void *if_grow(void); static void if_input_default(struct ifnet *, struct mbuf *); static int if_requestencap_default(struct ifnet *, struct if_encap_req *); static void if_route(struct ifnet *, int flag, int fam); @@ -369,15 +368,14 @@ ifnet_byindex_ref(u_short idx) } /* - * Allocate an ifindex array entry; return 0 on success or an error on - * failure. + * Allocate an ifindex array entry. */ -static u_short -ifindex_alloc(void **old) +static void +ifindex_alloc(struct ifnet *ifp) { u_short idx; - IFNET_WLOCK_ASSERT(); + IFNET_WLOCK(); /* * Try to find an empty slot below V_if_index. If we fail, take the * next slot. @@ -389,12 +387,24 @@ ifindex_alloc(void **old) /* Catch if_index overflow. */ if (idx >= V_if_indexlim) { - *old = if_grow(); - return (USHRT_MAX); + struct ifnet **new, **old; + int newlim; + + newlim = V_if_indexlim * 2; + new = malloc(newlim * sizeof(*new), M_IFNET, M_WAITOK | M_ZERO); + memcpy(new, V_ifindex_table, V_if_indexlim * sizeof(*new)); + old = V_ifindex_table; + ck_pr_store_ptr(&V_ifindex_table, new); + V_if_indexlim = newlim; + epoch_wait_preempt(net_epoch_preempt); + free(old, M_IFNET); } if (idx > V_if_index) V_if_index = idx; - return (idx); + + ifp->if_index = idx; + ck_pr_store_ptr(&V_ifindex_table[idx], ifp); + IFNET_WUNLOCK(); } static void @@ -409,14 +419,6 @@ ifindex_free(u_short idx) V_if_index--; } -static void -ifnet_setbyindex(u_short idx, struct ifnet *ifp) -{ - - ifp->if_index = idx; - ck_pr_store_ptr(&V_ifindex_table[idx], ifp); -} - struct ifaddr * ifaddr_byindex(u_short idx) { @@ -549,34 +551,6 @@ VNET_SYSUNINIT(vnet_if_return, SI_SUB_VNET_DONE, SI_ORDER_ANY, vnet_if_return, NULL); #endif -static void * -if_grow(void) -{ - int oldlim; - u_int n; - struct ifnet **e; - void *old; - - old = NULL; - IFNET_WLOCK_ASSERT(); - oldlim = V_if_indexlim; - IFNET_WUNLOCK(); - n = (oldlim << 1) * sizeof(*e); - e = malloc(n, M_IFNET, M_WAITOK | M_ZERO); - IFNET_WLOCK(); - if (V_if_indexlim != oldlim) { - free(e, M_IFNET); - return (NULL); - } - if (V_ifindex_table != NULL) { - memcpy((caddr_t)e, (caddr_t)V_ifindex_table, n/2); - old = V_ifindex_table; - } - V_if_indexlim <<= 1; - V_ifindex_table = e; - return (old); -} - /* * Allocate a struct ifnet and an index for an interface. A layer 2 * common structure will also be allocated if an allocation routine is @@ -586,8 +560,6 @@ static struct ifnet * if_alloc_domain(u_char type, int numa_domain) { struct ifnet *ifp; - u_short idx; - void *old; KASSERT(numa_domain <= IF_NODOM, ("numa_domain too large")); if (numa_domain == IF_NODOM) @@ -627,17 +599,7 @@ if_alloc_domain(u_char type, int numa_domain) ifp->if_get_counter = if_get_counter_default; ifp->if_pcp = IFNET_PCP_NONE; -restart: - IFNET_WLOCK(); - idx = ifindex_alloc(&old); - if (__predict_false(idx == USHRT_MAX)) { - IFNET_WUNLOCK(); - epoch_wait_preempt(net_epoch_preempt); - free(old, M_IFNET); - goto restart; - } - ifnet_setbyindex(idx, ifp); - IFNET_WUNLOCK(); + ifindex_alloc(ifp); return (ifp); } @@ -1301,9 +1263,6 @@ finish_vnet_shutdown: /* * if_vmove() performs a limited version of if_detach() in current * vnet and if_attach()es the ifnet to the vnet specified as 2nd arg. - * An attempt is made to shrink if_index in current vnet, find an - * unused if_index in target vnet and calls if_grow() if necessary, - * and finally find an unused if_xname for the target vnet. */ static int if_vmove(struct ifnet *ifp, struct vnet *new_vnet) @@ -1312,7 +1271,6 @@ if_vmove(struct ifnet *ifp, struct vnet *new_vnet) #ifdef DEV_BPF u_int bif_dlt, bif_hdrlen; #endif - void *old; int rc; #ifdef DEV_BPF @@ -1355,18 +1313,7 @@ if_vmove(struct ifnet *ifp, struct vnet *new_vnet) * Switch to the context of the target vnet. */ CURVNET_SET_QUIET(new_vnet); - restart: - IFNET_WLOCK(); - ifp->if_index = ifindex_alloc(&old); - if (__predict_false(ifp->if_index == USHRT_MAX)) { - IFNET_WUNLOCK(); - epoch_wait_preempt(net_epoch_preempt); - free(old, M_IFNET); - goto restart; - } - ifnet_setbyindex(ifp->if_index, ifp); - IFNET_WUNLOCK(); - + ifindex_alloc(ifp); if_attach_internal(ifp, 1, ifc); #ifdef DEV_BPF