ocfs2: improve recovery performance
PATCH v2 1/1 ocfs2: improve recovery performance
Journal replay will be run when do recovery for a dead node, to avoid the stale cache impact, all blocks of dead node's journal inode were reload from disk. This hurts the performance, check whether one block is cached before reload it can improve a lot performance. In my test env, the time doing recovery was improved from 120s to 1s.
--- fs/ocfs2/journal.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-)
fs/ocfs2/journal.c +22 -19
@@ -1159,10 +1159,8 @@ static int ocfs2_force_read_journal(struct inode *inode)int status =0 ;int i;u64 v_blkno, p_blkno, p_blocks, num_blocks; -#define CONCURRENT_JOURNAL_FILL 32ULL -struct buffer_head *bhs[CONCURRENT_JOURNAL_FILL ]; - -memset (bhs,0 ,sizeof (struct buffer_head *) *CONCURRENT_JOURNAL_FILL ); +struct buffer_head *bh =NULL ; +struct ocfs2_super *osb =OCFS2_SB (inode->i_sb); num_blocks =ocfs2_blocks_for_bytes (inode->i_sb,i_size_read (inode)); v_blkno =0 ;
@@ -1174,29 +1172,34 @@ static int ocfs2_force_read_journal(struct inode *inode) goto bail; } -if (p_blocks >CONCURRENT_JOURNAL_FILL ) - p_blocks =CONCURRENT_JOURNAL_FILL ; +for (i =0 ; i < p_blocks; i++) { + bh =__find_get_block (osb->sb->s_bdev, p_blkno, + osb->sb->s_blocksize); +/* block not cached. */ +if (!bh) { + p_blkno++; +continue ; + } -/* We are reading journal data which should not -* be put in the uptodate cache */ - status =ocfs2_read_blocks_sync (OCFS2_SB (inode->i_sb), - p_blkno, p_blocks, bhs); -if (status <0 ) { -mlog_errno (status); - goto bail; - } +brelse (bh); + bh =NULL ; +/* We are reading journal data which should not +* be put in the uptodate cache. +*/ + status =ocfs2_read_blocks_sync (osb, p_blkno,1 , &bh); +if (status <0 ) { +mlog_errno (status); + goto bail; + } -for (i =0 ; i < p_blocks; i++) { -brelse (bhs[i]); - bhs[i] =NULL ; +brelse (bh); + bh =NULL ; } v_blkno += p_blocks; } bail: -for (i =0 ; i <CONCURRENT_JOURNAL_FILL ; i++) -brelse (bhs[i]);return status; }
Signature · 1 line
1.7.9.5
PATCH v2 1/1 ocfs2: improve recovery performance
Quoted 8 lines · Junxiao Bi
Journal replay will be run when do recovery for a dead node, to avoid the stale cache impact, all blocks of dead node's journal inode were reload from disk. This hurts the performance, check whether one block is cached before reload it can improve a lot performance. In my test env, the time doing recovery was improved from 120s to 1s.
Signed-off-by Junxiao Bi <[email protected]>
Looks good to me. And it indeed has performance improvement from my test.
Quoted 72 lines
--- fs/ocfs2/journal.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-)fs/ocfs2/journal.c +22
-19@@ -1159,10 +1159,8 @@ static int ocfs2_force_read_journal(struct inode *inode)int status =0 ;int i;u64 v_blkno, p_blkno, p_blocks, num_blocks; -#define CONCURRENT_JOURNAL_FILL 32ULL -struct buffer_head *bhs[CONCURRENT_JOURNAL_FILL ]; - -memset (bhs,0 ,sizeof (struct buffer_head *) *CONCURRENT_JOURNAL_FILL ); +struct buffer_head *bh =NULL ; +struct ocfs2_super *osb =OCFS2_SB (inode->i_sb); num_blocks =ocfs2_blocks_for_bytes (inode->i_sb,i_size_read (inode)); v_blkno =0 ;@@ -1174,29 +1172,34 @@ static int ocfs2_force_read_journal(struct inode *inode) goto bail; } -if (p_blocks >CONCURRENT_JOURNAL_FILL ) - p_blocks =CONCURRENT_JOURNAL_FILL ; +for (i =0 ; i < p_blocks; i++) { + bh =__find_get_block (osb->sb->s_bdev, p_blkno, + osb->sb->s_blocksize); +/* block not cached. */ +if (!bh) { + p_blkno++; +continue ; + } -/* We are reading journal data which should not -* be put in the uptodate cache */ - status =ocfs2_read_blocks_sync (OCFS2_SB (inode->i_sb), - p_blkno, p_blocks, bhs); -if (status <0 ) { -mlog_errno (status); - goto bail; - } +brelse (bh); + bh =NULL ; +/* We are reading journal data which should not +* be put in the uptodate cache. +*/ + status =ocfs2_read_blocks_sync (osb, p_blkno,1 , &bh); +if (status <0 ) { +mlog_errno (status); + goto bail; + } -for (i =0 ; i < p_blocks; i++) { -brelse (bhs[i]); - bhs[i] =NULL ; +brelse (bh); + bh =NULL ; } v_blkno += p_blocks; } bail: -for (i =0 ; i <CONCURRENT_JOURNAL_FILL ; i++) -brelse (bhs[i]);return status; }
PATCH v2 1/1 ocfs2: improve recovery performance
Hello Junxiao,
I think this change will bring a performance improvement, but from the function comments /*
* JBD Might read a cached version of another nodes journal file. We
* don't want this as this file changes often and we get no
* notification on those changes. The only way to be sure that we've
* got the most up to date version of those blocks then is to force
* read them off disk. Just searching through the buffer cache won't
* work as there may be pages backing this file which are still marked
* up to date. We know things can't change on this file underneath us
* as we have the lock by now :)
*/
static int ocfs2_force_read_journal(struct inode *inode)
Did we consider this potential risk behind this patch? I am not familiar with this part code,
I want to know if there is any sync mechanism to make sure the block cache for another node journal file is really the latest data?
Thanks
Gang
Quoted 95 lines
Quoted 1 line
Quoted 1 line
Quoted 8 lines · Junxiao Bi
Journal replay will be run when do recovery for a dead node, to avoid the stale cache impact, all blocks of dead node's journal inode were reload from disk. This hurts the performance, check whether one block is cached before reload it can improve a lot performance. In my test env, the time doing recovery was improved from 120s to 1s.
Signed-off-by Junxiao Bi <[email protected]>Looks good to me. And it indeed has performance improvement from my test.
Reviewed-by Joseph Qi <[email protected]>fs/ocfs2/journal.c static int ocfs2_force_read_journal(struct inode
Quoted 9 lines
--- fs/ocfs2/journal.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-)fs/ocfs2/journal.c +0
-0@@ -1159,10 +1159,8 @@ static int ocfs2_force_read_journal(struct inode*inode)
fs/ocfs2/journal.c static int ocfs2_force_read_journal(struct inode
Quoted 13 lines
fs/ocfs2/journal.c +2
-4int status =0 ;int i;u64 v_blkno, p_blkno, p_blocks, num_blocks; -#define CONCURRENT_JOURNAL_FILL 32ULL -struct buffer_head *bhs[CONCURRENT_JOURNAL_FILL ]; - -memset (bhs,0 ,sizeof (struct buffer_head *) *CONCURRENT_JOURNAL_FILL ); +struct buffer_head *bh =NULL ; +struct ocfs2_super *osb =OCFS2_SB (inode->i_sb); num_blocks =ocfs2_blocks_for_bytes (inode->i_sb,i_size_read (inode)); v_blkno =0 ;@@ -1174,29 +1172,34 @@ static int ocfs2_force_read_journal(struct inode*inode)
Quoted 40 lines
fs/ocfs2/journal.c +20
-13goto bail; } -if (p_blocks >CONCURRENT_JOURNAL_FILL ) - p_blocks =CONCURRENT_JOURNAL_FILL ; +for (i =0 ; i < p_blocks; i++) { + bh =__find_get_block (osb->sb->s_bdev, p_blkno, + osb->sb->s_blocksize); +/* block not cached. */ +if (!bh) { + p_blkno++; +continue ; + } -/* We are reading journal data which should not -* be put in the uptodate cache */ - status =ocfs2_read_blocks_sync (OCFS2_SB (inode->i_sb), - p_blkno, p_blocks, bhs); -if (status <0 ) { -mlog_errno (status); - goto bail; - } +brelse (bh); + bh =NULL ; +/* We are reading journal data which should not +* be put in the uptodate cache. +*/ + status =ocfs2_read_blocks_sync (osb, p_blkno,1 , &bh); +if (status <0 ) { +mlog_errno (status); + goto bail; + } -for (i =0 ; i < p_blocks; i++) { -brelse (bhs[i]); - bhs[i] =NULL ; +brelse (bh); + bh =NULL ; }fs/ocfs2/journal.c static int ocfs2_force_read_journal(struct inode *inode) · line 1205
Quoted 10 lines
fs/ocfs2/journal.c +0
-2v_blkno += p_blocks; } bail: -for (i =0 ; i <CONCURRENT_JOURNAL_FILL ; i++) -brelse (bhs[i]);return status; }_______________________________________________
Ocfs2-devel mailing list
Ocfs2-devel at oss.oracle.com
https://oss.oracle.com/mailman/listinfo/ocfs2-devel
PATCH v2 1/1 ocfs2: improve recovery performance
Hi Gang,
Quoted 15 lines · Gang He
Hello Junxiao,
I think this change will bring a performance improvement, but from the function comments /*
* JBD Might read a cached version of another nodes journal file. We
* don't want this as this file changes often and we get no
* notification on those changes. The only way to be sure that we've
* got the most up to date version of those blocks then is to force
* read them off disk. Just searching through the buffer cache won't
* work as there may be pages backing this file which are still marked
* up to date. We know things can't change on this file underneath us
* as we have the lock by now :)
*/
static intocfs2_force_read_journal(struct inode *inode)
Quoted 2 lines
Did we consider this potential risk behind this patch? I am not familiar with this part code,
I want to know if there is any sync mechanism to make sure the block cache for another node journal file is really the latest data?
I don't see that is needed, because those stale info will not be used except journal replay.
Thanks,
Junxiao.
Quoted 103 lines
Thanks
GangQuoted 95 lines
Quoted 1 line
Quoted 1 line
Quoted 8 lines · Junxiao Bi
Journal replay will be run when do recovery for a dead node, to avoid the stale cache impact, all blocks of dead node's journal inode were reload from disk. This hurts the performance, check whether one block is cached before reload it can improve a lot performance. In my test env, the time doing recovery was improved from 120s to 1s.
Signed-off-by Junxiao Bi <[email protected]>Looks good to me. And it indeed has performance improvement from my test.
Reviewed-by Joseph Qi <[email protected]>fs/ocfs2/journal.c static int ocfs2_force_read_journal(struct inode
Quoted 9 lines
--- fs/ocfs2/journal.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-)fs/ocfs2/journal.c +0
-0@@ -1159,10 +1159,8 @@ static int ocfs2_force_read_journal(struct inode*inode)
fs/ocfs2/journal.c static int ocfs2_force_read_journal(struct inode
Quoted 13 lines
fs/ocfs2/journal.c +2
-4int status =0 ;int i;u64 v_blkno, p_blkno, p_blocks, num_blocks; -#define CONCURRENT_JOURNAL_FILL 32ULL -struct buffer_head *bhs[CONCURRENT_JOURNAL_FILL ]; - -memset (bhs,0 ,sizeof (struct buffer_head *) *CONCURRENT_JOURNAL_FILL ); +struct buffer_head *bh =NULL ; +struct ocfs2_super *osb =OCFS2_SB (inode->i_sb); num_blocks =ocfs2_blocks_for_bytes (inode->i_sb,i_size_read (inode)); v_blkno =0 ;@@ -1174,29 +1172,34 @@ static int ocfs2_force_read_journal(struct inode*inode)
Quoted 40 lines
fs/ocfs2/journal.c +20
-13goto bail; } -if (p_blocks >CONCURRENT_JOURNAL_FILL ) - p_blocks =CONCURRENT_JOURNAL_FILL ; +for (i =0 ; i < p_blocks; i++) { + bh =__find_get_block (osb->sb->s_bdev, p_blkno, + osb->sb->s_blocksize); +/* block not cached. */ +if (!bh) { + p_blkno++; +continue ; + } -/* We are reading journal data which should not -* be put in the uptodate cache */ - status =ocfs2_read_blocks_sync (OCFS2_SB (inode->i_sb), - p_blkno, p_blocks, bhs); -if (status <0 ) { -mlog_errno (status); - goto bail; - } +brelse (bh); + bh =NULL ; +/* We are reading journal data which should not +* be put in the uptodate cache. +*/ + status =ocfs2_read_blocks_sync (osb, p_blkno,1 , &bh); +if (status <0 ) { +mlog_errno (status); + goto bail; + } -for (i =0 ; i < p_blocks; i++) { -brelse (bhs[i]); - bhs[i] =NULL ; +brelse (bh); + bh =NULL ; }fs/ocfs2/journal.c static int ocfs2_force_read_journal(struct inode *inode) · line 1205
Quoted 10 lines
fs/ocfs2/journal.c +0
-2v_blkno += p_blocks; } bail: -for (i =0 ; i <CONCURRENT_JOURNAL_FILL ; i++) -brelse (bhs[i]);return status; }_______________________________________________
Ocfs2-devel mailing list
Ocfs2-devel at oss.oracle.com
https://oss.oracle.com/mailman/listinfo/ocfs2-devel
PATCH v2 1/1 ocfs2: improve recovery performance
In reply to Joseph QiHi Andrew,
Did you miss this patch to your tree?
Thanks,
Junxiao.
Quoted 87 lines · Joseph Qi
Quoted 8 lines · Junxiao Bi
Journal replay will be run when do recovery for a dead node, to avoid the stale cache impact, all blocks of dead node's journal inode were reload from disk. This hurts the performance, check whether one block is cached before reload it can improve a lot performance. In my test env, the time doing recovery was improved from 120s to 1s.
Signed-off-by Junxiao Bi <[email protected]>Looks good to me. And it indeed has performance improvement from my test.
Reviewed-by Joseph Qi <[email protected]>Quoted 72 lines
--- fs/ocfs2/journal.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-)fs/ocfs2/journal.c +22
-19@@ -1159,10 +1159,8 @@ static int ocfs2_force_read_journal(struct inode *inode)int status =0 ;int i;u64 v_blkno, p_blkno, p_blocks, num_blocks; -#define CONCURRENT_JOURNAL_FILL 32ULL -struct buffer_head *bhs[CONCURRENT_JOURNAL_FILL ]; - -memset (bhs,0 ,sizeof (struct buffer_head *) *CONCURRENT_JOURNAL_FILL ); +struct buffer_head *bh =NULL ; +struct ocfs2_super *osb =OCFS2_SB (inode->i_sb); num_blocks =ocfs2_blocks_for_bytes (inode->i_sb,i_size_read (inode)); v_blkno =0 ;@@ -1174,29 +1172,34 @@ static int ocfs2_force_read_journal(struct inode *inode) goto bail; } -if (p_blocks >CONCURRENT_JOURNAL_FILL ) - p_blocks =CONCURRENT_JOURNAL_FILL ; +for (i =0 ; i < p_blocks; i++) { + bh =__find_get_block (osb->sb->s_bdev, p_blkno, + osb->sb->s_blocksize); +/* block not cached. */ +if (!bh) { + p_blkno++; +continue ; + } -/* We are reading journal data which should not -* be put in the uptodate cache */ - status =ocfs2_read_blocks_sync (OCFS2_SB (inode->i_sb), - p_blkno, p_blocks, bhs); -if (status <0 ) { -mlog_errno (status); - goto bail; - } +brelse (bh); + bh =NULL ; +/* We are reading journal data which should not +* be put in the uptodate cache. +*/ + status =ocfs2_read_blocks_sync (osb, p_blkno,1 , &bh); +if (status <0 ) { +mlog_errno (status); + goto bail; + } -for (i =0 ; i < p_blocks; i++) { -brelse (bhs[i]); - bhs[i] =NULL ; +brelse (bh); + bh =NULL ; } v_blkno += p_blocks; } bail: -for (i =0 ; i <CONCURRENT_JOURNAL_FILL ; i++) -brelse (bhs[i]);return status; }
PATCH v2 1/1 ocfs2: improve recovery performance
Quoted 3 lines · On Thu, 23 Jun 2016 09:17:53 +0800 Junxiao Bi <[email protected]> wrote:
Hi Andrew,
Did you miss this patch to your tree?
I would have seen it eventually. Explicitly cc'ing me on patches helps, please.
PATCH v2 1/1 ocfs2: improve recovery performance
Quoted 8 lines · Andrew Morton
Quoted 3 lines · On Thu, 23 Jun 2016 09:17:53 +0800 Junxiao Bi <[email protected]> wrote:
Hi Andrew,
Did you miss this patch to your tree?
I would have seen it eventually. Explicitly cc'ing me on patches helps, please.
I see, will cc you next time.
Thanks,
Junxiao.
Quoted 1 line
PATCH v2 1/1 ocfs2: improve recovery performance
In reply to Junxiao BiHi Junxiao,p_blkno is not increased after force reading from disk, so this block is read many times from disk while other blocks remain in cached are not reloaded.
Thanks,
Jiufei
Quoted 80 lines · Junxiao Bi
Journal replay will be run when do recovery for a dead node, to avoid the stale cache impact, all blocks of dead node's journal inode were reload from disk. This hurts the performance, check whether one block is cached before reload it can improve a lot performance. In my test env, the time doing recovery was improved from 120s to 1s.
Signed-off-by Junxiao Bi <[email protected]>--- fs/ocfs2/journal.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-)fs/ocfs2/journal.c +22
-19@@ -1159,10 +1159,8 @@ static int ocfs2_force_read_journal(struct inode *inode)int status =0 ;int i;u64 v_blkno, p_blkno, p_blocks, num_blocks; -#define CONCURRENT_JOURNAL_FILL 32ULL -struct buffer_head *bhs[CONCURRENT_JOURNAL_FILL ]; - -memset (bhs,0 ,sizeof (struct buffer_head *) *CONCURRENT_JOURNAL_FILL ); +struct buffer_head *bh =NULL ; +struct ocfs2_super *osb =OCFS2_SB (inode->i_sb); num_blocks =ocfs2_blocks_for_bytes (inode->i_sb,i_size_read (inode)); v_blkno =0 ;@@ -1174,29 +1172,34 @@ static int ocfs2_force_read_journal(struct inode *inode) goto bail; } -if (p_blocks >CONCURRENT_JOURNAL_FILL ) - p_blocks =CONCURRENT_JOURNAL_FILL ; +for (i =0 ; i < p_blocks; i++) { + bh =__find_get_block (osb->sb->s_bdev, p_blkno, + osb->sb->s_blocksize); +/* block not cached. */ +if (!bh) { + p_blkno++; +continue ; + } -/* We are reading journal data which should not -* be put in the uptodate cache */ - status =ocfs2_read_blocks_sync (OCFS2_SB (inode->i_sb), - p_blkno, p_blocks, bhs); -if (status <0 ) { -mlog_errno (status); - goto bail; - } +brelse (bh); + bh =NULL ; +/* We are reading journal data which should not +* be put in the uptodate cache. +*/ + status =ocfs2_read_blocks_sync (osb, p_blkno,1 , &bh); +if (status <0 ) { +mlog_errno (status); + goto bail; + } -for (i =0 ; i < p_blocks; i++) { -brelse (bhs[i]); - bhs[i] =NULL ; +brelse (bh); + bh =NULL ; } v_blkno += p_blocks; } bail: -for (i =0 ; i <CONCURRENT_JOURNAL_FILL ; i++) -brelse (bhs[i]);return status; }
PATCH v2 1/1 ocfs2: improve recovery performance
Quoted 4 lines · xuejiufei
Hi Junxiao,
p_blknois not increased after force reading from disk, so this block is read many times from disk while other blocks remain in cached are not reloaded.
Good catch. Will send a v2 version.
Thanks,
Junxiao.
Quoted 86 lines
Thanks,
JiufeiQuoted 80 lines · Junxiao Bi
Journal replay will be run when do recovery for a dead node, to avoid the stale cache impact, all blocks of dead node's journal inode were reload from disk. This hurts the performance, check whether one block is cached before reload it can improve a lot performance. In my test env, the time doing recovery was improved from 120s to 1s.
Signed-off-by Junxiao Bi <[email protected]>--- fs/ocfs2/journal.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-)fs/ocfs2/journal.c +22
-19@@ -1159,10 +1159,8 @@ static int ocfs2_force_read_journal(struct inode *inode)int status =0 ;int i;u64 v_blkno, p_blkno, p_blocks, num_blocks; -#define CONCURRENT_JOURNAL_FILL 32ULL -struct buffer_head *bhs[CONCURRENT_JOURNAL_FILL ]; - -memset (bhs,0 ,sizeof (struct buffer_head *) *CONCURRENT_JOURNAL_FILL ); +struct buffer_head *bh =NULL ; +struct ocfs2_super *osb =OCFS2_SB (inode->i_sb); num_blocks =ocfs2_blocks_for_bytes (inode->i_sb,i_size_read (inode)); v_blkno =0 ;@@ -1174,29 +1172,34 @@ static int ocfs2_force_read_journal(struct inode *inode) goto bail; } -if (p_blocks >CONCURRENT_JOURNAL_FILL ) - p_blocks =CONCURRENT_JOURNAL_FILL ; +for (i =0 ; i < p_blocks; i++) { + bh =__find_get_block (osb->sb->s_bdev, p_blkno, + osb->sb->s_blocksize); +/* block not cached. */ +if (!bh) { + p_blkno++; +continue ; + } -/* We are reading journal data which should not -* be put in the uptodate cache */ - status =ocfs2_read_blocks_sync (OCFS2_SB (inode->i_sb), - p_blkno, p_blocks, bhs); -if (status <0 ) { -mlog_errno (status); - goto bail; - } +brelse (bh); + bh =NULL ; +/* We are reading journal data which should not +* be put in the uptodate cache. +*/ + status =ocfs2_read_blocks_sync (osb, p_blkno,1 , &bh); +if (status <0 ) { +mlog_errno (status); + goto bail; + } -for (i =0 ; i < p_blocks; i++) { -brelse (bhs[i]); - bhs[i] =NULL ; +brelse (bh); + bh =NULL ; } v_blkno += p_blocks; } bail: -for (i =0 ; i <CONCURRENT_JOURNAL_FILL ; i++) -brelse (bhs[i]);return status; }