Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 11 Jan 2020 00:08:16 +0000 (UTC)
From:      "Bjoern A. Zeeb" <bz@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r356621 - stable/12/sys/netinet
Message-ID:  <202001110008.00B08GDJ060385@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bz
Date: Sat Jan 11 00:08:16 2020
New Revision: 356621
URL: https://svnweb.freebsd.org/changeset/base/356621

Log:
  MFC r354857:
  
  Reduce the vnet_set module size of ip_mroute to allow loading as a module.
  
    With VIMAGE kernels modules get special treatment as they need
    to also keep the original values and make copies for each instance.
    For that a few pages of vnet modspace are provided and the
    kernel-linker and the VNET framework know how to deal with things.
    When the modspace is (almost) full, other modules which would
    overflow the modspace cannot be loaded and kldload will fail.
  
    ip_mroute uses a lot of variable space, mostly be four big arrays:
    set_vnet 0000000000000510 vnet_entry_multicast_register_if
    set_vnet 0000000000000700 vnet_entry_viftable
    set_vnet 0000000000002000 vnet_entry_bw_meter_timers
    set_vnet 0000000000002800 vnet_entry_bw_upcalls
  
    Dynamically malloc the three big ones for each instance we need
    and free them again on vnet teardown (the 4th is an ifnet).
    That way they only need module space for a single pointer and
    allow a lot more modules using virtualized variables to be loaded
    on a VNET kernel.
  
    PR:		206583

Modified:
  stable/12/sys/netinet/ip_mroute.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/netinet/ip_mroute.c
==============================================================================
--- stable/12/sys/netinet/ip_mroute.c	Fri Jan 10 23:52:36 2020	(r356620)
+++ stable/12/sys/netinet/ip_mroute.c	Sat Jan 11 00:08:16 2020	(r356621)
@@ -179,10 +179,14 @@ static struct mtx mfc_mtx;
 
 VNET_DEFINE_STATIC(vifi_t, numvifs);
 #define	V_numvifs		VNET(numvifs)
-VNET_DEFINE_STATIC(struct vif, viftable[MAXVIFS]);
+VNET_DEFINE_STATIC(struct vif *, viftable);
 #define	V_viftable		VNET(viftable)
+/*
+ * No one should be able to "query" this before initialisation happened in 
+ * vnet_mroute_init(), so we should still be fine.
+ */
 SYSCTL_OPAQUE(_net_inet_ip, OID_AUTO, viftable, CTLFLAG_VNET | CTLFLAG_RD,
-    &VNET_NAME(viftable), sizeof(V_viftable), "S,vif[MAXVIFS]",
+    &VNET_NAME(viftable), sizeof(*V_viftable) * MAXVIFS, "S,vif[MAXVIFS]",
     "IPv4 Multicast Interfaces (struct vif[MAXVIFS], netinet/ip_mroute.h)");
 
 static struct mtx vif_mtx;
@@ -210,7 +214,7 @@ static MALLOC_DEFINE(M_BWMETER, "bwmeter", "multicast 
  * expiration time. Periodically, the entries are analysed and processed.
  */
 #define	BW_METER_BUCKETS	1024
-VNET_DEFINE_STATIC(struct bw_meter*, bw_meter_timers[BW_METER_BUCKETS]);
+VNET_DEFINE_STATIC(struct bw_meter **, bw_meter_timers);
 #define	V_bw_meter_timers	VNET(bw_meter_timers)
 VNET_DEFINE_STATIC(struct callout, bw_meter_ch);
 #define	V_bw_meter_ch		VNET(bw_meter_ch)
@@ -220,7 +224,7 @@ VNET_DEFINE_STATIC(struct callout, bw_meter_ch);
  * Pending upcalls are stored in a vector which is flushed when
  * full, or periodically
  */
-VNET_DEFINE_STATIC(struct bw_upcall, bw_upcalls[BW_UPCALLS_MAX]);
+VNET_DEFINE_STATIC(struct bw_upcall *, bw_upcalls);
 #define	V_bw_upcalls		VNET(bw_upcalls)
 VNET_DEFINE_STATIC(u_int, bw_upcalls_n); /* # of pending upcalls */
 #define	V_bw_upcalls_n    	VNET(bw_upcalls_n)
@@ -764,7 +768,7 @@ X_ip_mrouter_done(void)
     bzero(V_nexpire, sizeof(V_nexpire[0]) * mfchashsize);
 
     V_bw_upcalls_n = 0;
-    bzero(V_bw_meter_timers, sizeof(V_bw_meter_timers));
+    bzero(V_bw_meter_timers, BW_METER_BUCKETS * sizeof(*V_bw_meter_timers));
 
     MFC_UNLOCK();
 
@@ -2805,7 +2809,14 @@ vnet_mroute_init(const void *unused __unused)
 {
 
 	V_nexpire = malloc(mfchashsize, M_MRTABLE, M_WAITOK|M_ZERO);
-	bzero(V_bw_meter_timers, sizeof(V_bw_meter_timers));
+
+	V_viftable = mallocarray(MAXVIFS, sizeof(*V_viftable),
+	    M_MRTABLE, M_WAITOK|M_ZERO);
+	V_bw_meter_timers = mallocarray(BW_METER_BUCKETS,
+	    sizeof(*V_bw_meter_timers), M_MRTABLE, M_WAITOK|M_ZERO);
+	V_bw_upcalls = mallocarray(BW_UPCALLS_MAX, sizeof(*V_bw_upcalls),
+	    M_MRTABLE, M_WAITOK|M_ZERO);
+
 	callout_init(&V_expire_upcalls_ch, 1);
 	callout_init(&V_bw_upcalls_ch, 1);
 	callout_init(&V_bw_meter_ch, 1);
@@ -2818,6 +2829,9 @@ static void
 vnet_mroute_uninit(const void *unused __unused)
 {
 
+	free(V_bw_upcalls, M_MRTABLE);
+	free(V_bw_meter_timers, M_MRTABLE);
+	free(V_viftable, M_MRTABLE);
 	free(V_nexpire, M_MRTABLE);
 	V_nexpire = NULL;
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202001110008.00B08GDJ060385>