linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/5] f2fs: manipulate dirty file inodes when DATA_FLUSH is set
@ 2016-05-16 22:30 Jaegeuk Kim
  2016-05-16 22:30 ` [PATCH 2/5] f2fs: use percpu_counter for page counters Jaegeuk Kim
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Jaegeuk Kim @ 2016-05-16 22:30 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel, linux-f2fs-devel; +Cc: Jaegeuk Kim

It needs to maintain dirty file inodes only if DATA_FLUSH is set.
Otherwise, let's avoid its overhead.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fs/f2fs/checkpoint.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 3da6499..d04113b 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -785,9 +785,11 @@ void update_dirty_page(struct inode *inode, struct page *page)
 			!S_ISLNK(inode->i_mode))
 		return;
 
-	spin_lock(&sbi->inode_lock[type]);
-	__add_dirty_inode(inode, type);
-	spin_unlock(&sbi->inode_lock[type]);
+	if (type != FILE_INODE || test_opt(sbi, DATA_FLUSH)) {
+		spin_lock(&sbi->inode_lock[type]);
+		__add_dirty_inode(inode, type);
+		spin_unlock(&sbi->inode_lock[type]);
+	}
 
 	inode_inc_dirty_pages(inode);
 	SetPagePrivate(page);
@@ -803,6 +805,9 @@ void remove_dirty_inode(struct inode *inode)
 			!S_ISLNK(inode->i_mode))
 		return;
 
+	if (type == FILE_INODE && !test_opt(sbi, DATA_FLUSH))
+		return;
+
 	spin_lock(&sbi->inode_lock[type]);
 	__remove_dirty_inode(inode, type);
 	spin_unlock(&sbi->inode_lock[type]);
-- 
2.6.3


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/5] f2fs: use percpu_counter for page counters
  2016-05-16 22:30 [PATCH 1/5] f2fs: manipulate dirty file inodes when DATA_FLUSH is set Jaegeuk Kim
@ 2016-05-16 22:30 ` Jaegeuk Kim
  2016-05-16 22:30 ` [PATCH 3/5] f2fs: use percpu_counter for # of dirty pages in inode Jaegeuk Kim
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Jaegeuk Kim @ 2016-05-16 22:30 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel, linux-f2fs-devel; +Cc: Jaegeuk Kim

This patch substitutes percpu_counter for atomic_counter when counting
various types of pages.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fs/f2fs/debug.c |  1 +
 fs/f2fs/f2fs.h  | 12 +++++++-----
 fs/f2fs/super.c | 31 +++++++++++++++++++++++++++----
 3 files changed, 35 insertions(+), 9 deletions(-)

diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
index 37615b2..2210c7c 100644
--- a/fs/f2fs/debug.c
+++ b/fs/f2fs/debug.c
@@ -144,6 +144,7 @@ static void update_mem_info(struct f2fs_sb_info *sbi)
 	si->base_mem = sizeof(struct f2fs_sb_info) + sbi->sb->s_blocksize;
 	si->base_mem += 2 * sizeof(struct f2fs_inode_info);
 	si->base_mem += sizeof(*sbi->ckpt);
+	si->base_mem += sizeof(struct percpu_counter) * NR_COUNT_TYPE;
 
 	/* build sm */
 	si->base_mem += sizeof(struct f2fs_sm_info);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 24f8170..2851078 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -833,7 +833,9 @@ struct f2fs_sb_info {
 	block_t discard_blks;			/* discard command candidats */
 	block_t last_valid_block_count;		/* for recovery */
 	u32 s_next_generation;			/* for NFS support */
-	atomic_t nr_pages[NR_COUNT_TYPE];	/* # of pages, see count_type */
+
+	/* # of pages, see count_type */
+	struct percpu_counter nr_pages[NR_COUNT_TYPE];
 
 	struct f2fs_mount_info mount_opt;	/* mount options */
 
@@ -1178,7 +1180,7 @@ static inline void dec_valid_block_count(struct f2fs_sb_info *sbi,
 
 static inline void inc_page_count(struct f2fs_sb_info *sbi, int count_type)
 {
-	atomic_inc(&sbi->nr_pages[count_type]);
+	percpu_counter_inc(&sbi->nr_pages[count_type]);
 	set_sbi_flag(sbi, SBI_IS_DIRTY);
 }
 
@@ -1191,7 +1193,7 @@ static inline void inode_inc_dirty_pages(struct inode *inode)
 
 static inline void dec_page_count(struct f2fs_sb_info *sbi, int count_type)
 {
-	atomic_dec(&sbi->nr_pages[count_type]);
+	percpu_counter_dec(&sbi->nr_pages[count_type]);
 }
 
 static inline void inode_dec_dirty_pages(struct inode *inode)
@@ -1205,9 +1207,9 @@ static inline void inode_dec_dirty_pages(struct inode *inode)
 				F2FS_DIRTY_DENTS : F2FS_DIRTY_DATA);
 }
 
-static inline int get_pages(struct f2fs_sb_info *sbi, int count_type)
+static inline s64 get_pages(struct f2fs_sb_info *sbi, int count_type)
 {
-	return atomic_read(&sbi->nr_pages[count_type]);
+	return percpu_counter_sum_positive(&sbi->nr_pages[count_type]);
 }
 
 static inline int get_dirty_pages(struct inode *inode)
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 9df6d72..b3030ed 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -606,6 +606,14 @@ static void f2fs_destroy_inode(struct inode *inode)
 	call_rcu(&inode->i_rcu, f2fs_i_callback);
 }
 
+static void destroy_percpu_info(struct f2fs_sb_info *sbi)
+{
+	int i;
+
+	for (i = 0; i < NR_COUNT_TYPE; i++)
+		percpu_counter_destroy(&sbi->nr_pages[i]);
+}
+
 static void f2fs_put_super(struct super_block *sb)
 {
 	struct f2fs_sb_info *sbi = F2FS_SB(sb);
@@ -667,6 +675,8 @@ static void f2fs_put_super(struct super_block *sb)
 	if (sbi->s_chksum_driver)
 		crypto_free_shash(sbi->s_chksum_driver);
 	kfree(sbi->raw_super);
+
+	destroy_percpu_info(sbi);
 	kfree(sbi);
 }
 
@@ -1325,7 +1335,6 @@ int sanity_check_ckpt(struct f2fs_sb_info *sbi)
 static void init_sb_info(struct f2fs_sb_info *sbi)
 {
 	struct f2fs_super_block *raw_super = sbi->raw_super;
-	int i;
 
 	sbi->log_sectors_per_block =
 		le32_to_cpu(raw_super->log_sectors_per_block);
@@ -1345,9 +1354,6 @@ static void init_sb_info(struct f2fs_sb_info *sbi)
 	sbi->cur_victim_sec = NULL_SECNO;
 	sbi->max_victim_search = DEF_MAX_VICTIM_SEARCH;
 
-	for (i = 0; i < NR_COUNT_TYPE; i++)
-		atomic_set(&sbi->nr_pages[i], 0);
-
 	sbi->dir_level = DEF_DIR_LEVEL;
 	sbi->interval_time[CP_TIME] = DEF_CP_INTERVAL;
 	sbi->interval_time[REQ_TIME] = DEF_IDLE_INTERVAL;
@@ -1363,6 +1369,18 @@ static void init_sb_info(struct f2fs_sb_info *sbi)
 #endif
 }
 
+static int init_percpu_info(struct f2fs_sb_info *sbi)
+{
+	int i, err;
+
+	for (i = 0; i < NR_COUNT_TYPE; i++) {
+		err = percpu_counter_init(&sbi->nr_pages[i], 0, GFP_KERNEL);
+		if (err)
+			return err;
+	}
+	return 0;
+}
+
 /*
  * Read f2fs raw super block.
  * Because we have two copies of super block, so read both of them
@@ -1553,6 +1571,10 @@ try_onemore:
 	init_waitqueue_head(&sbi->cp_wait);
 	init_sb_info(sbi);
 
+	err = init_percpu_info(sbi);
+	if (err)
+		goto free_options;
+
 	/* get an inode for meta space */
 	sbi->meta_inode = f2fs_iget(sb, F2FS_META_INO(sbi));
 	if (IS_ERR(sbi->meta_inode)) {
@@ -1755,6 +1777,7 @@ free_meta_inode:
 	make_bad_inode(sbi->meta_inode);
 	iput(sbi->meta_inode);
 free_options:
+	destroy_percpu_info(sbi);
 	kfree(options);
 free_sb_buf:
 	kfree(raw_super);
-- 
2.6.3


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/5] f2fs: use percpu_counter for # of dirty pages in inode
  2016-05-16 22:30 [PATCH 1/5] f2fs: manipulate dirty file inodes when DATA_FLUSH is set Jaegeuk Kim
  2016-05-16 22:30 ` [PATCH 2/5] f2fs: use percpu_counter for page counters Jaegeuk Kim
@ 2016-05-16 22:30 ` Jaegeuk Kim
  2016-05-16 22:30 ` [PATCH 4/5] f2fs: use percpu_counter for alloc_valid_block_count Jaegeuk Kim
  2016-05-16 22:30 ` [PATCH 5/5] f2fs: use percpu_counter for total_valid_inode_count Jaegeuk Kim
  3 siblings, 0 replies; 5+ messages in thread
From: Jaegeuk Kim @ 2016-05-16 22:30 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel, linux-f2fs-devel; +Cc: Jaegeuk Kim

This patch adds percpu_counter for # of dirty pages in inode.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fs/f2fs/f2fs.h  | 10 +++++-----
 fs/f2fs/file.c  |  2 +-
 fs/f2fs/super.c |  8 +++++++-
 3 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 2851078..ae978a1 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -456,7 +456,7 @@ struct f2fs_inode_info {
 	/* Use below internally in f2fs*/
 	unsigned long flags;		/* use to pass per-file flags */
 	struct rw_semaphore i_sem;	/* protect fi info */
-	atomic_t dirty_pages;		/* # of dirty pages */
+	struct percpu_counter dirty_pages;	/* # of dirty pages */
 	f2fs_hash_t chash;		/* hash value of given file name */
 	unsigned int clevel;		/* maximum level of given file name */
 	nid_t i_xattr_nid;		/* node id that contains xattrs */
@@ -1186,7 +1186,7 @@ static inline void inc_page_count(struct f2fs_sb_info *sbi, int count_type)
 
 static inline void inode_inc_dirty_pages(struct inode *inode)
 {
-	atomic_inc(&F2FS_I(inode)->dirty_pages);
+	percpu_counter_inc(&F2FS_I(inode)->dirty_pages);
 	inc_page_count(F2FS_I_SB(inode), S_ISDIR(inode->i_mode) ?
 				F2FS_DIRTY_DENTS : F2FS_DIRTY_DATA);
 }
@@ -1202,7 +1202,7 @@ static inline void inode_dec_dirty_pages(struct inode *inode)
 			!S_ISLNK(inode->i_mode))
 		return;
 
-	atomic_dec(&F2FS_I(inode)->dirty_pages);
+	percpu_counter_dec(&F2FS_I(inode)->dirty_pages);
 	dec_page_count(F2FS_I_SB(inode), S_ISDIR(inode->i_mode) ?
 				F2FS_DIRTY_DENTS : F2FS_DIRTY_DATA);
 }
@@ -1212,9 +1212,9 @@ static inline s64 get_pages(struct f2fs_sb_info *sbi, int count_type)
 	return percpu_counter_sum_positive(&sbi->nr_pages[count_type]);
 }
 
-static inline int get_dirty_pages(struct inode *inode)
+static inline s64 get_dirty_pages(struct inode *inode)
 {
-	return atomic_read(&F2FS_I(inode)->dirty_pages);
+	return percpu_counter_sum_positive(&F2FS_I(inode)->dirty_pages);
 }
 
 static inline int get_blocktype_secs(struct f2fs_sb_info *sbi, int block_type)
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index b5e3999..69451b83 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -1457,7 +1457,7 @@ static int f2fs_ioc_start_atomic_write(struct file *filp)
 		goto out;
 
 	f2fs_msg(F2FS_I_SB(inode)->sb, KERN_WARNING,
-		"Unexpected flush for atomic writes: ino=%lu, npages=%u",
+		"Unexpected flush for atomic writes: ino=%lu, npages=%lld",
 					inode->i_ino, get_dirty_pages(inode));
 	ret = filemap_write_and_wait_range(inode->i_mapping, 0, LLONG_MAX);
 	if (ret)
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index b3030ed..56f177b 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -526,9 +526,13 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb)
 
 	init_once((void *) fi);
 
+	if (percpu_counter_init(&fi->dirty_pages, 0, GFP_NOFS)) {
+		kmem_cache_free(f2fs_inode_cachep, fi);
+		return NULL;
+	}
+
 	/* Initialize f2fs-specific inode info */
 	fi->vfs_inode.i_version = 1;
-	atomic_set(&fi->dirty_pages, 0);
 	fi->i_current_depth = 1;
 	fi->i_advise = 0;
 	init_rwsem(&fi->i_sem);
@@ -598,6 +602,8 @@ static void f2fs_dirty_inode(struct inode *inode, int flags)
 static void f2fs_i_callback(struct rcu_head *head)
 {
 	struct inode *inode = container_of(head, struct inode, i_rcu);
+
+	percpu_counter_destroy(&F2FS_I(inode)->dirty_pages);
 	kmem_cache_free(f2fs_inode_cachep, F2FS_I(inode));
 }
 
-- 
2.6.3

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 4/5] f2fs: use percpu_counter for alloc_valid_block_count
  2016-05-16 22:30 [PATCH 1/5] f2fs: manipulate dirty file inodes when DATA_FLUSH is set Jaegeuk Kim
  2016-05-16 22:30 ` [PATCH 2/5] f2fs: use percpu_counter for page counters Jaegeuk Kim
  2016-05-16 22:30 ` [PATCH 3/5] f2fs: use percpu_counter for # of dirty pages in inode Jaegeuk Kim
@ 2016-05-16 22:30 ` Jaegeuk Kim
  2016-05-16 22:30 ` [PATCH 5/5] f2fs: use percpu_counter for total_valid_inode_count Jaegeuk Kim
  3 siblings, 0 replies; 5+ messages in thread
From: Jaegeuk Kim @ 2016-05-16 22:30 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel, linux-f2fs-devel; +Cc: Jaegeuk Kim

This patch uses percpu_count for sbi->alloc_valid_block_count.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fs/f2fs/checkpoint.c | 2 +-
 fs/f2fs/f2fs.h       | 8 +++++---
 fs/f2fs/recovery.c   | 5 +++--
 fs/f2fs/super.c      | 7 +++++--
 4 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index d04113b..140643d 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -1079,7 +1079,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
 
 	/* update user_block_counts */
 	sbi->last_valid_block_count = sbi->total_valid_block_count;
-	sbi->alloc_valid_block_count = 0;
+	percpu_counter_set(&sbi->alloc_valid_block_count, 0);
 
 	/* Here, we only have one bio having CP pack */
 	sync_meta_pages(sbi, META_FLUSH, LONG_MAX);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index ae978a1..43aa692 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -829,13 +829,14 @@ struct f2fs_sb_info {
 
 	block_t user_block_count;		/* # of user blocks */
 	block_t total_valid_block_count;	/* # of valid blocks */
-	block_t alloc_valid_block_count;	/* # of allocated blocks */
 	block_t discard_blks;			/* discard command candidats */
 	block_t last_valid_block_count;		/* for recovery */
 	u32 s_next_generation;			/* for NFS support */
 
 	/* # of pages, see count_type */
 	struct percpu_counter nr_pages[NR_COUNT_TYPE];
+	/* # of allocated blocks */
+	struct percpu_counter alloc_valid_block_count;
 
 	struct f2fs_mount_info mount_opt;	/* mount options */
 
@@ -1161,8 +1162,9 @@ static inline bool inc_valid_block_count(struct f2fs_sb_info *sbi,
 	inode->i_blocks += *count;
 	sbi->total_valid_block_count =
 		sbi->total_valid_block_count + (block_t)(*count);
-	sbi->alloc_valid_block_count += (block_t)(*count);
 	spin_unlock(&sbi->stat_lock);
+
+	percpu_counter_add(&sbi->alloc_valid_block_count, (*count));
 	return true;
 }
 
@@ -1310,11 +1312,11 @@ static inline bool inc_valid_node_count(struct f2fs_sb_info *sbi,
 	if (inode)
 		inode->i_blocks++;
 
-	sbi->alloc_valid_block_count++;
 	sbi->total_valid_node_count++;
 	sbi->total_valid_block_count++;
 	spin_unlock(&sbi->stat_lock);
 
+	percpu_counter_inc(&sbi->alloc_valid_block_count);
 	return true;
 }
 
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index 6303b2a..f89b70e 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -49,8 +49,9 @@ static struct kmem_cache *fsync_entry_slab;
 
 bool space_for_roll_forward(struct f2fs_sb_info *sbi)
 {
-	if (sbi->last_valid_block_count + sbi->alloc_valid_block_count
-			> sbi->user_block_count)
+	s64 nalloc = percpu_counter_sum_positive(&sbi->alloc_valid_block_count);
+
+	if (sbi->last_valid_block_count + nalloc > sbi->user_block_count)
 		return false;
 	return true;
 }
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 56f177b..c0fd075 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -618,6 +618,7 @@ static void destroy_percpu_info(struct f2fs_sb_info *sbi)
 
 	for (i = 0; i < NR_COUNT_TYPE; i++)
 		percpu_counter_destroy(&sbi->nr_pages[i]);
+	percpu_counter_destroy(&sbi->alloc_valid_block_count);
 }
 
 static void f2fs_put_super(struct super_block *sb)
@@ -1384,7 +1385,9 @@ static int init_percpu_info(struct f2fs_sb_info *sbi)
 		if (err)
 			return err;
 	}
-	return 0;
+
+	return percpu_counter_init(&sbi->alloc_valid_block_count, 0,
+								GFP_KERNEL);
 }
 
 /*
@@ -1603,7 +1606,7 @@ try_onemore:
 	sbi->total_valid_block_count =
 				le64_to_cpu(sbi->ckpt->valid_block_count);
 	sbi->last_valid_block_count = sbi->total_valid_block_count;
-	sbi->alloc_valid_block_count = 0;
+
 	for (i = 0; i < NR_INODE_TYPE; i++) {
 		INIT_LIST_HEAD(&sbi->inode_list[i]);
 		spin_lock_init(&sbi->inode_lock[i]);
-- 
2.6.3

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 5/5] f2fs: use percpu_counter for total_valid_inode_count
  2016-05-16 22:30 [PATCH 1/5] f2fs: manipulate dirty file inodes when DATA_FLUSH is set Jaegeuk Kim
                   ` (2 preceding siblings ...)
  2016-05-16 22:30 ` [PATCH 4/5] f2fs: use percpu_counter for alloc_valid_block_count Jaegeuk Kim
@ 2016-05-16 22:30 ` Jaegeuk Kim
  3 siblings, 0 replies; 5+ messages in thread
From: Jaegeuk Kim @ 2016-05-16 22:30 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel, linux-f2fs-devel; +Cc: Jaegeuk Kim

This patch uses percpu_counter to avoid stat_lock.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fs/f2fs/f2fs.h  | 18 +++++++-----------
 fs/f2fs/super.c | 11 ++++++++---
 2 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 43aa692..c965897 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -822,7 +822,6 @@ struct f2fs_sb_info {
 	unsigned int total_sections;		/* total section count */
 	unsigned int total_node_count;		/* total node block count */
 	unsigned int total_valid_node_count;	/* valid node block count */
-	unsigned int total_valid_inode_count;	/* valid inode count */
 	loff_t max_file_blocks;			/* max block index of file */
 	int active_logs;			/* # of active logs */
 	int dir_level;				/* directory level */
@@ -838,6 +837,9 @@ struct f2fs_sb_info {
 	/* # of allocated blocks */
 	struct percpu_counter alloc_valid_block_count;
 
+	/* valid inode count */
+	struct percpu_counter total_valid_inode_count;
+
 	struct f2fs_mount_info mount_opt;	/* mount options */
 
 	/* for cleaning operations */
@@ -1343,23 +1345,17 @@ static inline unsigned int valid_node_count(struct f2fs_sb_info *sbi)
 
 static inline void inc_valid_inode_count(struct f2fs_sb_info *sbi)
 {
-	spin_lock(&sbi->stat_lock);
-	f2fs_bug_on(sbi, sbi->total_valid_inode_count == sbi->total_node_count);
-	sbi->total_valid_inode_count++;
-	spin_unlock(&sbi->stat_lock);
+	percpu_counter_inc(&sbi->total_valid_inode_count);
 }
 
 static inline void dec_valid_inode_count(struct f2fs_sb_info *sbi)
 {
-	spin_lock(&sbi->stat_lock);
-	f2fs_bug_on(sbi, !sbi->total_valid_inode_count);
-	sbi->total_valid_inode_count--;
-	spin_unlock(&sbi->stat_lock);
+	percpu_counter_dec(&sbi->total_valid_inode_count);
 }
 
-static inline unsigned int valid_inode_count(struct f2fs_sb_info *sbi)
+static inline s64 valid_inode_count(struct f2fs_sb_info *sbi)
 {
-	return sbi->total_valid_inode_count;
+	return percpu_counter_sum_positive(&sbi->total_valid_inode_count);
 }
 
 static inline struct page *f2fs_grab_cache_page(struct address_space *mapping,
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index c0fd075..bbfeb6a 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -619,6 +619,7 @@ static void destroy_percpu_info(struct f2fs_sb_info *sbi)
 	for (i = 0; i < NR_COUNT_TYPE; i++)
 		percpu_counter_destroy(&sbi->nr_pages[i]);
 	percpu_counter_destroy(&sbi->alloc_valid_block_count);
+	percpu_counter_destroy(&sbi->total_valid_inode_count);
 }
 
 static void f2fs_put_super(struct super_block *sb)
@@ -1386,7 +1387,11 @@ static int init_percpu_info(struct f2fs_sb_info *sbi)
 			return err;
 	}
 
-	return percpu_counter_init(&sbi->alloc_valid_block_count, 0,
+	err = percpu_counter_init(&sbi->alloc_valid_block_count, 0, GFP_KERNEL);
+	if (err)
+		return err;
+
+	return percpu_counter_init(&sbi->total_valid_inode_count, 0,
 								GFP_KERNEL);
 }
 
@@ -1600,8 +1605,8 @@ try_onemore:
 
 	sbi->total_valid_node_count =
 				le32_to_cpu(sbi->ckpt->valid_node_count);
-	sbi->total_valid_inode_count =
-				le32_to_cpu(sbi->ckpt->valid_inode_count);
+	percpu_counter_set(&sbi->total_valid_inode_count,
+				le32_to_cpu(sbi->ckpt->valid_inode_count));
 	sbi->user_block_count = le64_to_cpu(sbi->ckpt->user_block_count);
 	sbi->total_valid_block_count =
 				le64_to_cpu(sbi->ckpt->valid_block_count);
-- 
2.6.3


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-05-16 22:30 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-16 22:30 [PATCH 1/5] f2fs: manipulate dirty file inodes when DATA_FLUSH is set Jaegeuk Kim
2016-05-16 22:30 ` [PATCH 2/5] f2fs: use percpu_counter for page counters Jaegeuk Kim
2016-05-16 22:30 ` [PATCH 3/5] f2fs: use percpu_counter for # of dirty pages in inode Jaegeuk Kim
2016-05-16 22:30 ` [PATCH 4/5] f2fs: use percpu_counter for alloc_valid_block_count Jaegeuk Kim
2016-05-16 22:30 ` [PATCH 5/5] f2fs: use percpu_counter for total_valid_inode_count Jaegeuk Kim

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).