Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 8 Jun 2018 21:40:04 +0000 (UTC)
From:      Mateusz Guzik <mjg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r334858 - in head/sys: netipsec netpfil/ipfw vm
Message-ID:  <201806082140.w58Le4Vf015842@repo.freebsd.org>

Next in thread | Raw E-Mail | Index | Archive | Help
Author: mjg
Date: Fri Jun  8 21:40:03 2018
New Revision: 334858
URL: https://svnweb.freebsd.org/changeset/base/334858

Log:
  uma: implement provisional api for per-cpu zones
  
  Per-cpu zone allocations are very rarely done compared to regular zones.
  The intent is to avoid pessimizing the latter case with per-cpu specific
  code.
  
  In particular contrary to the claim in r334824, M_ZERO is sometimes being
  used for such zones. But the zeroing method is completely different and
  braching on it in the fast path for regular zones is a waste of time.

Modified:
  head/sys/netipsec/key.c
  head/sys/netpfil/ipfw/ip_fw_sockopt.c
  head/sys/vm/uma.h
  head/sys/vm/uma_core.c

Modified: head/sys/netipsec/key.c
==============================================================================
--- head/sys/netipsec/key.c	Fri Jun  8 20:39:49 2018	(r334857)
+++ head/sys/netipsec/key.c	Fri Jun  8 21:40:03 2018	(r334858)
@@ -2957,7 +2957,7 @@ key_newsav(const struct sadb_msghdr *mhp, struct secas
 		goto done;
 	}
 	mtx_init(sav->lock, "ipsec association", NULL, MTX_DEF);
-	sav->lft_c = uma_zalloc(V_key_lft_zone, M_NOWAIT);
+	sav->lft_c = uma_zalloc_pcpu(V_key_lft_zone, M_NOWAIT);
 	if (sav->lft_c == NULL) {
 		*errp = ENOBUFS;
 		goto done;
@@ -3049,7 +3049,7 @@ done:
 				free(sav->lock, M_IPSEC_MISC);
 			}
 			if (sav->lft_c != NULL)
-				uma_zfree(V_key_lft_zone, sav->lft_c);
+				uma_zfree_pcpu(V_key_lft_zone, sav->lft_c);
 			free(sav, M_IPSEC_SA), sav = NULL;
 		}
 		if (sah != NULL)

Modified: head/sys/netpfil/ipfw/ip_fw_sockopt.c
==============================================================================
--- head/sys/netpfil/ipfw/ip_fw_sockopt.c	Fri Jun  8 20:39:49 2018	(r334857)
+++ head/sys/netpfil/ipfw/ip_fw_sockopt.c	Fri Jun  8 21:40:03 2018	(r334858)
@@ -208,7 +208,7 @@ ipfw_alloc_rule(struct ip_fw_chain *chain, size_t rule
 	struct ip_fw *rule;
 
 	rule = malloc(rulesize, M_IPFW, M_WAITOK | M_ZERO);
-	rule->cntr = uma_zalloc(V_ipfw_cntr_zone, M_WAITOK | M_ZERO);
+	rule->cntr = uma_zalloc_pcpu(V_ipfw_cntr_zone, M_WAITOK | M_ZERO);
 
 	return (rule);
 }
@@ -217,7 +217,7 @@ static void
 free_rule(struct ip_fw *rule)
 {
 
-	uma_zfree(V_ipfw_cntr_zone, rule->cntr);
+	uma_zfree_pcpu(V_ipfw_cntr_zone, rule->cntr);
 	free(rule, M_IPFW);
 }
 

Modified: head/sys/vm/uma.h
==============================================================================
--- head/sys/vm/uma.h	Fri Jun  8 20:39:49 2018	(r334857)
+++ head/sys/vm/uma.h	Fri Jun  8 21:40:03 2018	(r334858)
@@ -333,6 +333,7 @@ void uma_zdestroy(uma_zone_t zone);
  */
 
 void *uma_zalloc_arg(uma_zone_t zone, void *arg, int flags);
+void *uma_zalloc_pcpu_arg(uma_zone_t zone, void *arg, int flags);
 
 /*
  * Allocate an item from a specific NUMA domain.  This uses a slow path in
@@ -354,6 +355,7 @@ void *uma_zalloc_domain(uma_zone_t zone, void *arg, in
  *
  */
 static __inline void *uma_zalloc(uma_zone_t zone, int flags);
+static __inline void *uma_zalloc_pcpu(uma_zone_t zone, int flags);
 
 static __inline void *
 uma_zalloc(uma_zone_t zone, int flags)
@@ -361,6 +363,12 @@ uma_zalloc(uma_zone_t zone, int flags)
 	return uma_zalloc_arg(zone, NULL, flags);
 }
 
+static __inline void *
+uma_zalloc_pcpu(uma_zone_t zone, int flags)
+{
+	return uma_zalloc_pcpu_arg(zone, NULL, flags);
+}
+
 /*
  * Frees an item back into the specified zone.
  *
@@ -374,6 +382,7 @@ uma_zalloc(uma_zone_t zone, int flags)
  */
 
 void uma_zfree_arg(uma_zone_t zone, void *item, void *arg);
+void uma_zfree_pcpu_arg(uma_zone_t zone, void *item, void *arg);
 
 /*
  * Frees an item back to the specified zone's domain specific pool.
@@ -392,11 +401,18 @@ void uma_zfree_domain(uma_zone_t zone, void *item, voi
  *
  */
 static __inline void uma_zfree(uma_zone_t zone, void *item);
+static __inline void uma_zfree_pcpu(uma_zone_t zone, void *item);
 
 static __inline void
 uma_zfree(uma_zone_t zone, void *item)
 {
 	uma_zfree_arg(zone, item, NULL);
+}
+
+static __inline void
+uma_zfree_pcpu(uma_zone_t zone, void *item)
+{
+	uma_zfree_pcpu_arg(zone, item, NULL);
 }
 
 /*

Modified: head/sys/vm/uma_core.c
==============================================================================
--- head/sys/vm/uma_core.c	Fri Jun  8 20:39:49 2018	(r334857)
+++ head/sys/vm/uma_core.c	Fri Jun  8 21:40:03 2018	(r334858)
@@ -2230,6 +2230,32 @@ uma_zwait(uma_zone_t zone)
 	uma_zfree(zone, item);
 }
 
+void *
+uma_zalloc_pcpu_arg(uma_zone_t zone, void *udata, int flags)
+{
+	void *item;
+	int i;
+
+	MPASS(zone->uz_flags & UMA_ZONE_PCPU);
+	item = uma_zalloc_arg(zone, udata, flags &~ M_ZERO);
+	if (item != NULL && (flags & M_ZERO)) {
+		CPU_FOREACH(i)
+			bzero(zpcpu_get_cpu(item, i), zone->uz_size);
+	}
+	return (item);
+}
+
+/*
+ * A stub while both regular and pcpu cases are identical.
+ */
+void
+uma_zfree_pcpu_arg(uma_zone_t zone, void *item, void *udata)
+{
+
+	MPASS(zone->uz_flags & UMA_ZONE_PCPU);
+	uma_zfree_arg(zone, item, udata);
+}
+
 /* See uma.h */
 void *
 uma_zalloc_arg(uma_zone_t zone, void *udata, int flags)



Want to link to this message? Use this URL: <http://docs.FreeBSD.org/cgi/mid.cgi?201806082140.w58Le4Vf015842>