aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWang Shilong <wangsl.fnst@cn.fujitsu.com>2013-08-09 01:25:36 -0400
committerChris Mason <chris.mason@fusionio.com>2013-09-01 08:16:27 -0400
commitb9e9a6cbc6d25b89d8007e5a680319e07921ead8 (patch)
tree600fe0d3d6962bf13d6efbca1ddc9cbcb4f0d06b
parent742916b885edbc6453b4769458959929746e8e7e (diff)
Btrfs: allocate prelim_ref with a slab allocater
struct __prelim_ref is allocated and freed frequently when walking backref tree, using slab allocater can not only speed up allocating but also detect memory leaks. Signed-off-by: Wang Shilong <wangsl.fnst@cn.fujitsu.com> Reviewed-by: Miao Xie <miaox@cn.fujitsu.com> Reviewed-by: Jan Schmidt <list.btrfs@jan-o-sch.net> Signed-off-by: Josef Bacik <jbacik@fusionio.com> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
-rw-r--r--fs/btrfs/backref.c33
-rw-r--r--fs/btrfs/backref.h2
-rw-r--r--fs/btrfs/super.c8
3 files changed, 37 insertions, 6 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index f3cb19114c95..0552a599b28f 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -119,6 +119,26 @@ struct __prelim_ref {
119 u64 wanted_disk_byte; 119 u64 wanted_disk_byte;
120}; 120};
121 121
122static struct kmem_cache *btrfs_prelim_ref_cache;
123
124int __init btrfs_prelim_ref_init(void)
125{
126 btrfs_prelim_ref_cache = kmem_cache_create("btrfs_prelim_ref",
127 sizeof(struct __prelim_ref),
128 0,
129 SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD,
130 NULL);
131 if (!btrfs_prelim_ref_cache)
132 return -ENOMEM;
133 return 0;
134}
135
136void btrfs_prelim_ref_exit(void)
137{
138 if (btrfs_prelim_ref_cache)
139 kmem_cache_destroy(btrfs_prelim_ref_cache);
140}
141
122/* 142/*
123 * the rules for all callers of this function are: 143 * the rules for all callers of this function are:
124 * - obtaining the parent is the goal 144 * - obtaining the parent is the goal
@@ -165,7 +185,7 @@ static int __add_prelim_ref(struct list_head *head, u64 root_id,
165{ 185{
166 struct __prelim_ref *ref; 186 struct __prelim_ref *ref;
167 187
168 ref = kmalloc(sizeof(*ref), gfp_mask); 188 ref = kmem_cache_alloc(btrfs_prelim_ref_cache, gfp_mask);
169 if (!ref) 189 if (!ref)
170 return -ENOMEM; 190 return -ENOMEM;
171 191
@@ -368,7 +388,8 @@ static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info,
368 388
369 /* additional parents require new refs being added here */ 389 /* additional parents require new refs being added here */
370 while ((node = ulist_next(parents, &uiter))) { 390 while ((node = ulist_next(parents, &uiter))) {
371 new_ref = kmalloc(sizeof(*new_ref), GFP_NOFS); 391 new_ref = kmem_cache_alloc(btrfs_prelim_ref_cache,
392 GFP_NOFS);
372 if (!new_ref) { 393 if (!new_ref) {
373 ret = -ENOMEM; 394 ret = -ENOMEM;
374 goto out; 395 goto out;
@@ -492,7 +513,7 @@ static void __merge_refs(struct list_head *head, int mode)
492 ref1->count += ref2->count; 513 ref1->count += ref2->count;
493 514
494 list_del(&ref2->list); 515 list_del(&ref2->list);
495 kfree(ref2); 516 kmem_cache_free(btrfs_prelim_ref_cache, ref2);
496 } 517 }
497 518
498 } 519 }
@@ -955,7 +976,7 @@ again:
955 } 976 }
956 } 977 }
957 list_del(&ref->list); 978 list_del(&ref->list);
958 kfree(ref); 979 kmem_cache_free(btrfs_prelim_ref_cache, ref);
959 } 980 }
960 981
961out: 982out:
@@ -963,13 +984,13 @@ out:
963 while (!list_empty(&prefs)) { 984 while (!list_empty(&prefs)) {
964 ref = list_first_entry(&prefs, struct __prelim_ref, list); 985 ref = list_first_entry(&prefs, struct __prelim_ref, list);
965 list_del(&ref->list); 986 list_del(&ref->list);
966 kfree(ref); 987 kmem_cache_free(btrfs_prelim_ref_cache, ref);
967 } 988 }
968 while (!list_empty(&prefs_delayed)) { 989 while (!list_empty(&prefs_delayed)) {
969 ref = list_first_entry(&prefs_delayed, struct __prelim_ref, 990 ref = list_first_entry(&prefs_delayed, struct __prelim_ref,
970 list); 991 list);
971 list_del(&ref->list); 992 list_del(&ref->list);
972 kfree(ref); 993 kmem_cache_free(btrfs_prelim_ref_cache, ref);
973 } 994 }
974 995
975 return ret; 996 return ret;
diff --git a/fs/btrfs/backref.h b/fs/btrfs/backref.h
index 8f2e76702932..a910b27a8ad9 100644
--- a/fs/btrfs/backref.h
+++ b/fs/btrfs/backref.h
@@ -72,4 +72,6 @@ int btrfs_find_one_extref(struct btrfs_root *root, u64 inode_objectid,
72 struct btrfs_inode_extref **ret_extref, 72 struct btrfs_inode_extref **ret_extref,
73 u64 *found_off); 73 u64 *found_off);
74 74
75int __init btrfs_prelim_ref_init(void);
76void btrfs_prelim_ref_exit(void);
75#endif 77#endif
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 4d5d0f3eb0d8..3aab10ce63e8 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -56,6 +56,7 @@
56#include "rcu-string.h" 56#include "rcu-string.h"
57#include "dev-replace.h" 57#include "dev-replace.h"
58#include "free-space-cache.h" 58#include "free-space-cache.h"
59#include "backref.h"
59#include "tests/btrfs-tests.h" 60#include "tests/btrfs-tests.h"
60 61
61#define CREATE_TRACE_POINTS 62#define CREATE_TRACE_POINTS
@@ -1810,6 +1811,10 @@ static int __init init_btrfs_fs(void)
1810 if (err) 1811 if (err)
1811 goto free_auto_defrag; 1812 goto free_auto_defrag;
1812 1813
1814 err = btrfs_prelim_ref_init();
1815 if (err)
1816 goto free_prelim_ref;
1817
1813 err = btrfs_interface_init(); 1818 err = btrfs_interface_init();
1814 if (err) 1819 if (err)
1815 goto free_delayed_ref; 1820 goto free_delayed_ref;
@@ -1830,6 +1835,8 @@ static int __init init_btrfs_fs(void)
1830 1835
1831unregister_ioctl: 1836unregister_ioctl:
1832 btrfs_interface_exit(); 1837 btrfs_interface_exit();
1838free_prelim_ref:
1839 btrfs_prelim_ref_exit();
1833free_delayed_ref: 1840free_delayed_ref:
1834 btrfs_delayed_ref_exit(); 1841 btrfs_delayed_ref_exit();
1835free_auto_defrag: 1842free_auto_defrag:
@@ -1856,6 +1863,7 @@ static void __exit exit_btrfs_fs(void)
1856 btrfs_delayed_ref_exit(); 1863 btrfs_delayed_ref_exit();
1857 btrfs_auto_defrag_exit(); 1864 btrfs_auto_defrag_exit();
1858 btrfs_delayed_inode_exit(); 1865 btrfs_delayed_inode_exit();
1866 btrfs_prelim_ref_exit();
1859 ordered_data_exit(); 1867 ordered_data_exit();
1860 extent_map_exit(); 1868 extent_map_exit();
1861 extent_io_exit(); 1869 extent_io_exit();