Re: [f2fs-dev] [PATCH RFC v2] f2fs: flush cp pack except cp page2 at first

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Chao,

On 2018/1/25 16:18, Chao Yu wrote:
> On 2018/1/25 15:05, Gaoxiang (OS) wrote:
>> Previously, we attempt to flush the whole cp pack in a single bio,
>> however, when suddenly powering off at this time, we could get into
>> an extreme scenario that cp page1 and cp page2 are updated and
>> latest, but payload or current summaries are still partially outdated.
>> (see reliable write in the UFS specification)
>>
>> This patch submits the whole cp pack except cp page2 at first,
>> and then writes the cp page2 with an extra independent
>> bio with pre-io barrier.
>>
>> Signed-off-by: Gao Xiang <gaoxiang25@xxxxxxxxxx>
>> ---
>> Change log from v1:
>>    - Apply the review comments from Chao
>>    - time data from "finish block_ops" to " finish checkpoint" (tested on ARM64 with TOSHIBA 128GB UFS):
>>       Before patch: 0.002273  0.001973  0.002789  0.005159  0.002050
>>       After patch: 0.002502  0.001624  0.002487  0.003049  0.002696
> 
> Looks not very stable.
> 
The raw time is as follows, actually I think the time depends on the CPU 
, CPU schedule and some other conditions...

We drop REQ_PREFLUSH and REQ_FUA in the first bio and the second bio is
only 4k..  It would not have obvious performance difference, I think.

before:
    kworker/u16:3-220   [003] ...1   378.093580: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = start block_ops
    kworker/u16:3-220   [003] ...1   378.095468: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish block_ops
    kworker/u16:3-220   [003] ...1   378.097741: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish checkpoint (1)
    kworker/u16:1-97    [003] ...1   438.190720: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = start block_ops
    kworker/u16:1-97    [003] ...1   438.192693: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish block_ops
    kworker/u16:1-97    [003] ...1   438.195540: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish checkpoint (2)
    kworker/u16:4-238   [001] ...1   498.301875: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = start block_ops
    kworker/u16:4-238   [001] ...1   498.304664: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish block_ops
    kworker/u16:4-238   [001] ...1   498.308997: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish checkpoint (3)
    kworker/u16:4-238   [002] ...1   558.414151: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = start block_ops
    kworker/u16:4-238   [002] ...1   558.417236: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish block_ops
    kworker/u16:4-238   [002] ...1   558.422395: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish checkpoint (4)
    kworker/u16:4-238   [001] ...1   618.525854: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = start block_ops
    kworker/u16:4-238   [001] ...1   618.527882: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish block_ops
    kworker/u16:4-238   [000] ...1   618.529932: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish checkpoint (5)
    kworker/u16:4-238   [002] ...1   678.639271: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = start block_ops
    kworker/u16:4-238   [002] ...1   678.644787: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish block_ops
    kworker/u16:4-238   [003] ...1   678.651480: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish checkpoint (6)
    kworker/u16:1-97    [002] ...1   738.765589: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = start block_ops
    kworker/u16:1-97    [002] ...1   738.767638: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish block_ops
    kworker/u16:1-97    [000] ...1   738.770752: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish checkpoint (7)
    kworker/u16:4-238   [003] ...1   798.895281: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = start block_ops
    kworker/u16:4-238   [003] ...1   798.897615: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish block_ops
    kworker/u16:4-238   [001] ...1   798.902006: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish checkpoint (8)
    kworker/u16:1-97    [003] ...1   859.021172: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = start block_ops
    kworker/u16:1-97    [003] ...1   859.022934: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish block_ops
    kworker/u16:1-97    [003] ...1   859.024095: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish checkpoint (9)
    kworker/u16:3-220   [002] ...1   919.133620: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = start block_ops
    kworker/u16:3-220   [002] ...1   919.135558: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish block_ops
    kworker/u16:3-220   [002] ...1   919.137182: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish checkpoint (10)

after:
    kworker/u16:3-222   [000] ...1   137.820152: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = start block_ops
    kworker/u16:3-222   [000] ...1   137.822471: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish block_ops
    kworker/u16:3-222   [000] ...1   137.824973: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish checkpoint (1)
    kworker/u16:1-96    [002] ...1   197.917060: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = start block_ops
    kworker/u16:1-96    [002] ...1   197.919031: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish block_ops
    kworker/u16:1-96    [002] ...1   197.920655: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish checkpoint (2)
    kworker/u16:1-96    [002] ...1   258.013014: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = start block_ops
    kworker/u16:1-96    [002] ...1   258.014914: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish block_ops
    kworker/u16:1-96    [002] ...1   258.017401: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish checkpoint (3)
    kworker/u16:0-6     [002] ...1   318.109930: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = start block_ops
    kworker/u16:0-6     [002] ...1   318.111908: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish block_ops
    kworker/u16:0-6     [002] ...1   318.114957: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish checkpoint (4)
    kworker/u16:1-96    [003] ...1   378.222490: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = start block_ops
    kworker/u16:1-96    [003] ...1   378.224729: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish block_ops
    kworker/u16:1-96    [002] ...1   378.227425: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish checkpoint (5)
    kworker/u16:1-96    [001] ...1   438.334204: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = start block_ops
    kworker/u16:1-96    [001] ...1   438.337002: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish block_ops
    kworker/u16:1-96    [001] ...1   438.341479: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish checkpoint (6)
    kworker/u16:1-96    [002] ...1   498.462207: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = start block_ops
    kworker/u16:1-96    [002] ...1   498.465213: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish block_ops
    kworker/u16:1-96    [003] ...1   498.469858: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish checkpoint (7)
    kworker/u16:0-6     [003] ...1   558.589039: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = start block_ops
    kworker/u16:0-6     [003] ...1   558.591138: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish block_ops
    kworker/u16:0-6     [002] ...1   558.594847: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish checkpoint (8)
    kworker/u16:3-222   [003] ...1   618.702535: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = start block_ops
    kworker/u16:3-222   [003] ...1   618.708222: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish block_ops
    kworker/u16:3-222   [003] ...1   618.724619: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish checkpoint (9)
    kworker/u16:3-222   [002] ...1   678.830550: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = start block_ops
    kworker/u16:3-222   [002] ...1   678.832785: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish block_ops
    kworker/u16:3-222   [002] ...1   678.835356: f2fs_write_checkpoint: 
dev = (259,44), checkpoint for Sync, state = finish checkpoint (10)
>>   fs/f2fs/checkpoint.c | 41 ++++++++++++++++++++++++++++++++++++-----
>>   1 file changed, 36 insertions(+), 5 deletions(-)
>>
>> diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
>> index 14d2fed..70deb09 100644
>> --- a/fs/f2fs/checkpoint.c
>> +++ b/fs/f2fs/checkpoint.c
>> @@ -300,6 +300,36 @@ static int f2fs_write_meta_pages(struct address_space *mapping,
>>   	return 0;
>>   }
>>   
>> +static void commit_checkpoint_with_barrier(struct f2fs_sb_info *sbi,
> 
> Minor, {commit,sync}_checkpoint will be OK to me, since we will decide to
> keep barrier in more deep places according to NOBARRIER mount option,
> instead of this function.
OK, I agree.

> 
>> +	void *src, block_t blk_addr)
>> +{
>> +	struct writeback_control wbc = {
>> +		.for_reclaim = 0,
>> +	};
>> +	struct page *page = grab_meta_page(sbi, blk_addr);
>> +	int err;
>> +
>> +	memcpy(page_address(page), src, PAGE_SIZE);
>> +	set_page_dirty(page);
>> +
>> +	f2fs_wait_on_page_writeback(page, META, true);
>> +	BUG_ON(PageWriteback(page));
>> +	if (unlikely(!clear_page_dirty_for_io(page)))
>> +		BUG();
> 
> f2fs_bug_on(sbi, PageWriteback(page));
Will fix.

> f2fs_bug_on(sbi, unlikely(!clear_page_dirty_for_io(page)));
>

I attempt to use
if (unlikely(!clear_page_dirty_for_io(page))
     f2fs_bug_on(1);
since It is better to contain judgement only for assert-like functions 
(In case that clear_page_dirty_for_io could be omited by changing BUG_ON 
definition in the future).

>> +
>> +	/* writeout cp page2 */
> 
> Please keep defined terms as the same in all places:
> 
> s/cp page2/cp pack 2 page
> 
>> +	err = __f2fs_write_meta_page(page, &wbc, FS_CP_META_IO);
>> +	if (err) {
>> +		f2fs_put_page(page, 1);
>> +		f2fs_stop_checkpoint(sbi, false);
>> +		return;
> 
> How about f2fs_bug_on(sbi, err), since we should not fail in
> __f2fs_write_meta_page, right?
OK, will fix in that way.

> 
>> +	}
>> +	f2fs_put_page(page, 0);
>> +
>> +	/* submit checkpoint with barrier */
>> +	f2fs_submit_merged_write(sbi, META_FLUSH);
>> +}
>> +
>>   long sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type,
>>   				long nr_to_write, enum iostat_type io_type)
>>   {
>> @@ -1297,9 +1327,6 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
>>   		start_blk += NR_CURSEG_NODE_TYPE;
>>   	}
>>   
>> -	/* writeout checkpoint block */
>> -	update_meta_page(sbi, ckpt, start_blk);
>> -
>>   	/* wait for previous submitted node/meta pages writeback */
>>   	wait_on_all_pages_writeback(sbi);
>>   
>> @@ -1313,12 +1340,16 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
>>   	sbi->last_valid_block_count = sbi->total_valid_block_count;
>>   	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, FS_CP_META_IO);
>> +	/* Here, we have one bio having CP pack except cp page2 */
>> +	sync_meta_pages(sbi, META, LONG_MAX, FS_CP_META_IO);
>>   
>>   	/* wait for previous submitted meta pages writeback */
>>   	wait_on_all_pages_writeback(sbi);
> 
> /* wait for previous submitted meta pages writeback */
> if (!test_opt(sbi, NOBARRIER)
> 	wait_on_all_pages_writeback(sbi);
> 
OK.

Thanks,

> Thanks,
> 
>>   
>> +	/* barrier and flush checkpoint cp page2 */
>> +	commit_checkpoint_with_barrier(sbi, ckpt, start_blk);
>> +	wait_on_all_pages_writeback(sbi);
>> +
>>   	release_ino_entry(sbi, false);
>>   
>>   	if (unlikely(f2fs_cp_error(sbi)))
>>
> 



[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux