git: 7afcdd13a49c - stable/13 - ifnet: allocate index at the end of if_alloc_domain()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 10 Oct 2024 10:03:22 UTC
The branch stable/13 has been updated by zlei: URL: https://cgit.FreeBSD.org/src/commit/?id=7afcdd13a49c50c5c2396543ddeba1c283202eb7 commit 7afcdd13a49c50c5c2396543ddeba1c283202eb7 Author: Gleb Smirnoff <glebius@FreeBSD.org> AuthorDate: 2021-12-04 17:49:35 +0000 Commit: Zhenlei Huang <zlei@FreeBSD.org> CommitDate: 2024-10-10 10:00:47 +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 (cherry picked from commit 8062e5759cb4886ad4630d52c212d8ca77ef9c95) --- 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 78da7cf02bfb..4182f22c848e 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -323,13 +323,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) @@ -345,13 +338,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 * @@ -414,6 +405,7 @@ static void ifnet_setbyindex(u_short idx, struct ifnet *ifp) { + ifp->if_index = idx; V_ifindex_table[idx] = ifp; } @@ -602,18 +594,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; @@ -644,7 +624,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); }