diff options
author | Dave Chinner <dchinner@redhat.com> | 2013-08-27 20:18:09 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-09-10 18:56:31 -0400 |
commit | 1ab6c4997e04a00c50c6d786c2f046adc0d1f5de (patch) | |
tree | 55561fc74c062a8ed0e03fe56f54d7db9cfd9e12 /fs/ext4 | |
parent | 35163417fb7a55a24b6b0ebb102e9991adf309aa (diff) |
fs: convert fs shrinkers to new scan/count API
Convert the filesystem shrinkers to use the new API, and standardise some
of the behaviours of the shrinkers at the same time. For example,
nr_to_scan means the number of objects to scan, not the number of objects
to free.
I refactored the CIFS idmap shrinker a little - it really needs to be
broken up into a shrinker per tree and keep an item count with the tree
root so that we don't need to walk the tree every time the shrinker needs
to count the number of objects in the tree (i.e. all the time under
memory pressure).
[glommer@openvz.org: fixes for ext4, ubifs, nfs, cifs and glock. Fixes are needed mainly due to new code merged in the tree]
[assorted fixes folded in]
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Glauber Costa <glommer@openvz.org>
Acked-by: Mel Gorman <mgorman@suse.de>
Acked-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Acked-by: Jan Kara <jack@suse.cz>
Acked-by: Steven Whitehouse <swhiteho@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: "Theodore Ts'o" <tytso@mit.edu>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Cc: Arve Hjønnevåg <arve@android.com>
Cc: Carlos Maiolino <cmaiolino@redhat.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Chuck Lever <chuck.lever@oracle.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: David Rientjes <rientjes@google.com>
Cc: Gleb Natapov <gleb@redhat.com>
Cc: Greg Thelen <gthelen@google.com>
Cc: J. Bruce Fields <bfields@redhat.com>
Cc: Jan Kara <jack@suse.cz>
Cc: Jerome Glisse <jglisse@redhat.com>
Cc: John Stultz <john.stultz@linaro.org>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Kent Overstreet <koverstreet@google.com>
Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Steven Whitehouse <swhiteho@redhat.com>
Cc: Thomas Hellstrom <thellstrom@vmware.com>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/extents_status.c | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c index 2d1bdbe78c04..3981ff783950 100644 --- a/fs/ext4/extents_status.c +++ b/fs/ext4/extents_status.c | |||
@@ -931,13 +931,15 @@ static int __ext4_es_shrink(struct ext4_sb_info *sbi, int nr_to_scan, | |||
931 | struct ext4_inode_info *ei; | 931 | struct ext4_inode_info *ei; |
932 | struct list_head *cur, *tmp; | 932 | struct list_head *cur, *tmp; |
933 | LIST_HEAD(skipped); | 933 | LIST_HEAD(skipped); |
934 | int ret, nr_shrunk = 0; | 934 | int nr_shrunk = 0; |
935 | int retried = 0, skip_precached = 1, nr_skipped = 0; | 935 | int retried = 0, skip_precached = 1, nr_skipped = 0; |
936 | 936 | ||
937 | spin_lock(&sbi->s_es_lru_lock); | 937 | spin_lock(&sbi->s_es_lru_lock); |
938 | 938 | ||
939 | retry: | 939 | retry: |
940 | list_for_each_safe(cur, tmp, &sbi->s_es_lru) { | 940 | list_for_each_safe(cur, tmp, &sbi->s_es_lru) { |
941 | int shrunk; | ||
942 | |||
941 | /* | 943 | /* |
942 | * If we have already reclaimed all extents from extent | 944 | * If we have already reclaimed all extents from extent |
943 | * status tree, just stop the loop immediately. | 945 | * status tree, just stop the loop immediately. |
@@ -964,13 +966,13 @@ retry: | |||
964 | continue; | 966 | continue; |
965 | 967 | ||
966 | write_lock(&ei->i_es_lock); | 968 | write_lock(&ei->i_es_lock); |
967 | ret = __es_try_to_reclaim_extents(ei, nr_to_scan); | 969 | shrunk = __es_try_to_reclaim_extents(ei, nr_to_scan); |
968 | if (ei->i_es_lru_nr == 0) | 970 | if (ei->i_es_lru_nr == 0) |
969 | list_del_init(&ei->i_es_lru); | 971 | list_del_init(&ei->i_es_lru); |
970 | write_unlock(&ei->i_es_lock); | 972 | write_unlock(&ei->i_es_lock); |
971 | 973 | ||
972 | nr_shrunk += ret; | 974 | nr_shrunk += shrunk; |
973 | nr_to_scan -= ret; | 975 | nr_to_scan -= shrunk; |
974 | if (nr_to_scan == 0) | 976 | if (nr_to_scan == 0) |
975 | break; | 977 | break; |
976 | } | 978 | } |
@@ -1007,7 +1009,20 @@ retry: | |||
1007 | return nr_shrunk; | 1009 | return nr_shrunk; |
1008 | } | 1010 | } |
1009 | 1011 | ||
1010 | static int ext4_es_shrink(struct shrinker *shrink, struct shrink_control *sc) | 1012 | static unsigned long ext4_es_count(struct shrinker *shrink, |
1013 | struct shrink_control *sc) | ||
1014 | { | ||
1015 | unsigned long nr; | ||
1016 | struct ext4_sb_info *sbi; | ||
1017 | |||
1018 | sbi = container_of(shrink, struct ext4_sb_info, s_es_shrinker); | ||
1019 | nr = percpu_counter_read_positive(&sbi->s_extent_cache_cnt); | ||
1020 | trace_ext4_es_shrink_enter(sbi->s_sb, sc->nr_to_scan, nr); | ||
1021 | return nr; | ||
1022 | } | ||
1023 | |||
1024 | static unsigned long ext4_es_scan(struct shrinker *shrink, | ||
1025 | struct shrink_control *sc) | ||
1011 | { | 1026 | { |
1012 | struct ext4_sb_info *sbi = container_of(shrink, | 1027 | struct ext4_sb_info *sbi = container_of(shrink, |
1013 | struct ext4_sb_info, s_es_shrinker); | 1028 | struct ext4_sb_info, s_es_shrinker); |
@@ -1022,9 +1037,8 @@ static int ext4_es_shrink(struct shrinker *shrink, struct shrink_control *sc) | |||
1022 | 1037 | ||
1023 | nr_shrunk = __ext4_es_shrink(sbi, nr_to_scan, NULL); | 1038 | nr_shrunk = __ext4_es_shrink(sbi, nr_to_scan, NULL); |
1024 | 1039 | ||
1025 | ret = percpu_counter_read_positive(&sbi->s_extent_cache_cnt); | ||
1026 | trace_ext4_es_shrink_exit(sbi->s_sb, nr_shrunk, ret); | 1040 | trace_ext4_es_shrink_exit(sbi->s_sb, nr_shrunk, ret); |
1027 | return ret; | 1041 | return nr_shrunk; |
1028 | } | 1042 | } |
1029 | 1043 | ||
1030 | void ext4_es_register_shrinker(struct ext4_sb_info *sbi) | 1044 | void ext4_es_register_shrinker(struct ext4_sb_info *sbi) |
@@ -1032,7 +1046,8 @@ void ext4_es_register_shrinker(struct ext4_sb_info *sbi) | |||
1032 | INIT_LIST_HEAD(&sbi->s_es_lru); | 1046 | INIT_LIST_HEAD(&sbi->s_es_lru); |
1033 | spin_lock_init(&sbi->s_es_lru_lock); | 1047 | spin_lock_init(&sbi->s_es_lru_lock); |
1034 | sbi->s_es_last_sorted = 0; | 1048 | sbi->s_es_last_sorted = 0; |
1035 | sbi->s_es_shrinker.shrink = ext4_es_shrink; | 1049 | sbi->s_es_shrinker.scan_objects = ext4_es_scan; |
1050 | sbi->s_es_shrinker.count_objects = ext4_es_count; | ||
1036 | sbi->s_es_shrinker.seeks = DEFAULT_SEEKS; | 1051 | sbi->s_es_shrinker.seeks = DEFAULT_SEEKS; |
1037 | register_shrinker(&sbi->s_es_shrinker); | 1052 | register_shrinker(&sbi->s_es_shrinker); |
1038 | } | 1053 | } |
@@ -1076,7 +1091,7 @@ static int __es_try_to_reclaim_extents(struct ext4_inode_info *ei, | |||
1076 | struct ext4_es_tree *tree = &ei->i_es_tree; | 1091 | struct ext4_es_tree *tree = &ei->i_es_tree; |
1077 | struct rb_node *node; | 1092 | struct rb_node *node; |
1078 | struct extent_status *es; | 1093 | struct extent_status *es; |
1079 | int nr_shrunk = 0; | 1094 | unsigned long nr_shrunk = 0; |
1080 | static DEFINE_RATELIMIT_STATE(_rs, DEFAULT_RATELIMIT_INTERVAL, | 1095 | static DEFINE_RATELIMIT_STATE(_rs, DEFAULT_RATELIMIT_INTERVAL, |
1081 | DEFAULT_RATELIMIT_BURST); | 1096 | DEFAULT_RATELIMIT_BURST); |
1082 | 1097 | ||