From 3699e3a44bf56e0cd58c97e8655f375ad9b65d9d Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Wed, 17 Jan 2007 15:09:20 +0000 Subject: [GFS2] Clean up/speed up readdir This removes the extra filldir callback which gfs2 was using to enclose an attempt at readahead for inodes during readdir. The code was too complicated and also hurts performance badly in the case that the getdents64/readdir call isn't being followed by stat() and it wasn't even getting it right all the time when it was. As a result, on my test box an "ls" of a directory containing 250000 files fell from about 7mins (freshly mounted, so nothing cached) to between about 15 to 25 seconds. When the directory content was cached, the time taken fell from about 3mins to about 4 or 5 seconds. Interestingly in the cached case, running "ls -l" once reduced the time taken for subsequent runs of "ls" to about 6 secs even without this patch. Now it turns out that there was a special case of glocks being used for prefetching the metadata, but because of the timeouts for these locks (set to 10 secs) the metadata was being timed out before it was being used and this the prefetch code was constantly trying to prefetch the same data over and over. Calling "ls -l" meant that the inodes were brought into memory and once the inodes are cached, the glocks are not disposed of until the inodes are pushed out of the cache, thus extending the lifetime of the glocks, and thus bringing down the time for subsequent runs of "ls" considerably. Signed-off-by: Steven Whitehouse --- fs/gfs2/incore.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'fs/gfs2/incore.h') diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 734421e..8075870 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -147,7 +147,6 @@ struct gfs2_holder { enum { GLF_LOCK = 1, GLF_STICKY = 2, - GLF_PREFETCH = 3, GLF_DIRTY = 5, GLF_SKIP_WAITERS2 = 6, GLF_GREEDY = 7, @@ -425,7 +424,6 @@ struct gfs2_tune { unsigned int gt_complain_secs; unsigned int gt_reclaim_limit; /* Max num of glocks in reclaim list */ unsigned int gt_entries_per_readdir; - unsigned int gt_prefetch_secs; /* Usage window for prefetched glocks */ unsigned int gt_greedy_default; unsigned int gt_greedy_quantum; unsigned int gt_greedy_max; -- cgit v1.1 From 330005c2b23e71e54931913e9b63d1712a19e444 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Mon, 15 Jan 2007 16:36:26 -0500 Subject: [GFS2] Remove max_atomic_write tunable This removes an unused sysfs tunable parameter. Signed-off-by: Steven Whitehouse --- fs/gfs2/incore.h | 1 - 1 file changed, 1 deletion(-) (limited to 'fs/gfs2/incore.h') diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 8075870..9114851 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -417,7 +417,6 @@ struct gfs2_tune { unsigned int gt_atime_quantum; /* Min secs between atime updates */ unsigned int gt_new_files_jdata; unsigned int gt_new_files_directio; - unsigned int gt_max_atomic_write; /* Split big writes into this size */ unsigned int gt_max_readahead; /* Max bytes to read-ahead from disk */ unsigned int gt_lockdump_size; unsigned int gt_stall_secs; /* Detects trouble! */ -- cgit v1.1 From fee852e374fb367c5436b1226eb93b35f8355ed9 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Wed, 17 Jan 2007 15:33:23 +0000 Subject: [GFS2] Shrink gfs2_inode memory by half Here is something I spotted (while looking for something entirely different) the other day. Rather than using a completion in each and every struct gfs2_holder, this removes it in favour of hashed wait queues, thus saving a considerable amount of memory both on the stack (where a number of gfs2_holder structures are allocated) and in particular in the gfs2_inode which has 8 gfs2_holder structures embedded within it. As a result on x86_64 the gfs2_inode shrinks from 2488 bytes to 1912 bytes, a saving of 576 bytes per inode (no thats not a typo!). In actual practice we get a much better result than that since now that a gfs2_inode is under the 2048 byte barrier, we get two per 4k slab page effectively halving the amount of memory required to store gfs2_inodes. Signed-off-by: Steven Whitehouse --- fs/gfs2/incore.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/gfs2/incore.h') diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 9114851..a24c4af 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -128,6 +128,7 @@ enum { HIF_HOLDER = 6, HIF_FIRST = 7, HIF_ABORTED = 9, + HIF_WAIT = 10, }; struct gfs2_holder { @@ -140,7 +141,6 @@ struct gfs2_holder { int gh_error; unsigned long gh_iflags; - struct completion gh_wait; unsigned long gh_ip; }; -- cgit v1.1 From e5dab552c82ce416d7be867b1e5a0fa585dcf590 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Thu, 18 Jan 2007 17:44:20 +0000 Subject: [GFS2] Remove the "greedy" function from glock.[ch] The "greedy" code was an attempt to retain glocks for a minimum length of time when they relate to mmap()ed files. The current implementation of this feature is not, however, ideal in that it required allocating memory in order to do this and its overly complicated. It also misses the mark by ignoring the other I/O operations which are just as likely to suffer from the same problem. So the plan is to remove this now and then add the functionality back as part of the glock state machine at a later date (and thus take into account all the possible users of this feature) Signed-off-by: Steven Whitehouse --- fs/gfs2/incore.h | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'fs/gfs2/incore.h') diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index a24c4af..dc024b1 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -111,7 +111,6 @@ struct gfs2_glock_operations { int (*go_lock) (struct gfs2_holder *gh); void (*go_unlock) (struct gfs2_holder *gh); void (*go_callback) (struct gfs2_glock *gl, unsigned int state); - void (*go_greedy) (struct gfs2_glock *gl); const int go_type; }; @@ -120,7 +119,6 @@ enum { HIF_MUTEX = 0, HIF_PROMOTE = 1, HIF_DEMOTE = 2, - HIF_GREEDY = 3, /* States */ HIF_ALLOCED = 4, @@ -149,7 +147,6 @@ enum { GLF_STICKY = 2, GLF_DIRTY = 5, GLF_SKIP_WAITERS2 = 6, - GLF_GREEDY = 7, }; struct gfs2_glock { @@ -166,7 +163,7 @@ struct gfs2_glock { unsigned long gl_ip; struct list_head gl_holders; struct list_head gl_waiters1; /* HIF_MUTEX */ - struct list_head gl_waiters2; /* HIF_DEMOTE, HIF_GREEDY */ + struct list_head gl_waiters2; /* HIF_DEMOTE */ struct list_head gl_waiters3; /* HIF_PROMOTE */ const struct gfs2_glock_operations *gl_ops; @@ -235,7 +232,6 @@ struct gfs2_inode { spinlock_t i_spin; struct rw_semaphore i_rw_mutex; - unsigned int i_greedy; unsigned long i_last_pfault; struct buffer_head *i_cache[GFS2_MAX_META_HEIGHT]; @@ -423,9 +419,6 @@ struct gfs2_tune { unsigned int gt_complain_secs; unsigned int gt_reclaim_limit; /* Max num of glocks in reclaim list */ unsigned int gt_entries_per_readdir; - unsigned int gt_greedy_default; - unsigned int gt_greedy_quantum; - unsigned int gt_greedy_max; unsigned int gt_statfs_quantum; unsigned int gt_statfs_slow; }; -- cgit v1.1 From 6bd9c8c2fb99d1f5af6201db2f063c1d754c230a Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Fri, 19 Jan 2007 13:57:36 -0500 Subject: [GFS2] Remove unused go_callback operation This is never used, so we might as well remove it. Signed-off-by: Steven Whitehouse --- fs/gfs2/incore.h | 1 - 1 file changed, 1 deletion(-) (limited to 'fs/gfs2/incore.h') diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index dc024b1..1acbcc2 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -110,7 +110,6 @@ struct gfs2_glock_operations { int (*go_demote_ok) (struct gfs2_glock *gl); int (*go_lock) (struct gfs2_holder *gh); void (*go_unlock) (struct gfs2_holder *gh); - void (*go_callback) (struct gfs2_glock *gl, unsigned int state); const int go_type; }; -- cgit v1.1 From b5d32bead1578afc5ca817d40c320764d50a8600 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Mon, 22 Jan 2007 12:15:34 -0500 Subject: [GFS2] Tidy up glops calls This patch doesn't make any changes to the ordering of the various operations related to glocking, but it does tidy up the calls to the glops.c functions to make the structure more obvious. The two functions: gfs2_glock_xmote_th() and gfs2_glock_drop_th() can be made static within glock.c since they are called by every set of glock operations. The xmote_th and drop_th glock operations are then made conditional upon those two routines existing and called from the previously mentioned functions in glock.c respectively. Also it can be seen that the go_sync operation isn't needed since it can easily be replaced by calls to xmote_bh and drop_bh respectively. This results in no longer (confusingly) calling back into routines in glock.c from glops.c and also reducing the glock operations by one member. Signed-off-by: Steven Whitehouse --- fs/gfs2/incore.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'fs/gfs2/incore.h') diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 1acbcc2..12c80fd 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -101,11 +101,10 @@ struct gfs2_bufdata { }; struct gfs2_glock_operations { - void (*go_xmote_th) (struct gfs2_glock *gl, unsigned int state, int flags); + void (*go_xmote_th) (struct gfs2_glock *gl); void (*go_xmote_bh) (struct gfs2_glock *gl); void (*go_drop_th) (struct gfs2_glock *gl); void (*go_drop_bh) (struct gfs2_glock *gl); - void (*go_sync) (struct gfs2_glock *gl); void (*go_inval) (struct gfs2_glock *gl, int flags); int (*go_demote_ok) (struct gfs2_glock *gl); int (*go_lock) (struct gfs2_holder *gh); -- cgit v1.1