On 2017/11/11 8:14, Jaegeuk Kim wrote:
> On 11/10, heyunlei wrote:
>>
>>
>>> -----Original Message-----
>>> From: Jaegeuk Kim [mailto:[email protected]]
>>> Sent: Friday, November 10, 2017 2:05 AM
>>> To: heyunlei
>>> Cc: Yuchao (T); [email protected]; Wangbintian; 
>>> Jianing (Euler)
>>> Subject: Re: [f2fs-dev][PATCH v5] f2fs: Separate nat entry mem alloc from 
>>> nat_tree_locks
>>>
>>> On 11/07, 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 | 56 
>>>> +++++++++++++++++++++++++++++++++++++++-----------------
>>>>  1 file changed, 39 insertions(+), 17 deletions(-)
>>>>
>>>> diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
>>>> index fef5c68..c6aea33 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;
>>>>  }
>>>>
>>>> @@ -282,17 +275,32 @@ 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;
>>>>
>>>> +#ifdef CONFIG_F2FS_CHECK_FS
>>>> +  down_read(&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);
>>>> -  } else {
>>>> +  if (unlikely(e)) {
>>>>            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_blkaddr(e) != le32_to_cpu(ne->block_addr) ||
>>>>                            nat_get_version(e) != ne->version);
>>>> +          up_read(&nm_i->nat_tree_lock);
>>>> +          return;
>>>> +  }
>>>> +  up_read(&nm_i->nat_tree_lock);
>>>> +#endif
>>>
>>> Please avoid #ifdef as much as possible, which is totally undesirable.
>>> BTW, it'd be better to give the mallocated e to grab_nat_entry() to 
>>> consolidate
>>> initialization stuffs?
>>
>> Do you mean that delete the found nat entry and use the new alloced one?
> 
> Like this?

From my aspect, more neat. :)

Reviewed-by: Chao Yu <[email protected]>

Trivial comments as below:

> 
> ---
>  fs/f2fs/node.c | 82 
> ++++++++++++++++++++++++++++++++++++----------------------
>  1 file changed, 51 insertions(+), 31 deletions(-)
> 
> diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
> index d2530179cc9c..856b3aa9cab1 100644
> --- a/fs/f2fs/node.c
> +++ b/fs/f2fs/node.c
> @@ -250,49 +250,67 @@ bool need_inode_block_update(struct f2fs_sb_info *sbi, 
> nid_t ino)
>       return need_update;
>  }
>  
> -static struct nat_entry *grab_nat_entry(struct f2fs_nm_info *nm_i, nid_t nid,
> -                                                             bool no_fail)
> +static struct nat_entry *__alloc_nat_entry(nid_t nid, bool no_fail)
>  {
> -     struct nat_entry *new;
> +     struct nat_entry *new = NULL;

No need to initialize new?

>  
> -     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;
> -             }
> +     if (no_fail)
> +             new = f2fs_kmem_cache_alloc(nat_entry_slab,
> +                                             GFP_NOFS | __GFP_ZERO);
> +     else
> +             new = kmem_cache_alloc(nat_entry_slab,
> +                                             GFP_NOFS | __GFP_ZERO);
> +     if (new) {
> +             nat_set_nid(new, nid);
> +             nat_reset_flag(new);
>       }
> +     return new;
> +}
> +
> +static void __free_nat_entry(struct nat_entry *e)
> +{
> +     kmem_cache_free(nat_entry_slab, e);

Should also replace kmem_cache_free in __del_from_nat_cache?

Thanks,

> +}
>  
> -     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);
> +/* must be locked by nat_tree_lock */
> +static struct nat_entry *__init_nat_entry(struct f2fs_nm_info *nm_i,
> +     struct nat_entry *ne, struct f2fs_nat_entry *raw_ne, bool no_fail)
> +{
> +     if (no_fail)
> +             f2fs_radix_tree_insert(&nm_i->nat_root, nat_get_nid(ne), ne);
> +     else if (radix_tree_insert(&nm_i->nat_root, nat_get_nid(ne), ne))
> +             return NULL;
> +
> +     if (raw_ne)
> +             node_info_from_raw_nat(&ne->ni, raw_ne);
> +     list_add_tail(&ne->list, &nm_i->nat_entries);
>       nm_i->nat_cnt++;
> -     return new;
> +     return ne;
>  }
>  
> +/* must be locked by nat_tree_lock */
>  static void cache_nat_entry(struct f2fs_sb_info *sbi, nid_t nid,
>                                               struct f2fs_nat_entry *ne)
>  {
>       struct f2fs_nm_info *nm_i = NM_I(sbi);
> -     struct nat_entry *e;
> +     struct nat_entry *new, *e;
> +
> +     new = __alloc_nat_entry(nid, false);
> +     if (!new)
> +             return;
>  
> +     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);
> -     } else {
> +     if (!e)
> +             e = __init_nat_entry(nm_i, new, ne, false);
> +     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);
> -     }
> +     up_write(&nm_i->nat_tree_lock);
> +     if (e != new)
> +             __free_nat_entry(new);
>  }
>  
>  static void set_node_addr(struct f2fs_sb_info *sbi, struct node_info *ni,
> @@ -300,11 +318,12 @@ 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 = __alloc_nat_entry(ni->nid, true);
>  
>       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 = __init_nat_entry(nm_i, new, NULL, true);
>               copy_node_info(&e->ni, ni);
>               f2fs_bug_on(sbi, ni->blk_addr == NEW_ADDR);
>       } else if (new_blkaddr == NEW_ADDR) {
> @@ -316,6 +335,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);
>       }
> +     /* let's free early to reduce memory consumption */
> +     if (e != new)
> +             __free_nat_entry(new);
>  
>       /* sanity check */
>       f2fs_bug_on(sbi, nat_get_blkaddr(e) != ni->blk_addr);
> @@ -424,9 +446,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);
>  }
>  
>  /*
> @@ -2371,8 +2391,8 @@ 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);
> -                     node_info_from_raw_nat(&ne->ni, &raw_ne);
> +                     ne = __alloc_nat_entry(nid, true);
> +                     __init_nat_entry(nm_i, ne, &raw_ne, true);
>               }
>  
>               /*
> 

------------------------------------------------------------------------------
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

Reply via email to