Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 06292073 authored by Chao Yu's avatar Chao Yu Committed by Jaegeuk Kim
Browse files

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: default avatarChao Yu <chao2.yu@samsung.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 2ace38e0
Loading
Loading
Loading
Loading
+9 −9
Original line number Original line Diff line number Diff line
@@ -24,7 +24,7 @@
#include <trace/events/f2fs.h>
#include <trace/events/f2fs.h>


static struct kmem_cache *ino_entry_slab;
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.
 * We guarantee no failure on the returned page.
@@ -673,7 +673,7 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi)
	return -EINVAL;
	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);
	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)
void update_dirty_page(struct inode *inode, struct page *page)
{
{
	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
	struct dir_inode_entry *new;
	struct inode_entry *new;
	int ret = 0;
	int ret = 0;


	if (!S_ISDIR(inode->i_mode) && !S_ISREG(inode->i_mode))
	if (!S_ISDIR(inode->i_mode) && !S_ISREG(inode->i_mode))
@@ -720,7 +720,7 @@ void update_dirty_page(struct inode *inode, struct page *page)
void add_dirty_dir_inode(struct inode *inode)
void add_dirty_dir_inode(struct inode *inode)
{
{
	struct f2fs_sb_info *sbi = F2FS_I_SB(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);
			f2fs_kmem_cache_alloc(inode_entry_slab, GFP_NOFS);
	int ret = 0;
	int ret = 0;


@@ -738,7 +738,7 @@ void add_dirty_dir_inode(struct inode *inode)
void remove_dirty_dir_inode(struct inode *inode)
void remove_dirty_dir_inode(struct inode *inode)
{
{
	struct f2fs_sb_info *sbi = F2FS_I_SB(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))
	if (!S_ISDIR(inode->i_mode))
		return;
		return;
@@ -768,7 +768,7 @@ void remove_dirty_dir_inode(struct inode *inode)
void sync_dirty_dir_inodes(struct f2fs_sb_info *sbi)
void sync_dirty_dir_inodes(struct f2fs_sb_info *sbi)
{
{
	struct list_head *head;
	struct list_head *head;
	struct dir_inode_entry *entry;
	struct inode_entry *entry;
	struct inode *inode;
	struct inode *inode;
retry:
retry:
	if (unlikely(f2fs_cp_error(sbi)))
	if (unlikely(f2fs_cp_error(sbi)))
@@ -781,7 +781,7 @@ void sync_dirty_dir_inodes(struct f2fs_sb_info *sbi)
		spin_unlock(&sbi->dir_inode_lock);
		spin_unlock(&sbi->dir_inode_lock);
		return;
		return;
	}
	}
	entry = list_entry(head->next, struct dir_inode_entry, list);
	entry = list_entry(head->next, struct inode_entry, list);
	inode = igrab(entry->inode);
	inode = igrab(entry->inode);
	spin_unlock(&sbi->dir_inode_lock);
	spin_unlock(&sbi->dir_inode_lock);
	if (inode) {
	if (inode) {
@@ -1107,8 +1107,8 @@ int __init create_checkpoint_caches(void)
			sizeof(struct ino_entry));
			sizeof(struct ino_entry));
	if (!ino_entry_slab)
	if (!ino_entry_slab)
		return -ENOMEM;
		return -ENOMEM;
	inode_entry_slab = f2fs_kmem_cache_create("f2fs_dirty_dir_entry",
	inode_entry_slab = f2fs_kmem_cache_create("f2fs_inode_entry",
			sizeof(struct dir_inode_entry));
			sizeof(struct inode_entry));
	if (!inode_entry_slab) {
	if (!inode_entry_slab) {
		kmem_cache_destroy(ino_entry_slab);
		kmem_cache_destroy(ino_entry_slab);
		return -ENOMEM;
		return -ENOMEM;
+1 −1
Original line number Original line Diff line number Diff line
@@ -172,7 +172,7 @@ static void update_mem_info(struct f2fs_sb_info *sbi)
	si->cache_mem += npages << PAGE_CACHE_SHIFT;
	si->cache_mem += npages << PAGE_CACHE_SHIFT;
	npages = META_MAPPING(sbi)->nrpages;
	npages = META_MAPPING(sbi)->nrpages;
	si->cache_mem += npages << PAGE_CACHE_SHIFT;
	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++)
	for (i = 0; i <= UPDATE_INO; i++)
		si->cache_mem += sbi->im[i].ino_num * sizeof(struct ino_entry);
		si->cache_mem += sbi->im[i].ino_num * sizeof(struct ino_entry);
}
}
+9 −5
Original line number Original line Diff line number Diff line
@@ -136,8 +136,14 @@ struct ino_entry {
	nid_t ino;		/* inode number */
	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 list_head list;	/* list head */
	struct inode *inode;	/* vfs inode pointer */
	struct inode *inode;	/* vfs inode pointer */
};
};
@@ -297,7 +303,7 @@ struct f2fs_inode_info {
	nid_t i_xattr_nid;		/* node id that contains xattrs */
	nid_t i_xattr_nid;		/* node id that contains xattrs */
	unsigned long long xattr_ver;	/* cp version of xattr modification */
	unsigned long long xattr_ver;	/* cp version of xattr modification */
	struct extent_info ext;		/* in-memory extent cache entry */
	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 radix_tree_root inmem_root;	/* radix tree for inmem pages */
	struct list_head inmem_pages;	/* inmemory pages managed by f2fs */
	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 *);
block_t start_bidx_of_node(unsigned int, struct f2fs_inode_info *);
int f2fs_gc(struct f2fs_sb_info *);
int f2fs_gc(struct f2fs_sb_info *);
void build_gc_manager(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
 * recovery.c
+2 −18
Original line number Original line Diff line number Diff line
@@ -24,8 +24,6 @@
#include "gc.h"
#include "gc.h"
#include <trace/events/f2fs.h>
#include <trace/events/f2fs.h>


static struct kmem_cache *winode_slab;

static int gc_thread_func(void *data)
static int gc_thread_func(void *data)
{
{
	struct f2fs_sb_info *sbi = 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);
		iput(inode);
		return;
		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;
	new_ie->inode = inode;
retry:
retry:
	if (radix_tree_insert(&gc_list->iroot, inode->i_ino, new_ie)) {
	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);
		radix_tree_delete(&gc_list->iroot, ie->inode->i_ino);
		iput(ie->inode);
		iput(ie->inode);
		list_del(&ie->list);
		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;
	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);
}
+2 −5
Original line number Original line Diff line number Diff line
@@ -35,16 +35,13 @@ struct f2fs_gc_kthread {
	unsigned int gc_idle;
	unsigned int gc_idle;
};
};


struct inode_entry {
	struct list_head list;
	struct inode *inode;
};

struct gc_inode_list {
struct gc_inode_list {
	struct list_head ilist;
	struct list_head ilist;
	struct radix_tree_root iroot;
	struct radix_tree_root iroot;
};
};


extern struct kmem_cache *inode_entry_slab;

/*
/*
 * inline functions
 * inline functions
 */
 */
Loading