diff options
author | Jaegeuk Kim <jaegeuk@kernel.org> | 2014-12-05 13:39:49 -0500 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2014-12-08 13:35:05 -0500 |
commit | 9be32d72becca41d7d9b010d7d9be1d39489414f (patch) | |
tree | 7ac34f8b38e3db9411a175b4e5f0ee810c57d7ef /fs/f2fs | |
parent | 769ec6e5b7d4a8115447736871be8bffaaba3a7d (diff) |
f2fs: do retry operations with cond_resched
This patch revists retrial paths in f2fs.
The basic idea is to use cond_resched instead of retrying from the very early
stage.
Suggested-by: Gu Zheng <guz.fnst@cn.fujitsu.com>
Reviewed-by: Chao Yu <chao2.yu@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs')
-rw-r--r-- | fs/f2fs/f2fs.h | 7 | ||||
-rw-r--r-- | fs/f2fs/gc.c | 5 | ||||
-rw-r--r-- | fs/f2fs/node.c | 41 | ||||
-rw-r--r-- | fs/f2fs/segment.c | 5 |
4 files changed, 20 insertions, 38 deletions
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index c87314099d26..c787fe302918 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
@@ -1021,6 +1021,13 @@ retry: | |||
1021 | return entry; | 1021 | return entry; |
1022 | } | 1022 | } |
1023 | 1023 | ||
1024 | static inline void f2fs_radix_tree_insert(struct radix_tree_root *root, | ||
1025 | unsigned long index, void *item) | ||
1026 | { | ||
1027 | while (radix_tree_insert(root, index, item)) | ||
1028 | cond_resched(); | ||
1029 | } | ||
1030 | |||
1024 | #define RAW_IS_INODE(p) ((p)->footer.nid == (p)->footer.ino) | 1031 | #define RAW_IS_INODE(p) ((p)->footer.nid == (p)->footer.ino) |
1025 | 1032 | ||
1026 | static inline bool IS_INODE(struct page *page) | 1033 | static inline bool IS_INODE(struct page *page) |
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 2c58c587a3c6..eec0933a4819 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c | |||
@@ -356,12 +356,11 @@ static void add_gc_inode(struct gc_inode_list *gc_list, struct inode *inode) | |||
356 | iput(inode); | 356 | iput(inode); |
357 | return; | 357 | return; |
358 | } | 358 | } |
359 | retry: | ||
360 | new_ie = f2fs_kmem_cache_alloc(winode_slab, GFP_NOFS); | 359 | new_ie = f2fs_kmem_cache_alloc(winode_slab, GFP_NOFS); |
361 | new_ie->inode = inode; | 360 | new_ie->inode = inode; |
362 | 361 | retry: | |
363 | if (radix_tree_insert(&gc_list->iroot, inode->i_ino, new_ie)) { | 362 | if (radix_tree_insert(&gc_list->iroot, inode->i_ino, new_ie)) { |
364 | kmem_cache_free(winode_slab, new_ie); | 363 | cond_resched(); |
365 | goto retry; | 364 | goto retry; |
366 | } | 365 | } |
367 | list_add_tail(&new_ie->list, &gc_list->ilist); | 366 | list_add_tail(&new_ie->list, &gc_list->ilist); |
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 8de4f555d530..f83326ca32ef 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c | |||
@@ -147,7 +147,7 @@ static void __set_nat_cache_dirty(struct f2fs_nm_info *nm_i, | |||
147 | 147 | ||
148 | if (get_nat_flag(ne, IS_DIRTY)) | 148 | if (get_nat_flag(ne, IS_DIRTY)) |
149 | return; | 149 | return; |
150 | retry: | 150 | |
151 | head = radix_tree_lookup(&nm_i->nat_set_root, set); | 151 | head = radix_tree_lookup(&nm_i->nat_set_root, set); |
152 | if (!head) { | 152 | if (!head) { |
153 | head = f2fs_kmem_cache_alloc(nat_entry_set_slab, GFP_ATOMIC); | 153 | head = f2fs_kmem_cache_alloc(nat_entry_set_slab, GFP_ATOMIC); |
@@ -156,11 +156,7 @@ retry: | |||
156 | INIT_LIST_HEAD(&head->set_list); | 156 | INIT_LIST_HEAD(&head->set_list); |
157 | head->set = set; | 157 | head->set = set; |
158 | head->entry_cnt = 0; | 158 | head->entry_cnt = 0; |
159 | 159 | f2fs_radix_tree_insert(&nm_i->nat_set_root, set, head); | |
160 | if (radix_tree_insert(&nm_i->nat_set_root, set, head)) { | ||
161 | kmem_cache_free(nat_entry_set_slab, head); | ||
162 | goto retry; | ||
163 | } | ||
164 | } | 160 | } |
165 | list_move_tail(&ne->list, &head->entry_list); | 161 | list_move_tail(&ne->list, &head->entry_list); |
166 | nm_i->dirty_nat_cnt++; | 162 | nm_i->dirty_nat_cnt++; |
@@ -238,13 +234,8 @@ static struct nat_entry *grab_nat_entry(struct f2fs_nm_info *nm_i, nid_t nid) | |||
238 | { | 234 | { |
239 | struct nat_entry *new; | 235 | struct nat_entry *new; |
240 | 236 | ||
241 | new = kmem_cache_alloc(nat_entry_slab, GFP_ATOMIC); | 237 | new = f2fs_kmem_cache_alloc(nat_entry_slab, GFP_ATOMIC); |
242 | if (!new) | 238 | f2fs_radix_tree_insert(&nm_i->nat_root, nid, new); |
243 | return NULL; | ||
244 | if (radix_tree_insert(&nm_i->nat_root, nid, new)) { | ||
245 | kmem_cache_free(nat_entry_slab, new); | ||
246 | return NULL; | ||
247 | } | ||
248 | memset(new, 0, sizeof(struct nat_entry)); | 239 | memset(new, 0, sizeof(struct nat_entry)); |
249 | nat_set_nid(new, nid); | 240 | nat_set_nid(new, nid); |
250 | nat_reset_flag(new); | 241 | nat_reset_flag(new); |
@@ -257,15 +248,11 @@ static void cache_nat_entry(struct f2fs_nm_info *nm_i, nid_t nid, | |||
257 | struct f2fs_nat_entry *ne) | 248 | struct f2fs_nat_entry *ne) |
258 | { | 249 | { |
259 | struct nat_entry *e; | 250 | struct nat_entry *e; |
260 | retry: | 251 | |
261 | down_write(&nm_i->nat_tree_lock); | 252 | down_write(&nm_i->nat_tree_lock); |
262 | e = __lookup_nat_cache(nm_i, nid); | 253 | e = __lookup_nat_cache(nm_i, nid); |
263 | if (!e) { | 254 | if (!e) { |
264 | e = grab_nat_entry(nm_i, nid); | 255 | e = grab_nat_entry(nm_i, nid); |
265 | if (!e) { | ||
266 | up_write(&nm_i->nat_tree_lock); | ||
267 | goto retry; | ||
268 | } | ||
269 | node_info_from_raw_nat(&e->ni, ne); | 256 | node_info_from_raw_nat(&e->ni, ne); |
270 | } | 257 | } |
271 | up_write(&nm_i->nat_tree_lock); | 258 | up_write(&nm_i->nat_tree_lock); |
@@ -276,15 +263,11 @@ static void set_node_addr(struct f2fs_sb_info *sbi, struct node_info *ni, | |||
276 | { | 263 | { |
277 | struct f2fs_nm_info *nm_i = NM_I(sbi); | 264 | struct f2fs_nm_info *nm_i = NM_I(sbi); |
278 | struct nat_entry *e; | 265 | struct nat_entry *e; |
279 | retry: | 266 | |
280 | down_write(&nm_i->nat_tree_lock); | 267 | down_write(&nm_i->nat_tree_lock); |
281 | e = __lookup_nat_cache(nm_i, ni->nid); | 268 | e = __lookup_nat_cache(nm_i, ni->nid); |
282 | if (!e) { | 269 | if (!e) { |
283 | e = grab_nat_entry(nm_i, ni->nid); | 270 | e = grab_nat_entry(nm_i, ni->nid); |
284 | if (!e) { | ||
285 | up_write(&nm_i->nat_tree_lock); | ||
286 | goto retry; | ||
287 | } | ||
288 | e->ni = *ni; | 271 | e->ni = *ni; |
289 | f2fs_bug_on(sbi, ni->blk_addr == NEW_ADDR); | 272 | f2fs_bug_on(sbi, ni->blk_addr == NEW_ADDR); |
290 | } else if (new_blkaddr == NEW_ADDR) { | 273 | } else if (new_blkaddr == NEW_ADDR) { |
@@ -1833,19 +1816,13 @@ static void remove_nats_in_journal(struct f2fs_sb_info *sbi) | |||
1833 | nid_t nid = le32_to_cpu(nid_in_journal(sum, i)); | 1816 | nid_t nid = le32_to_cpu(nid_in_journal(sum, i)); |
1834 | 1817 | ||
1835 | raw_ne = nat_in_journal(sum, i); | 1818 | raw_ne = nat_in_journal(sum, i); |
1836 | retry: | 1819 | |
1837 | down_write(&nm_i->nat_tree_lock); | 1820 | down_write(&nm_i->nat_tree_lock); |
1838 | ne = __lookup_nat_cache(nm_i, nid); | 1821 | ne = __lookup_nat_cache(nm_i, nid); |
1839 | if (ne) | ||
1840 | goto found; | ||
1841 | |||
1842 | ne = grab_nat_entry(nm_i, nid); | ||
1843 | if (!ne) { | 1822 | if (!ne) { |
1844 | up_write(&nm_i->nat_tree_lock); | 1823 | ne = grab_nat_entry(nm_i, nid); |
1845 | goto retry; | 1824 | node_info_from_raw_nat(&ne->ni, &raw_ne); |
1846 | } | 1825 | } |
1847 | node_info_from_raw_nat(&ne->ni, &raw_ne); | ||
1848 | found: | ||
1849 | __set_nat_cache_dirty(nm_i, ne); | 1826 | __set_nat_cache_dirty(nm_i, ne); |
1850 | up_write(&nm_i->nat_tree_lock); | 1827 | up_write(&nm_i->nat_tree_lock); |
1851 | } | 1828 | } |
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 9a33e34d26ce..c79d67e5045f 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c | |||
@@ -179,13 +179,13 @@ void register_inmem_page(struct inode *inode, struct page *page) | |||
179 | struct f2fs_inode_info *fi = F2FS_I(inode); | 179 | struct f2fs_inode_info *fi = F2FS_I(inode); |
180 | struct inmem_pages *new; | 180 | struct inmem_pages *new; |
181 | int err; | 181 | int err; |
182 | retry: | 182 | |
183 | new = f2fs_kmem_cache_alloc(inmem_entry_slab, GFP_NOFS); | 183 | new = f2fs_kmem_cache_alloc(inmem_entry_slab, GFP_NOFS); |
184 | 184 | ||
185 | /* add atomic page indices to the list */ | 185 | /* add atomic page indices to the list */ |
186 | new->page = page; | 186 | new->page = page; |
187 | INIT_LIST_HEAD(&new->list); | 187 | INIT_LIST_HEAD(&new->list); |
188 | 188 | retry: | |
189 | /* increase reference count with clean state */ | 189 | /* increase reference count with clean state */ |
190 | mutex_lock(&fi->inmem_lock); | 190 | mutex_lock(&fi->inmem_lock); |
191 | err = radix_tree_insert(&fi->inmem_root, page->index, new); | 191 | err = radix_tree_insert(&fi->inmem_root, page->index, new); |
@@ -195,7 +195,6 @@ retry: | |||
195 | return; | 195 | return; |
196 | } else if (err) { | 196 | } else if (err) { |
197 | mutex_unlock(&fi->inmem_lock); | 197 | mutex_unlock(&fi->inmem_lock); |
198 | kmem_cache_free(inmem_entry_slab, new); | ||
199 | goto retry; | 198 | goto retry; |
200 | } | 199 | } |
201 | get_page(page); | 200 | get_page(page); |