aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fscache/main.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2010-07-20 16:09:01 -0400
committerTejun Heo <tj@kernel.org>2010-07-22 16:58:34 -0400
commit8b8edefa2fffbff97f9eec8b70e78ae23abad1a0 (patch)
tree7f0efac8adb9c9ed7be8af63e51510954f1c51dc /fs/fscache/main.c
parente120153ddf8620fd0a194d301e9c5a8b28483bb5 (diff)
fscache: convert object to use workqueue instead of slow-work
Make fscache object state transition callbacks use workqueue instead of slow-work. New dedicated unbound CPU workqueue fscache_object_wq is created. get/put callbacks are renamed and modified to take @object and called directly from the enqueue wrapper and the work function. While at it, make all open coded instances of get/put to use fscache_get/put_object(). * Unbound workqueue is used. * work_busy() output is printed instead of slow-work flags in object debugging outputs. They mean basically the same thing bit-for-bit. * sysctl fscache.object_max_active added to control concurrency. The default value is nr_cpus clamped between 4 and WQ_UNBOUND_MAX_ACTIVE. * slow_work_sleep_till_thread_needed() is replaced with fscache private implementation fscache_object_sleep_till_congested() which waits on fscache_object_wq congestion. * debugfs support is dropped for now. Tracing API based debug facility is planned to be added. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/fscache/main.c')
-rw-r--r--fs/fscache/main.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/fs/fscache/main.c b/fs/fscache/main.c
index add6bdb53f0..bb8d4c35c7a 100644
--- a/fs/fscache/main.c
+++ b/fs/fscache/main.c
@@ -15,6 +15,7 @@
15#include <linux/sched.h> 15#include <linux/sched.h>
16#include <linux/completion.h> 16#include <linux/completion.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/seq_file.h>
18#include "internal.h" 19#include "internal.h"
19 20
20MODULE_DESCRIPTION("FS Cache Manager"); 21MODULE_DESCRIPTION("FS Cache Manager");
@@ -40,22 +41,89 @@ MODULE_PARM_DESC(fscache_debug,
40 "FS-Cache debugging mask"); 41 "FS-Cache debugging mask");
41 42
42struct kobject *fscache_root; 43struct kobject *fscache_root;
44struct workqueue_struct *fscache_object_wq;
45
46DEFINE_PER_CPU(wait_queue_head_t, fscache_object_cong_wait);
47
48/* these values serve as lower bounds, will be adjusted in fscache_init() */
49static unsigned fscache_object_max_active = 4;
50
51#ifdef CONFIG_SYSCTL
52static struct ctl_table_header *fscache_sysctl_header;
53
54static int fscache_max_active_sysctl(struct ctl_table *table, int write,
55 void __user *buffer,
56 size_t *lenp, loff_t *ppos)
57{
58 struct workqueue_struct **wqp = table->extra1;
59 unsigned int *datap = table->data;
60 int ret;
61
62 ret = proc_dointvec(table, write, buffer, lenp, ppos);
63 if (ret == 0)
64 workqueue_set_max_active(*wqp, *datap);
65 return ret;
66}
67
68ctl_table fscache_sysctls[] = {
69 {
70 .procname = "object_max_active",
71 .data = &fscache_object_max_active,
72 .maxlen = sizeof(unsigned),
73 .mode = 0644,
74 .proc_handler = fscache_max_active_sysctl,
75 .extra1 = &fscache_object_wq,
76 },
77 {}
78};
79
80ctl_table fscache_sysctls_root[] = {
81 {
82 .procname = "fscache",
83 .mode = 0555,
84 .child = fscache_sysctls,
85 },
86 {}
87};
88#endif
43 89
44/* 90/*
45 * initialise the fs caching module 91 * initialise the fs caching module
46 */ 92 */
47static int __init fscache_init(void) 93static int __init fscache_init(void)
48{ 94{
95 unsigned int nr_cpus = num_possible_cpus();
96 unsigned int cpu;
49 int ret; 97 int ret;
50 98
51 ret = slow_work_register_user(THIS_MODULE); 99 ret = slow_work_register_user(THIS_MODULE);
52 if (ret < 0) 100 if (ret < 0)
53 goto error_slow_work; 101 goto error_slow_work;
54 102
103 fscache_object_max_active =
104 clamp_val(nr_cpus,
105 fscache_object_max_active, WQ_UNBOUND_MAX_ACTIVE);
106
107 ret = -ENOMEM;
108 fscache_object_wq = alloc_workqueue("fscache_object", WQ_UNBOUND,
109 fscache_object_max_active);
110 if (!fscache_object_wq)
111 goto error_object_wq;
112
113 for_each_possible_cpu(cpu)
114 init_waitqueue_head(&per_cpu(fscache_object_cong_wait, cpu));
115
55 ret = fscache_proc_init(); 116 ret = fscache_proc_init();
56 if (ret < 0) 117 if (ret < 0)
57 goto error_proc; 118 goto error_proc;
58 119
120#ifdef CONFIG_SYSCTL
121 ret = -ENOMEM;
122 fscache_sysctl_header = register_sysctl_table(fscache_sysctls_root);
123 if (!fscache_sysctl_header)
124 goto error_sysctl;
125#endif
126
59 fscache_cookie_jar = kmem_cache_create("fscache_cookie_jar", 127 fscache_cookie_jar = kmem_cache_create("fscache_cookie_jar",
60 sizeof(struct fscache_cookie), 128 sizeof(struct fscache_cookie),
61 0, 129 0,
@@ -78,8 +146,14 @@ static int __init fscache_init(void)
78error_kobj: 146error_kobj:
79 kmem_cache_destroy(fscache_cookie_jar); 147 kmem_cache_destroy(fscache_cookie_jar);
80error_cookie_jar: 148error_cookie_jar:
149#ifdef CONFIG_SYSCTL
150 unregister_sysctl_table(fscache_sysctl_header);
151error_sysctl:
152#endif
81 fscache_proc_cleanup(); 153 fscache_proc_cleanup();
82error_proc: 154error_proc:
155 destroy_workqueue(fscache_object_wq);
156error_object_wq:
83 slow_work_unregister_user(THIS_MODULE); 157 slow_work_unregister_user(THIS_MODULE);
84error_slow_work: 158error_slow_work:
85 return ret; 159 return ret;
@@ -96,7 +170,9 @@ static void __exit fscache_exit(void)
96 170
97 kobject_put(fscache_root); 171 kobject_put(fscache_root);
98 kmem_cache_destroy(fscache_cookie_jar); 172 kmem_cache_destroy(fscache_cookie_jar);
173 unregister_sysctl_table(fscache_sysctl_header);
99 fscache_proc_cleanup(); 174 fscache_proc_cleanup();
175 destroy_workqueue(fscache_object_wq);
100 slow_work_unregister_user(THIS_MODULE); 176 slow_work_unregister_user(THIS_MODULE);
101 printk(KERN_NOTICE "FS-Cache: Unloaded\n"); 177 printk(KERN_NOTICE "FS-Cache: Unloaded\n");
102} 178}