aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2007-08-01 08:57:10 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2007-10-10 03:55:08 -0400
commit8fbbfd214c853102b614f4705c1904ed14f5a808 (patch)
treeb33cb7ee7392d64f99124588ef6af7c0d0bc7e9d
parentca5a939b33166a9f5a2556e6c4ec031524852ba2 (diff)
[GFS2] Reduce number of gfs2_scand processes to one
We only need a single gfs2_scand process rather than the one per filesystem which we had previously. As a result the parameter determining the frequency of gfs2_scand runs becomes a module parameter rather than a mount parameter as it was before. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
-rw-r--r--fs/gfs2/daemon.c24
-rw-r--r--fs/gfs2/daemon.h1
-rw-r--r--fs/gfs2/glock.c63
-rw-r--r--fs/gfs2/glock.h4
-rw-r--r--fs/gfs2/incore.h2
-rw-r--r--fs/gfs2/main.c3
-rw-r--r--fs/gfs2/ops_fstype.c9
-rw-r--r--fs/gfs2/ops_super.c1
-rw-r--r--fs/gfs2/super.c1
-rw-r--r--fs/gfs2/sys.c2
10 files changed, 53 insertions, 57 deletions
diff --git a/fs/gfs2/daemon.c b/fs/gfs2/daemon.c
index 3548d9f31e0..3731ab0771d 100644
--- a/fs/gfs2/daemon.c
+++ b/fs/gfs2/daemon.c
@@ -35,30 +35,6 @@
35 The kthread functions used to start these daemons block and flush signals. */ 35 The kthread functions used to start these daemons block and flush signals. */
36 36
37/** 37/**
38 * gfs2_scand - Look for cached glocks and inodes to toss from memory
39 * @sdp: Pointer to GFS2 superblock
40 *
41 * One of these daemons runs, finding candidates to add to sd_reclaim_list.
42 * See gfs2_glockd()
43 */
44
45int gfs2_scand(void *data)
46{
47 struct gfs2_sbd *sdp = data;
48 unsigned long t;
49
50 while (!kthread_should_stop()) {
51 gfs2_scand_internal(sdp);
52 t = gfs2_tune_get(sdp, gt_scand_secs) * HZ;
53 if (freezing(current))
54 refrigerator();
55 schedule_timeout_interruptible(t);
56 }
57
58 return 0;
59}
60
61/**
62 * gfs2_glockd - Reclaim unused glock structures 38 * gfs2_glockd - Reclaim unused glock structures
63 * @sdp: Pointer to GFS2 superblock 39 * @sdp: Pointer to GFS2 superblock
64 * 40 *
diff --git a/fs/gfs2/daemon.h b/fs/gfs2/daemon.h
index 801007120fb..0de9b355795 100644
--- a/fs/gfs2/daemon.h
+++ b/fs/gfs2/daemon.h
@@ -10,7 +10,6 @@
10#ifndef __DAEMON_DOT_H__ 10#ifndef __DAEMON_DOT_H__
11#define __DAEMON_DOT_H__ 11#define __DAEMON_DOT_H__
12 12
13int gfs2_scand(void *data);
14int gfs2_glockd(void *data); 13int gfs2_glockd(void *data);
15int gfs2_recoverd(void *data); 14int gfs2_recoverd(void *data);
16int gfs2_logd(void *data); 15int gfs2_logd(void *data);
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 0054b7df714..559937c710f 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -25,6 +25,8 @@
25#include <asm/uaccess.h> 25#include <asm/uaccess.h>
26#include <linux/seq_file.h> 26#include <linux/seq_file.h>
27#include <linux/debugfs.h> 27#include <linux/debugfs.h>
28#include <linux/kthread.h>
29#include <linux/freezer.h>
28 30
29#include "gfs2.h" 31#include "gfs2.h"
30#include "incore.h" 32#include "incore.h"
@@ -58,6 +60,8 @@ static void gfs2_glock_xmote_th(struct gfs2_glock *gl, struct gfs2_holder *gh);
58static void gfs2_glock_drop_th(struct gfs2_glock *gl); 60static void gfs2_glock_drop_th(struct gfs2_glock *gl);
59static DECLARE_RWSEM(gfs2_umount_flush_sem); 61static DECLARE_RWSEM(gfs2_umount_flush_sem);
60static struct dentry *gfs2_root; 62static struct dentry *gfs2_root;
63static struct task_struct *scand_process;
64static unsigned int scand_secs = 5;
61 65
62#define GFS2_GL_HASH_SHIFT 15 66#define GFS2_GL_HASH_SHIFT 15
63#define GFS2_GL_HASH_SIZE (1 << GFS2_GL_HASH_SHIFT) 67#define GFS2_GL_HASH_SIZE (1 << GFS2_GL_HASH_SHIFT)
@@ -1627,7 +1631,7 @@ static int examine_bucket(glock_examiner examiner, struct gfs2_sbd *sdp,
1627 goto out; 1631 goto out;
1628 gl = list_entry(head->first, struct gfs2_glock, gl_list); 1632 gl = list_entry(head->first, struct gfs2_glock, gl_list);
1629 while(1) { 1633 while(1) {
1630 if (gl->gl_sbd == sdp) { 1634 if (!sdp || gl->gl_sbd == sdp) {
1631 gfs2_glock_hold(gl); 1635 gfs2_glock_hold(gl);
1632 read_unlock(gl_lock_addr(hash)); 1636 read_unlock(gl_lock_addr(hash));
1633 if (prev) 1637 if (prev)
@@ -1645,6 +1649,7 @@ out:
1645 read_unlock(gl_lock_addr(hash)); 1649 read_unlock(gl_lock_addr(hash));
1646 if (prev) 1650 if (prev)
1647 gfs2_glock_put(prev); 1651 gfs2_glock_put(prev);
1652 cond_resched();
1648 return has_entries; 1653 return has_entries;
1649} 1654}
1650 1655
@@ -1673,20 +1678,6 @@ out_schedule:
1673} 1678}
1674 1679
1675/** 1680/**
1676 * gfs2_scand_internal - Look for glocks and inodes to toss from memory
1677 * @sdp: the filesystem
1678 *
1679 */
1680
1681void gfs2_scand_internal(struct gfs2_sbd *sdp)
1682{
1683 unsigned int x;
1684
1685 for (x = 0; x < GFS2_GL_HASH_SIZE; x++)
1686 examine_bucket(scan_glock, sdp, x);
1687}
1688
1689/**
1690 * clear_glock - look at a glock and see if we can free it from glock cache 1681 * clear_glock - look at a glock and see if we can free it from glock cache
1691 * @gl: the glock to look at 1682 * @gl: the glock to look at
1692 * 1683 *
@@ -1973,6 +1964,35 @@ static int gfs2_dump_lockstate(struct gfs2_sbd *sdp)
1973 return error; 1964 return error;
1974} 1965}
1975 1966
1967/**
1968 * gfs2_scand - Look for cached glocks and inodes to toss from memory
1969 * @sdp: Pointer to GFS2 superblock
1970 *
1971 * One of these daemons runs, finding candidates to add to sd_reclaim_list.
1972 * See gfs2_glockd()
1973 */
1974
1975static int gfs2_scand(void *data)
1976{
1977 unsigned x;
1978 unsigned delay;
1979
1980 while (!kthread_should_stop()) {
1981 for (x = 0; x < GFS2_GL_HASH_SIZE; x++)
1982 examine_bucket(scan_glock, NULL, x);
1983 if (freezing(current))
1984 refrigerator();
1985 delay = scand_secs;
1986 if (delay < 1)
1987 delay = 1;
1988 schedule_timeout_interruptible(delay * HZ);
1989 }
1990
1991 return 0;
1992}
1993
1994
1995
1976int __init gfs2_glock_init(void) 1996int __init gfs2_glock_init(void)
1977{ 1997{
1978 unsigned i; 1998 unsigned i;
@@ -1984,9 +2004,22 @@ int __init gfs2_glock_init(void)
1984 rwlock_init(&gl_hash_locks[i]); 2004 rwlock_init(&gl_hash_locks[i]);
1985 } 2005 }
1986#endif 2006#endif
2007
2008 scand_process = kthread_run(gfs2_scand, NULL, "gfs2_scand");
2009 if (IS_ERR(scand_process))
2010 return PTR_ERR(scand_process);
2011
1987 return 0; 2012 return 0;
1988} 2013}
1989 2014
2015void gfs2_glock_exit(void)
2016{
2017 kthread_stop(scand_process);
2018}
2019
2020module_param(scand_secs, uint, S_IRUGO|S_IWUSR);
2021MODULE_PARM_DESC(scand_secs, "The number of seconds between scand runs");
2022
1990static int gfs2_glock_iter_next(struct glock_iter *gi) 2023static int gfs2_glock_iter_next(struct glock_iter *gi)
1991{ 2024{
1992 struct gfs2_glock *gl; 2025 struct gfs2_glock *gl;
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h
index 7721ca3fff9..f7a8e626aa0 100644
--- a/fs/gfs2/glock.h
+++ b/fs/gfs2/glock.h
@@ -132,11 +132,11 @@ void gfs2_glock_cb(void *cb_data, unsigned int type, void *data);
132 132
133void gfs2_glock_schedule_for_reclaim(struct gfs2_glock *gl); 133void gfs2_glock_schedule_for_reclaim(struct gfs2_glock *gl);
134void gfs2_reclaim_glock(struct gfs2_sbd *sdp); 134void gfs2_reclaim_glock(struct gfs2_sbd *sdp);
135
136void gfs2_scand_internal(struct gfs2_sbd *sdp);
137void gfs2_gl_hash_clear(struct gfs2_sbd *sdp, int wait); 135void gfs2_gl_hash_clear(struct gfs2_sbd *sdp, int wait);
138 136
139int __init gfs2_glock_init(void); 137int __init gfs2_glock_init(void);
138void gfs2_glock_exit(void);
139
140int gfs2_create_debugfs_file(struct gfs2_sbd *sdp); 140int gfs2_create_debugfs_file(struct gfs2_sbd *sdp);
141void gfs2_delete_debugfs_file(struct gfs2_sbd *sdp); 141void gfs2_delete_debugfs_file(struct gfs2_sbd *sdp);
142int gfs2_register_debugfs(void); 142int gfs2_register_debugfs(void);
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 170ba93829c..1390b30daf1 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -429,7 +429,6 @@ struct gfs2_tune {
429 unsigned int gt_log_flush_secs; 429 unsigned int gt_log_flush_secs;
430 unsigned int gt_jindex_refresh_secs; /* Check for new journal index */ 430 unsigned int gt_jindex_refresh_secs; /* Check for new journal index */
431 431
432 unsigned int gt_scand_secs;
433 unsigned int gt_recoverd_secs; 432 unsigned int gt_recoverd_secs;
434 unsigned int gt_logd_secs; 433 unsigned int gt_logd_secs;
435 unsigned int gt_quotad_secs; 434 unsigned int gt_quotad_secs;
@@ -574,7 +573,6 @@ struct gfs2_sbd {
574 573
575 /* Daemon stuff */ 574 /* Daemon stuff */
576 575
577 struct task_struct *sd_scand_process;
578 struct task_struct *sd_recoverd_process; 576 struct task_struct *sd_recoverd_process;
579 struct task_struct *sd_logd_process; 577 struct task_struct *sd_logd_process;
580 struct task_struct *sd_quotad_process; 578 struct task_struct *sd_quotad_process;
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c
index d5d4e68b880..79c91fd8381 100644
--- a/fs/gfs2/main.c
+++ b/fs/gfs2/main.c
@@ -107,6 +107,8 @@ static int __init init_gfs2_fs(void)
107fail_unregister: 107fail_unregister:
108 unregister_filesystem(&gfs2_fs_type); 108 unregister_filesystem(&gfs2_fs_type);
109fail: 109fail:
110 gfs2_glock_exit();
111
110 if (gfs2_bufdata_cachep) 112 if (gfs2_bufdata_cachep)
111 kmem_cache_destroy(gfs2_bufdata_cachep); 113 kmem_cache_destroy(gfs2_bufdata_cachep);
112 114
@@ -127,6 +129,7 @@ fail:
127 129
128static void __exit exit_gfs2_fs(void) 130static void __exit exit_gfs2_fs(void)
129{ 131{
132 gfs2_glock_exit();
130 gfs2_unregister_debugfs(); 133 gfs2_unregister_debugfs();
131 unregister_filesystem(&gfs2_fs_type); 134 unregister_filesystem(&gfs2_fs_type);
132 unregister_filesystem(&gfs2meta_fs_type); 135 unregister_filesystem(&gfs2meta_fs_type);
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 9a5e84038dd..58c730be207 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -160,14 +160,6 @@ static int init_locking(struct gfs2_sbd *sdp, struct gfs2_holder *mount_gh,
160 if (undo) 160 if (undo)
161 goto fail_trans; 161 goto fail_trans;
162 162
163 p = kthread_run(gfs2_scand, sdp, "gfs2_scand");
164 error = IS_ERR(p);
165 if (error) {
166 fs_err(sdp, "can't start scand thread: %d\n", error);
167 return error;
168 }
169 sdp->sd_scand_process = p;
170
171 for (sdp->sd_glockd_num = 0; 163 for (sdp->sd_glockd_num = 0;
172 sdp->sd_glockd_num < sdp->sd_args.ar_num_glockd; 164 sdp->sd_glockd_num < sdp->sd_args.ar_num_glockd;
173 sdp->sd_glockd_num++) { 165 sdp->sd_glockd_num++) {
@@ -228,7 +220,6 @@ fail:
228 while (sdp->sd_glockd_num--) 220 while (sdp->sd_glockd_num--)
229 kthread_stop(sdp->sd_glockd_process[sdp->sd_glockd_num]); 221 kthread_stop(sdp->sd_glockd_process[sdp->sd_glockd_num]);
230 222
231 kthread_stop(sdp->sd_scand_process);
232 return error; 223 return error;
233} 224}
234 225
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c
index 603d940f115..4316690d86f 100644
--- a/fs/gfs2/ops_super.c
+++ b/fs/gfs2/ops_super.c
@@ -92,7 +92,6 @@ static void gfs2_put_super(struct super_block *sb)
92 kthread_stop(sdp->sd_recoverd_process); 92 kthread_stop(sdp->sd_recoverd_process);
93 while (sdp->sd_glockd_num--) 93 while (sdp->sd_glockd_num--)
94 kthread_stop(sdp->sd_glockd_process[sdp->sd_glockd_num]); 94 kthread_stop(sdp->sd_glockd_process[sdp->sd_glockd_num]);
95 kthread_stop(sdp->sd_scand_process);
96 95
97 if (!(sb->s_flags & MS_RDONLY)) { 96 if (!(sb->s_flags & MS_RDONLY)) {
98 error = gfs2_make_fs_ro(sdp); 97 error = gfs2_make_fs_ro(sdp);
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index f916b9740c7..55898023782 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -58,7 +58,6 @@ void gfs2_tune_init(struct gfs2_tune *gt)
58 gt->gt_incore_log_blocks = 1024; 58 gt->gt_incore_log_blocks = 1024;
59 gt->gt_log_flush_secs = 60; 59 gt->gt_log_flush_secs = 60;
60 gt->gt_jindex_refresh_secs = 60; 60 gt->gt_jindex_refresh_secs = 60;
61 gt->gt_scand_secs = 15;
62 gt->gt_recoverd_secs = 60; 61 gt->gt_recoverd_secs = 60;
63 gt->gt_logd_secs = 1; 62 gt->gt_logd_secs = 1;
64 gt->gt_quotad_secs = 5; 63 gt->gt_quotad_secs = 5;
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c
index c26c21b53c1..ba3a1729cc1 100644
--- a/fs/gfs2/sys.c
+++ b/fs/gfs2/sys.c
@@ -442,7 +442,6 @@ TUNE_ATTR(quota_simul_sync, 1);
442TUNE_ATTR(quota_cache_secs, 1); 442TUNE_ATTR(quota_cache_secs, 1);
443TUNE_ATTR(stall_secs, 1); 443TUNE_ATTR(stall_secs, 1);
444TUNE_ATTR(statfs_quantum, 1); 444TUNE_ATTR(statfs_quantum, 1);
445TUNE_ATTR_DAEMON(scand_secs, scand_process);
446TUNE_ATTR_DAEMON(recoverd_secs, recoverd_process); 445TUNE_ATTR_DAEMON(recoverd_secs, recoverd_process);
447TUNE_ATTR_DAEMON(logd_secs, logd_process); 446TUNE_ATTR_DAEMON(logd_secs, logd_process);
448TUNE_ATTR_DAEMON(quotad_secs, quotad_process); 447TUNE_ATTR_DAEMON(quotad_secs, quotad_process);
@@ -464,7 +463,6 @@ static struct attribute *tune_attrs[] = {
464 &tune_attr_quota_cache_secs.attr, 463 &tune_attr_quota_cache_secs.attr,
465 &tune_attr_stall_secs.attr, 464 &tune_attr_stall_secs.attr,
466 &tune_attr_statfs_quantum.attr, 465 &tune_attr_statfs_quantum.attr,
467 &tune_attr_scand_secs.attr,
468 &tune_attr_recoverd_secs.attr, 466 &tune_attr_recoverd_secs.attr,
469 &tune_attr_logd_secs.attr, 467 &tune_attr_logd_secs.attr,
470 &tune_attr_quotad_secs.attr, 468 &tune_attr_quotad_secs.attr,