Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 3 Feb 2016 23:30:17 +0000 (UTC)
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r295222 - in head/sys: amd64/amd64 kern vm
Message-ID:  <201602032330.u13NUHiE034771@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: glebius
Date: Wed Feb  3 23:30:17 2016
New Revision: 295222
URL: https://svnweb.freebsd.org/changeset/base/295222

Log:
  Redo r292484. Embed task(9) into zone, so that uz_maxaction is called
  in a context that can sleep, allowing consumers of the KPI to run their
  drain routines without any extra measures.
  
  Discussed with:	jtl

Modified:
  head/sys/amd64/amd64/uma_machdep.c
  head/sys/kern/kern_malloc.c
  head/sys/kern/kern_mbuf.c
  head/sys/vm/memguard.c
  head/sys/vm/uma.h
  head/sys/vm/uma_core.c
  head/sys/vm/uma_dbg.c
  head/sys/vm/uma_int.h
  head/sys/vm/vm_page.c

Modified: head/sys/amd64/amd64/uma_machdep.c
==============================================================================
--- head/sys/amd64/amd64/uma_machdep.c	Wed Feb  3 22:02:36 2016	(r295221)
+++ head/sys/amd64/amd64/uma_machdep.c	Wed Feb  3 23:30:17 2016	(r295222)
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/malloc.h>
 #include <sys/mutex.h>
 #include <sys/systm.h>
+#include <sys/taskqueue.h>
 #include <vm/vm.h>
 #include <vm/vm_page.h>
 #include <vm/vm_pageout.h>

Modified: head/sys/kern/kern_malloc.c
==============================================================================
--- head/sys/kern/kern_malloc.c	Wed Feb  3 22:02:36 2016	(r295221)
+++ head/sys/kern/kern_malloc.c	Wed Feb  3 23:30:17 2016	(r295222)
@@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/proc.h>
 #include <sys/sbuf.h>
 #include <sys/sysctl.h>
+#include <sys/taskqueue.h>
 #include <sys/time.h>
 #include <sys/vmem.h>
 

Modified: head/sys/kern/kern_mbuf.c
==============================================================================
--- head/sys/kern/kern_mbuf.c	Wed Feb  3 22:02:36 2016	(r295221)
+++ head/sys/kern/kern_mbuf.c	Wed Feb  3 23:30:17 2016	(r295222)
@@ -274,12 +274,6 @@ uma_zone_t	zone_jumbo16;
 uma_zone_t	zone_ext_refcnt;
 
 /*
- * Callout to assist us in freeing mbufs.
- */
-static struct callout	mb_reclaim_callout;
-static struct mtx	mb_reclaim_callout_mtx;
-
-/*
  * Local prototypes.
  */
 static int	mb_ctor_mbuf(void *, int, void *, int);
@@ -291,9 +285,8 @@ static void	mb_dtor_pack(void *, int, vo
 static int	mb_zinit_pack(void *, int, int);
 static void	mb_zfini_pack(void *, int);
 
-static void	mb_reclaim(void *);
+static void	mb_reclaim(uma_zone_t, int);
 static void    *mbuf_jumbo_alloc(uma_zone_t, vm_size_t, uint8_t *, int);
-static void	mb_maxaction(uma_zone_t);
 
 /* Ensure that MSIZE is a power of 2. */
 CTASSERT((((MSIZE - 1) ^ MSIZE) + 1) >> 1 == MSIZE);
@@ -319,7 +312,7 @@ mbuf_init(void *dummy)
 	if (nmbufs > 0)
 		nmbufs = uma_zone_set_max(zone_mbuf, nmbufs);
 	uma_zone_set_warning(zone_mbuf, "kern.ipc.nmbufs limit reached");
-	uma_zone_set_maxaction(zone_mbuf, mb_maxaction);
+	uma_zone_set_maxaction(zone_mbuf, mb_reclaim);
 
 	zone_clust = uma_zcreate(MBUF_CLUSTER_MEM_NAME, MCLBYTES,
 	    mb_ctor_clust, mb_dtor_clust,
@@ -332,7 +325,7 @@ mbuf_init(void *dummy)
 	if (nmbclusters > 0)
 		nmbclusters = uma_zone_set_max(zone_clust, nmbclusters);
 	uma_zone_set_warning(zone_clust, "kern.ipc.nmbclusters limit reached");
-	uma_zone_set_maxaction(zone_clust, mb_maxaction);
+	uma_zone_set_maxaction(zone_clust, mb_reclaim);
 
 	zone_pack = uma_zsecond_create(MBUF_PACKET_MEM_NAME, mb_ctor_pack,
 	    mb_dtor_pack, mb_zinit_pack, mb_zfini_pack, zone_mbuf);
@@ -349,7 +342,7 @@ mbuf_init(void *dummy)
 	if (nmbjumbop > 0)
 		nmbjumbop = uma_zone_set_max(zone_jumbop, nmbjumbop);
 	uma_zone_set_warning(zone_jumbop, "kern.ipc.nmbjumbop limit reached");
-	uma_zone_set_maxaction(zone_jumbop, mb_maxaction);
+	uma_zone_set_maxaction(zone_jumbop, mb_reclaim);
 
 	zone_jumbo9 = uma_zcreate(MBUF_JUMBO9_MEM_NAME, MJUM9BYTES,
 	    mb_ctor_clust, mb_dtor_clust,
@@ -363,7 +356,7 @@ mbuf_init(void *dummy)
 	if (nmbjumbo9 > 0)
 		nmbjumbo9 = uma_zone_set_max(zone_jumbo9, nmbjumbo9);
 	uma_zone_set_warning(zone_jumbo9, "kern.ipc.nmbjumbo9 limit reached");
-	uma_zone_set_maxaction(zone_jumbo9, mb_maxaction);
+	uma_zone_set_maxaction(zone_jumbo9, mb_reclaim);
 
 	zone_jumbo16 = uma_zcreate(MBUF_JUMBO16_MEM_NAME, MJUM16BYTES,
 	    mb_ctor_clust, mb_dtor_clust,
@@ -377,20 +370,13 @@ mbuf_init(void *dummy)
 	if (nmbjumbo16 > 0)
 		nmbjumbo16 = uma_zone_set_max(zone_jumbo16, nmbjumbo16);
 	uma_zone_set_warning(zone_jumbo16, "kern.ipc.nmbjumbo16 limit reached");
-	uma_zone_set_maxaction(zone_jumbo16, mb_maxaction);
+	uma_zone_set_maxaction(zone_jumbo16, mb_reclaim);
 
 	zone_ext_refcnt = uma_zcreate(MBUF_EXTREFCNT_MEM_NAME, sizeof(u_int),
 	    NULL, NULL,
 	    NULL, NULL,
 	    UMA_ALIGN_PTR, UMA_ZONE_ZINIT);
 
-	/* uma_prealloc() goes here... */
-
-	/* Initialize the mb_reclaim() callout. */
-	mtx_init(&mb_reclaim_callout_mtx, "mb_reclaim_callout_mtx", NULL,
-	    MTX_DEF);
-	callout_init(&mb_reclaim_callout, 1);
-
 	/*
 	 * Hook event handler for low-memory situation, used to
 	 * drain protocols and push data back to the caches (UMA
@@ -677,81 +663,23 @@ m_pkthdr_init(struct mbuf *m, int how)
 }
 
 /*
- * This is the protocol drain routine.
+ * This is the protocol drain routine.  Called by UMA whenever any of the
+ * mbuf zones is closed to its limit.
  *
  * No locks should be held when this is called.  The drain routines have to
  * presently acquire some locks which raises the possibility of lock order
  * reversal.
  */
 static void
-mb_reclaim(void *junk)
+mb_reclaim(uma_zone_t zone __unused, int pending __unused)
 {
 	struct domain *dp;
 	struct protosw *pr;
 
-	WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK | WARN_PANIC, NULL,
-	    "mb_reclaim()");
+	WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK | WARN_PANIC, NULL, __func__);
 
 	for (dp = domains; dp != NULL; dp = dp->dom_next)
 		for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
 			if (pr->pr_drain != NULL)
 				(*pr->pr_drain)();
 }
-
-/*
- * This is the function called by the mb_reclaim_callout, which is
- * used when we hit the maximum for a zone.
- *
- * (See mb_maxaction() below.)
- */
-static void
-mb_reclaim_timer(void *junk __unused)
-{
-
-	mtx_lock(&mb_reclaim_callout_mtx);
-
-	/*
-	 * Avoid running this function extra times by skipping this invocation
-	 * if the callout has already been rescheduled.
-	 */
-	if (callout_pending(&mb_reclaim_callout) ||
-	    !callout_active(&mb_reclaim_callout)) {
-		mtx_unlock(&mb_reclaim_callout_mtx);
-		return;
-	}
-	mtx_unlock(&mb_reclaim_callout_mtx);
-
-	mb_reclaim(NULL);
-
-	mtx_lock(&mb_reclaim_callout_mtx);
-	callout_deactivate(&mb_reclaim_callout);
-	mtx_unlock(&mb_reclaim_callout_mtx);
-}
-
-/*
- * This function is called when we hit the maximum for a zone.
- *
- * At that point, we want to call the protocol drain routine to free up some
- * mbufs. However, we will use the callout routines to schedule this to
- * occur in another thread. (The thread calling this function holds the
- * zone lock.)
- */
-static void
-mb_maxaction(uma_zone_t zone __unused)
-{
-
-	/*
-	 * If we can't immediately obtain the lock, either the callout
-	 * is currently running, or another thread is scheduling the
-	 * callout.
-	 */
-	if (!mtx_trylock(&mb_reclaim_callout_mtx))
-		return;
-
-	/* If not already scheduled/running, schedule the callout. */
-	if (!callout_active(&mb_reclaim_callout)) {
-		callout_reset(&mb_reclaim_callout, 1, mb_reclaim_timer, NULL);
-	}
-
-	mtx_unlock(&mb_reclaim_callout_mtx);
-}

Modified: head/sys/vm/memguard.c
==============================================================================
--- head/sys/vm/memguard.c	Wed Feb  3 22:02:36 2016	(r295221)
+++ head/sys/vm/memguard.c	Wed Feb  3 23:30:17 2016	(r295222)
@@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/mutex.h>
 #include <sys/malloc.h>
 #include <sys/sysctl.h>
+#include <sys/taskqueue.h>
 #include <sys/vmem.h>
 
 #include <vm/vm.h>

Modified: head/sys/vm/uma.h
==============================================================================
--- head/sys/vm/uma.h	Wed Feb  3 22:02:36 2016	(r295221)
+++ head/sys/vm/uma.h	Wed Feb  3 23:30:17 2016	(r295222)
@@ -530,7 +530,7 @@ void uma_zone_set_warning(uma_zone_t zon
  * Returns:
  *	Nothing
  */
-typedef void (*uma_maxaction_t)(uma_zone_t);
+typedef void (*uma_maxaction_t)(uma_zone_t, int);
 void uma_zone_set_maxaction(uma_zone_t zone, uma_maxaction_t);
 
 /*

Modified: head/sys/vm/uma_core.c
==============================================================================
--- head/sys/vm/uma_core.c	Wed Feb  3 22:02:36 2016	(r295221)
+++ head/sys/vm/uma_core.c	Wed Feb  3 23:30:17 2016	(r295222)
@@ -78,6 +78,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/sbuf.h>
 #include <sys/sched.h>
 #include <sys/smp.h>
+#include <sys/taskqueue.h>
 #include <sys/vmmeter.h>
 
 #include <vm/vm.h>
@@ -439,8 +440,9 @@ zone_log_warning(uma_zone_t zone)
 static inline void
 zone_maxaction(uma_zone_t zone)
 {
-	if (zone->uz_maxaction)
-		(*zone->uz_maxaction)(zone);
+
+	if (zone->uz_maxaction.ta_func != NULL)
+		taskqueue_enqueue(taskqueue_thread, &zone->uz_maxaction);
 }
 
 static void
@@ -1590,7 +1592,6 @@ zone_ctor(void *mem, int size, void *uda
 	zone->uz_flags = 0;
 	zone->uz_warning = NULL;
 	timevalclear(&zone->uz_ratecheck);
-	zone->uz_maxaction = NULL;
 	keg = arg->keg;
 
 	ZONE_LOCK_INIT(zone, (arg->flags & UMA_ZONE_MTXCLASS));
@@ -3027,7 +3028,7 @@ uma_zone_set_maxaction(uma_zone_t zone, 
 {
 
 	ZONE_LOCK(zone);
-	zone->uz_maxaction = maxaction;
+	TASK_INIT(&zone->uz_maxaction, 0, (task_fn_t *)maxaction, zone);
 	ZONE_UNLOCK(zone);
 }
 

Modified: head/sys/vm/uma_dbg.c
==============================================================================
--- head/sys/vm/uma_dbg.c	Wed Feb  3 22:02:36 2016	(r295221)
+++ head/sys/vm/uma_dbg.c	Wed Feb  3 23:30:17 2016	(r295222)
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/lock.h>
 #include <sys/mutex.h>
 #include <sys/malloc.h>
+#include <sys/taskqueue.h>
 
 #include <vm/vm.h>
 #include <vm/vm_object.h>

Modified: head/sys/vm/uma_int.h
==============================================================================
--- head/sys/vm/uma_int.h	Wed Feb  3 22:02:36 2016	(r295221)
+++ head/sys/vm/uma_int.h	Wed Feb  3 23:30:17 2016	(r295222)
@@ -307,7 +307,7 @@ struct uma_zone {
 	const char	*uz_warning;	/* Warning to print on failure */
 	struct timeval	uz_ratecheck;	/* Warnings rate-limiting */
 
-	uma_maxaction_t	uz_maxaction;	/* Function to run when at limit */
+	struct task	uz_maxaction;	/* Task to run when at limit */
 
 	/*
 	 * This HAS to be the last item because we adjust the zone size

Modified: head/sys/vm/vm_page.c
==============================================================================
--- head/sys/vm/vm_page.c	Wed Feb  3 22:02:36 2016	(r295221)
+++ head/sys/vm/vm_page.c	Wed Feb  3 23:30:17 2016	(r295222)
@@ -102,6 +102,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/sysctl.h>
 #include <sys/vmmeter.h>
 #include <sys/vnode.h>
+#include <sys/taskqueue.h>
 
 #include <vm/vm.h>
 #include <vm/pmap.h>



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