f2fs: reuse inode_entry_slab in gc procedure for using slab more effectively
PATCH 1/1 f2fs: reuse inode_entry_slab in gc procedure for using slab more effectively
There are two slab cache inode_entry_slab and winode_slab using the same structure as below:
struct dir_inode_entry {
struct list_head list; /* list head */
struct inode *inode; /* vfs inode pointer */
};
struct inode_entry {
struct list_head list;
struct inode *inode;
};It's a little waste that the two cache can not share their memory space for each other.
So in this patch we remove one redundant winode_slab slab cache, then use more universal name struct inode_entry as remaining data structure name of slab, finally we reuse the inode_entry_slab to store dirty dir item and gc item for more effective.
Signed-off-by Chao Yu <[email protected]>
--- fs/f2fs/checkpoint.c | 18 +++++++++--------- fs/f2fs/debug.c | 2 +- fs/f2fs/f2fs.h | 14 +++++++++----- fs/f2fs/gc.c | 20 ++------------------ fs/f2fs/gc.h | 7 ++----- fs/f2fs/super.c | 8 +------- 6 files changed, 24 insertions(+), 45 deletions(-)
fs/f2fs/checkpoint.c +9 -9
@@ -24,7 +24,7 @@#include <trace/events/f2fs.h> static struct kmem_cache *ino_entry_slab; -static struct kmem_cache *inode_entry_slab; +struct kmem_cache *inode_entry_slab;/* * We guarantee no failure on the returned page.
@@ -673,7 +673,7 @@ fail_no_cp:return -EINVAL ; } -static int __add_dirty_inode (struct inode *inode,struct dir_inode_entry *new) +static int __add_dirty_inode (struct inode *inode,struct inode_entry *new) {struct f2fs_sb_info *sbi =F2FS_I_SB (inode);
@@ -690,7 +690,7 @@ static int __add_dirty_inode(struct inode *inode, struct dir_inode_entry *new)void update_dirty_page (struct inode *inode,struct page *page) {struct f2fs_sb_info *sbi =F2FS_I_SB (inode); -struct dir_inode_entry *new; +struct inode_entry *new;int ret =0 ;if (!S_ISDIR (inode->i_mode) && !S_ISREG (inode->i_mode))
@@ -720,7 +720,7 @@ out:void add_dirty_dir_inode (struct inode *inode) {struct f2fs_sb_info *sbi =F2FS_I_SB (inode); -struct dir_inode_entry *new = +struct inode_entry *new =f2fs_kmem_cache_alloc (inode_entry_slab,GFP_NOFS );int ret =0 ;
@@ -738,7 +738,7 @@ void add_dirty_dir_inode(struct inode *inode)void remove_dirty_dir_inode (struct inode *inode) {struct f2fs_sb_info *sbi =F2FS_I_SB (inode); -struct dir_inode_entry *entry; +struct inode_entry *entry;if (!S_ISDIR (inode->i_mode))return ;
@@ -768,7 +768,7 @@ void remove_dirty_dir_inode(struct inode *inode)void sync_dirty_dir_inodes (struct f2fs_sb_info *sbi) {struct list_head *head; -struct dir_inode_entry *entry; +struct inode_entry *entry;struct inode *inode; retry:if (unlikely (f2fs_cp_error (sbi)))
@@ -781,7 +781,7 @@ retry:spin_unlock (&sbi->dir_inode_lock);return ; } - entry = list_entry(head->next, struct dir_inode_entry, list); + entry = list_entry(head->next, struct inode_entry, list); inode =igrab (entry->inode);spin_unlock (&sbi->dir_inode_lock);if (inode) {
@@ -1107,8 +1107,8 @@ int __init create_checkpoint_caches(void) sizeof(struct ino_entry));if (!ino_entry_slab)return -ENOMEM ; - inode_entry_slab =f2fs_kmem_cache_create ("f2fs_dirty_dir_entry" , -sizeof (struct dir_inode_entry )); + inode_entry_slab =f2fs_kmem_cache_create ("f2fs_inode_entry" , +sizeof (struct inode_entry ));if (!inode_entry_slab) {kmem_cache_destroy (ino_entry_slab);return -ENOMEM ;
fs/f2fs/debug.c +1 -1
@@ -172,7 +172,7 @@ get_cache: si->cache_mem += npages <<PAGE_CACHE_SHIFT ; npages =META_MAPPING (sbi)->nrpages; si->cache_mem += npages <<PAGE_CACHE_SHIFT ; - si->cache_mem += sbi->n_dirty_dirs *sizeof (struct dir_inode_entry ); + si->cache_mem += sbi->n_dirty_dirs *sizeof (struct inode_entry );for (i =0 ; i <=UPDATE_INO ; i++) si->cache_mem += sbi->im[i].ino_num *sizeof (struct ino_entry ); }
fs/f2fs/f2fs.h +9 -5
@@ -136,8 +136,14 @@ struct ino_entry {nid_t ino;/* inode number */ }; -/* for the list of directory inodes */ -struct dir_inode_entry { +/* +* for the list of directory inodes or gc inodes. +* NOTE: there are two slab users for this structure, if we add/modify/delete +* fields in structure for one of slab users, it may affect fields or size of +* other one, in this condition, it's better to split both of slab and related +* data structure. +*/ +struct inode_entry {struct list_head list;/* list head */ struct inode *inode;/* vfs inode pointer */ };
@@ -297,7 +303,7 @@ struct f2fs_inode_info {nid_t i_xattr_nid;/* node id that contains xattrs */ unsigned long long xattr_ver;/* cp version of xattr modification */ struct extent_info ext;/* in-memory extent cache entry */ -struct dir_inode_entry *dirty_dir;/* the pointer of dirty dir */ +struct inode_entry *dirty_dir;/* the pointer of dirty dir */ struct radix_tree_root inmem_root;/* radix tree for inmem pages */ struct list_head inmem_pages;/* inmemory pages managed by f2fs */
@@ -1487,8 +1493,6 @@ void stop_gc_thread(struct f2fs_sb_info *);block_t start_bidx_of_node (unsigned int ,struct f2fs_inode_info *);int f2fs_gc (struct f2fs_sb_info *);void build_gc_manager (struct f2fs_sb_info *); -int __init create_gc_caches (void ); -void destroy_gc_caches (void );/* * recovery.c
fs/f2fs/gc.c +2 -18
@@ -24,8 +24,6 @@#include "gc.h" #include <trace/events/f2fs.h> -static struct kmem_cache *winode_slab; -static int gc_thread_func (void *data) {struct f2fs_sb_info *sbi = data;
@@ -356,7 +354,7 @@ static void add_gc_inode(struct gc_inode_list *gc_list, struct inode *inode)iput (inode);return ; } - new_ie =f2fs_kmem_cache_alloc (winode_slab,GFP_NOFS ); + new_ie =f2fs_kmem_cache_alloc (inode_entry_slab,GFP_NOFS ); new_ie->inode = inode; retry:if (radix_tree_insert (&gc_list->iroot, inode->i_ino, new_ie)) {
@@ -373,7 +371,7 @@ static void put_gc_inode(struct gc_inode_list *gc_list)radix_tree_delete (&gc_list->iroot, ie->inode->i_ino);iput (ie->inode);list_del (&ie->list); -kmem_cache_free (winode_slab, ie); +kmem_cache_free (inode_entry_slab, ie); } }
@@ -750,17 +748,3 @@ void build_gc_manager(struct f2fs_sb_info *sbi) {DIRTY_I (sbi)->v_ops = &default_v_ops; } - -int __init create_gc_caches (void ) -{ - winode_slab =f2fs_kmem_cache_create ("f2fs_gc_inodes" , -sizeof (struct inode_entry )); -if (!winode_slab) -return -ENOMEM ; -return 0 ; -} - -void destroy_gc_caches (void ) -{ -kmem_cache_destroy (winode_slab); -}
fs/f2fs/gc.h +2 -5
@@ -35,16 +35,13 @@ struct f2fs_gc_kthread {unsigned int gc_idle; }; -struct inode_entry { -struct list_head list; -struct inode *inode; -}; -struct gc_inode_list {struct list_head ilist;struct radix_tree_root iroot; }; +extern struct kmem_cache *inode_entry_slab; +/* * inline functions */
fs/f2fs/super.c +1 -7
@@ -1231,12 +1231,9 @@ static int __init init_f2fs_fs(void) err =create_segment_manager_caches ();if (err) goto free_node_manager_caches; - err =create_gc_caches (); -if (err) - goto free_segment_manager_caches; err =create_checkpoint_caches ();if (err) - goto free_gc_caches; + goto free_segment_manager_caches; f2fs_kset =kset_create_and_add ("f2fs" ,NULL , fs_kobj);if (!f2fs_kset) { err = -ENOMEM ;
@@ -1253,8 +1250,6 @@ free_kset:kset_unregister (f2fs_kset); free_checkpoint_caches:destroy_checkpoint_caches (); -free_gc_caches: -destroy_gc_caches (); free_segment_manager_caches:destroy_segment_manager_caches (); free_node_manager_caches:
@@ -1271,7 +1266,6 @@ static void __exit exit_f2fs_fs(void)f2fs_destroy_root_stats ();unregister_filesystem (&f2fs_fs_type);destroy_checkpoint_caches (); -destroy_gc_caches ();destroy_segment_manager_caches ();destroy_node_manager_caches ();destroy_inodecache ();
Signature · 1 line
2.2.1