summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua M. Clulow <josh@sysmgr.org>2021-02-02 16:42:59 -0800
committerJoshua M. Clulow <josh@sysmgr.org>2021-02-02 16:42:59 -0800
commitf6ef42236c2f60c5f16c454c9b574a4dc35e1cab (patch)
tree57d0f31fddee4ed44aa63057f4042a78e3446a0c
parent2d9166aee5315081107056f3d663e4adee4c1c2a (diff)
downloadillumos-joyent-f6ef42236c2f60c5f16c454c9b574a4dc35e1cab.tar.gz
13092 ZFS I/O pipeline should use the pageout_reserve pool
Reviewed by: Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org> Reviewed by: Jason King <jason.brian.king@gmail.com> Approved by: Dan McDonald <danmcd@joyent.com>
-rw-r--r--usr/src/uts/common/fs/zfs/zio.c27
-rw-r--r--usr/src/uts/common/sys/thread.h1
-rw-r--r--usr/src/uts/common/sys/vmsystm.h9
3 files changed, 33 insertions, 4 deletions
diff --git a/usr/src/uts/common/fs/zfs/zio.c b/usr/src/uts/common/fs/zfs/zio.c
index a00e7ff850..0fa1445217 100644
--- a/usr/src/uts/common/fs/zfs/zio.c
+++ b/usr/src/uts/common/fs/zfs/zio.c
@@ -49,6 +49,7 @@
#include <sys/abd.h>
#include <sys/cityhash.h>
#include <sys/dsl_crypt.h>
+#include <sys/stdbool.h>
/*
* ==========================================================================
@@ -1853,10 +1854,36 @@ zio_execute(zio_t *zio)
return;
}
+#ifdef _KERNEL
+ /*
+ * The I/O pipeline is a part of the machinery responsible for
+ * evacuation of memory pages to disk when we are under
+ * sufficient memory pressure for pageout to run. By setting
+ * this flag, allocations may dip into pages in the pageout
+ * reserved pool in order to try to make forward progress.
+ */
+ bool set_pushpage = false;
+ if (!(curthread->t_flag & T_PUSHPAGE)) {
+ /*
+ * We can be called recursively, so we need to remember
+ * if this frame was the one that first set the flag or
+ * not.
+ */
+ set_pushpage = true;
+ curthread->t_flag |= T_PUSHPAGE;
+ }
+#endif
+
zio->io_stage = stage;
zio->io_pipeline_trace |= zio->io_stage;
rv = zio_pipeline[highbit64(stage) - 1](zio);
+#ifdef _KERNEL
+ if (set_pushpage) {
+ curthread->t_flag &= ~T_PUSHPAGE;
+ }
+#endif
+
if (rv == ZIO_PIPELINE_STOP)
return;
diff --git a/usr/src/uts/common/sys/thread.h b/usr/src/uts/common/sys/thread.h
index de130e81cb..8b78e00a24 100644
--- a/usr/src/uts/common/sys/thread.h
+++ b/usr/src/uts/common/sys/thread.h
@@ -385,6 +385,7 @@ typedef struct _kthread {
#define T_VFPARENT 0x4000 /* thread is vfork parent, must call vfwait */
#define T_DONTDTRACE 0x8000 /* disable DTrace probes */
#define T_KFPU 0x10000 /* kernel FPU active */
+#define T_PUSHPAGE 0x20000 /* this thread may be assisting pageout */
/*
* Flags in t_proc_flag.
diff --git a/usr/src/uts/common/sys/vmsystm.h b/usr/src/uts/common/sys/vmsystm.h
index c274bae805..e8e30b7608 100644
--- a/usr/src/uts/common/sys/vmsystm.h
+++ b/usr/src/uts/common/sys/vmsystm.h
@@ -70,13 +70,14 @@ extern pgcnt_t pageout_reserve; /* point at which we deny non-PG_WAIT calls */
extern pgcnt_t pages_before_pager; /* XXX */
/*
- * TRUE if the pageout daemon, fsflush daemon or the scheduler. These
- * processes can't sleep while trying to free up memory since a deadlock
- * will occur if they do sleep.
+ * TRUE if the pageout daemon, fsflush daemon, or the scheduler. These threads
+ * can't sleep while trying to free up memory since a deadlock will occur if
+ * they do sleep.
*/
#define NOMEMWAIT() (ttoproc(curthread) == proc_pageout || \
ttoproc(curthread) == proc_fsflush || \
- ttoproc(curthread) == proc_sched)
+ ttoproc(curthread) == proc_sched || \
+ (curthread->t_flag & T_PUSHPAGE) != 0)
/* insure non-zero */
#define nz(x) ((x) != 0 ? (x) : 1)