diff options
author | Tang Junhui <tang.junhui@zte.com.cn> | 2018-03-18 20:36:19 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2018-03-18 22:15:20 -0400 |
commit | bc082a55d25c837341709accaf11311c3a9af727 (patch) | |
tree | 4a3bf3286ad08651cda3698ceff5799d4b7d9b87 /drivers/md/bcache/request.c | |
parent | 7e027ca4b534b6b99a7c0471e13ba075ffa3f482 (diff) |
bcache: fix inaccurate io state for detached bcache devices
When we run IO in a detached device, and run iostat to shows IO status,
normally it will show like bellow (Omitted some fields):
Device: ... avgrq-sz avgqu-sz await r_await w_await svctm %util
sdd ... 15.89 0.53 1.82 0.20 2.23 1.81 52.30
bcache0 ... 15.89 115.42 0.00 0.00 0.00 2.40 69.60
but after IO stopped, there are still very big avgqu-sz and %util
values as bellow:
Device: ... avgrq-sz avgqu-sz await r_await w_await svctm %util
bcache0 ... 0 5326.32 0.00 0.00 0.00 0.00 100.10
The reason for this issue is that, only generic_start_io_acct() called
and no generic_end_io_acct() called for detached device in
cached_dev_make_request(). See the code:
//start generic_start_io_acct()
generic_start_io_acct(q, rw, bio_sectors(bio), &d->disk->part0);
if (cached_dev_get(dc)) {
//will callback generic_end_io_acct()
}
else {
//will not call generic_end_io_acct()
}
This patch calls generic_end_io_acct() in the end of IO for detached
devices, so we can show IO state correctly.
(Modified to use GFP_NOIO in kzalloc() by Coly Li)
Changelog:
v2: fix typo.
v1: the initial version.
Signed-off-by: Tang Junhui <tang.junhui@zte.com.cn>
Reviewed-by: Coly Li <colyli@suse.de>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Reviewed-by: Michael Lyle <mlyle@lyle.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/md/bcache/request.c')
-rw-r--r-- | drivers/md/bcache/request.c | 58 |
1 files changed, 51 insertions, 7 deletions
diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c index 7aca308bee5b..5c8ae69c8502 100644 --- a/drivers/md/bcache/request.c +++ b/drivers/md/bcache/request.c | |||
@@ -986,6 +986,55 @@ static void cached_dev_nodata(struct closure *cl) | |||
986 | continue_at(cl, cached_dev_bio_complete, NULL); | 986 | continue_at(cl, cached_dev_bio_complete, NULL); |
987 | } | 987 | } |
988 | 988 | ||
989 | struct detached_dev_io_private { | ||
990 | struct bcache_device *d; | ||
991 | unsigned long start_time; | ||
992 | bio_end_io_t *bi_end_io; | ||
993 | void *bi_private; | ||
994 | }; | ||
995 | |||
996 | static void detached_dev_end_io(struct bio *bio) | ||
997 | { | ||
998 | struct detached_dev_io_private *ddip; | ||
999 | |||
1000 | ddip = bio->bi_private; | ||
1001 | bio->bi_end_io = ddip->bi_end_io; | ||
1002 | bio->bi_private = ddip->bi_private; | ||
1003 | |||
1004 | generic_end_io_acct(ddip->d->disk->queue, | ||
1005 | bio_data_dir(bio), | ||
1006 | &ddip->d->disk->part0, ddip->start_time); | ||
1007 | |||
1008 | kfree(ddip); | ||
1009 | |||
1010 | bio->bi_end_io(bio); | ||
1011 | } | ||
1012 | |||
1013 | static void detached_dev_do_request(struct bcache_device *d, struct bio *bio) | ||
1014 | { | ||
1015 | struct detached_dev_io_private *ddip; | ||
1016 | struct cached_dev *dc = container_of(d, struct cached_dev, disk); | ||
1017 | |||
1018 | /* | ||
1019 | * no need to call closure_get(&dc->disk.cl), | ||
1020 | * because upper layer had already opened bcache device, | ||
1021 | * which would call closure_get(&dc->disk.cl) | ||
1022 | */ | ||
1023 | ddip = kzalloc(sizeof(struct detached_dev_io_private), GFP_NOIO); | ||
1024 | ddip->d = d; | ||
1025 | ddip->start_time = jiffies; | ||
1026 | ddip->bi_end_io = bio->bi_end_io; | ||
1027 | ddip->bi_private = bio->bi_private; | ||
1028 | bio->bi_end_io = detached_dev_end_io; | ||
1029 | bio->bi_private = ddip; | ||
1030 | |||
1031 | if ((bio_op(bio) == REQ_OP_DISCARD) && | ||
1032 | !blk_queue_discard(bdev_get_queue(dc->bdev))) | ||
1033 | bio->bi_end_io(bio); | ||
1034 | else | ||
1035 | generic_make_request(bio); | ||
1036 | } | ||
1037 | |||
989 | /* Cached devices - read & write stuff */ | 1038 | /* Cached devices - read & write stuff */ |
990 | 1039 | ||
991 | static blk_qc_t cached_dev_make_request(struct request_queue *q, | 1040 | static blk_qc_t cached_dev_make_request(struct request_queue *q, |
@@ -1028,13 +1077,8 @@ static blk_qc_t cached_dev_make_request(struct request_queue *q, | |||
1028 | else | 1077 | else |
1029 | cached_dev_read(dc, s); | 1078 | cached_dev_read(dc, s); |
1030 | } | 1079 | } |
1031 | } else { | 1080 | } else |
1032 | if ((bio_op(bio) == REQ_OP_DISCARD) && | 1081 | detached_dev_do_request(d, bio); |
1033 | !blk_queue_discard(bdev_get_queue(dc->bdev))) | ||
1034 | bio_endio(bio); | ||
1035 | else | ||
1036 | generic_make_request(bio); | ||
1037 | } | ||
1038 | 1082 | ||
1039 | return BLK_QC_T_NONE; | 1083 | return BLK_QC_T_NONE; |
1040 | } | 1084 | } |