f2fs: detect congestion of flush command issues
authorJaegeuk Kim <jaegeuk@kernel.org>
Mon, 23 May 2016 19:04:56 +0000 (12:04 -0700)
committerJaegeuk Kim <jaegeuk@kernel.org>
Fri, 3 Jun 2016 01:05:15 +0000 (18:05 -0700)
If flush commands do not incur any congestion, we don't need to throw that to
dispatching queue which causes unnecessary latency.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/f2fs.h
fs/f2fs/segment.c

index bf1c8b0ef6c7386f13944d3135b0cc75037785fb..f02a3572fff3c4c6e2952e3d053f583b6656f6e4 100644 (file)
@@ -603,6 +603,7 @@ struct flush_cmd {
 struct flush_cmd_control {
        struct task_struct *f2fs_issue_flush;   /* flush thread */
        wait_queue_head_t flush_wait_queue;     /* waiting queue for wake-up */
+       atomic_t submit_flush;                  /* # of issued flushes */
        struct llist_head issue_list;           /* list for command issue */
        struct llist_node *dispatch_list;       /* list for command dispatch */
 };
index 77dc929715cff9c1362567a0a8fe239d0e5aaa12..34a9159cf5ac3f3dfc4d6930e7e8ef542ce96a6f 100644 (file)
@@ -433,24 +433,28 @@ int f2fs_issue_flush(struct f2fs_sb_info *sbi)
        if (test_opt(sbi, NOBARRIER))
                return 0;
 
-       if (!test_opt(sbi, FLUSH_MERGE)) {
+       if (!test_opt(sbi, FLUSH_MERGE) || !atomic_read(&fcc->submit_flush)) {
                struct bio *bio = f2fs_bio_alloc(0);
                int ret;
 
+               atomic_inc(&fcc->submit_flush);
                bio->bi_bdev = sbi->sb->s_bdev;
                ret = submit_bio_wait(WRITE_FLUSH, bio);
+               atomic_dec(&fcc->submit_flush);
                bio_put(bio);
                return ret;
        }
 
        init_completion(&cmd.wait);
 
+       atomic_inc(&fcc->submit_flush);
        llist_add(&cmd.llnode, &fcc->issue_list);
 
        if (!fcc->dispatch_list)
                wake_up(&fcc->flush_wait_queue);
 
        wait_for_completion(&cmd.wait);
+       atomic_dec(&fcc->submit_flush);
 
        return cmd.ret;
 }
@@ -464,6 +468,7 @@ int create_flush_cmd_control(struct f2fs_sb_info *sbi)
        fcc = kzalloc(sizeof(struct flush_cmd_control), GFP_KERNEL);
        if (!fcc)
                return -ENOMEM;
+       atomic_set(&fcc->submit_flush, 0);
        init_waitqueue_head(&fcc->flush_wait_queue);
        init_llist_head(&fcc->issue_list);
        SM_I(sbi)->cmd_control_info = fcc;