From: Jaegeuk Kim <jaegeuk@kernel.org>
To: Chao Yu <chao2.yu@samsung.com>
Cc: Changman Lee <cm224.lee@samsung.com>,
linux-f2fs-devel@lists.sourceforge.net,
linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [f2fs-dev] [PATCH v2 RESEND] f2fs: refactor flush_nat_entries codes for reducing NAT writes
Date: Tue, 24 Jun 2014 06:40:53 +0900 [thread overview]
Message-ID: <20140623214053.GA3088@jmac.local> (raw)
In-Reply-To: <003a01cf8c6b$ff39a170$fdace450$@samsung.com>
Hi Chao,
Thank you for the patch. :)
Just one minor suggestion.
[snip]
> /*
> @@ -1792,80 +1864,87 @@ void flush_nat_entries(struct f2fs_sb_info *sbi)
> struct f2fs_nm_info *nm_i = NM_I(sbi);
> struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA);
> struct f2fs_summary_block *sum = curseg->sum_blk;
> - struct nat_entry *ne, *cur;
> - struct page *page = NULL;
> - struct f2fs_nat_block *nat_blk = NULL;
> - nid_t start_nid = 0, end_nid = 0;
> - bool flushed;
> -
> - flushed = flush_nats_in_journal(sbi);
> -
> - if (!flushed)
> - mutex_lock(&curseg->curseg_mutex);
> -
> - /* 1) flush dirty nat caches */
> - list_for_each_entry_safe(ne, cur, &nm_i->dirty_nat_entries, list) {
> - nid_t nid;
> - struct f2fs_nat_entry raw_ne;
> - int offset = -1;
> -
> - if (nat_get_blkaddr(ne) == NEW_ADDR)
> - continue;
> + struct nat_entry_set *nes, *tmp;
> + struct list_head *head = &nm_i->nat_entry_set;
> + bool to_journal = true;
>
> - nid = nat_get_nid(ne);
> + /* merge nat entries of dirty list to nat entry set temporarily */
> + merge_nats_in_set(sbi);
>
> - if (flushed)
> - goto to_nat_page;
> + if (!__has_cursum_space(sum, nm_i->dirty_nat_cnt)) {
> + /*
> + * if there are no enough space in journal to store dirty nat
> + * entries, remove all entries from journal and merge them
> + * into nat entry set.
> + */
> + remove_nats_in_journal(sbi);
> + merge_nats_in_set(sbi);
> + }
How about this?
/*
* if there are no enough space in journal to store dirty nat
* entries, remove all entries from journal and merge them
* into nat entry set.
*/
if (!__has_cursum_space(sum, nm_i->dirty_nat_cnt))
remove_nats_in_journal(sbi);
/* merge nat entries of dirty list to nat entry set temporarily */
merge_nats_in_set(sbi);
Thanks,
>
> - /* if there is room for nat enries in curseg->sumpage */
> - offset = lookup_journal_in_cursum(sum, NAT_JOURNAL, nid, 1);
> - if (offset >= 0) {
> - raw_ne = nat_in_journal(sum, offset);
> - goto flush_now;
> - }
> -to_nat_page:
> - if (!page || (start_nid > nid || nid > end_nid)) {
> - if (page) {
> - f2fs_put_page(page, 1);
> - page = NULL;
> - }
> - start_nid = START_NID(nid);
> - end_nid = start_nid + NAT_ENTRY_PER_BLOCK - 1;
> + if (!nm_i->dirty_nat_cnt)
> + return;
>
> - /*
> - * get nat block with dirty flag, increased reference
> - * count, mapped and lock
> - */
> + /*
> + * there are two steps to flush nat entries:
> + * #1, flush nat entries to journal in current hot data summary block.
> + * #2, flush nat entries to nat page.
> + */
> + list_for_each_entry_safe(nes, tmp, head, set_list) {
> + struct f2fs_nat_block *nat_blk;
> + struct nat_entry *ne, *cur;
> + struct page *page;
> + nid_t start_nid = nes->start_nid;
> +
> + if (to_journal && !__has_cursum_space(sum, nes->entry_cnt))
> + to_journal = false;
> +
> + if (to_journal) {
> + mutex_lock(&curseg->curseg_mutex);
> + } else {
> page = get_next_nat_page(sbi, start_nid);
> nat_blk = page_address(page);
> + f2fs_bug_on(!nat_blk);
> }
>
> - f2fs_bug_on(!nat_blk);
> - raw_ne = nat_blk->entries[nid - start_nid];
> -flush_now:
> - raw_nat_from_node_info(&raw_ne, &ne->ni);
> -
> - if (offset < 0) {
> - nat_blk->entries[nid - start_nid] = raw_ne;
> - } else {
> - nat_in_journal(sum, offset) = raw_ne;
> - nid_in_journal(sum, offset) = cpu_to_le32(nid);
> - }
> + /* flush dirty nats in nat entry set */
> + list_for_each_entry_safe(ne, cur, &nes->entry_list, list) {
> + struct f2fs_nat_entry *raw_ne;
> + nid_t nid = nat_get_nid(ne);
> + int offset;
> +
> + if (to_journal) {
> + offset = lookup_journal_in_cursum(sum,
> + NAT_JOURNAL, nid, 1);
> + f2fs_bug_on(offset < 0);
> + raw_ne = &nat_in_journal(sum, offset);
> + nid_in_journal(sum, offset) = cpu_to_le32(nid);
> + } else {
> + raw_ne = &nat_blk->entries[nid - start_nid];
> + }
> + raw_nat_from_node_info(raw_ne, &ne->ni);
>
> - if (nat_get_blkaddr(ne) == NULL_ADDR &&
> + if (nat_get_blkaddr(ne) == NULL_ADDR &&
> add_free_nid(sbi, nid, false) <= 0) {
> - write_lock(&nm_i->nat_tree_lock);
> - __del_from_nat_cache(nm_i, ne);
> - write_unlock(&nm_i->nat_tree_lock);
> - } else {
> - write_lock(&nm_i->nat_tree_lock);
> - __clear_nat_cache_dirty(nm_i, ne);
> - write_unlock(&nm_i->nat_tree_lock);
> + write_lock(&nm_i->nat_tree_lock);
> + __del_from_nat_cache(nm_i, ne);
> + write_unlock(&nm_i->nat_tree_lock);
> + } else {
> + write_lock(&nm_i->nat_tree_lock);
> + __clear_nat_cache_dirty(nm_i, ne);
> + write_unlock(&nm_i->nat_tree_lock);
> + }
> }
> +
> + if (to_journal)
> + mutex_unlock(&curseg->curseg_mutex);
> + else
> + f2fs_put_page(page, 1);
> +
> + release_nat_entry_set(nes, nm_i);
> }
> - if (!flushed)
> - mutex_unlock(&curseg->curseg_mutex);
> - f2fs_put_page(page, 1);
> +
> + f2fs_bug_on(!list_empty(head));
> + f2fs_bug_on(nm_i->dirty_nat_cnt);
> }
>
> static int init_node_manager(struct f2fs_sb_info *sbi)
> @@ -1894,6 +1973,7 @@ static int init_node_manager(struct f2fs_sb_info *sbi)
> INIT_RADIX_TREE(&nm_i->nat_root, GFP_ATOMIC);
> INIT_LIST_HEAD(&nm_i->nat_entries);
> INIT_LIST_HEAD(&nm_i->dirty_nat_entries);
> + INIT_LIST_HEAD(&nm_i->nat_entry_set);
>
> mutex_init(&nm_i->build_lock);
> spin_lock_init(&nm_i->free_nid_list_lock);
> @@ -1974,19 +2054,30 @@ int __init create_node_manager_caches(void)
> nat_entry_slab = f2fs_kmem_cache_create("nat_entry",
> sizeof(struct nat_entry));
> if (!nat_entry_slab)
> - return -ENOMEM;
> + goto fail;
>
> free_nid_slab = f2fs_kmem_cache_create("free_nid",
> sizeof(struct free_nid));
> - if (!free_nid_slab) {
> - kmem_cache_destroy(nat_entry_slab);
> - return -ENOMEM;
> - }
> + if (!free_nid_slab)
> + goto destory_nat_entry;
> +
> + nat_entry_set_slab = f2fs_kmem_cache_create("nat_entry_set",
> + sizeof(struct nat_entry_set));
> + if (!nat_entry_set_slab)
> + goto destory_free_nid;
> return 0;
> +
> +destory_free_nid:
> + kmem_cache_destroy(free_nid_slab);
> +destory_nat_entry:
> + kmem_cache_destroy(nat_entry_slab);
> +fail:
> + return -ENOMEM;
> }
>
> void destroy_node_manager_caches(void)
> {
> + kmem_cache_destroy(nat_entry_set_slab);
> kmem_cache_destroy(free_nid_slab);
> kmem_cache_destroy(nat_entry_slab);
> }
> diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h
> index 7281112..8a116a4 100644
> --- a/fs/f2fs/node.h
> +++ b/fs/f2fs/node.h
> @@ -89,6 +89,13 @@ enum mem_type {
> DIRTY_DENTS /* indicates dirty dentry pages */
> };
>
> +struct nat_entry_set {
> + struct list_head set_list; /* link with all nat sets */
> + struct list_head entry_list; /* link with dirty nat entries */
> + nid_t start_nid; /* start nid of nats in set */
> + unsigned int entry_cnt; /* the # of nat entries in set */
> +};
> +
> /*
> * For free nid mangement
> */
> --
> 1.7.9.5
--
Jaegeuk Kim
prev parent reply other threads:[~2014-06-23 21:40 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-20 9:41 [PATCH v2 RESEND] f2fs: refactor flush_nat_entries codes for reducing NAT writes Chao Yu
2014-06-20 9:41 ` [f2fs-dev] " Chao Yu
2014-06-23 21:40 ` Jaegeuk Kim [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140623214053.GA3088@jmac.local \
--to=jaegeuk@kernel.org \
--cc=chao2.yu@samsung.com \
--cc=cm224.lee@samsung.com \
--cc=linux-f2fs-devel@lists.sourceforge.net \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.