diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2007-08-01 08:57:10 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2007-10-10 03:55:08 -0400 |
commit | 8fbbfd214c853102b614f4705c1904ed14f5a808 (patch) | |
tree | b33cb7ee7392d64f99124588ef6af7c0d0bc7e9d /fs | |
parent | ca5a939b33166a9f5a2556e6c4ec031524852ba2 (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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/gfs2/daemon.c | 24 | ||||
-rw-r--r-- | fs/gfs2/daemon.h | 1 | ||||
-rw-r--r-- | fs/gfs2/glock.c | 63 | ||||
-rw-r--r-- | fs/gfs2/glock.h | 4 | ||||
-rw-r--r-- | fs/gfs2/incore.h | 2 | ||||
-rw-r--r-- | fs/gfs2/main.c | 3 | ||||
-rw-r--r-- | fs/gfs2/ops_fstype.c | 9 | ||||
-rw-r--r-- | fs/gfs2/ops_super.c | 1 | ||||
-rw-r--r-- | fs/gfs2/super.c | 1 | ||||
-rw-r--r-- | fs/gfs2/sys.c | 2 |
10 files changed, 53 insertions, 57 deletions
diff --git a/fs/gfs2/daemon.c b/fs/gfs2/daemon.c index 3548d9f31e0d..3731ab0771d5 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 | |||
45 | int 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 801007120fb2..0de9b3557955 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 | ||
13 | int gfs2_scand(void *data); | ||
14 | int gfs2_glockd(void *data); | 13 | int gfs2_glockd(void *data); |
15 | int gfs2_recoverd(void *data); | 14 | int gfs2_recoverd(void *data); |
16 | int gfs2_logd(void *data); | 15 | int gfs2_logd(void *data); |
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 0054b7df714a..559937c710fc 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); | |||
58 | static void gfs2_glock_drop_th(struct gfs2_glock *gl); | 60 | static void gfs2_glock_drop_th(struct gfs2_glock *gl); |
59 | static DECLARE_RWSEM(gfs2_umount_flush_sem); | 61 | static DECLARE_RWSEM(gfs2_umount_flush_sem); |
60 | static struct dentry *gfs2_root; | 62 | static struct dentry *gfs2_root; |
63 | static struct task_struct *scand_process; | ||
64 | static 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 | |||
1681 | void 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 | |||
1975 | static 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 | |||
1976 | int __init gfs2_glock_init(void) | 1996 | int __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 | ||
2015 | void gfs2_glock_exit(void) | ||
2016 | { | ||
2017 | kthread_stop(scand_process); | ||
2018 | } | ||
2019 | |||
2020 | module_param(scand_secs, uint, S_IRUGO|S_IWUSR); | ||
2021 | MODULE_PARM_DESC(scand_secs, "The number of seconds between scand runs"); | ||
2022 | |||
1990 | static int gfs2_glock_iter_next(struct glock_iter *gi) | 2023 | static 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 7721ca3fff9e..f7a8e626aa08 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 | ||
133 | void gfs2_glock_schedule_for_reclaim(struct gfs2_glock *gl); | 133 | void gfs2_glock_schedule_for_reclaim(struct gfs2_glock *gl); |
134 | void gfs2_reclaim_glock(struct gfs2_sbd *sdp); | 134 | void gfs2_reclaim_glock(struct gfs2_sbd *sdp); |
135 | |||
136 | void gfs2_scand_internal(struct gfs2_sbd *sdp); | ||
137 | void gfs2_gl_hash_clear(struct gfs2_sbd *sdp, int wait); | 135 | void gfs2_gl_hash_clear(struct gfs2_sbd *sdp, int wait); |
138 | 136 | ||
139 | int __init gfs2_glock_init(void); | 137 | int __init gfs2_glock_init(void); |
138 | void gfs2_glock_exit(void); | ||
139 | |||
140 | int gfs2_create_debugfs_file(struct gfs2_sbd *sdp); | 140 | int gfs2_create_debugfs_file(struct gfs2_sbd *sdp); |
141 | void gfs2_delete_debugfs_file(struct gfs2_sbd *sdp); | 141 | void gfs2_delete_debugfs_file(struct gfs2_sbd *sdp); |
142 | int gfs2_register_debugfs(void); | 142 | int gfs2_register_debugfs(void); |
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 170ba93829c0..1390b30daf19 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 d5d4e68b8807..79c91fd8381b 100644 --- a/fs/gfs2/main.c +++ b/fs/gfs2/main.c | |||
@@ -107,6 +107,8 @@ static int __init init_gfs2_fs(void) | |||
107 | fail_unregister: | 107 | fail_unregister: |
108 | unregister_filesystem(&gfs2_fs_type); | 108 | unregister_filesystem(&gfs2_fs_type); |
109 | fail: | 109 | fail: |
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 | ||
128 | static void __exit exit_gfs2_fs(void) | 130 | static 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 9a5e84038dd6..58c730be2073 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 603d940f1159..4316690d86f6 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 f916b9740c75..55898023782b 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 c26c21b53c19..ba3a1729cc1a 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c | |||
@@ -442,7 +442,6 @@ TUNE_ATTR(quota_simul_sync, 1); | |||
442 | TUNE_ATTR(quota_cache_secs, 1); | 442 | TUNE_ATTR(quota_cache_secs, 1); |
443 | TUNE_ATTR(stall_secs, 1); | 443 | TUNE_ATTR(stall_secs, 1); |
444 | TUNE_ATTR(statfs_quantum, 1); | 444 | TUNE_ATTR(statfs_quantum, 1); |
445 | TUNE_ATTR_DAEMON(scand_secs, scand_process); | ||
446 | TUNE_ATTR_DAEMON(recoverd_secs, recoverd_process); | 445 | TUNE_ATTR_DAEMON(recoverd_secs, recoverd_process); |
447 | TUNE_ATTR_DAEMON(logd_secs, logd_process); | 446 | TUNE_ATTR_DAEMON(logd_secs, logd_process); |
448 | TUNE_ATTR_DAEMON(quotad_secs, quotad_process); | 447 | TUNE_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, |