git: 8062e5759cb4 - main - ifnet: allocate index at the end of if_alloc_domain()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 06 Dec 2021 17:32:45 UTC
The branch main has been updated by glebius: URL: https://cgit.FreeBSD.org/src/commit/?id=8062e5759cb4886ad4630d52c212d8ca77ef9c95 commit 8062e5759cb4886ad4630d52c212d8ca77ef9c95 Author: Gleb Smirnoff <glebius@FreeBSD.org> AuthorDate: 2021-12-04 17:49:35 +0000 Commit: Gleb Smirnoff <glebius@FreeBSD.org> CommitDate: 2021-12-06 17:32:30 +0000 ifnet: allocate index at the end of if_alloc_domain() Now that if_alloc_domain() never fails and actually doesn't expose ifnet to outside we can eliminate IFNET_HOLD and two step index allocation. Reviewed by: kp Differential revision: https://reviews.freebsd.org/D33259 --- sys/net/if.c | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/sys/net/if.c b/sys/net/if.c index 75e67c3dd8ba..520e8b4de393 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -331,13 +331,6 @@ struct sx ifnet_detach_sxlock; SX_SYSINIT_FLAGS(ifnet_detach, &ifnet_detach_sxlock, "ifnet_detach_sx", SX_RECURSE); -/* - * The allocation of network interfaces is a rather non-atomic affair; we - * need to select an index before we are ready to expose the interface for - * use, so will use this pointer value to indicate reservation. - */ -#define IFNET_HOLD (void *)(uintptr_t)(-1) - #ifdef VIMAGE #define VNET_IS_SHUTTING_DOWN(_vnet) \ ((_vnet)->vnet_shutdown && (_vnet)->vnet_state < SI_SUB_VNET_DONE) @@ -353,13 +346,11 @@ MALLOC_DEFINE(M_IFMADDR, "ether_multi", "link-level multicast address"); struct ifnet * ifnet_byindex(u_short idx) { - struct ifnet *ifp; if (__predict_false(idx > V_if_index)) return (NULL); - ifp = *(struct ifnet * const volatile *)(V_ifindex_table + idx); - return (__predict_false(ifp == IFNET_HOLD) ? NULL : ifp); + return (V_ifindex_table[idx]); } struct ifnet * @@ -422,6 +413,7 @@ static void ifnet_setbyindex(u_short idx, struct ifnet *ifp) { + ifp->if_index = idx; V_ifindex_table[idx] = ifp; } @@ -608,18 +600,6 @@ if_alloc_domain(u_char type, int numa_domain) else ifp = malloc_domainset(sizeof(struct ifnet), M_IFNET, DOMAINSET_PREF(numa_domain), M_WAITOK | M_ZERO); - 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, IFNET_HOLD); - IFNET_WUNLOCK(); - ifp->if_index = idx; ifp->if_type = type; ifp->if_alloctype = type; ifp->if_numa_domain = numa_domain; @@ -650,7 +630,19 @@ if_alloc_domain(u_char type, int numa_domain) ifp->if_counters[i] = counter_u64_alloc(M_WAITOK); ifp->if_get_counter = if_get_counter_default; ifp->if_pcp = IFNET_PCP_NONE; - ifnet_setbyindex(ifp->if_index, ifp); + +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(); + return (ifp); }