On 2017/11/7 12:54, Jaegeuk Kim wrote:
> On 11/07, heyunlei wrote:
>>
>>> -----Original Message-----
>>> From: Jaegeuk Kim [mailto:[email protected]]
>>> Sent: Tuesday, November 07, 2017 10:16 AM
>>> To: heyunlei
>>> Cc: Yuchao (T); [email protected]; Wangbintian;
>>> Wangkai (Morgan)
>>> Subject: Re: [f2fs-dev][PATCH v3] f2fs: Separate nat entry mem alloc from
>>> nat_tree_locks
>>>
>>> On 11/06, Yunlei He wrote:
>>>> This path separate nat_entry mem alloc from nat_tree_lock,
>>>> which will benefit in some low mem case.
>>>>
>>>> Signed-off-by: Yunlei He <[email protected]>
>>>> ---
>>>> fs/f2fs/node.c | 48 +++++++++++++++++++++++++++++++++++-------------
>>>> 1 file changed, 35 insertions(+), 13 deletions(-)
>>>>
>>>> diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
>>>> index fef5c68..4af6277 100644
>>>> --- a/fs/f2fs/node.c
>>>> +++ b/fs/f2fs/node.c
>>>> @@ -257,22 +257,15 @@ static struct nat_entry *grab_nat_entry(struct
>>>> f2fs_nm_info *nm_i, nid_t nid,
>>>>
>>>> if (no_fail) {
>>>> new = f2fs_kmem_cache_alloc(nat_entry_slab, GFP_NOFS);
>>>> - f2fs_radix_tree_insert(&nm_i->nat_root, nid, new);
>>>> } else {
>>>> new = kmem_cache_alloc(nat_entry_slab, GFP_NOFS);
>>>> if (!new)
>>>> return NULL;
>>>> - if (radix_tree_insert(&nm_i->nat_root, nid, new)) {
>>>> - kmem_cache_free(nat_entry_slab, new);
>>>> - return NULL;
>>>> - }
>>>> }
>>>>
>>>> memset(new, 0, sizeof(struct nat_entry));
>>>> nat_set_nid(new, nid);
>>>> nat_reset_flag(new);
>>>> - list_add_tail(&new->list, &nm_i->nat_entries);
>>>> - nm_i->nat_cnt++;
>>>> return new;
>>>> }
>>>>
>>>> @@ -281,18 +274,33 @@ static void cache_nat_entry(struct f2fs_sb_info
>>>> *sbi, nid_t nid,
>>>> {
>>>> struct f2fs_nm_info *nm_i = NM_I(sbi);
>>>> struct nat_entry *e;
>>>> + struct nat_entry *new = grab_nat_entry(nm_i, nid, false);
>>>
>>> How about this?
>>>
>>> {
>>> struct nat_entry *new = grab_nat_entry(nm_i, nid, false);
>>> bool free = false;
>>>
>>> if (!new)
>>> return;
>>
>> Return here may loss nat cache check blow?
>
> We don't need to cache this entry all the time with down_write(), and the
> below
> bug_on would not be a big concern.
>
>>
>> BTW, here __lookup_nat_cache() could find an nat entry? We look up earlier
>> and
>> node page lock always held during whole get node info process.
>
> Well, we don't really have to make such the hard assumption in order to avoid
> just one condition check.
Actually, in production, file system's environment is not very well, suffering
issues caused by CPU, memory or storage oftenly, IMO, in-memory consistence
check of fs meta info is needed.
How do you think of check this under CONFIG_F2FS_CHECK_FS as below:
#ifdef CONFIG_F2FS_CHECK_FS
down_read()
e = __lookup_nat_cache()
f2fs_bug_on(sbi, e && other_condition);
up_read()
#endif
down_write()
....
Thanks,
>
> Thanks,
>
>>
>> Thanks.
>>>
>>> down_write();
>>> e = __lookup_nat_cache();
>>> if (!e) {
>>> if (!radix_tree_insert(new)) {
>>> list_add_tail(new);
>>> nm_i->nat_cnt++;
>>> node_info_from_raw_nat(&new);
>>> } else {
>>> free = true;
>>> }
>>> } else {
>>> f2fs_bug_on();
>>> free = true;
>>> }
>>> up_write();
>>> if (free)
>>> kmem_cache_free(new);
>>> }
>>>
>>>>
>>>> + down_write(&nm_i->nat_tree_lock);
>>>> e = __lookup_nat_cache(nm_i, nid);
>>>> if (!e) {
>>>> - e = grab_nat_entry(nm_i, nid, false);
>>>> - if (e)
>>>> - node_info_from_raw_nat(&e->ni, ne);
>>>> + if (!new)
>>>> + goto out;
>>>> +
>>>> + e = new;
>>>> + if (radix_tree_insert(&nm_i->nat_root, nid, e)) {
>>>> + kmem_cache_free(nat_entry_slab, e);
>>>> + goto out;
>>>> + }
>>>> +
>>>> + list_add_tail(&e->list, &nm_i->nat_entries);
>>>> + nm_i->nat_cnt++;
>>>> + node_info_from_raw_nat(&e->ni, ne);
>>>> } else {
>>>> f2fs_bug_on(sbi, nat_get_ino(e) != le32_to_cpu(ne->ino) ||
>>>> nat_get_blkaddr(e) !=
>>>> le32_to_cpu(ne->block_addr) ||
>>>> nat_get_version(e) != ne->version);
>>>> + if (new)
>>>> + kmem_cache_free(nat_entry_slab, new);
>>>> }
>>>> +out:
>>>> + up_write(&nm_i->nat_tree_lock);
>>>> }
>>>>
>>>> static void set_node_addr(struct f2fs_sb_info *sbi, struct node_info *ni,
>>>> @@ -300,11 +308,21 @@ static void set_node_addr(struct f2fs_sb_info *sbi,
>>>> struct node_info *ni,
>>>> {
>>>> struct f2fs_nm_info *nm_i = NM_I(sbi);
>>>> struct nat_entry *e;
>>>> + struct nat_entry *new = grab_nat_entry(nm_i, ni->nid, true);
>>>>
>>>> +retry:
>>>> down_write(&nm_i->nat_tree_lock);
>>>> e = __lookup_nat_cache(nm_i, ni->nid);
>>>> if (!e) {
>>>> - e = grab_nat_entry(nm_i, ni->nid, true);
>>>> + e = new;
>>>> + if (radix_tree_insert(&nm_i->nat_root, ni->nid, e)) {
>>>> + up_write(&nm_i->nat_tree_lock);
>>>> + cond_resched();
>>>> + goto retry;
>>>> + }
>>>> +
>>>> + list_add_tail(&e->list, &nm_i->nat_entries);
>>>> + nm_i->nat_cnt++;
>>>> copy_node_info(&e->ni, ni);
>>>> f2fs_bug_on(sbi, ni->blk_addr == NEW_ADDR);
>>>> } else if (new_blkaddr == NEW_ADDR) {
>>>> @@ -315,6 +333,9 @@ static void set_node_addr(struct f2fs_sb_info *sbi,
>>>> struct node_info *ni,
>>>> */
>>>> copy_node_info(&e->ni, ni);
>>>> f2fs_bug_on(sbi, ni->blk_addr != NULL_ADDR);
>>>> + kmem_cache_free(nat_entry_slab, new);
>>>> + } else {
>>>> + kmem_cache_free(nat_entry_slab, new);
>>>> }
>>>>
>>>> /* sanity check */
>>>> @@ -424,9 +445,7 @@ void get_node_info(struct f2fs_sb_info *sbi, nid_t
>>>> nid, struct node_info *ni)
>>>> f2fs_put_page(page, 1);
>>>> cache:
>>>> /* cache nat entry */
>>>> - down_write(&nm_i->nat_tree_lock);
>>>> cache_nat_entry(sbi, nid, &ne);
>>>> - up_write(&nm_i->nat_tree_lock);
>>>> }
>>>>
>>>> /*
>>>> @@ -2375,6 +2394,9 @@ static void remove_nats_in_journal(struct
>>>> f2fs_sb_info *sbi)
>>>> ne = __lookup_nat_cache(nm_i, nid);
>>>> if (!ne) {
>>>> ne = grab_nat_entry(nm_i, nid, true);
>>>> + f2fs_radix_tree_insert(&nm_i->nat_root, nid, ne);
>>>> + list_add_tail(&ne->list, &nm_i->nat_entries);
>>>> + nm_i->nat_cnt++;
>>>> node_info_from_raw_nat(&ne->ni, &raw_ne);
>>>> }
>>>>
>>>> --
>>>> 1.9.1
>
> .
>
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel