From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752975AbdJaNiL (ORCPT ); Tue, 31 Oct 2017 09:38:11 -0400 Received: from mailout2.samsung.com ([203.254.224.25]:40128 "EHLO mailout2.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751269AbdJaNiJ (ORCPT ); Tue, 31 Oct 2017 09:38:09 -0400 DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.samsung.com 20171031133806epoutp023d7f47d86876cd1e330ebfa88ac304c4~yqzkQw9KW3049530495epoutp02W X-AuditID: b6c32a47-cd7ff7000000102c-1c-59f87cbe1476 From: Fan Li To: "'Jaegeuk Kim'" , "'Chao Yu'" Cc: linux-kernel@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net Subject: [f2fs-dev] [PATCH] f2fs: modify the procedure of scan free nid Date: Tue, 31 Oct 2017 21:37:24 +0800 Message-id: <001401d3524d$7b411aa0$71c34fe0$@samsung.com> MIME-version: 1.0 Content-type: text/plain; charset="Windows-1252" Content-transfer-encoding: 7bit X-Mailer: Microsoft Outlook 14.0 Content-language: en-us Thread-index: AdNSTUO0DL6WsC6tSriyIRGrT6Z4eQ== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrJIsWRmVeSWpSXmKPExsWy7bCmhe6+mh+RBjfeKlqcnnqWyeLJ+lnM FpcWuVtc3jWHzYHFY9OqTjaP3Qs+M3l83iQXwBzFZZOSmpNZllqkb5fAlfHqaQt7wSK1inkT mpgaGF/LdTFyckgImEicWrGWuYuRi0NIYAejxO1vPUwQzndGibszljDBVB3ZdZkRIrGbUWLX g+csEM4rRonVT7sZQarYBNQltszsBusQEXCWOLV6GlARBwezgIfErmOlIGFhAXeJH0cawEpY BFQlvm7pZAexeQUsJe6vmMoKYQtK/Jh8jwXEZhYwkHj9awk7hC0vsXnNW2aIgxQkdpx9zQgR F5eY9OAhO8RaPYlJr6azgdwmITCHTeLNotlQDS4SM5o3s0PYwhKvjm+BsqUlnq3ayAhhr2OU +HzGAqJ5O6PEvI8fod63Btr8C+oKPomOw3/ZQR6TEOCV6GgTgigB+nH9MahyR4nTOxaDPSAk ECuxvuss+wRGuVlIfpuF5LdZSH6bheSfBYwsqxjFUguKc9NTi40KjPWKE3OLS/PS9ZLzczcx ghOElvsOxm3nfA4xCnAwKvHwOsR/jxRiTSwrrsw9xCjBwawkwste+iNSiDclsbIqtSg/vqg0 J7X4EKM0B4uSOG/dtmsRQgLpiSWp2ampBalFMFkmDk6pBkZ2X12FqQ/4VlcH1PQd/3S9WNM0 6IpY8kmbfx8C1dI5+9t2eMlW1Ov+udBxN+ve5zyOJ3/y5Yy3Tc29MVGXvevA+b7DgZX/Fz78 NOlTsaTjP8XHPElxexVXaXgKxErOcud+fKdX4fP9DezLk28w/Cxi2x4UcaG4SmjKdM9b2e9D GdQjfaMDlZRYijMSDbWYi4oTAeYgsTIMAwAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrKLMWRmVeSWpSXmKPExsVy+t9jAd19NT8iDX53s1qcnnqWyeLJ+lnM FpcWuVtc3jWHzYHFY9OqTjaP3Qs+M3l83iQXwBzFZZOSmpNZllqkb5fAlfHqaQt7wSK1inkT mpgaGF/LdTFyckgImEgc2XWZsYuRi0NIYCejxOJHL1ghnFeMErsbjzOBVLEJqEtsmdkNZosI OEucWj2NpYuRg4NZwENi17FSkLCwgLvEjyMNYCUsAqoSX7d0soPYvAKWEvdXTGWFsAUlfky+ xwJiMwvoSXz8c5sRwpaX2LzmLTPEQQoSO86+hoqLS0x68JAdYq2exKRX09kmMPLPQjJqFpJR s5CMmoWkfQEjyypGydSC4tz03GKjAqO81HK94sTc4tK8dL3k/NxNjMDA3XZYq38H4+Ml8YcY BTgYlXh4ZyR+jxRiTSwrrsw9xCjBwawkwste+iNSiDclsbIqtSg/vqg0J7X4EKM0B4uSOC9/ /rFIIYH0xJLU7NTUgtQimCwTB6dUA+Psvye7/7TNmL/82QozhbK/ra4mClXbpFf8ienIlT6b XGh1e0K3P7O1iauozs3XGdN8/Xd8qoguej/J+uRR32DWCZsTJ7+cx8n2cPMBxuBnH2YFJnQ4 Ggb9c/xt0DFHYi+TafsZPy+2hgmr+lc2uMhOmf9kReus9MfsS5sP/DSv0jC3PPb29wMlluKM REMt5qLiRAA8iveVWAIAAA== X-CMS-MailID: 20171031133806epcas2p3635a1d26726b94dd5f106d0171baaa74 X-Msg-Generator: CA CMS-TYPE: 102P X-CMS-RootMailID: 20171031133806epcas2p3635a1d26726b94dd5f106d0171baaa74 X-RootMTR: 20171031133806epcas2p3635a1d26726b94dd5f106d0171baaa74 References: Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In current version, we preserve 8 pages of nat blocks as free nids, build bitmaps for it and use them to allocate nids until its number drops below NAT_ENTRY_PER_BLOCK. After that, we have a problem, scan_free_nid_bits will scan the same 8 pages trying to find more free nids, but in most cases the free nids in these bitmaps are already in free list, scan them won't get us any new nids. Further more, after scan_free_nid_bits, the search is over if nid_cnt[FREE_NID] != 0. It causes that we scan the same pages over and over again, yet no new free nids are found until nid_cnt[FREE_NID]==0. This patch mark the range where new free nids could exist and keep scan for free nids until nid_cnt[FREE_NID] >= NAT_ENTRY_PER_BLOCK. The new vairable first_scan_block marks the start of the range, it's initialized with NEW_ADDR, which means all free nids before next_scan_nid are already in free list; and use next_scan_nid as the end of the range since all free nids which are scanned must be smaller next_scan_nid. Signed-off-by: Fan li --- fs/f2fs/f2fs.h | 1 + fs/f2fs/node.c | 30 ++++++++++++++++++++++++++---- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index e0ef31c..ae1cf91 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -705,6 +705,7 @@ struct f2fs_nm_info { nid_t max_nid; /* maximum possible node ids */ nid_t available_nids; /* # of available node ids */ nid_t next_scan_nid; /* the next nid to be scanned */ + block_t first_scan_block; /* the first NAT block to be scanned */ unsigned int ram_thresh; /* control the memory footprint */ unsigned int ra_nid_pages; /* # of nid pages to be readaheaded */ unsigned int dirty_nats_ratio; /* control dirty nats ratio threshold */ diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 3d0d1be..7834097 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -1950,10 +1950,23 @@ static void scan_free_nid_bits(struct f2fs_sb_info *sbi) struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA); struct f2fs_journal *journal = curseg->journal; unsigned int i, idx; + unsigned int max_blocks = NAT_BLOCK_OFFSET(nm_i->next_scan_nid); - down_read(&nm_i->nat_tree_lock); + /* every free nid in blocks scanned previously is in the free list */ + if (nm_i->first_scan_block == NEW_ADDR) + return; - for (i = 0; i < nm_i->nat_blocks; i++) { + /* + * TODO: "next_scan_nid == 0" means after searching every nat block, + * we still can't find enough free nids, there may not be any + * more nid left to be found, we should stop at somewhere + * instead of going through these all over again. + */ + if (max_blocks == 0) + max_blocks = nm_i->nat_blocks; + + down_read(&nm_i->nat_tree_lock); + for (i = nm_i->first_scan_block; i < max_blocks; i++) { if (!test_bit_le(i, nm_i->nat_block_bitmap)) continue; if (!nm_i->free_nid_count[i]) @@ -1967,10 +1980,13 @@ static void scan_free_nid_bits(struct f2fs_sb_info *sbi) nid = i * NAT_ENTRY_PER_BLOCK + idx; add_free_nid(sbi, nid, true); - if (nm_i->nid_cnt[FREE_NID] >= MAX_FREE_NIDS) + if (nm_i->nid_cnt[FREE_NID] >= MAX_FREE_NIDS) { + nm_i->first_scan_block = i; goto out; + } } } + nm_i->first_scan_block = NEW_ADDR; out: down_read(&curseg->journal_rwsem); for (i = 0; i < nats_in_cursum(journal); i++) { @@ -2010,7 +2026,7 @@ static void __build_free_nids(struct f2fs_sb_info *sbi, bool sync, bool mount) /* try to find free nids in free_nid_bitmap */ scan_free_nid_bits(sbi); - if (nm_i->nid_cnt[FREE_NID]) + if (nm_i->nid_cnt[FREE_NID] >= NAT_ENTRY_PER_BLOCK) return; } @@ -2163,6 +2179,7 @@ int try_to_free_nids(struct f2fs_sb_info *sbi, int nr_shrink) struct f2fs_nm_info *nm_i = NM_I(sbi); struct free_nid *i, *next; int nr = nr_shrink; + nid_t min_nid = nm_i->max_nid; if (nm_i->nid_cnt[FREE_NID] <= MAX_FREE_NIDS) return 0; @@ -2176,11 +2193,15 @@ int try_to_free_nids(struct f2fs_sb_info *sbi, int nr_shrink) nm_i->nid_cnt[FREE_NID] <= MAX_FREE_NIDS) break; + if (i->nid < min_nid) + min_nid = i->nid; __remove_free_nid(sbi, i, FREE_NID); kmem_cache_free(free_nid_slab, i); nr_shrink--; } spin_unlock(&nm_i->nid_list_lock); + if (min_nid != nm_i->max_nid) + nm_i->first_scan_block = NAT_BLOCK_OFFSET(min_nid); mutex_unlock(&nm_i->build_lock); return nr - nr_shrink; @@ -2674,6 +2695,7 @@ static int init_node_manager(struct f2fs_sb_info *sbi) init_rwsem(&nm_i->nat_tree_lock); nm_i->next_scan_nid = le32_to_cpu(sbi->ckpt->next_free_nid); + nm_i->first_scan_block = NEW_ADDR; nm_i->bitmap_size = __bitmap_size(sbi, NAT_BITMAP); version_bitmap = __bitmap_ptr(sbi, NAT_BITMAP); if (!version_bitmap) -- 2.7.4