Index: share/man/man9/ifnet.9 =================================================================== --- share/man/man9/ifnet.9 +++ share/man/man9/ifnet.9 @@ -48,6 +48,8 @@ .Ss "Interface Manipulation Functions" .Ft "struct ifnet *" .Fn if_alloc "u_char type" +.Ft "struct ifnet *" +.Fn if_alloc_domain "u_char type" "int numa_domain" .Ft void .Fn if_attach "struct ifnet *ifp" .Ft void @@ -440,6 +442,14 @@ but unlike .Va if_type , it would not be changed by drivers. +.It Va if_numa_domain +.Pq Vt uint8_t +The NUMA domain of the hardware device associated with the interface. +This is filled in with a wildcard value unless the kernel is NUMA +aware, the system is a NUMA system, and the device driver +allocates the ifnet using +.Fn if_alloc_domain +. .El .Pp References to @@ -1151,6 +1161,15 @@ .Fa type specific structure in .Va if_l2com . +.It Fn if_alloc_domain +Allocate and initialize +.Vt "struct ifnet" +exactly as +.Fn if_alloc +does, but with the difference being that a driver can +pass a +.Fa numa_domain +argument so that the ifnet is tagged with the appropriate NUMA domain. .It Fn if_attach Link the specified interface .Fa ifp @@ -1168,7 +1187,9 @@ The .Fa ifp must have been allocated by -.Fn if_alloc . +.Fn if_alloc +or +.Fn if_alloc_domain . .It Fn if_detach Shut down and unlink the specified .Fa ifp Index: sys/dev/cxgbe/t4_main.c =================================================================== --- sys/dev/cxgbe/t4_main.c +++ sys/dev/cxgbe/t4_main.c @@ -1631,12 +1631,16 @@ { struct ifnet *ifp; struct sbuf *sb; + int numa_domain; vi->xact_addr_filt = -1; callout_init(&vi->tick, 1); /* Allocate an ifnet and set it up */ - ifp = if_alloc(IFT_ETHER); + if (bus_get_domain(dev, &numa_domain) != 0) + ifp = if_alloc(IFT_ETHER); + else + ifp = if_alloc_domain(IFT_ETHER, numa_domain); if (ifp == NULL) { device_printf(dev, "Cannot allocate ifnet\n"); return (ENOMEM); Index: sys/dev/mlx5/mlx5_en/mlx5_en_main.c =================================================================== --- sys/dev/mlx5/mlx5_en/mlx5_en_main.c +++ sys/dev/mlx5/mlx5_en/mlx5_en_main.c @@ -3666,7 +3666,7 @@ char unit[16]; struct pfil_head_args pa; int err; - int i; + int i, numa_domain; u32 eth_proto_cap; if (mlx5e_check_required_hca_cap(mdev)) { @@ -3682,7 +3682,10 @@ M_MLX5EN, M_WAITOK | M_ZERO); mlx5e_priv_mtx_init(priv); - ifp = priv->ifp = if_alloc(IFT_ETHER); + if (bus_get_domain(mdev->pdev->dev.bsddev, &numa_domain) != 0) + ifp = priv->ifp = if_alloc(IFT_ETHER); + else + ifp = priv->ifp = if_alloc_domain(IFT_ETHER, numa_domain); if (ifp == NULL) { mlx5_core_err(mdev, "if_alloc() failed\n"); goto err_free_priv; Index: sys/net/if.c =================================================================== --- sys/net/if.c +++ sys/net/if.c @@ -39,6 +39,8 @@ #include #include #include +#include +#include #include #include #include @@ -526,13 +528,19 @@ * registered for the passed type. */ struct ifnet * -if_alloc(u_char type) +if_alloc_domain(u_char type, int numa_domain) { struct ifnet *ifp; u_short idx; void *old; - ifp = malloc(sizeof(struct ifnet), M_IFNET, M_WAITOK|M_ZERO); + + KASSERT(numa_domain <= IF_NODOM, ("numa_domain too large")); + if (numa_domain == IF_NODOM) + ifp = malloc(sizeof(struct ifnet), M_IFNET, M_WAITOK|M_ZERO); + else + ifp = malloc_domainset(sizeof(struct ifnet), M_IFNET, + DOMAINSET_PREF(numa_domain), M_WAITOK|M_ZERO); restart: IFNET_WLOCK(); idx = ifindex_alloc(&old); @@ -547,6 +555,7 @@ ifp->if_index = idx; ifp->if_type = type; ifp->if_alloctype = type; + ifp->if_numa_domain = numa_domain; #ifdef VIMAGE ifp->if_vnet = curvnet; #endif @@ -580,6 +589,11 @@ return (ifp); } +struct ifnet * +if_alloc(u_char type) +{ + return (if_alloc_domain(type, IF_NODOM)); +} /* * Do the actual work of freeing a struct ifnet, and layer 2 common * structure. This call is made when the last reference to an @@ -608,7 +622,10 @@ free(ifp->if_description, M_IFDESCR); free(ifp->if_hw_addr, M_IFADDR); - free(ifp, M_IFNET); + if (ifp->if_numa_domain == IF_NODOM) + free(ifp, M_IFNET); + else + free_domain(ifp, M_IFNET); } static void Index: sys/net/if_var.h =================================================================== --- sys/net/if_var.h +++ sys/net/if_var.h @@ -244,7 +244,7 @@ CK_STAILQ_HEAD(, ifg_list) if_groups; /* linked list of groups per if (CK_) */ /* protected by if_addr_lock */ u_char if_alloctype; /* if_type at time of allocation */ - + uint8_t if_numa_domain; /* NUMA domain of device */ /* Driver and protocol specific information that remains stable. */ void *if_softc; /* pointer to driver state */ void *if_llsoftc; /* link layer softc */ @@ -394,6 +394,7 @@ /* for compatibility with other BSDs */ #define if_name(ifp) ((ifp)->if_xname) +#define IF_NODOM 255 /* * Locks for address lists on the network interface. */ @@ -622,6 +623,7 @@ int if_addmulti(struct ifnet *, struct sockaddr *, struct ifmultiaddr **); int if_allmulti(struct ifnet *, int); struct ifnet* if_alloc(u_char); +struct ifnet* if_alloc_domain(u_char, int numa_domain); void if_attach(struct ifnet *); void if_dead(struct ifnet *); int if_delmulti(struct ifnet *, struct sockaddr *);