aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2009-09-18 13:38:55 -0400
committerTheodore Ts'o <tytso@mit.edu>2009-09-18 13:38:55 -0400
commit6ba495e9259cd9a0b40ebd6c315143535c92542f (patch)
tree7d43ea10a8971087e6e8b00c9934b0cf83e53d1e
parent91cc219ad963731191247c5f2db4118be2bc341a (diff)
ext4: Add configurable run-time mballoc debugging
Allow mballoc debugging to be enabled at run-time instead of just at compile time. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-rw-r--r--fs/ext4/Kconfig9
-rw-r--r--fs/ext4/mballoc.c81
-rw-r--r--fs/ext4/mballoc.h16
3 files changed, 80 insertions, 26 deletions
diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig
index 152304624644..d5c0ea2e8f2d 100644
--- a/fs/ext4/Kconfig
+++ b/fs/ext4/Kconfig
@@ -77,3 +77,12 @@ config EXT4_FS_SECURITY
77 77
78 If you are not using a security module that requires using 78 If you are not using a security module that requires using
79 extended attributes for file security labels, say N. 79 extended attributes for file security labels, say N.
80
81config EXT4_DEBUG
82 bool "EXT4 debugging support"
83 depends on EXT4_FS
84 help
85 Enables run-time debugging support for the ext4 filesystem.
86
87 If you select Y here, then you will be able to turn on debugging
88 with a command such as "echo 1 > /sys/kernel/debug/ext4/mballoc-debug"
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 68cde598b3bf..d80b300c1779 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -22,6 +22,7 @@
22 */ 22 */
23 23
24#include "mballoc.h" 24#include "mballoc.h"
25#include <linux/debugfs.h>
25#include <trace/events/ext4.h> 26#include <trace/events/ext4.h>
26 27
27/* 28/*
@@ -743,7 +744,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
743 char *data; 744 char *data;
744 char *bitmap; 745 char *bitmap;
745 746
746 mb_debug("init page %lu\n", page->index); 747 mb_debug(1, "init page %lu\n", page->index);
747 748
748 inode = page->mapping->host; 749 inode = page->mapping->host;
749 sb = inode->i_sb; 750 sb = inode->i_sb;
@@ -822,7 +823,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
822 set_bitmap_uptodate(bh[i]); 823 set_bitmap_uptodate(bh[i]);
823 bh[i]->b_end_io = end_buffer_read_sync; 824 bh[i]->b_end_io = end_buffer_read_sync;
824 submit_bh(READ, bh[i]); 825 submit_bh(READ, bh[i]);
825 mb_debug("read bitmap for group %u\n", first_group + i); 826 mb_debug(1, "read bitmap for group %u\n", first_group + i);
826 } 827 }
827 828
828 /* wait for I/O completion */ 829 /* wait for I/O completion */
@@ -862,7 +863,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
862 if ((first_block + i) & 1) { 863 if ((first_block + i) & 1) {
863 /* this is block of buddy */ 864 /* this is block of buddy */
864 BUG_ON(incore == NULL); 865 BUG_ON(incore == NULL);
865 mb_debug("put buddy for group %u in page %lu/%x\n", 866 mb_debug(1, "put buddy for group %u in page %lu/%x\n",
866 group, page->index, i * blocksize); 867 group, page->index, i * blocksize);
867 grinfo = ext4_get_group_info(sb, group); 868 grinfo = ext4_get_group_info(sb, group);
868 grinfo->bb_fragments = 0; 869 grinfo->bb_fragments = 0;
@@ -878,7 +879,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
878 } else { 879 } else {
879 /* this is block of bitmap */ 880 /* this is block of bitmap */
880 BUG_ON(incore != NULL); 881 BUG_ON(incore != NULL);
881 mb_debug("put bitmap for group %u in page %lu/%x\n", 882 mb_debug(1, "put bitmap for group %u in page %lu/%x\n",
882 group, page->index, i * blocksize); 883 group, page->index, i * blocksize);
883 884
884 /* see comments in ext4_mb_put_pa() */ 885 /* see comments in ext4_mb_put_pa() */
@@ -922,7 +923,7 @@ ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group,
922 struct ext4_sb_info *sbi = EXT4_SB(sb); 923 struct ext4_sb_info *sbi = EXT4_SB(sb);
923 struct inode *inode = sbi->s_buddy_cache; 924 struct inode *inode = sbi->s_buddy_cache;
924 925
925 mb_debug("load group %u\n", group); 926 mb_debug(1, "load group %u\n", group);
926 927
927 blocks_per_page = PAGE_CACHE_SIZE / sb->s_blocksize; 928 blocks_per_page = PAGE_CACHE_SIZE / sb->s_blocksize;
928 grp = ext4_get_group_info(sb, group); 929 grp = ext4_get_group_info(sb, group);
@@ -1851,7 +1852,7 @@ int ext4_mb_init_group(struct super_block *sb, ext4_group_t group)
1851 struct inode *inode = sbi->s_buddy_cache; 1852 struct inode *inode = sbi->s_buddy_cache;
1852 struct page *page = NULL, *bitmap_page = NULL; 1853 struct page *page = NULL, *bitmap_page = NULL;
1853 1854
1854 mb_debug("init group %u\n", group); 1855 mb_debug(1, "init group %u\n", group);
1855 blocks_per_page = PAGE_CACHE_SIZE / sb->s_blocksize; 1856 blocks_per_page = PAGE_CACHE_SIZE / sb->s_blocksize;
1856 this_grp = ext4_get_group_info(sb, group); 1857 this_grp = ext4_get_group_info(sb, group);
1857 /* 1858 /*
@@ -2739,7 +2740,7 @@ static void ext4_mb_cleanup_pa(struct ext4_group_info *grp)
2739 kmem_cache_free(ext4_pspace_cachep, pa); 2740 kmem_cache_free(ext4_pspace_cachep, pa);
2740 } 2741 }
2741 if (count) 2742 if (count)
2742 mb_debug("mballoc: %u PAs left\n", count); 2743 mb_debug(1, "mballoc: %u PAs left\n", count);
2743 2744
2744} 2745}
2745 2746
@@ -2820,7 +2821,7 @@ static void release_blocks_on_commit(journal_t *journal, transaction_t *txn)
2820 list_for_each_safe(l, ltmp, &txn->t_private_list) { 2821 list_for_each_safe(l, ltmp, &txn->t_private_list) {
2821 entry = list_entry(l, struct ext4_free_data, list); 2822 entry = list_entry(l, struct ext4_free_data, list);
2822 2823
2823 mb_debug("gonna free %u blocks in group %u (0x%p):", 2824 mb_debug(1, "gonna free %u blocks in group %u (0x%p):",
2824 entry->count, entry->group, entry); 2825 entry->count, entry->group, entry);
2825 2826
2826 err = ext4_mb_load_buddy(sb, entry->group, &e4b); 2827 err = ext4_mb_load_buddy(sb, entry->group, &e4b);
@@ -2855,9 +2856,43 @@ static void release_blocks_on_commit(journal_t *journal, transaction_t *txn)
2855 ext4_mb_release_desc(&e4b); 2856 ext4_mb_release_desc(&e4b);
2856 } 2857 }
2857 2858
2858 mb_debug("freed %u blocks in %u structures\n", count, count2); 2859 mb_debug(1, "freed %u blocks in %u structures\n", count, count2);
2859} 2860}
2860 2861
2862#ifdef CONFIG_EXT4_DEBUG
2863u8 mb_enable_debug __read_mostly;
2864
2865static struct dentry *debugfs_dir;
2866static struct dentry *debugfs_debug;
2867
2868static void __init ext4_create_debugfs_entry(void)
2869{
2870 debugfs_dir = debugfs_create_dir("ext4", NULL);
2871 if (debugfs_dir)
2872 debugfs_debug = debugfs_create_u8("mballoc-debug",
2873 S_IRUGO | S_IWUSR,
2874 debugfs_dir,
2875 &mb_enable_debug);
2876}
2877
2878static void ext4_remove_debugfs_entry(void)
2879{
2880 debugfs_remove(debugfs_debug);
2881 debugfs_remove(debugfs_dir);
2882}
2883
2884#else
2885
2886static void __init ext4_create_debugfs_entry(void)
2887{
2888}
2889
2890static void ext4_remove_debugfs_entry(void)
2891{
2892}
2893
2894#endif
2895
2861int __init init_ext4_mballoc(void) 2896int __init init_ext4_mballoc(void)
2862{ 2897{
2863 ext4_pspace_cachep = 2898 ext4_pspace_cachep =
@@ -2885,6 +2920,7 @@ int __init init_ext4_mballoc(void)
2885 kmem_cache_destroy(ext4_ac_cachep); 2920 kmem_cache_destroy(ext4_ac_cachep);
2886 return -ENOMEM; 2921 return -ENOMEM;
2887 } 2922 }
2923 ext4_create_debugfs_entry();
2888 return 0; 2924 return 0;
2889} 2925}
2890 2926
@@ -2898,6 +2934,7 @@ void exit_ext4_mballoc(void)
2898 kmem_cache_destroy(ext4_pspace_cachep); 2934 kmem_cache_destroy(ext4_pspace_cachep);
2899 kmem_cache_destroy(ext4_ac_cachep); 2935 kmem_cache_destroy(ext4_ac_cachep);
2900 kmem_cache_destroy(ext4_free_ext_cachep); 2936 kmem_cache_destroy(ext4_free_ext_cachep);
2937 ext4_remove_debugfs_entry();
2901} 2938}
2902 2939
2903 2940
@@ -3042,7 +3079,7 @@ static void ext4_mb_normalize_group_request(struct ext4_allocation_context *ac)
3042 ac->ac_g_ex.fe_len = EXT4_SB(sb)->s_stripe; 3079 ac->ac_g_ex.fe_len = EXT4_SB(sb)->s_stripe;
3043 else 3080 else
3044 ac->ac_g_ex.fe_len = EXT4_SB(sb)->s_mb_group_prealloc; 3081 ac->ac_g_ex.fe_len = EXT4_SB(sb)->s_mb_group_prealloc;
3045 mb_debug("#%u: goal %u blocks for locality group\n", 3082 mb_debug(1, "#%u: goal %u blocks for locality group\n",
3046 current->pid, ac->ac_g_ex.fe_len); 3083 current->pid, ac->ac_g_ex.fe_len);
3047} 3084}
3048 3085
@@ -3232,7 +3269,7 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,
3232 ac->ac_flags |= EXT4_MB_HINT_TRY_GOAL; 3269 ac->ac_flags |= EXT4_MB_HINT_TRY_GOAL;
3233 } 3270 }
3234 3271
3235 mb_debug("goal: %u(was %u) blocks at %u\n", (unsigned) size, 3272 mb_debug(1, "goal: %u(was %u) blocks at %u\n", (unsigned) size,
3236 (unsigned) orig_size, (unsigned) start); 3273 (unsigned) orig_size, (unsigned) start);
3237} 3274}
3238 3275
@@ -3281,7 +3318,7 @@ static void ext4_mb_use_inode_pa(struct ext4_allocation_context *ac,
3281 BUG_ON(pa->pa_free < len); 3318 BUG_ON(pa->pa_free < len);
3282 pa->pa_free -= len; 3319 pa->pa_free -= len;
3283 3320
3284 mb_debug("use %llu/%u from inode pa %p\n", start, len, pa); 3321 mb_debug(1, "use %llu/%u from inode pa %p\n", start, len, pa);
3285} 3322}
3286 3323
3287/* 3324/*
@@ -3305,7 +3342,7 @@ static void ext4_mb_use_group_pa(struct ext4_allocation_context *ac,
3305 * in on-disk bitmap -- see ext4_mb_release_context() 3342 * in on-disk bitmap -- see ext4_mb_release_context()
3306 * Other CPUs are prevented from allocating from this pa by lg_mutex 3343 * Other CPUs are prevented from allocating from this pa by lg_mutex
3307 */ 3344 */
3308 mb_debug("use %u/%u from group pa %p\n", pa->pa_lstart-len, len, pa); 3345 mb_debug(1, "use %u/%u from group pa %p\n", pa->pa_lstart-len, len, pa);
3309} 3346}
3310 3347
3311/* 3348/*
@@ -3484,7 +3521,7 @@ void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap,
3484 preallocated += len; 3521 preallocated += len;
3485 count++; 3522 count++;
3486 } 3523 }
3487 mb_debug("prellocated %u for group %u\n", preallocated, group); 3524 mb_debug(1, "prellocated %u for group %u\n", preallocated, group);
3488} 3525}
3489 3526
3490static void ext4_mb_pa_callback(struct rcu_head *head) 3527static void ext4_mb_pa_callback(struct rcu_head *head)
@@ -3619,7 +3656,7 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac)
3619 pa->pa_deleted = 0; 3656 pa->pa_deleted = 0;
3620 pa->pa_type = MB_INODE_PA; 3657 pa->pa_type = MB_INODE_PA;
3621 3658
3622 mb_debug("new inode pa %p: %llu/%u for %u\n", pa, 3659 mb_debug(1, "new inode pa %p: %llu/%u for %u\n", pa,
3623 pa->pa_pstart, pa->pa_len, pa->pa_lstart); 3660 pa->pa_pstart, pa->pa_len, pa->pa_lstart);
3624 trace_ext4_mb_new_inode_pa(ac, pa); 3661 trace_ext4_mb_new_inode_pa(ac, pa);
3625 3662
@@ -3679,7 +3716,7 @@ ext4_mb_new_group_pa(struct ext4_allocation_context *ac)
3679 pa->pa_deleted = 0; 3716 pa->pa_deleted = 0;
3680 pa->pa_type = MB_GROUP_PA; 3717 pa->pa_type = MB_GROUP_PA;
3681 3718
3682 mb_debug("new group pa %p: %llu/%u for %u\n", pa, 3719 mb_debug(1, "new group pa %p: %llu/%u for %u\n", pa,
3683 pa->pa_pstart, pa->pa_len, pa->pa_lstart); 3720 pa->pa_pstart, pa->pa_len, pa->pa_lstart);
3684 trace_ext4_mb_new_group_pa(ac, pa); 3721 trace_ext4_mb_new_group_pa(ac, pa);
3685 3722
@@ -3758,7 +3795,7 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh,
3758 next = mb_find_next_bit(bitmap_bh->b_data, end, bit); 3795 next = mb_find_next_bit(bitmap_bh->b_data, end, bit);
3759 start = group * EXT4_BLOCKS_PER_GROUP(sb) + bit + 3796 start = group * EXT4_BLOCKS_PER_GROUP(sb) + bit +
3760 le32_to_cpu(sbi->s_es->s_first_data_block); 3797 le32_to_cpu(sbi->s_es->s_first_data_block);
3761 mb_debug(" free preallocated %u/%u in group %u\n", 3798 mb_debug(1, " free preallocated %u/%u in group %u\n",
3762 (unsigned) start, (unsigned) next - bit, 3799 (unsigned) start, (unsigned) next - bit,
3763 (unsigned) group); 3800 (unsigned) group);
3764 free += next - bit; 3801 free += next - bit;
@@ -3849,7 +3886,7 @@ ext4_mb_discard_group_preallocations(struct super_block *sb,
3849 int busy = 0; 3886 int busy = 0;
3850 int free = 0; 3887 int free = 0;
3851 3888
3852 mb_debug("discard preallocation for group %u\n", group); 3889 mb_debug(1, "discard preallocation for group %u\n", group);
3853 3890
3854 if (list_empty(&grp->bb_prealloc_list)) 3891 if (list_empty(&grp->bb_prealloc_list))
3855 return 0; 3892 return 0;
@@ -3973,7 +4010,7 @@ void ext4_discard_preallocations(struct inode *inode)
3973 return; 4010 return;
3974 } 4011 }
3975 4012
3976 mb_debug("discard preallocation for inode %lu\n", inode->i_ino); 4013 mb_debug(1, "discard preallocation for inode %lu\n", inode->i_ino);
3977 trace_ext4_discard_preallocations(inode); 4014 trace_ext4_discard_preallocations(inode);
3978 4015
3979 INIT_LIST_HEAD(&list); 4016 INIT_LIST_HEAD(&list);
@@ -4078,7 +4115,7 @@ static void ext4_mb_return_to_preallocation(struct inode *inode,
4078{ 4115{
4079 BUG_ON(!list_empty(&EXT4_I(inode)->i_prealloc_list)); 4116 BUG_ON(!list_empty(&EXT4_I(inode)->i_prealloc_list));
4080} 4117}
4081#ifdef MB_DEBUG 4118#ifdef CONFIG_EXT4_DEBUG
4082static void ext4_mb_show_ac(struct ext4_allocation_context *ac) 4119static void ext4_mb_show_ac(struct ext4_allocation_context *ac)
4083{ 4120{
4084 struct super_block *sb = ac->ac_sb; 4121 struct super_block *sb = ac->ac_sb;
@@ -4227,7 +4264,7 @@ ext4_mb_initialize_context(struct ext4_allocation_context *ac,
4227 * locality group. this is a policy, actually */ 4264 * locality group. this is a policy, actually */
4228 ext4_mb_group_or_file(ac); 4265 ext4_mb_group_or_file(ac);
4229 4266
4230 mb_debug("init ac: %u blocks @ %u, goal %u, flags %x, 2^%d, " 4267 mb_debug(1, "init ac: %u blocks @ %u, goal %u, flags %x, 2^%d, "
4231 "left: %u/%u, right %u/%u to %swritable\n", 4268 "left: %u/%u, right %u/%u to %swritable\n",
4232 (unsigned) ar->len, (unsigned) ar->logical, 4269 (unsigned) ar->len, (unsigned) ar->logical,
4233 (unsigned) ar->goal, ac->ac_flags, ac->ac_2order, 4270 (unsigned) ar->goal, ac->ac_flags, ac->ac_2order,
@@ -4249,7 +4286,7 @@ ext4_mb_discard_lg_preallocations(struct super_block *sb,
4249 struct ext4_prealloc_space *pa, *tmp; 4286 struct ext4_prealloc_space *pa, *tmp;
4250 struct ext4_allocation_context *ac; 4287 struct ext4_allocation_context *ac;
4251 4288
4252 mb_debug("discard locality group preallocation\n"); 4289 mb_debug(1, "discard locality group preallocation\n");
4253 4290
4254 INIT_LIST_HEAD(&discard_list); 4291 INIT_LIST_HEAD(&discard_list);
4255 ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS); 4292 ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS);
diff --git a/fs/ext4/mballoc.h b/fs/ext4/mballoc.h
index c96bb19f58f9..9db890d4d275 100644
--- a/fs/ext4/mballoc.h
+++ b/fs/ext4/mballoc.h
@@ -37,11 +37,19 @@
37 37
38/* 38/*
39 */ 39 */
40#define MB_DEBUG__ 40#ifdef CONFIG_EXT4_DEBUG
41#ifdef MB_DEBUG 41extern u8 mb_enable_debug;
42#define mb_debug(fmt, a...) printk(fmt, ##a) 42
43#define mb_debug(n, fmt, a...) \
44 do { \
45 if ((n) <= mb_enable_debug) { \
46 printk(KERN_DEBUG "(%s, %d): %s: ", \
47 __FILE__, __LINE__, __func__); \
48 printk(fmt, ## a); \
49 } \
50 } while (0)
43#else 51#else
44#define mb_debug(fmt, a...) 52#define mb_debug(n, fmt, a...)
45#endif 53#endif
46 54
47/* 55/*