f2fs: release cp and dnode lock before IPU
Chao Yu
maintainerPATCH RESEND v2 1/1 f2fs: release cp and dnode lock before IPU
From: Hou Pengyang <[email protected]>
We don't need to rewrite the page under cp_rwsem and dnode locks.
--- fs/f2fs/data.c | 39 ++++++++++++++++++++++++--------------- fs/f2fs/f2fs.h | 2 +- fs/f2fs/gc.c | 1 + fs/f2fs/segment.c | 1 + 4 files changed, 27 insertions(+), 16 deletions(-)
fs/f2fs/data.c +24 -15
@@ -1361,12 +1361,17 @@ int do_write_data_page(struct f2fs_io_info *fio)if (fio->old_blkaddr !=NULL_ADDR && fio->old_blkaddr !=NEW_ADDR ) { ipu_force = true; + fio->need_lock = false; goto got_it; } } + +if (fio->need_lock) +f2fs_lock_op (fio->sbi); + err =get_dnode_of_data (&dn, page->index,LOOKUP_NODE );if (err) -return err; + goto out; fio->old_blkaddr = dn.data_blkaddr;
@@ -1387,22 +1392,26 @@ int do_write_data_page(struct f2fs_io_info *fio)* it had better in-place writes for updated data. */ if (ipu_force ||need_inplace_update (fio)) { -f2fs_bug_on (fio->sbi, !fio->cp_rwsem_locked); -f2fs_unlock_op (fio->sbi); - fio->cp_rwsem_locked = false; - +f2fs_put_dnode (&dn); +if (fio->need_lock) +f2fs_unlock_op (fio->sbi); err =rewrite_data_page (fio);trace_f2fs_do_write_data_page (fio->page,IPU );set_inode_flag (inode,FI_UPDATE_WRITE ); - }else { -write_data_page (&dn, fio); -trace_f2fs_do_write_data_page (page,OPU ); -set_inode_flag (inode,FI_APPEND_WRITE ); -if (page->index ==0 ) -set_inode_flag (inode,FI_FIRST_BLOCK_WRITTEN ); +return err; } + +/* LFS mode write path */ +write_data_page (&dn, fio); +trace_f2fs_do_write_data_page (page,OPU ); +set_inode_flag (inode,FI_APPEND_WRITE ); +if (page->index ==0 ) +set_inode_flag (inode,FI_FIRST_BLOCK_WRITTEN ); out_writepage:f2fs_put_dnode (&dn); +out: +if (fio->need_lock) +f2fs_unlock_op (fio->sbi);return err; }
@@ -1427,7 +1436,7 @@ static int __write_data_page(struct page *page, bool *submitted, .page = page, .encrypted_page = NULL, .submitted = false, - .cp_rwsem_locked = true, + .need_lock = true, };trace_f2fs_writepage (page,DATA );
@@ -1463,6 +1472,7 @@ static int __write_data_page(struct page *page, bool *submitted,/* Dentry blocks are controlled by checkpoint */ if (S_ISDIR (inode->i_mode)) { + fio.need_lock = false; err =do_write_data_page (&fio); goto done; }
@@ -1480,13 +1490,12 @@ static int __write_data_page(struct page *page, bool *submitted,if (!err) goto out; } -f2fs_lock_op (sbi); +if (err == -EAGAIN ) err =do_write_data_page (&fio);if (F2FS_I (inode)->last_disk_size < psize)F2FS_I (inode)->last_disk_size = psize; -if (fio.cp_rwsem_locked) -f2fs_unlock_op (sbi); + done:if (err && err != -ENOENT ) goto redirty_out;
fs/f2fs/f2fs.h +1 -1
@@ -802,7 +802,7 @@ struct f2fs_io_info {struct page *page;/* page to be written */ struct page *encrypted_page;/* encrypted page */ bool submitted;/* indicate IO submission */ -bool cp_rwsem_locked;/* indicate cp_rwsem is held */ +bool need_lock;/* indicate we need to lock cp_rwsem */ };#define is_read_io (rw) ((rw) == READ)
fs/f2fs/gc.c +1 -0
@@ -717,6 +717,7 @@ static void move_data_page(struct inode *inode, block_t bidx, int gc_type, .old_blkaddr = NULL_ADDR, .page = page, .encrypted_page = NULL, + .need_lock = false, };bool is_dirty =PageDirty (page);int err;
fs/f2fs/segment.c +1 -0
@@ -293,6 +293,7 @@ static int __commit_inmem_pages(struct inode *inode, .op_flags = REQ_SYNC | REQ_PRIO, .old_blkaddr = NULL_ADDR, .encrypted_page = NULL, + .need_lock = false, };pgoff_t last_idx =ULONG_MAX ;int err =0 ;
Signature · 6 lines
2.12.2.575.gb14f27f ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot
Jaegeuk Kim
maintainerHi Chao,
Quoted 125 lines · Chao Yu
From: Hou Pengyang <[email protected]>
We don't need to rewrite the page under
cp_rwsemand dnode locks.Signed-off-by Hou Pengyang <[email protected]>Signed-off-by Chao Yu <[email protected]>Signed-off-by Jaegeuk Kim <[email protected]>--- fs/f2fs/data.c | 39 ++++++++++++++++++++++++--------------- fs/f2fs/f2fs.h | 2 +- fs/f2fs/gc.c | 1 + fs/f2fs/segment.c | 1 + 4 files changed, 27 insertions(+), 16 deletions(-)fs/f2fs/data.c +24
-15@@ -1361,12 +1361,17 @@ int do_write_data_page(struct f2fs_io_info *fio)if (fio->old_blkaddr !=NULL_ADDR && fio->old_blkaddr !=NEW_ADDR ) { ipu_force = true; + fio->need_lock = false; goto got_it; } } + +if (fio->need_lock) +f2fs_lock_op (fio->sbi); + err =get_dnode_of_data (&dn, page->index,LOOKUP_NODE );if (err) -return err; + goto out; fio->old_blkaddr = dn.data_blkaddr;@@ -1387,22 +1392,26 @@ int do_write_data_page(struct f2fs_io_info *fio)* it had better in-place writes for updated data. */ if (ipu_force ||need_inplace_update (fio)) { -f2fs_bug_on (fio->sbi, !fio->cp_rwsem_locked); -f2fs_unlock_op (fio->sbi); - fio->cp_rwsem_locked = false; - +f2fs_put_dnode (&dn); +if (fio->need_lock) +f2fs_unlock_op (fio->sbi); err =rewrite_data_page (fio);trace_f2fs_do_write_data_page (fio->page,IPU );set_inode_flag (inode,FI_UPDATE_WRITE ); - }else { -write_data_page (&dn, fio); -trace_f2fs_do_write_data_page (page,OPU ); -set_inode_flag (inode,FI_APPEND_WRITE ); -if (page->index ==0 ) -set_inode_flag (inode,FI_FIRST_BLOCK_WRITTEN ); +return err; } + +/* LFS mode write path */ +write_data_page (&dn, fio); +trace_f2fs_do_write_data_page (page,OPU ); +set_inode_flag (inode,FI_APPEND_WRITE ); +if (page->index ==0 ) +set_inode_flag (inode,FI_FIRST_BLOCK_WRITTEN ); out_writepage:f2fs_put_dnode (&dn); +out: +if (fio->need_lock) +f2fs_unlock_op (fio->sbi);return err; }@@ -1427,7 +1436,7 @@ static int __write_data_page(struct page *page, bool *submitted, .page = page, .encrypted_page = NULL, .submitted = false, - .cp_rwsem_locked = true, + .need_lock = true, };trace_f2fs_writepage (page,DATA );@@ -1463,6 +1472,7 @@ static int __write_data_page(struct page *page, bool *submitted,/* Dentry blocks are controlled by checkpoint */ if (S_ISDIR (inode->i_mode)) { + fio.need_lock = false; err =do_write_data_page (&fio); goto done; }@@ -1480,13 +1490,12 @@ static int __write_data_page(struct page *page, bool *submitted,if (!err) goto out; } -f2fs_lock_op (sbi); +if (err == -EAGAIN ) err =do_write_data_page (&fio);if (F2FS_I (inode)->last_disk_size < psize)F2FS_I (inode)->last_disk_size = psize; -if (fio.cp_rwsem_locked) -f2fs_unlock_op (sbi); + done:if (err && err != -ENOENT ) goto redirty_out;fs/f2fs/f2fs.h +1
-1@@ -802,7 +802,7 @@ struct f2fs_io_info {struct page *page;/* page to be written */ struct page *encrypted_page;/* encrypted page */ bool submitted;/* indicate IO submission */ -bool cp_rwsem_locked;/* indicate cp_rwsem is held */ +bool need_lock;/* indicate we need to lock cp_rwsem */ };#define is_read_io (rw) ((rw) == READ)fs/f2fs/gc.c +0
-0
fs/f2fs/gc.c static void move_data_page(struct inode *inode, block_t bidx, int gc_type, · line 720
Quoted 4 lines
fs/f2fs/gc.c +1
-0@@ -717,6 +717,7 @@ static void move_data_page(struct inode *inode, block_t bidx, int gc_type, .old_blkaddr = NULL_ADDR, .page = page, .encrypted_page = NULL, + .need_lock = false,
Should be true.
fs/f2fs/segment.c static int __commit_inmem_pages(struct inode *inode, · line 296
Quoted 12 lines
fs/f2fs/gc.c +0
-0};bool is_dirty =PageDirty (page);int err;fs/f2fs/segment.c +1
-0@@ -293,6 +293,7 @@ static int __commit_inmem_pages(struct inode *inode, .op_flags = REQ_SYNC | REQ_PRIO, .old_blkaddr = NULL_ADDR, .encrypted_page = NULL, + .need_lock = false,
Set it below per each do_write_page() call.
Quoted 5 lines
fs/f2fs/segment.c +0
-0};pgoff_t last_idx =ULONG_MAX ;int err =0 ;Signature · 1 line
2.12.2.575.gb14f27f
So, like this?
Quoted 1 line
From
7718913e1c2bf8eb7f7719c40390e86f11d00f28Mon Sep 17 00:00:00 2001
From: Hou Pengyang <[email protected]>
Date: Thu, 27 Apr 2017 00:17:21 +0800
Subject: [PATCH] f2fs: release cp and dnode lock before IPU
We don't need to rewrite the page under cp_rwsem and dnode locks.
--- fs/f2fs/data.c | 39 ++++++++++++++++++++++++--------------- fs/f2fs/f2fs.h | 2 +- fs/f2fs/gc.c | 1 + fs/f2fs/segment.c | 1 + 4 files changed, 27 insertions(+), 16 deletions(-)
fs/f2fs/data.c +24 -15
@@ -1368,12 +1368,17 @@ int do_write_data_page(struct f2fs_io_info *fio)if (valid_ipu_blkaddr (fio)) { ipu_force = true; + fio->need_lock = false; goto got_it; } } + +if (fio->need_lock) +f2fs_lock_op (fio->sbi); + err =get_dnode_of_data (&dn, page->index,LOOKUP_NODE );if (err) -return err; + goto out; fio->old_blkaddr = dn.data_blkaddr;
@@ -1394,22 +1399,26 @@ int do_write_data_page(struct f2fs_io_info *fio)* it had better in-place writes for updated data. */ if (ipu_force || (valid_ipu_blkaddr (fio) &&need_inplace_update (fio))) { -f2fs_bug_on (fio->sbi, !fio->cp_rwsem_locked); -f2fs_unlock_op (fio->sbi); - fio->cp_rwsem_locked = false; - +f2fs_put_dnode (&dn); +if (fio->need_lock) +f2fs_unlock_op (fio->sbi); err =rewrite_data_page (fio);trace_f2fs_do_write_data_page (fio->page,IPU );set_inode_flag (inode,FI_UPDATE_WRITE ); - }else { -write_data_page (&dn, fio); -trace_f2fs_do_write_data_page (page,OPU ); -set_inode_flag (inode,FI_APPEND_WRITE ); -if (page->index ==0 ) -set_inode_flag (inode,FI_FIRST_BLOCK_WRITTEN ); +return err; } + +/* LFS mode write path */ +write_data_page (&dn, fio); +trace_f2fs_do_write_data_page (page,OPU ); +set_inode_flag (inode,FI_APPEND_WRITE ); +if (page->index ==0 ) +set_inode_flag (inode,FI_FIRST_BLOCK_WRITTEN ); out_writepage:f2fs_put_dnode (&dn); +out: +if (fio->need_lock) +f2fs_unlock_op (fio->sbi);return err; }
@@ -1434,7 +1443,7 @@ static int __write_data_page(struct page *page, bool *submitted, .page = page, .encrypted_page = NULL, .submitted = false, - .cp_rwsem_locked = true, + .need_lock = true, };trace_f2fs_writepage (page,DATA );
@@ -1470,6 +1479,7 @@ static int __write_data_page(struct page *page, bool *submitted,/* Dentry blocks are controlled by checkpoint */ if (S_ISDIR (inode->i_mode)) { + fio.need_lock = false; err =do_write_data_page (&fio); goto done; }
@@ -1487,13 +1497,12 @@ static int __write_data_page(struct page *page, bool *submitted,if (!err) goto out; } -f2fs_lock_op (sbi); +if (err == -EAGAIN ) err =do_write_data_page (&fio);if (F2FS_I (inode)->last_disk_size < psize)F2FS_I (inode)->last_disk_size = psize; -if (fio.cp_rwsem_locked) -f2fs_unlock_op (sbi); + done:if (err && err != -ENOENT ) goto redirty_out;
fs/f2fs/f2fs.h +1 -1
@@ -803,7 +803,7 @@ struct f2fs_io_info {struct page *page;/* page to be written */ struct page *encrypted_page;/* encrypted page */ bool submitted;/* indicate IO submission */ -bool cp_rwsem_locked;/* indicate cp_rwsem is held */ +bool need_lock;/* indicate we need to lock cp_rwsem */ };#define is_read_io (rw) ((rw) == READ)
fs/f2fs/gc.c +1 -0
@@ -717,6 +717,7 @@ static void move_data_page(struct inode *inode, block_t bidx, int gc_type, .old_blkaddr = NULL_ADDR, .page = page, .encrypted_page = NULL, + .need_lock = true, };bool is_dirty =PageDirty (page);int err;
fs/f2fs/segment.c +1 -0
@@ -312,6 +312,7 @@ static int __commit_inmem_pages(struct inode *inode, fio.page = page; fio.old_blkaddr =NULL_ADDR ; fio.encrypted_page =NULL ; + fio.need_lock = false, err =do_write_data_page (&fio);if (err) {unlock_page (page);
Signature · 7 lines
2.11.0 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot
Hi Jaegeuk,
Quoted 150 lines · Jaegeuk Kim
Hi Chao,
Quoted 125 lines · Chao Yu
From: Hou Pengyang <[email protected]>
We don't need to rewrite the page under
cp_rwsemand dnode locks.Signed-off-by Hou Pengyang <[email protected]>Signed-off-by Chao Yu <[email protected]>Signed-off-by Jaegeuk Kim <[email protected]>--- fs/f2fs/data.c | 39 ++++++++++++++++++++++++--------------- fs/f2fs/f2fs.h | 2 +- fs/f2fs/gc.c | 1 + fs/f2fs/segment.c | 1 + 4 files changed, 27 insertions(+), 16 deletions(-)fs/f2fs/data.c +24
-15@@ -1361,12 +1361,17 @@ int do_write_data_page(struct f2fs_io_info *fio)if (fio->old_blkaddr !=NULL_ADDR && fio->old_blkaddr !=NEW_ADDR ) { ipu_force = true; + fio->need_lock = false; goto got_it; } } + +if (fio->need_lock) +f2fs_lock_op (fio->sbi); + err =get_dnode_of_data (&dn, page->index,LOOKUP_NODE );if (err) -return err; + goto out; fio->old_blkaddr = dn.data_blkaddr;@@ -1387,22 +1392,26 @@ int do_write_data_page(struct f2fs_io_info *fio)* it had better in-place writes for updated data. */ if (ipu_force ||need_inplace_update (fio)) { -f2fs_bug_on (fio->sbi, !fio->cp_rwsem_locked); -f2fs_unlock_op (fio->sbi); - fio->cp_rwsem_locked = false; - +f2fs_put_dnode (&dn); +if (fio->need_lock) +f2fs_unlock_op (fio->sbi); err =rewrite_data_page (fio);trace_f2fs_do_write_data_page (fio->page,IPU );set_inode_flag (inode,FI_UPDATE_WRITE ); - }else { -write_data_page (&dn, fio); -trace_f2fs_do_write_data_page (page,OPU ); -set_inode_flag (inode,FI_APPEND_WRITE ); -if (page->index ==0 ) -set_inode_flag (inode,FI_FIRST_BLOCK_WRITTEN ); +return err; } + +/* LFS mode write path */ +write_data_page (&dn, fio); +trace_f2fs_do_write_data_page (page,OPU ); +set_inode_flag (inode,FI_APPEND_WRITE ); +if (page->index ==0 ) +set_inode_flag (inode,FI_FIRST_BLOCK_WRITTEN ); out_writepage:f2fs_put_dnode (&dn); +out: +if (fio->need_lock) +f2fs_unlock_op (fio->sbi);return err; }@@ -1427,7 +1436,7 @@ static int __write_data_page(struct page *page, bool *submitted, .page = page, .encrypted_page = NULL, .submitted = false, - .cp_rwsem_locked = true, + .need_lock = true, };trace_f2fs_writepage (page,DATA );@@ -1463,6 +1472,7 @@ static int __write_data_page(struct page *page, bool *submitted,/* Dentry blocks are controlled by checkpoint */ if (S_ISDIR (inode->i_mode)) { + fio.need_lock = false; err =do_write_data_page (&fio); goto done; }@@ -1480,13 +1490,12 @@ static int __write_data_page(struct page *page, bool *submitted,if (!err) goto out; } -f2fs_lock_op (sbi); +if (err == -EAGAIN ) err =do_write_data_page (&fio);if (F2FS_I (inode)->last_disk_size < psize)F2FS_I (inode)->last_disk_size = psize; -if (fio.cp_rwsem_locked) -f2fs_unlock_op (sbi); + done:if (err && err != -ENOENT ) goto redirty_out;fs/f2fs/f2fs.h +1
-1@@ -802,7 +802,7 @@ struct f2fs_io_info {struct page *page;/* page to be written */ struct page *encrypted_page;/* encrypted page */ bool submitted;/* indicate IO submission */ -bool cp_rwsem_locked;/* indicate cp_rwsem is held */ +bool need_lock;/* indicate we need to lock cp_rwsem */ };#define is_read_io (rw) ((rw) == READ)fs/f2fs/gc.c +0
-0fs/f2fs/gc.c static void move_data_page(struct inode *inode, block_t bidx, int gc_type, · line 720
Quoted 4 lines
fs/f2fs/gc.c +1
-0@@ -717,6 +717,7 @@ static void move_data_page(struct inode *inode, block_t bidx, int gc_type, .old_blkaddr = NULL_ADDR, .page = page, .encrypted_page = NULL, + .need_lock = false,Should be true.
fs/f2fs/segment.c static int __commit_inmem_pages(struct inode *inode, · line 296
Quoted 12 lines
fs/f2fs/gc.c +0
-0};bool is_dirty =PageDirty (page);int err;fs/f2fs/segment.c +1
-0@@ -293,6 +293,7 @@ static int __commit_inmem_pages(struct inode *inode, .op_flags = REQ_SYNC | REQ_PRIO, .old_blkaddr = NULL_ADDR, .encrypted_page = NULL, + .need_lock = false,Set it below per each
do_write_page()call.
Quoted 7 lines
Quoted 5 lines
fs/f2fs/segment.c +0
-0};pgoff_t last_idx =ULONG_MAX ;int err =0 ;Signature · 1 line
2.12.2.575.gb14f27fSo, like this?
Yup, thanks for the fixing. ;)
Thanks,
Quoted 149 lines
Quoted 2 lines
From
7718913e1c2bf8eb7f7719c40390e86f11d00f28Mon Sep 17 00:00:00 2001From: Hou Pengyang <[email protected]>
Date: Thu, 27 Apr 2017 00:17:21 +0800
Subject: [PATCH] f2fs: release cp and dnode lock before IPUWe don't need to rewrite the page under
cp_rwsemand dnode locks.Signed-off-by Hou Pengyang <[email protected]>Signed-off-by Chao Yu <[email protected]>Signed-off-by Jaegeuk Kim <[email protected]>--- fs/f2fs/data.c | 39 ++++++++++++++++++++++++--------------- fs/f2fs/f2fs.h | 2 +- fs/f2fs/gc.c | 1 + fs/f2fs/segment.c | 1 + 4 files changed, 27 insertions(+), 16 deletions(-)fs/f2fs/data.c +24
-15@@ -1368,12 +1368,17 @@ int do_write_data_page(struct f2fs_io_info *fio)if (valid_ipu_blkaddr (fio)) { ipu_force = true; + fio->need_lock = false; goto got_it; } } + +if (fio->need_lock) +f2fs_lock_op (fio->sbi); + err =get_dnode_of_data (&dn, page->index,LOOKUP_NODE );if (err) -return err; + goto out; fio->old_blkaddr = dn.data_blkaddr;@@ -1394,22 +1399,26 @@ int do_write_data_page(struct f2fs_io_info *fio)* it had better in-place writes for updated data. */ if (ipu_force || (valid_ipu_blkaddr (fio) &&need_inplace_update (fio))) { -f2fs_bug_on (fio->sbi, !fio->cp_rwsem_locked); -f2fs_unlock_op (fio->sbi); - fio->cp_rwsem_locked = false; - +f2fs_put_dnode (&dn); +if (fio->need_lock) +f2fs_unlock_op (fio->sbi); err =rewrite_data_page (fio);trace_f2fs_do_write_data_page (fio->page,IPU );set_inode_flag (inode,FI_UPDATE_WRITE ); - }else { -write_data_page (&dn, fio); -trace_f2fs_do_write_data_page (page,OPU ); -set_inode_flag (inode,FI_APPEND_WRITE ); -if (page->index ==0 ) -set_inode_flag (inode,FI_FIRST_BLOCK_WRITTEN ); +return err; } + +/* LFS mode write path */ +write_data_page (&dn, fio); +trace_f2fs_do_write_data_page (page,OPU ); +set_inode_flag (inode,FI_APPEND_WRITE ); +if (page->index ==0 ) +set_inode_flag (inode,FI_FIRST_BLOCK_WRITTEN ); out_writepage:f2fs_put_dnode (&dn); +out: +if (fio->need_lock) +f2fs_unlock_op (fio->sbi);return err; }@@ -1434,7 +1443,7 @@ static int __write_data_page(struct page *page, bool *submitted, .page = page, .encrypted_page = NULL, .submitted = false, - .cp_rwsem_locked = true, + .need_lock = true, };trace_f2fs_writepage (page,DATA );@@ -1470,6 +1479,7 @@ static int __write_data_page(struct page *page, bool *submitted,/* Dentry blocks are controlled by checkpoint */ if (S_ISDIR (inode->i_mode)) { + fio.need_lock = false; err =do_write_data_page (&fio); goto done; }@@ -1487,13 +1497,12 @@ static int __write_data_page(struct page *page, bool *submitted,if (!err) goto out; } -f2fs_lock_op (sbi); +if (err == -EAGAIN ) err =do_write_data_page (&fio);if (F2FS_I (inode)->last_disk_size < psize)F2FS_I (inode)->last_disk_size = psize; -if (fio.cp_rwsem_locked) -f2fs_unlock_op (sbi); + done:if (err && err != -ENOENT ) goto redirty_out;fs/f2fs/f2fs.h +1
-1@@ -803,7 +803,7 @@ struct f2fs_io_info {struct page *page;/* page to be written */ struct page *encrypted_page;/* encrypted page */ bool submitted;/* indicate IO submission */ -bool cp_rwsem_locked;/* indicate cp_rwsem is held */ +bool need_lock;/* indicate we need to lock cp_rwsem */ };#define is_read_io (rw) ((rw) == READ)fs/f2fs/gc.c +1
-0@@ -717,6 +717,7 @@ static void move_data_page(struct inode *inode, block_t bidx, int gc_type, .old_blkaddr = NULL_ADDR, .page = page, .encrypted_page = NULL, + .need_lock = true, };bool is_dirty =PageDirty (page);int err;fs/f2fs/segment.c +1
-0@@ -312,6 +312,7 @@ static int __commit_inmem_pages(struct inode *inode, fio.page = page; fio.old_blkaddr =NULL_ADDR ; fio.encrypted_page =NULL ; + fio.need_lock = false, err =do_write_data_page (&fio);if (err) {unlock_page (page);