From: David Howells <dhowells@redhat.com>
To: trond.myklebust@fys.uio.no, viro@ZenIV.linux.org.uk
Cc: dhowells@redhat.com, nfsv4@linux-nfs.org,
linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org
Subject: [PATCH 03/45] Make the slow work pool configurable [ver #41]
Date: Thu, 20 Nov 2008 14:41:55 +0000 [thread overview]
Message-ID: <20081120144155.10667.38747.stgit@warthog.procyon.org.uk> (raw)
In-Reply-To: <20081120144139.10667.75519.stgit@warthog.procyon.org.uk>
Make the slow work pool configurable through /proc/sys/kernel/slow-work.
(*) /proc/sys/kernel/slow-work/min-threads
The minimum number of threads that should be in the pool as long as it is
in use. This may be anywhere between 2 and max-threads.
(*) /proc/sys/kernel/slow-work/max-threads
The maximum number of threads that should in the pool. This may be
anywhere between min-threads and 255 or NR_CPUS * 2, whichever is greater.
(*) /proc/sys/kernel/slow-work/vslow-percentage
The percentage of active threads in the pool that may be used to execute
very slow work items. This may be between 1 and 99. The resultant number
is bounded to between 1 and one fewer than the number of active threads.
This ensures there is always at least one thread that can process very
slow work items, and always at least one thread that won't.
Signed-off-by: David Howells <dhowells@redhat.com>
---
include/linux/slow-work.h | 5 ++
kernel/slow-work.c | 115 ++++++++++++++++++++++++++++++++++++++++++++-
kernel/sysctl.c | 9 ++++
3 files changed, 127 insertions(+), 2 deletions(-)
diff --git a/include/linux/slow-work.h b/include/linux/slow-work.h
index 16c3ea8..3be8aea 100644
--- a/include/linux/slow-work.h
+++ b/include/linux/slow-work.h
@@ -14,6 +14,8 @@
#ifdef CONFIG_SLOW_WORK
+#include <linux/sysctl.h>
+
struct slow_work;
/*
@@ -83,6 +85,9 @@ extern int slow_work_enqueue(struct slow_work *work);
extern int slow_work_register_user(void);
extern void slow_work_unregister_user(void);
+#ifdef CONFIG_SYSCTL
+extern ctl_table slow_work_sysctls[];
+#endif
#endif /* CONFIG_SLOW_WORK */
#endif /* _LINUX_SLOW_WORK_H */
diff --git a/kernel/slow-work.c b/kernel/slow-work.c
index 313640c..3d6ce3b 100644
--- a/kernel/slow-work.c
+++ b/kernel/slow-work.c
@@ -14,7 +14,6 @@
#include <linux/kthread.h>
#include <linux/freezer.h>
#include <linux/wait.h>
-#include <asm/system.h>
#define SLOW_WORK_CULL_TIMEOUT (5 * HZ) /* cull threads 5s after running out of
* things to do */
@@ -24,6 +23,14 @@
static void slow_work_cull_timeout(unsigned long);
static void slow_work_oom_timeout(unsigned long);
+#ifdef CONFIG_SYSCTL
+static int slow_work_min_threads_sysctl(struct ctl_table *table, int write, struct file *filp,
+ void __user *buffer, size_t *lenp, loff_t *ppos);
+
+static int slow_work_max_threads_sysctl(struct ctl_table *table, int write, struct file *filp,
+ void __user *buffer, size_t *lenp, loff_t *ppos);
+#endif
+
/*
* The pool of threads has at least min threads in it as long as someone is
* using the facility, and may have as many as max.
@@ -34,6 +41,52 @@ static unsigned slow_work_min_threads = 2;
static unsigned slow_work_max_threads = (NR_CPUS > 4) ? NR_CPUS : 4;
static unsigned vslow_work_proportion = 50; /* % of threads that may process
* very slow work */
+
+#ifdef CONFIG_SYSCTL
+static const int slow_work_min_min_threads = 2;
+static const int slow_work_max_max_threads =
+ (NR_CPUS * 2 > 255) ? NR_CPUS * 2 : 255;
+static const int slow_work_min_vslow = 1;
+static const int slow_work_max_vslow = 99;
+
+ctl_table slow_work_sysctls[] = {
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "min-threads",
+ .data = &slow_work_min_threads,
+ .maxlen = sizeof(unsigned),
+ .mode = 0644,
+ .proc_handler = slow_work_min_threads_sysctl,
+ .extra1 = (void *) &slow_work_min_min_threads,
+ .extra2 = &slow_work_max_threads,
+ },
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "max-threads",
+ .data = &slow_work_max_threads,
+ .maxlen = sizeof(unsigned),
+ .mode = 0644,
+ .proc_handler = slow_work_max_threads_sysctl,
+ .extra1 = &slow_work_min_threads,
+ .extra2 = (void *) &slow_work_max_max_threads,
+ },
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "vslow-percentage",
+ .data = &vslow_work_proportion,
+ .maxlen = sizeof(unsigned),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_minmax,
+ .extra1 = (void *) &slow_work_min_vslow,
+ .extra2 = (void *) &slow_work_max_vslow,
+ },
+ { .ctl_name = 0 }
+};
+#endif
+
+/*
+ * The active state of the thread pool
+ */
static atomic_t slow_work_thread_count;
static atomic_t vslow_work_executing_count;
@@ -157,7 +210,7 @@ static bool slow_work_execute(void)
*/
if (test_bit(SLOW_WORK_PENDING, &work->flags)) {
spin_lock_irq(&slow_work_queue_lock);
-
+
if (!test_bit(SLOW_WORK_EXECUTING, &work->flags) &&
test_and_clear_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags))
goto auto_requeue;
@@ -404,6 +457,64 @@ static void slow_work_oom_timeout(unsigned long data)
slow_work_may_not_start_new_thread = false;
}
+#ifdef CONFIG_SYSCTL
+/*
+ * Handle adjustment of the minimum number of threads
+ */
+static int slow_work_min_threads_sysctl(struct ctl_table *table, int write,
+ struct file *filp, void __user *buffer,
+ size_t *lenp, loff_t *ppos)
+{
+ int ret = proc_dointvec_minmax(table, write, filp, buffer, lenp, ppos);
+ int n;
+
+ if (ret == 0) {
+ mutex_lock(&slow_work_user_lock);
+ if (slow_work_user_count > 0) {
+ /* see if we need to start or stop threads */
+ n = atomic_read(&slow_work_thread_count) -
+ slow_work_min_threads;
+
+ if (n < 0 && !slow_work_may_not_start_new_thread)
+ slow_work_enqueue(&slow_work_new_thread);
+ else if (n > 0)
+ mod_timer(&slow_work_cull_timer,
+ jiffies + SLOW_WORK_CULL_TIMEOUT);
+ }
+ mutex_unlock(&slow_work_user_lock);
+ }
+
+ return ret;
+}
+
+/*
+ * Handle adjustment of the maximum number of threads
+ */
+static int slow_work_max_threads_sysctl(struct ctl_table *table, int write,
+ struct file *filp, void __user *buffer,
+ size_t *lenp, loff_t *ppos)
+{
+ int ret = proc_dointvec_minmax(table, write, filp, buffer, lenp, ppos);
+ int n;
+
+ if (ret == 0) {
+ mutex_lock(&slow_work_user_lock);
+ if (slow_work_user_count > 0) {
+ /* see if we need to stop threads */
+ n = slow_work_max_threads -
+ atomic_read(&slow_work_thread_count);
+
+ if (n < 0)
+ mod_timer(&slow_work_cull_timer,
+ jiffies + SLOW_WORK_CULL_TIMEOUT);
+ }
+ mutex_unlock(&slow_work_user_lock);
+ }
+
+ return ret;
+}
+#endif /* CONFIG_SYSCTL */
+
/**
* slow_work_register_user - Register a user of the facility
*
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 5110313..81f4654 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -48,6 +48,7 @@
#include <linux/acpi.h>
#include <linux/reboot.h>
#include <linux/ftrace.h>
+#include <linux/slow-work.h>
#include <asm/uaccess.h>
#include <asm/processor.h>
@@ -853,6 +854,14 @@ static struct ctl_table kern_table[] = {
.proc_handler = &scan_unevictable_handler,
},
#endif
+#ifdef CONFIG_SLOW_WORK
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "slow-work",
+ .mode = 0555,
+ .child = slow_work_sysctls,
+ },
+#endif
/*
* NOTE: do not add new entries to this table unless you have read
* Documentation/sysctl/ctl_unnumbered.txt
next prev parent reply other threads:[~2008-11-20 14:43 UTC|newest]
Thread overview: 81+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-11-20 14:41 [PATCH 00/45] Permit filesystem local caching " David Howells
2008-11-20 14:41 ` [PATCH 01/45] Create a dynamically sized pool of threads for doing very slow work items " David Howells
2008-11-21 8:09 ` Andrew Morton
2008-11-21 10:24 ` David Howells
2008-11-21 18:17 ` Andrew Morton
2008-11-22 0:38 ` David Howells
2008-12-19 4:14 ` Serge E. Hallyn
2008-12-19 4:19 ` Serge E. Hallyn
2008-12-19 7:15 ` Andrew Morton
2008-12-19 11:42 ` David Howells
2008-12-19 11:44 ` David Howells
2008-12-19 12:12 ` David Howells
2008-12-19 16:52 ` Serge E. Hallyn
2008-12-19 12:54 ` David Howells
2008-11-20 14:41 ` [PATCH 02/45] Make slow-work thread pool actually dynamic " David Howells
2008-12-19 17:58 ` Serge E. Hallyn
2008-11-20 14:41 ` David Howells [this message]
2008-12-19 18:33 ` [PATCH 03/45] Make the slow work pool configurable " Serge E. Hallyn
2008-11-20 14:42 ` [PATCH 04/45] Document the slow work thread pool " David Howells
2008-11-20 14:42 ` [PATCH 05/45] FS-Cache: Release page->private after failed readahead " David Howells
2008-11-21 8:12 ` Andrew Morton
2008-11-21 10:27 ` David Howells
2008-11-20 14:42 ` [PATCH 06/45] FS-Cache: Recruit a couple of page flags for cache management " David Howells
2008-11-21 8:17 ` Andrew Morton
2008-11-21 10:31 ` David Howells
2008-11-20 14:42 ` [PATCH 07/45] FS-Cache: Provide an add_wait_queue_tail() function " David Howells
2008-11-21 8:17 ` Andrew Morton
2008-11-21 13:32 ` David Howells
2008-11-20 14:42 ` [PATCH 08/45] FS-Cache: Add the FS-Cache netfs API and documentation " David Howells
2008-11-20 14:42 ` [PATCH 09/45] FS-Cache: Add the FS-Cache cache backend " David Howells
2008-11-20 14:42 ` [PATCH 10/45] FS-Cache: Add main configuration option, module entry points and debugging " David Howells
2008-11-20 14:42 ` [PATCH 11/45] FS-Cache: Add use of /proc and presentation of statistics " David Howells
2008-11-21 0:15 ` Alexey Dobriyan
2008-11-21 2:17 ` David Howells
2008-11-21 2:34 ` Alexey Dobriyan
2008-11-21 15:32 ` David Howells
2008-11-20 14:42 ` [PATCH 12/45] FS-Cache: Root index definition " David Howells
2008-11-20 14:42 ` [PATCH 13/45] FS-Cache: Add cache tag handling " David Howells
2008-11-20 14:42 ` [PATCH 14/45] FS-Cache: Add cache management " David Howells
2008-11-20 14:42 ` [PATCH 15/45] FS-Cache: Provide a slab for cookie allocation " David Howells
2008-11-20 14:43 ` [PATCH 16/45] FS-Cache: Add netfs registration " David Howells
2008-11-20 14:43 ` [PATCH 17/45] FS-Cache: Bit waiting helpers " David Howells
2008-11-20 14:43 ` [PATCH 18/45] FS-Cache: Object management state machine " David Howells
2008-11-20 14:43 ` [PATCH 19/45] FS-Cache: Implement the cookie management part of the netfs API " David Howells
2008-11-20 14:43 ` [PATCH 20/45] FS-Cache: Add and document asynchronous operation handling " David Howells
2008-11-20 14:43 ` [PATCH 21/45] FS-Cache: Implement data I/O part of netfs API " David Howells
2008-11-20 14:43 ` [PATCH 22/45] CacheFiles: Add missing copy_page export for ia64 " David Howells
2008-11-20 14:43 ` [PATCH 23/45] CacheFiles: Be consistent about the use of mapping vs file->f_mapping in Ext3 " David Howells
2008-11-20 14:43 ` [PATCH 24/45] CacheFiles: Add a hook to write a single page of data to an inode " David Howells
2008-11-21 8:23 ` Andrew Morton
2008-11-21 12:43 ` David Howells
2008-11-21 13:00 ` Jamie Lokier
2008-11-21 17:15 ` Valdis.Kletnieks
2008-11-21 17:36 ` Randy Dunlap
2008-11-21 18:31 ` Andrew Morton
2008-11-22 0:48 ` David Howells
2008-11-20 14:43 ` [PATCH 25/45] CacheFiles: Permit the page lock state to be monitored " David Howells
2008-11-20 14:43 ` [PATCH 26/45] CacheFiles: Export things for CacheFiles " David Howells
2008-11-20 14:43 ` [PATCH 27/45] CacheFiles: A cache that backs onto a mounted filesystem " David Howells
2008-11-20 14:44 ` [PATCH 28/45] FS-Cache: Make kAFS use FS-Cache " David Howells
2008-11-20 14:44 ` [PATCH 29/45] NFS: Add comment banners to some NFS functions " David Howells
2008-11-20 14:44 ` [PATCH 30/45] NFS: Add FS-Cache option bit and debug bit " David Howells
2008-11-20 14:44 ` [PATCH 31/45] NFS: Permit local filesystem caching to be enabled for NFS " David Howells
2008-11-20 14:44 ` [PATCH 32/45] NFS: Register NFS for caching and retrieve the top-level index " David Howells
2008-11-20 14:44 ` [PATCH 33/45] NFS: Define and create server-level objects " David Howells
2008-11-20 14:44 ` [PATCH 34/45] NFS: Define and create superblock-level " David Howells
2008-11-20 14:44 ` [PATCH 35/45] NFS: Define and create inode-level cache " David Howells
2008-11-20 14:44 ` [PATCH 36/45] NFS: Use local disk inode cache " David Howells
2008-11-20 14:44 ` [PATCH 37/45] NFS: Invalidate FsCache page flags when cache removed " David Howells
2008-11-20 14:44 ` [PATCH 38/45] NFS: Add some new I/O counters for FS-Cache doing things for NFS " David Howells
2008-11-20 14:45 ` [PATCH 39/45] NFS: FS-Cache page management " David Howells
2008-11-20 14:45 ` [PATCH 40/45] NFS: Add read context retention for FS-Cache to call back with " David Howells
2008-11-20 14:45 ` [PATCH 41/45] NFS: nfs_readpage_async() needs to be accessible as a fallback for local caching " David Howells
2008-11-20 14:45 ` [PATCH 42/45] NFS: Read pages from FS-Cache into an NFS inode " David Howells
2008-11-20 14:45 ` [PATCH 43/45] NFS: Store pages from an NFS inode into a local cache " David Howells
2008-11-20 14:45 ` [PATCH 44/45] NFS: Display local caching state " David Howells
2008-11-20 14:45 ` [PATCH 45/45] NFS: Add mount options to enable local caching on NFS " David Howells
2008-11-21 8:28 ` [PATCH 00/45] Permit filesystem local caching " Andrew Morton
2008-11-22 1:11 ` David Howells
2008-11-25 0:09 ` David Howells
2008-11-25 13:39 ` FS-Cache Benchmarks David Howells
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20081120144155.10667.38747.stgit@warthog.procyon.org.uk \
--to=dhowells@redhat.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=nfsv4@linux-nfs.org \
--cc=trond.myklebust@fys.uio.no \
--cc=viro@ZenIV.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®