summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2016-02-03 23:30:17 +0000
committerglebius <glebius@FreeBSD.org>2016-02-03 23:30:17 +0000
commit953ea03018f155940b6a4b4d34edf9d5107822fe (patch)
treeab0931af6386f78986bd989d411e612dfc082b5c /sys/kern
parent8f977b6c5c07cc8b9c845778b9b384d9e37482ee (diff)
downloadFreeBSD-src-953ea03018f155940b6a4b4d34edf9d5107822fe.zip
FreeBSD-src-953ea03018f155940b6a4b4d34edf9d5107822fe.tar.gz
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
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_malloc.c1
-rw-r--r--sys/kern/kern_mbuf.c92
2 files changed, 11 insertions, 82 deletions
diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c
index e7c81d6..f7c67f2 100644
--- a/sys/kern/kern_malloc.c
+++ b/sys/kern/kern_malloc.c
@@ -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>
diff --git a/sys/kern/kern_mbuf.c b/sys/kern/kern_mbuf.c
index 779c62a..5596439 100644
--- a/sys/kern/kern_mbuf.c
+++ b/sys/kern/kern_mbuf.c
@@ -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, void *);
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);
-}
OpenPOWER on IntegriCloud