Skip to contentSkip to conversation

f2fs: avoid cpu lockup

PATCH In review Jaegeuk Kim 3 participants 5 messages Jul 15, 2017 – Jul 18, 2017

Subsystems (2)
lore
Share & tools
lore

Jaegeuk Kim

author maintainer
#0 lore raw

PATCH 1/1 f2fs: avoid cpu lockup

Before retrying to flush data or dentry pages, we need to release cpu in order to prevent watchdog.

---
 fs/f2fs/checkpoint.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
fs/f2fs/checkpoint.c +4 -1
index 56bbf592e487..c96913c56f6c 100644
@@ -909,8 +909,11 @@ int sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type)
 		 * wribacking dentry pages in the freeing inode.
 		 */
 		f2fs_submit_merged_write(sbi, DATA);
-		cond_resched();
 	}
+	/* We need to give a chance to get cpu for user file writers. */
+	if (!is_dir)
+		congestion_wait(BLK_RW_ASYNC, HZ/50);
+	cond_resched();
 	goto retry;
 }
 
Signature · 1 line
2.13.0.rc1.294.g07d810a77f-goog
author maintainer
#1 lore raw

Before retrying to flush data or dentry pages, we need to release cpu in order to prevent watchdog.

---
Change log from v1:
- timeout more specifically

 fs/f2fs/checkpoint.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
fs/f2fs/checkpoint.c +10 -0
index 56bbf592e487..5b876f6d3f6b 100644
@@ -879,6 +879,7 @@ int sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type)
 	struct inode *inode;
 	struct f2fs_inode_info *fi;
 	bool is_dir = (type == DIR_INODE);
+	unsigned long ino = 0;
 
 	trace_f2fs_sync_dirty_inodes_enter(sbi->sb, is_dir,
 				get_pages(sbi, is_dir ?
@@ -901,8 +902,17 @@ int sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type)
 	inode = igrab(&fi->vfs_inode);
 	spin_unlock(&sbi->inode_lock[type]);
 	if (inode) {
+		unsigned long cur_ino = inode->i_ino;
+
 		filemap_fdatawrite(inode->i_mapping);
 		iput(inode);
+		/* We need to give cpu to another writers. */
+		if (ino == cur_ino) {
+			congestion_wait(BLK_RW_ASYNC, HZ/50);
+			cond_resched();
+		} else {
+			ino = cur_ino;
+		}
 	} else {
 		/*
 		 * We should submit bio, since it exists several
Signature · 1 line
2.13.0.rc1.294.g07d810a77f-goog
maintainer Reviewed-by
#2 lore raw
Quoted 4 lines · Jaegeuk Kim

Before retrying to flush data or dentry pages, we need to release cpu in order to prevent watchdog.

Quoted 20 lines

---
Change log from v1:
- timeout more specifically

 fs/f2fs/checkpoint.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
fs/f2fs/checkpoint.c +1 -0
index 56bbf592e487..5b876f6d3f6b 100644
@@ -879,6 +879,7 @@ int sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type)
 	struct inode *inode;
 	struct f2fs_inode_info *fi;
 	bool is_dir = (type == DIR_INODE);
+	unsigned long ino = 0;
 
 	trace_f2fs_sync_dirty_inodes_enter(sbi->sb, is_dir,
 				get_pages(sbi, is_dir ?

fs/f2fs/checkpoint.c int sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type) · line 910

Quoted 9 lines
fs/f2fs/checkpoint.c +4 -0
@@ -901,8 +902,17 @@ int sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type)
 	inode = igrab(&fi->vfs_inode);
 	spin_unlock(&sbi->inode_lock[type]);
 	if (inode) {
+		unsigned long cur_ino = inode->i_ino;
+
 		filemap_fdatawrite(inode->i_mapping);
 		iput(inode);
+		/* We need to give cpu to another writers. */
+		if (ino == cur_ino) {

We failed to flush dirty pages of inode due to encountering -EAGAIN of writepage?

Thanks,

Quoted 9 lines
fs/f2fs/checkpoint.c +5 -0
+			congestion_wait(BLK_RW_ASYNC, HZ/50);
+			cond_resched();
+		} else {
+			ino = cur_ino;
+		}
 	} else {
 		/*
 		 * We should submit bio, since it exists several
author maintainer
#3 lore raw
Quoted 25 lines · Chao Yu
Quoted 4 lines · Jaegeuk Kim

Before retrying to flush data or dentry pages, we need to release cpu in order to prevent watchdog.

Quoted 17 lines

---
Change log from v1:
- timeout more specifically

 fs/f2fs/checkpoint.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
fs/f2fs/checkpoint.c +1 -0
index 56bbf592e487..5b876f6d3f6b 100644
@@ -879,6 +879,7 @@ int sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type)
 	struct inode *inode;
 	struct f2fs_inode_info *fi;
 	bool is_dir = (type == DIR_INODE);
+	unsigned long ino = 0;
 
Quoted 14 lines

fs/f2fs/checkpoint.c int sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type) · line 910

Quoted 12 lines
fs/f2fs/checkpoint.c +4 -0
 	trace_f2fs_sync_dirty_inodes_enter(sbi->sb, is_dir,
 				get_pages(sbi, is_dir ?
@@ -901,8 +902,17 @@ int sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type)
 	inode = igrab(&fi->vfs_inode);
 	spin_unlock(&sbi->inode_lock[type]);
 	if (inode) {
+		unsigned long cur_ino = inode->i_ino;
+
 		filemap_fdatawrite(inode->i_mapping);
 		iput(inode);
+		/* We need to give cpu to another writers. */
+		if (ino == cur_ino) {

We failed to flush dirty pages of inode due to encountering -EAGAIN of writepage?

Actually, I found this from a bug case in experimental patches which just skips it accidently. I think WB_SYNC_ALL doesn't return EAGAIN.

Thanks,

Quoted 12 lines

Thanks,

Quoted 9 lines
fs/f2fs/checkpoint.c +5 -0
+			congestion_wait(BLK_RW_ASYNC, HZ/50);
+			cond_resched();
+		} else {
+			ino = cur_ino;
+		}
 	} else {
 		/*
 		 * We should submit bio, since it exists several
#4 lore raw
Quoted 41 lines · Jaegeuk Kim
Quoted 25 lines · Chao Yu
Quoted 4 lines · Jaegeuk Kim

Before retrying to flush data or dentry pages, we need to release cpu in order to prevent watchdog.

Quoted 17 lines

---
Change log from v1:
- timeout more specifically

 fs/f2fs/checkpoint.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
fs/f2fs/checkpoint.c +1 -0
index 56bbf592e487..5b876f6d3f6b 100644
@@ -879,6 +879,7 @@ int sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type)
 	struct inode *inode;
 	struct f2fs_inode_info *fi;
 	bool is_dir = (type == DIR_INODE);
+	unsigned long ino = 0;
 
Quoted 14 lines

fs/f2fs/checkpoint.c int sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type) · line 910

Quoted 12 lines
fs/f2fs/checkpoint.c +4 -0
 	trace_f2fs_sync_dirty_inodes_enter(sbi->sb, is_dir,
 				get_pages(sbi, is_dir ?
@@ -901,8 +902,17 @@ int sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type)
 	inode = igrab(&fi->vfs_inode);
 	spin_unlock(&sbi->inode_lock[type]);
 	if (inode) {
+		unsigned long cur_ino = inode->i_ino;
+
 		filemap_fdatawrite(inode->i_mapping);
 		iput(inode);
+		/* We need to give cpu to another writers. */
+		if (ino == cur_ino) {

We failed to flush dirty pages of inode due to encountering -EAGAIN of writepage?

Quoted 2 lines

Actually, I found this from a bug case in experimental patches which just skips it accidently. I think WB_SYNC_ALL doesn't return EAGAIN.

Alright, thanks for explanation. :)

Thanks,

Quoted 6 lines

Thanks,

Quoted 3 lines

Thanks,

Quoted 12 lines
Quoted 9 lines

fs/f2fs/checkpoint.c int sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type) · line 918

Quoted 9 lines
fs/f2fs/checkpoint.c +5 -0
+			congestion_wait(BLK_RW_ASYNC, HZ/50);
+			cond_resched();
+		} else {
+			ino = cur_ino;
+		}
 	} else {
 		/*
 		 * We should submit bio, since it exists several

.

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot