Page MenuHomeFreeBSD

D33936.diff
No OneTemporary

D33936.diff

diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -133,6 +133,7 @@
int bd_lim;
/* atomics */
int bd_wanted;
+ bool bd_shutdown;
int __aligned(CACHE_LINE_SIZE) bd_numdirtybuffers;
int __aligned(CACHE_LINE_SIZE) bd_running;
long __aligned(CACHE_LINE_SIZE) bd_bufspace;
@@ -340,6 +341,11 @@
*/
static struct mtx_padalign __exclusive_cache_line bdirtylock;
+/*
+ * bufdaemon shutdown request and sleep channel.
+ */
+static bool bd_shutdown;
+
/*
* Wakeup point for bufdaemon, as well as indicator of whether it is already
* active. Set to 1 when the bufdaemon is already "on" the queue, 0 when it
@@ -628,33 +634,6 @@
}
}
-/*
- * bufspace_daemon_wait:
- *
- * Sleep until the domain falls below a limit or one second passes.
- */
-static void
-bufspace_daemon_wait(struct bufdomain *bd)
-{
- /*
- * Re-check our limits and sleep. bd_running must be
- * cleared prior to checking the limits to avoid missed
- * wakeups. The waker will adjust one of bufspace or
- * freebuffers prior to checking bd_running.
- */
- BD_RUN_LOCK(bd);
- atomic_store_int(&bd->bd_running, 0);
- if (bd->bd_bufspace < bd->bd_bufspacethresh &&
- bd->bd_freebuffers > bd->bd_lofreebuffers) {
- msleep(&bd->bd_running, BD_RUN_LOCKPTR(bd), PRIBIO|PDROP,
- "-", hz);
- } else {
- /* Avoid spurious wakeups while running. */
- atomic_store_int(&bd->bd_running, 1);
- BD_RUN_UNLOCK(bd);
- }
-}
-
/*
* bufspace_adjust:
*
@@ -785,6 +764,22 @@
BD_UNLOCK(bd);
}
+static void
+bufspace_daemon_shutdown(void *arg, int howto __unused)
+{
+ struct bufdomain *bd = arg;
+ int error;
+
+ BD_RUN_LOCK(bd);
+ bd->bd_shutdown = true;
+ wakeup(&bd->bd_running);
+ error = msleep(&bd->bd_shutdown, BD_RUN_LOCKPTR(bd), 0,
+ "bufspace_shutdown", 60 * hz);
+ BD_RUN_UNLOCK(bd);
+ if (error != 0)
+ printf("bufspacedaemon wait error: %d\n", error);
+}
+
/*
* bufspace_daemon:
*
@@ -795,14 +790,14 @@
static void
bufspace_daemon(void *arg)
{
- struct bufdomain *bd;
+ struct bufdomain *bd = arg;
- EVENTHANDLER_REGISTER(shutdown_pre_sync, kthread_shutdown, curthread,
+ EVENTHANDLER_REGISTER(shutdown_pre_sync, bufspace_daemon_shutdown, bd,
SHUTDOWN_PRI_LAST + 100);
- bd = arg;
- for (;;) {
- kthread_suspend_check();
+ BD_RUN_LOCK(bd);
+ while (!bd->bd_shutdown) {
+ BD_RUN_UNLOCK(bd);
/*
* Free buffers from the clean queue until we meet our
@@ -852,8 +847,29 @@
}
maybe_yield();
}
- bufspace_daemon_wait(bd);
+
+ /*
+ * Re-check our limits and sleep. bd_running must be
+ * cleared prior to checking the limits to avoid missed
+ * wakeups. The waker will adjust one of bufspace or
+ * freebuffers prior to checking bd_running.
+ */
+ BD_RUN_LOCK(bd);
+ if (bd->bd_shutdown)
+ break;
+ atomic_store_int(&bd->bd_running, 0);
+ if (bd->bd_bufspace < bd->bd_bufspacethresh &&
+ bd->bd_freebuffers > bd->bd_lofreebuffers) {
+ msleep(&bd->bd_running, BD_RUN_LOCKPTR(bd),
+ PRIBIO, "-", hz);
+ } else {
+ /* Avoid spurious wakeups while running. */
+ atomic_store_int(&bd->bd_running, 1);
+ }
}
+ wakeup(&bd->bd_shutdown);
+ BD_RUN_UNLOCK(bd);
+ kthread_exit();
}
/*
@@ -3391,6 +3407,21 @@
return (flushed);
}
+static void
+buf_daemon_shutdown(void *arg __unused, int howto __unused)
+{
+ int error;
+
+ mtx_lock(&bdlock);
+ bd_shutdown = true;
+ wakeup(&bd_request);
+ error = msleep(&bd_shutdown, &bdlock, 0, "buf_daemon_shutdown",
+ 60 * hz);
+ mtx_unlock(&bdlock);
+ if (error != 0)
+ printf("bufdaemon wait error: %d\n", error);
+}
+
static void
buf_daemon()
{
@@ -3402,7 +3433,7 @@
/*
* This process needs to be suspended prior to shutdown sync.
*/
- EVENTHANDLER_REGISTER(shutdown_pre_sync, kthread_shutdown, curthread,
+ EVENTHANDLER_REGISTER(shutdown_pre_sync, buf_daemon_shutdown, NULL,
SHUTDOWN_PRI_LAST + 100);
/*
@@ -3422,12 +3453,10 @@
*/
curthread->td_pflags |= TDP_NORUNNINGBUF | TDP_BUFNEED;
mtx_lock(&bdlock);
- for (;;) {
+ while (!bd_shutdown) {
bd_request = 0;
mtx_unlock(&bdlock);
- kthread_suspend_check();
-
/*
* Save speedupreq for this pass and reset to capture new
* requests.
@@ -3464,6 +3493,8 @@
* to avoid endless loops on unlockable buffers.
*/
mtx_lock(&bdlock);
+ if (bd_shutdown)
+ break;
if (BIT_EMPTY(BUF_DOMAINS, &bdlodirty)) {
/*
* We reached our low water mark, reset the
@@ -3489,6 +3520,9 @@
msleep(&bd_request, &bdlock, PVM, "qsleep", hz / 10);
}
}
+ wakeup(&bd_shutdown);
+ mtx_unlock(&bdlock);
+ kthread_exit();
}
/*

File Metadata

Mime Type
text/plain
Expires
Fri, Jan 31, 7:42 PM (19 h, 20 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16369531
Default Alt Text
D33936.diff (4 KB)

Event Timeline