git: fa93ba4097f0 - main - if_tuntap: simplify storage of per-vnet cloners

From: Gleb Smirnoff <glebius_at_FreeBSD.org>
Date: Fri, 29 Mar 2024 19:36:05 UTC
The branch main has been updated by glebius:

URL: https://cgit.FreeBSD.org/src/commit/?id=fa93ba4097f0db31b8f1b3d081979a4e6f34c191

commit fa93ba4097f0db31b8f1b3d081979a4e6f34c191
Author:     Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2024-03-29 19:35:41 +0000
Commit:     Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2024-03-29 19:35:41 +0000

    if_tuntap: simplify storage of per-vnet cloners
    
    There is no need for a separate structure neither for a linked list.
    Provide each VNET with an array of pointers to if_clone that has the same
    size as the driver list.
    
    Reviewed by:            zlei, kevans, kp
    Differential Revision:  https://reviews.freebsd.org/D44307
---
 sys/net/if_tuntap.c | 68 ++++++++++++++---------------------------------------
 1 file changed, 18 insertions(+), 50 deletions(-)

diff --git a/sys/net/if_tuntap.c b/sys/net/if_tuntap.c
index 4cb219dc92b6..1009dc7b3806 100644
--- a/sys/net/if_tuntap.c
+++ b/sys/net/if_tuntap.c
@@ -328,16 +328,9 @@ static struct tuntap_driver {
 		.clone_destroy_fn =	tun_clone_destroy,
 	},
 };
+#define	NDRV	nitems(tuntap_drivers)
 
-struct tuntap_driver_cloner {
-	SLIST_ENTRY(tuntap_driver_cloner)	 link;
-	struct tuntap_driver			*drv;
-	struct if_clone				*cloner;
-};
-
-VNET_DEFINE_STATIC(SLIST_HEAD(, tuntap_driver_cloner), tuntap_driver_cloners) =
-    SLIST_HEAD_INITIALIZER(tuntap_driver_cloners);
-
+VNET_DEFINE_STATIC(struct if_clone *, tuntap_driver_cloners[NDRV]);
 #define	V_tuntap_driver_cloners	VNET(tuntap_driver_cloners)
 
 /*
@@ -406,7 +399,6 @@ static int
 tuntap_name2info(const char *name, int *outunit, int *outflags)
 {
 	struct tuntap_driver *drv;
-	struct tuntap_driver_cloner *drvc;
 	char *dname;
 	int flags, unit;
 	bool found;
@@ -422,12 +414,8 @@ tuntap_name2info(const char *name, int *outunit, int *outflags)
 	dname = __DECONST(char *, name);
 	found = false;
 
-	KASSERT(!SLIST_EMPTY(&V_tuntap_driver_cloners),
-	    ("tuntap_driver_cloners failed to initialize"));
-	SLIST_FOREACH(drvc, &V_tuntap_driver_cloners, link) {
-		KASSERT(drvc->drv != NULL,
-		    ("tuntap_driver_cloners entry not properly initialized"));
-		drv = drvc->drv;
+	for (u_int i = 0; i < NDRV; i++) {
+		drv = &tuntap_drivers[i];
 
 		if (strcmp(name, drv->cdevsw.d_name) == 0) {
 			found = true;
@@ -456,23 +444,16 @@ tuntap_name2info(const char *name, int *outunit, int *outflags)
 /*
  * Get driver information from a set of flags specified.  Masks the identifying
  * part of the flags and compares it against all of the available
- * tuntap_drivers. Must be called with correct vnet context.
+ * tuntap_drivers.
  */
 static struct tuntap_driver *
 tuntap_driver_from_flags(int tun_flags)
 {
-	struct tuntap_driver *drv;
-	struct tuntap_driver_cloner *drvc;
-
-	KASSERT(!SLIST_EMPTY(&V_tuntap_driver_cloners),
-	    ("tuntap_driver_cloners failed to initialize"));
-	SLIST_FOREACH(drvc, &V_tuntap_driver_cloners, link) {
-		KASSERT(drvc->drv != NULL,
-		    ("tuntap_driver_cloners entry not properly initialized"));
-		drv = drvc->drv;
-		if ((tun_flags & TUN_DRIVER_IDENT_MASK) == drv->ident_flags)
-			return (drv);
-	}
+
+	for (u_int i = 0; i < NDRV; i++)
+		if ((tun_flags & TUN_DRIVER_IDENT_MASK) ==
+		    tuntap_drivers[i].ident_flags)
+			return (&tuntap_drivers[i]);
 
 	return (NULL);
 }
@@ -674,22 +655,15 @@ tun_clone_destroy(struct if_clone *ifc __unused, struct ifnet *ifp, uint32_t fla
 static void
 vnet_tun_init(const void *unused __unused)
 {
-	struct tuntap_driver *drv;
-	struct tuntap_driver_cloner *drvc;
-	int i;
 
-	for (i = 0; i < nitems(tuntap_drivers); ++i) {
-		drv = &tuntap_drivers[i];
-		drvc = malloc(sizeof(*drvc), M_TUN, M_WAITOK | M_ZERO);
-
-		drvc->drv = drv;
+	for (u_int i = 0; i < NDRV; ++i) {
 		struct if_clone_addreq req = {
-			.match_f = drv->clone_match_fn,
-			.create_f = drv->clone_create_fn,
-			.destroy_f = drv->clone_destroy_fn,
+			.match_f = tuntap_drivers[i].clone_match_fn,
+			.create_f = tuntap_drivers[i].clone_create_fn,
+			.destroy_f = tuntap_drivers[i].clone_destroy_fn,
 		};
-		drvc->cloner = ifc_attach_cloner(drv->cdevsw.d_name, &req);
-		SLIST_INSERT_HEAD(&V_tuntap_driver_cloners, drvc, link);
+		V_tuntap_driver_cloners[i] =
+		    ifc_attach_cloner(tuntap_drivers[i].cdevsw.d_name, &req);
 	};
 }
 VNET_SYSINIT(vnet_tun_init, SI_SUB_PROTO_IF, SI_ORDER_ANY,
@@ -698,15 +672,9 @@ VNET_SYSINIT(vnet_tun_init, SI_SUB_PROTO_IF, SI_ORDER_ANY,
 static void
 vnet_tun_uninit(const void *unused __unused)
 {
-	struct tuntap_driver_cloner *drvc;
-
-	while (!SLIST_EMPTY(&V_tuntap_driver_cloners)) {
-		drvc = SLIST_FIRST(&V_tuntap_driver_cloners);
-		SLIST_REMOVE_HEAD(&V_tuntap_driver_cloners, link);
 
-		if_clone_detach(drvc->cloner);
-		free(drvc, M_TUN);
-	}
+	for (u_int i = 0; i < NDRV; ++i)
+		if_clone_detach(V_tuntap_driver_cloners[i]);
 }
 VNET_SYSUNINIT(vnet_tun_uninit, SI_SUB_PROTO_IF, SI_ORDER_ANY,
     vnet_tun_uninit, NULL);