aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs/checkpoint.c
diff options
context:
space:
mode:
authorChao Yu <chao2.yu@samsung.com>2014-04-01 20:55:00 -0400
committerJaegeuk Kim <jaegeuk.kim@samsung.com>2014-04-01 20:56:12 -0400
commitcf0ee0f09bc09f54b9852dda1088b9cdcd4f8683 (patch)
tree2f816e75d32c40fbaff30fea217ace4bef0001f4 /fs/f2fs/checkpoint.c
parent6e452d69d421e10e99446c6de16a19604149c40f (diff)
f2fs: avoid free slab cache under spinlock
Move kmem_cache_free out of spinlock protection region for better performance. Change log from v1: o remove spinlock protection for kmem_cache_free in destroy_node_manager suggested by Jaegeuk Kim. Signed-off-by: Chao Yu <chao2.yu@samsung.com> Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
Diffstat (limited to 'fs/f2fs/checkpoint.c')
-rw-r--r--fs/f2fs/checkpoint.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index a80be5121e8a..d877f46c75ed 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -347,10 +347,11 @@ void remove_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
347 list_for_each_entry(orphan, head, list) { 347 list_for_each_entry(orphan, head, list) {
348 if (orphan->ino == ino) { 348 if (orphan->ino == ino) {
349 list_del(&orphan->list); 349 list_del(&orphan->list);
350 kmem_cache_free(orphan_entry_slab, orphan);
351 f2fs_bug_on(sbi->n_orphans == 0); 350 f2fs_bug_on(sbi->n_orphans == 0);
352 sbi->n_orphans--; 351 sbi->n_orphans--;
353 break; 352 spin_unlock(&sbi->orphan_inode_lock);
353 kmem_cache_free(orphan_entry_slab, orphan);
354 return;
354 } 355 }
355 } 356 }
356 spin_unlock(&sbi->orphan_inode_lock); 357 spin_unlock(&sbi->orphan_inode_lock);
@@ -577,6 +578,7 @@ void set_dirty_dir_page(struct inode *inode, struct page *page)
577{ 578{
578 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 579 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
579 struct dir_inode_entry *new; 580 struct dir_inode_entry *new;
581 int ret = 0;
580 582
581 if (!S_ISDIR(inode->i_mode)) 583 if (!S_ISDIR(inode->i_mode))
582 return; 584 return;
@@ -586,12 +588,13 @@ void set_dirty_dir_page(struct inode *inode, struct page *page)
586 INIT_LIST_HEAD(&new->list); 588 INIT_LIST_HEAD(&new->list);
587 589
588 spin_lock(&sbi->dir_inode_lock); 590 spin_lock(&sbi->dir_inode_lock);
589 if (__add_dirty_inode(inode, new)) 591 ret = __add_dirty_inode(inode, new);
590 kmem_cache_free(inode_entry_slab, new);
591
592 inode_inc_dirty_dents(inode); 592 inode_inc_dirty_dents(inode);
593 SetPagePrivate(page); 593 SetPagePrivate(page);
594 spin_unlock(&sbi->dir_inode_lock); 594 spin_unlock(&sbi->dir_inode_lock);
595
596 if (ret)
597 kmem_cache_free(inode_entry_slab, new);
595} 598}
596 599
597void add_dirty_dir_inode(struct inode *inode) 600void add_dirty_dir_inode(struct inode *inode)
@@ -599,20 +602,22 @@ void add_dirty_dir_inode(struct inode *inode)
599 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 602 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
600 struct dir_inode_entry *new = 603 struct dir_inode_entry *new =
601 f2fs_kmem_cache_alloc(inode_entry_slab, GFP_NOFS); 604 f2fs_kmem_cache_alloc(inode_entry_slab, GFP_NOFS);
605 int ret = 0;
602 606
603 new->inode = inode; 607 new->inode = inode;
604 INIT_LIST_HEAD(&new->list); 608 INIT_LIST_HEAD(&new->list);
605 609
606 spin_lock(&sbi->dir_inode_lock); 610 spin_lock(&sbi->dir_inode_lock);
607 if (__add_dirty_inode(inode, new)) 611 ret = __add_dirty_inode(inode, new);
608 kmem_cache_free(inode_entry_slab, new);
609 spin_unlock(&sbi->dir_inode_lock); 612 spin_unlock(&sbi->dir_inode_lock);
613
614 if (ret)
615 kmem_cache_free(inode_entry_slab, new);
610} 616}
611 617
612void remove_dirty_dir_inode(struct inode *inode) 618void remove_dirty_dir_inode(struct inode *inode)
613{ 619{
614 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 620 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
615
616 struct list_head *this, *head; 621 struct list_head *this, *head;
617 622
618 if (!S_ISDIR(inode->i_mode)) 623 if (!S_ISDIR(inode->i_mode))
@@ -630,13 +635,15 @@ void remove_dirty_dir_inode(struct inode *inode)
630 entry = list_entry(this, struct dir_inode_entry, list); 635 entry = list_entry(this, struct dir_inode_entry, list);
631 if (entry->inode == inode) { 636 if (entry->inode == inode) {
632 list_del(&entry->list); 637 list_del(&entry->list);
633 kmem_cache_free(inode_entry_slab, entry);
634 stat_dec_dirty_dir(sbi); 638 stat_dec_dirty_dir(sbi);
635 break; 639 spin_unlock(&sbi->dir_inode_lock);
640 kmem_cache_free(inode_entry_slab, entry);
641 goto done;
636 } 642 }
637 } 643 }
638 spin_unlock(&sbi->dir_inode_lock); 644 spin_unlock(&sbi->dir_inode_lock);
639 645
646done:
640 /* Only from the recovery routine */ 647 /* Only from the recovery routine */
641 if (is_inode_flag_set(F2FS_I(inode), FI_DELAY_IPUT)) { 648 if (is_inode_flag_set(F2FS_I(inode), FI_DELAY_IPUT)) {
642 clear_inode_flag(F2FS_I(inode), FI_DELAY_IPUT); 649 clear_inode_flag(F2FS_I(inode), FI_DELAY_IPUT);