aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/ext4.h4
-rw-r--r--fs/ext4/extents_status.c186
-rw-r--r--fs/ext4/extents_status.h13
-rw-r--r--fs/ext4/super.c11
-rw-r--r--include/trace/events/ext4.h31
5 files changed, 224 insertions, 21 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index c07f43f8eb93..00fd822ac6e4 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -891,6 +891,7 @@ struct ext4_inode_info {
891 struct ext4_es_tree i_es_tree; 891 struct ext4_es_tree i_es_tree;
892 rwlock_t i_es_lock; 892 rwlock_t i_es_lock;
893 struct list_head i_es_lru; 893 struct list_head i_es_lru;
894 unsigned int i_es_all_nr; /* protected by i_es_lock */
894 unsigned int i_es_lru_nr; /* protected by i_es_lock */ 895 unsigned int i_es_lru_nr; /* protected by i_es_lock */
895 unsigned long i_touch_when; /* jiffies of last accessing */ 896 unsigned long i_touch_when; /* jiffies of last accessing */
896 897
@@ -1331,8 +1332,7 @@ struct ext4_sb_info {
1331 /* Reclaim extents from extent status tree */ 1332 /* Reclaim extents from extent status tree */
1332 struct shrinker s_es_shrinker; 1333 struct shrinker s_es_shrinker;
1333 struct list_head s_es_lru; 1334 struct list_head s_es_lru;
1334 unsigned long s_es_last_sorted; 1335 struct ext4_es_stats s_es_stats;
1335 struct percpu_counter s_extent_cache_cnt;
1336 struct mb_cache *s_mb_cache; 1336 struct mb_cache *s_mb_cache;
1337 spinlock_t s_es_lru_lock ____cacheline_aligned_in_smp; 1337 spinlock_t s_es_lru_lock ____cacheline_aligned_in_smp;
1338 1338
diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c
index 95da65c60d83..09fd57667262 100644
--- a/fs/ext4/extents_status.c
+++ b/fs/ext4/extents_status.c
@@ -11,6 +11,8 @@
11 */ 11 */
12#include <linux/rbtree.h> 12#include <linux/rbtree.h>
13#include <linux/list_sort.h> 13#include <linux/list_sort.h>
14#include <linux/proc_fs.h>
15#include <linux/seq_file.h>
14#include "ext4.h" 16#include "ext4.h"
15#include "extents_status.h" 17#include "extents_status.h"
16 18
@@ -313,19 +315,27 @@ ext4_es_alloc_extent(struct inode *inode, ext4_lblk_t lblk, ext4_lblk_t len,
313 */ 315 */
314 if (!ext4_es_is_delayed(es)) { 316 if (!ext4_es_is_delayed(es)) {
315 EXT4_I(inode)->i_es_lru_nr++; 317 EXT4_I(inode)->i_es_lru_nr++;
316 percpu_counter_inc(&EXT4_SB(inode->i_sb)->s_extent_cache_cnt); 318 percpu_counter_inc(&EXT4_SB(inode->i_sb)->
319 s_es_stats.es_stats_lru_cnt);
317 } 320 }
318 321
322 EXT4_I(inode)->i_es_all_nr++;
323 percpu_counter_inc(&EXT4_SB(inode->i_sb)->s_es_stats.es_stats_all_cnt);
324
319 return es; 325 return es;
320} 326}
321 327
322static void ext4_es_free_extent(struct inode *inode, struct extent_status *es) 328static void ext4_es_free_extent(struct inode *inode, struct extent_status *es)
323{ 329{
330 EXT4_I(inode)->i_es_all_nr--;
331 percpu_counter_dec(&EXT4_SB(inode->i_sb)->s_es_stats.es_stats_all_cnt);
332
324 /* Decrease the lru counter when this es is not delayed */ 333 /* Decrease the lru counter when this es is not delayed */
325 if (!ext4_es_is_delayed(es)) { 334 if (!ext4_es_is_delayed(es)) {
326 BUG_ON(EXT4_I(inode)->i_es_lru_nr == 0); 335 BUG_ON(EXT4_I(inode)->i_es_lru_nr == 0);
327 EXT4_I(inode)->i_es_lru_nr--; 336 EXT4_I(inode)->i_es_lru_nr--;
328 percpu_counter_dec(&EXT4_SB(inode->i_sb)->s_extent_cache_cnt); 337 percpu_counter_dec(&EXT4_SB(inode->i_sb)->
338 s_es_stats.es_stats_lru_cnt);
329 } 339 }
330 340
331 kmem_cache_free(ext4_es_cachep, es); 341 kmem_cache_free(ext4_es_cachep, es);
@@ -729,6 +739,7 @@ int ext4_es_lookup_extent(struct inode *inode, ext4_lblk_t lblk,
729 struct extent_status *es) 739 struct extent_status *es)
730{ 740{
731 struct ext4_es_tree *tree; 741 struct ext4_es_tree *tree;
742 struct ext4_es_stats *stats;
732 struct extent_status *es1 = NULL; 743 struct extent_status *es1 = NULL;
733 struct rb_node *node; 744 struct rb_node *node;
734 int found = 0; 745 int found = 0;
@@ -765,11 +776,15 @@ int ext4_es_lookup_extent(struct inode *inode, ext4_lblk_t lblk,
765 } 776 }
766 777
767out: 778out:
779 stats = &EXT4_SB(inode->i_sb)->s_es_stats;
768 if (found) { 780 if (found) {
769 BUG_ON(!es1); 781 BUG_ON(!es1);
770 es->es_lblk = es1->es_lblk; 782 es->es_lblk = es1->es_lblk;
771 es->es_len = es1->es_len; 783 es->es_len = es1->es_len;
772 es->es_pblk = es1->es_pblk; 784 es->es_pblk = es1->es_pblk;
785 stats->es_stats_cache_hits++;
786 } else {
787 stats->es_stats_cache_misses++;
773 } 788 }
774 789
775 read_unlock(&EXT4_I(inode)->i_es_lock); 790 read_unlock(&EXT4_I(inode)->i_es_lock);
@@ -931,11 +946,16 @@ static int __ext4_es_shrink(struct ext4_sb_info *sbi, int nr_to_scan,
931 struct ext4_inode_info *locked_ei) 946 struct ext4_inode_info *locked_ei)
932{ 947{
933 struct ext4_inode_info *ei; 948 struct ext4_inode_info *ei;
949 struct ext4_es_stats *es_stats;
934 struct list_head *cur, *tmp; 950 struct list_head *cur, *tmp;
935 LIST_HEAD(skipped); 951 LIST_HEAD(skipped);
952 ktime_t start_time;
953 u64 scan_time;
936 int nr_shrunk = 0; 954 int nr_shrunk = 0;
937 int retried = 0, skip_precached = 1, nr_skipped = 0; 955 int retried = 0, skip_precached = 1, nr_skipped = 0;
938 956
957 es_stats = &sbi->s_es_stats;
958 start_time = ktime_get();
939 spin_lock(&sbi->s_es_lru_lock); 959 spin_lock(&sbi->s_es_lru_lock);
940 960
941retry: 961retry:
@@ -946,7 +966,8 @@ retry:
946 * If we have already reclaimed all extents from extent 966 * If we have already reclaimed all extents from extent
947 * status tree, just stop the loop immediately. 967 * status tree, just stop the loop immediately.
948 */ 968 */
949 if (percpu_counter_read_positive(&sbi->s_extent_cache_cnt) == 0) 969 if (percpu_counter_read_positive(
970 &es_stats->es_stats_lru_cnt) == 0)
950 break; 971 break;
951 972
952 ei = list_entry(cur, struct ext4_inode_info, i_es_lru); 973 ei = list_entry(cur, struct ext4_inode_info, i_es_lru);
@@ -956,7 +977,7 @@ retry:
956 * time. Normally we try hard to avoid shrinking 977 * time. Normally we try hard to avoid shrinking
957 * precached inodes, but we will as a last resort. 978 * precached inodes, but we will as a last resort.
958 */ 979 */
959 if ((sbi->s_es_last_sorted < ei->i_touch_when) || 980 if ((es_stats->es_stats_last_sorted < ei->i_touch_when) ||
960 (skip_precached && ext4_test_inode_state(&ei->vfs_inode, 981 (skip_precached && ext4_test_inode_state(&ei->vfs_inode,
961 EXT4_STATE_EXT_PRECACHED))) { 982 EXT4_STATE_EXT_PRECACHED))) {
962 nr_skipped++; 983 nr_skipped++;
@@ -990,7 +1011,7 @@ retry:
990 if ((nr_shrunk == 0) && nr_skipped && !retried) { 1011 if ((nr_shrunk == 0) && nr_skipped && !retried) {
991 retried++; 1012 retried++;
992 list_sort(NULL, &sbi->s_es_lru, ext4_inode_touch_time_cmp); 1013 list_sort(NULL, &sbi->s_es_lru, ext4_inode_touch_time_cmp);
993 sbi->s_es_last_sorted = jiffies; 1014 es_stats->es_stats_last_sorted = jiffies;
994 ei = list_first_entry(&sbi->s_es_lru, struct ext4_inode_info, 1015 ei = list_first_entry(&sbi->s_es_lru, struct ext4_inode_info,
995 i_es_lru); 1016 i_es_lru);
996 /* 1017 /*
@@ -1008,6 +1029,22 @@ retry:
1008 if (locked_ei && nr_shrunk == 0) 1029 if (locked_ei && nr_shrunk == 0)
1009 nr_shrunk = __es_try_to_reclaim_extents(locked_ei, nr_to_scan); 1030 nr_shrunk = __es_try_to_reclaim_extents(locked_ei, nr_to_scan);
1010 1031
1032 scan_time = ktime_to_ns(ktime_sub(ktime_get(), start_time));
1033 if (likely(es_stats->es_stats_scan_time))
1034 es_stats->es_stats_scan_time = (scan_time +
1035 es_stats->es_stats_scan_time*3) / 4;
1036 else
1037 es_stats->es_stats_scan_time = scan_time;
1038 if (scan_time > es_stats->es_stats_max_scan_time)
1039 es_stats->es_stats_max_scan_time = scan_time;
1040 if (likely(es_stats->es_stats_shrunk))
1041 es_stats->es_stats_shrunk = (nr_shrunk +
1042 es_stats->es_stats_shrunk*3) / 4;
1043 else
1044 es_stats->es_stats_shrunk = nr_shrunk;
1045
1046 trace_ext4_es_shrink(sbi->s_sb, nr_shrunk, scan_time, skip_precached,
1047 nr_skipped, retried);
1011 return nr_shrunk; 1048 return nr_shrunk;
1012} 1049}
1013 1050
@@ -1018,7 +1055,7 @@ static unsigned long ext4_es_count(struct shrinker *shrink,
1018 struct ext4_sb_info *sbi; 1055 struct ext4_sb_info *sbi;
1019 1056
1020 sbi = container_of(shrink, struct ext4_sb_info, s_es_shrinker); 1057 sbi = container_of(shrink, struct ext4_sb_info, s_es_shrinker);
1021 nr = percpu_counter_read_positive(&sbi->s_extent_cache_cnt); 1058 nr = percpu_counter_read_positive(&sbi->s_es_stats.es_stats_lru_cnt);
1022 trace_ext4_es_shrink_count(sbi->s_sb, sc->nr_to_scan, nr); 1059 trace_ext4_es_shrink_count(sbi->s_sb, sc->nr_to_scan, nr);
1023 return nr; 1060 return nr;
1024} 1061}
@@ -1031,7 +1068,7 @@ static unsigned long ext4_es_scan(struct shrinker *shrink,
1031 int nr_to_scan = sc->nr_to_scan; 1068 int nr_to_scan = sc->nr_to_scan;
1032 int ret, nr_shrunk; 1069 int ret, nr_shrunk;
1033 1070
1034 ret = percpu_counter_read_positive(&sbi->s_extent_cache_cnt); 1071 ret = percpu_counter_read_positive(&sbi->s_es_stats.es_stats_lru_cnt);
1035 trace_ext4_es_shrink_scan_enter(sbi->s_sb, nr_to_scan, ret); 1072 trace_ext4_es_shrink_scan_enter(sbi->s_sb, nr_to_scan, ret);
1036 1073
1037 if (!nr_to_scan) 1074 if (!nr_to_scan)
@@ -1043,19 +1080,148 @@ static unsigned long ext4_es_scan(struct shrinker *shrink,
1043 return nr_shrunk; 1080 return nr_shrunk;
1044} 1081}
1045 1082
1046void ext4_es_register_shrinker(struct ext4_sb_info *sbi) 1083static void *ext4_es_seq_shrinker_info_start(struct seq_file *seq, loff_t *pos)
1084{
1085 return *pos ? NULL : SEQ_START_TOKEN;
1086}
1087
1088static void *
1089ext4_es_seq_shrinker_info_next(struct seq_file *seq, void *v, loff_t *pos)
1090{
1091 return NULL;
1092}
1093
1094static int ext4_es_seq_shrinker_info_show(struct seq_file *seq, void *v)
1095{
1096 struct ext4_sb_info *sbi = seq->private;
1097 struct ext4_es_stats *es_stats = &sbi->s_es_stats;
1098 struct ext4_inode_info *ei, *max = NULL;
1099 unsigned int inode_cnt = 0;
1100
1101 if (v != SEQ_START_TOKEN)
1102 return 0;
1103
1104 /* here we just find an inode that has the max nr. of objects */
1105 spin_lock(&sbi->s_es_lru_lock);
1106 list_for_each_entry(ei, &sbi->s_es_lru, i_es_lru) {
1107 inode_cnt++;
1108 if (max && max->i_es_all_nr < ei->i_es_all_nr)
1109 max = ei;
1110 else if (!max)
1111 max = ei;
1112 }
1113 spin_unlock(&sbi->s_es_lru_lock);
1114
1115 seq_printf(seq, "stats:\n %lld objects\n %lld reclaimable objects\n",
1116 percpu_counter_sum_positive(&es_stats->es_stats_all_cnt),
1117 percpu_counter_sum_positive(&es_stats->es_stats_lru_cnt));
1118 seq_printf(seq, " %lu/%lu cache hits/misses\n",
1119 es_stats->es_stats_cache_hits,
1120 es_stats->es_stats_cache_misses);
1121 if (es_stats->es_stats_last_sorted != 0)
1122 seq_printf(seq, " %u ms last sorted interval\n",
1123 jiffies_to_msecs(jiffies -
1124 es_stats->es_stats_last_sorted));
1125 if (inode_cnt)
1126 seq_printf(seq, " %d inodes on lru list\n", inode_cnt);
1127
1128 seq_printf(seq, "average:\n %llu us scan time\n",
1129 div_u64(es_stats->es_stats_scan_time, 1000));
1130 seq_printf(seq, " %lu shrunk objects\n", es_stats->es_stats_shrunk);
1131 if (inode_cnt)
1132 seq_printf(seq,
1133 "maximum:\n %lu inode (%u objects, %u reclaimable)\n"
1134 " %llu us max scan time\n",
1135 max->vfs_inode.i_ino, max->i_es_all_nr, max->i_es_lru_nr,
1136 div_u64(es_stats->es_stats_max_scan_time, 1000));
1137
1138 return 0;
1139}
1140
1141static void ext4_es_seq_shrinker_info_stop(struct seq_file *seq, void *v)
1142{
1143}
1144
1145static const struct seq_operations ext4_es_seq_shrinker_info_ops = {
1146 .start = ext4_es_seq_shrinker_info_start,
1147 .next = ext4_es_seq_shrinker_info_next,
1148 .stop = ext4_es_seq_shrinker_info_stop,
1149 .show = ext4_es_seq_shrinker_info_show,
1150};
1151
1152static int
1153ext4_es_seq_shrinker_info_open(struct inode *inode, struct file *file)
1154{
1155 int ret;
1156
1157 ret = seq_open(file, &ext4_es_seq_shrinker_info_ops);
1158 if (!ret) {
1159 struct seq_file *m = file->private_data;
1160 m->private = PDE_DATA(inode);
1161 }
1162
1163 return ret;
1164}
1165
1166static int
1167ext4_es_seq_shrinker_info_release(struct inode *inode, struct file *file)
1168{
1169 return seq_release(inode, file);
1170}
1171
1172static const struct file_operations ext4_es_seq_shrinker_info_fops = {
1173 .owner = THIS_MODULE,
1174 .open = ext4_es_seq_shrinker_info_open,
1175 .read = seq_read,
1176 .llseek = seq_lseek,
1177 .release = ext4_es_seq_shrinker_info_release,
1178};
1179
1180int ext4_es_register_shrinker(struct ext4_sb_info *sbi)
1047{ 1181{
1182 int err;
1183
1048 INIT_LIST_HEAD(&sbi->s_es_lru); 1184 INIT_LIST_HEAD(&sbi->s_es_lru);
1049 spin_lock_init(&sbi->s_es_lru_lock); 1185 spin_lock_init(&sbi->s_es_lru_lock);
1050 sbi->s_es_last_sorted = 0; 1186 sbi->s_es_stats.es_stats_last_sorted = 0;
1187 sbi->s_es_stats.es_stats_shrunk = 0;
1188 sbi->s_es_stats.es_stats_cache_hits = 0;
1189 sbi->s_es_stats.es_stats_cache_misses = 0;
1190 sbi->s_es_stats.es_stats_scan_time = 0;
1191 sbi->s_es_stats.es_stats_max_scan_time = 0;
1192 err = percpu_counter_init(&sbi->s_es_stats.es_stats_all_cnt, 0);
1193 if (err)
1194 return err;
1195 err = percpu_counter_init(&sbi->s_es_stats.es_stats_lru_cnt, 0);
1196 if (err)
1197 goto err1;
1198
1051 sbi->s_es_shrinker.scan_objects = ext4_es_scan; 1199 sbi->s_es_shrinker.scan_objects = ext4_es_scan;
1052 sbi->s_es_shrinker.count_objects = ext4_es_count; 1200 sbi->s_es_shrinker.count_objects = ext4_es_count;
1053 sbi->s_es_shrinker.seeks = DEFAULT_SEEKS; 1201 sbi->s_es_shrinker.seeks = DEFAULT_SEEKS;
1054 register_shrinker(&sbi->s_es_shrinker); 1202 err = register_shrinker(&sbi->s_es_shrinker);
1203 if (err)
1204 goto err2;
1205
1206 if (sbi->s_proc)
1207 proc_create_data("es_shrinker_info", S_IRUGO, sbi->s_proc,
1208 &ext4_es_seq_shrinker_info_fops, sbi);
1209
1210 return 0;
1211
1212err2:
1213 percpu_counter_destroy(&sbi->s_es_stats.es_stats_lru_cnt);
1214err1:
1215 percpu_counter_destroy(&sbi->s_es_stats.es_stats_all_cnt);
1216 return err;
1055} 1217}
1056 1218
1057void ext4_es_unregister_shrinker(struct ext4_sb_info *sbi) 1219void ext4_es_unregister_shrinker(struct ext4_sb_info *sbi)
1058{ 1220{
1221 if (sbi->s_proc)
1222 remove_proc_entry("es_shrinker_info", sbi->s_proc);
1223 percpu_counter_destroy(&sbi->s_es_stats.es_stats_all_cnt);
1224 percpu_counter_destroy(&sbi->s_es_stats.es_stats_lru_cnt);
1059 unregister_shrinker(&sbi->s_es_shrinker); 1225 unregister_shrinker(&sbi->s_es_shrinker);
1060} 1226}
1061 1227
diff --git a/fs/ext4/extents_status.h b/fs/ext4/extents_status.h
index f1b62a419920..efd5f970b501 100644
--- a/fs/ext4/extents_status.h
+++ b/fs/ext4/extents_status.h
@@ -64,6 +64,17 @@ struct ext4_es_tree {
64 struct extent_status *cache_es; /* recently accessed extent */ 64 struct extent_status *cache_es; /* recently accessed extent */
65}; 65};
66 66
67struct ext4_es_stats {
68 unsigned long es_stats_last_sorted;
69 unsigned long es_stats_shrunk;
70 unsigned long es_stats_cache_hits;
71 unsigned long es_stats_cache_misses;
72 u64 es_stats_scan_time;
73 u64 es_stats_max_scan_time;
74 struct percpu_counter es_stats_all_cnt;
75 struct percpu_counter es_stats_lru_cnt;
76};
77
67extern int __init ext4_init_es(void); 78extern int __init ext4_init_es(void);
68extern void ext4_exit_es(void); 79extern void ext4_exit_es(void);
69extern void ext4_es_init_tree(struct ext4_es_tree *tree); 80extern void ext4_es_init_tree(struct ext4_es_tree *tree);
@@ -138,7 +149,7 @@ static inline void ext4_es_store_pblock_status(struct extent_status *es,
138 (pb & ~ES_MASK)); 149 (pb & ~ES_MASK));
139} 150}
140 151
141extern void ext4_es_register_shrinker(struct ext4_sb_info *sbi); 152extern int ext4_es_register_shrinker(struct ext4_sb_info *sbi);
142extern void ext4_es_unregister_shrinker(struct ext4_sb_info *sbi); 153extern void ext4_es_unregister_shrinker(struct ext4_sb_info *sbi);
143extern void ext4_es_lru_add(struct inode *inode); 154extern void ext4_es_lru_add(struct inode *inode);
144extern void ext4_es_lru_del(struct inode *inode); 155extern void ext4_es_lru_del(struct inode *inode);
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 7194a51eb217..487c65b8cff0 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -820,7 +820,6 @@ static void ext4_put_super(struct super_block *sb)
820 percpu_counter_destroy(&sbi->s_freeinodes_counter); 820 percpu_counter_destroy(&sbi->s_freeinodes_counter);
821 percpu_counter_destroy(&sbi->s_dirs_counter); 821 percpu_counter_destroy(&sbi->s_dirs_counter);
822 percpu_counter_destroy(&sbi->s_dirtyclusters_counter); 822 percpu_counter_destroy(&sbi->s_dirtyclusters_counter);
823 percpu_counter_destroy(&sbi->s_extent_cache_cnt);
824 brelse(sbi->s_sbh); 823 brelse(sbi->s_sbh);
825#ifdef CONFIG_QUOTA 824#ifdef CONFIG_QUOTA
826 for (i = 0; i < MAXQUOTAS; i++) 825 for (i = 0; i < MAXQUOTAS; i++)
@@ -885,6 +884,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
885 ext4_es_init_tree(&ei->i_es_tree); 884 ext4_es_init_tree(&ei->i_es_tree);
886 rwlock_init(&ei->i_es_lock); 885 rwlock_init(&ei->i_es_lock);
887 INIT_LIST_HEAD(&ei->i_es_lru); 886 INIT_LIST_HEAD(&ei->i_es_lru);
887 ei->i_es_all_nr = 0;
888 ei->i_es_lru_nr = 0; 888 ei->i_es_lru_nr = 0;
889 ei->i_touch_when = 0; 889 ei->i_touch_when = 0;
890 ei->i_reserved_data_blocks = 0; 890 ei->i_reserved_data_blocks = 0;
@@ -3890,12 +3890,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
3890 sbi->s_err_report.data = (unsigned long) sb; 3890 sbi->s_err_report.data = (unsigned long) sb;
3891 3891
3892 /* Register extent status tree shrinker */ 3892 /* Register extent status tree shrinker */
3893 ext4_es_register_shrinker(sbi); 3893 if (ext4_es_register_shrinker(sbi))
3894
3895 if ((err = percpu_counter_init(&sbi->s_extent_cache_cnt, 0)) != 0) {
3896 ext4_msg(sb, KERN_ERR, "insufficient memory");
3897 goto failed_mount3; 3894 goto failed_mount3;
3898 }
3899 3895
3900 sbi->s_stripe = ext4_get_stripe_size(sbi); 3896 sbi->s_stripe = ext4_get_stripe_size(sbi);
3901 sbi->s_extent_max_zeroout_kb = 32; 3897 sbi->s_extent_max_zeroout_kb = 32;
@@ -4225,10 +4221,9 @@ failed_mount_wq:
4225 jbd2_journal_destroy(sbi->s_journal); 4221 jbd2_journal_destroy(sbi->s_journal);
4226 sbi->s_journal = NULL; 4222 sbi->s_journal = NULL;
4227 } 4223 }
4228failed_mount3:
4229 ext4_es_unregister_shrinker(sbi); 4224 ext4_es_unregister_shrinker(sbi);
4225failed_mount3:
4230 del_timer_sync(&sbi->s_err_report); 4226 del_timer_sync(&sbi->s_err_report);
4231 percpu_counter_destroy(&sbi->s_extent_cache_cnt);
4232 if (sbi->s_mmp_tsk) 4227 if (sbi->s_mmp_tsk)
4233 kthread_stop(sbi->s_mmp_tsk); 4228 kthread_stop(sbi->s_mmp_tsk);
4234failed_mount2: 4229failed_mount2:
diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h
index 849aaba75dc8..ff4bd1b35246 100644
--- a/include/trace/events/ext4.h
+++ b/include/trace/events/ext4.h
@@ -2450,6 +2450,37 @@ TRACE_EVENT(ext4_collapse_range,
2450 __entry->offset, __entry->len) 2450 __entry->offset, __entry->len)
2451); 2451);
2452 2452
2453TRACE_EVENT(ext4_es_shrink,
2454 TP_PROTO(struct super_block *sb, int nr_shrunk, u64 scan_time,
2455 int skip_precached, int nr_skipped, int retried),
2456
2457 TP_ARGS(sb, nr_shrunk, scan_time, skip_precached, nr_skipped, retried),
2458
2459 TP_STRUCT__entry(
2460 __field( dev_t, dev )
2461 __field( int, nr_shrunk )
2462 __field( unsigned long long, scan_time )
2463 __field( int, skip_precached )
2464 __field( int, nr_skipped )
2465 __field( int, retried )
2466 ),
2467
2468 TP_fast_assign(
2469 __entry->dev = sb->s_dev;
2470 __entry->nr_shrunk = nr_shrunk;
2471 __entry->scan_time = div_u64(scan_time, 1000);
2472 __entry->skip_precached = skip_precached;
2473 __entry->nr_skipped = nr_skipped;
2474 __entry->retried = retried;
2475 ),
2476
2477 TP_printk("dev %d,%d nr_shrunk %d, scan_time %llu skip_precached %d "
2478 "nr_skipped %d retried %d",
2479 MAJOR(__entry->dev), MINOR(__entry->dev), __entry->nr_shrunk,
2480 __entry->scan_time, __entry->skip_precached,
2481 __entry->nr_skipped, __entry->retried)
2482);
2483
2453#endif /* _TRACE_EXT4_H */ 2484#endif /* _TRACE_EXT4_H */
2454 2485
2455/* This part must be outside protection */ 2486/* This part must be outside protection */