Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 02b16d0a authored by Chao Yu's avatar Chao Yu Committed by Jaegeuk Kim
Browse files

f2fs: add to account direct IO



This patch adds f2fs_dio_submit_bio() to hook submit_io/end_io functions
in direct IO path, in order to account DIO.

Later, we will add this count into is_idle() to let background GC/Discard
thread be aware of DIO.

Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent b61ac5b7
Loading
Loading
Loading
Loading
+50 −1
Original line number Diff line number Diff line
@@ -2548,6 +2548,53 @@ static int check_direct_IO(struct inode *inode, struct iov_iter *iter,
	return 0;
}

static void f2fs_dio_end_io(struct bio *bio)
{
	struct f2fs_private_dio *dio = bio->bi_private;

	dec_page_count(F2FS_I_SB(dio->inode),
			dio->write ? F2FS_DIO_WRITE : F2FS_DIO_READ);

	bio->bi_private = dio->orig_private;
	bio->bi_end_io = dio->orig_end_io;

	kfree(dio);

	bio_endio(bio);
}

static void f2fs_dio_submit_bio(struct bio *bio, struct inode *inode,
							loff_t file_offset)
{
	struct f2fs_private_dio *dio;
	bool write = (bio_op(bio) == REQ_OP_WRITE);
	int err;

	dio = f2fs_kzalloc(F2FS_I_SB(inode),
			sizeof(struct f2fs_private_dio), GFP_NOFS);
	if (!dio) {
		err = -ENOMEM;
		goto out;
	}

	dio->inode = inode;
	dio->orig_end_io = bio->bi_end_io;
	dio->orig_private = bio->bi_private;
	dio->write = write;

	bio->bi_end_io = f2fs_dio_end_io;
	bio->bi_private = dio;

	inc_page_count(F2FS_I_SB(inode),
			write ? F2FS_DIO_WRITE : F2FS_DIO_READ);

	submit_bio(bio);
	return;
out:
	bio->bi_status = BLK_STS_IOERR;
	bio_endio(bio);
}

static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
{
	struct address_space *mapping = iocb->ki_filp->f_mapping;
@@ -2594,7 +2641,9 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
			down_read(&fi->i_gc_rwsem[READ]);
	}

	err = blockdev_direct_IO(iocb, inode, iter, get_data_block_dio);
	err = __blockdev_direct_IO(iocb, inode, inode->i_sb->s_bdev,
			iter, get_data_block_dio, NULL, f2fs_dio_submit_bio,
			DIO_LOCKING | DIO_SKIP_HOLES);

	if (do_opu)
		up_read(&fi->i_gc_rwsem[READ]);
+4 −0
Original line number Diff line number Diff line
@@ -53,6 +53,8 @@ static void update_general_status(struct f2fs_sb_info *sbi)
	si->vw_cnt = atomic_read(&sbi->vw_cnt);
	si->max_aw_cnt = atomic_read(&sbi->max_aw_cnt);
	si->max_vw_cnt = atomic_read(&sbi->max_vw_cnt);
	si->nr_dio_read = get_pages(sbi, F2FS_DIO_READ);
	si->nr_dio_write = get_pages(sbi, F2FS_DIO_WRITE);
	si->nr_wb_cp_data = get_pages(sbi, F2FS_WB_CP_DATA);
	si->nr_wb_data = get_pages(sbi, F2FS_WB_DATA);
	si->nr_rd_data = get_pages(sbi, F2FS_RD_DATA);
@@ -374,6 +376,8 @@ static int stat_show(struct seq_file *s, void *v)
		seq_printf(s, "  - Inner Struct Count: tree: %d(%d), node: %d\n",
				si->ext_tree, si->zombie_tree, si->ext_node);
		seq_puts(s, "\nBalancing F2FS Async:\n");
		seq_printf(s, "  - DIO (R: %4d, W: %4d)\n",
			   si->nr_dio_read, si->nr_dio_write);
		seq_printf(s, "  - IO_R (Data: %4d, Node: %4d, Meta: %4d\n",
			   si->nr_rd_data, si->nr_rd_node, si->nr_rd_meta);
		seq_printf(s, "  - IO_W (CP: %4d, Data: %4d, Flush: (%4d %4d %4d), "
+10 −0
Original line number Diff line number Diff line
@@ -957,6 +957,8 @@ enum count_type {
	F2FS_RD_DATA,
	F2FS_RD_NODE,
	F2FS_RD_META,
	F2FS_DIO_WRITE,
	F2FS_DIO_READ,
	NR_COUNT_TYPE,
};

@@ -1333,6 +1335,13 @@ struct f2fs_sb_info {
	__u32 s_chksum_seed;
};

struct f2fs_private_dio {
	struct inode *inode;
	void *orig_private;
	bio_end_io_t *orig_end_io;
	bool write;
};

#ifdef CONFIG_F2FS_FAULT_INJECTION
#define f2fs_show_injection_info(type)					\
	printk_ratelimited("%sF2FS-fs : inject %s in %s of %pF\n",	\
@@ -3152,6 +3161,7 @@ struct f2fs_stat_info {
	int total_count, utilization;
	int bg_gc, nr_wb_cp_data, nr_wb_data;
	int nr_rd_data, nr_rd_node, nr_rd_meta;
	int nr_dio_read, nr_dio_write;
	unsigned int io_skip_bggc, other_skip_bggc;
	int nr_flushing, nr_flushed, flush_list_empty;
	int nr_discarding, nr_discarded;